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);
59 bool isReorder() const { return Reorder; }
60 void setReorder() { Reorder = true; }
61 void setNoReorder() { Reorder = false; }
63 bool isMacro() const { return Macro; }
64 void setMacro() { Macro = true; }
65 void setNoMacro() { Macro = false; }
67 uint64_t getFeatures() const { return Features; }
68 void setFeatures(uint64_t Features_) { Features = Features_; }
70 // Set of features that are either architecture features or referenced
71 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
72 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
73 // The reason we need this mask is explained in the selectArch function.
74 // FIXME: Ideally we would like TableGen to generate this information.
75 static const FeatureBitset AllArchRelatedMask;
85 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
86 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
87 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
88 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
89 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
90 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
91 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
92 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
93 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
97 class MipsAsmParser : public MCTargetAsmParser {
98 MipsTargetStreamer &getTargetStreamer() {
99 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
100 return static_cast<MipsTargetStreamer &>(TS);
103 MCSubtargetInfo &STI;
105 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
106 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
107 // nullptr, which indicates that no function is currently
108 // selected. This usually happens after an '.end func'
111 // Print a warning along with its fix-it message at the given range.
112 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
113 SMRange Range, bool ShowColors = true);
115 #define GET_ASSEMBLER_HEADER
116 #include "MipsGenAsmMatcher.inc"
118 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
120 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
121 OperandVector &Operands, MCStreamer &Out,
123 bool MatchingInlineAsm) override;
125 /// Parse a register as used in CFI directives
126 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
128 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
130 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
132 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
133 SMLoc NameLoc, OperandVector &Operands) override;
135 bool ParseDirective(AsmToken DirectiveID) override;
137 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
139 MipsAsmParser::OperandMatchResultTy
140 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
141 StringRef Identifier, SMLoc S);
143 MipsAsmParser::OperandMatchResultTy
144 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
148 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
150 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
152 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy
157 parseRegisterPair (OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseMovePRegPair(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterList (OperandVector &Operands);
165 bool searchSymbolAlias(OperandVector &Operands);
167 bool parseOperand(OperandVector &, StringRef Mnemonic);
169 bool needsExpansion(MCInst &Inst);
171 // Expands assembly pseudo instructions.
172 // Returns false on success, true otherwise.
173 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
174 SmallVectorImpl<MCInst> &Instructions);
176 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
187 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
188 SmallVectorImpl<MCInst> &Instructions);
190 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
197 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
198 SmallVectorImpl<MCInst> &Instructions);
200 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 bool reportParseError(Twine ErrorMsg);
204 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
206 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
207 bool parseRelocOperand(const MCExpr *&Res);
209 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
211 bool isEvaluated(const MCExpr *Expr);
212 bool parseSetMips0Directive();
213 bool parseSetArchDirective();
214 bool parseSetFeature(uint64_t Feature);
215 bool parseDirectiveCpLoad(SMLoc Loc);
216 bool parseDirectiveCPSetup();
217 bool parseDirectiveNaN();
218 bool parseDirectiveSet();
219 bool parseDirectiveOption();
221 bool parseSetAtDirective();
222 bool parseSetNoAtDirective();
223 bool parseSetMacroDirective();
224 bool parseSetNoMacroDirective();
225 bool parseSetMsaDirective();
226 bool parseSetNoMsaDirective();
227 bool parseSetNoDspDirective();
228 bool parseSetReorderDirective();
229 bool parseSetNoReorderDirective();
230 bool parseSetMips16Directive();
231 bool parseSetNoMips16Directive();
232 bool parseSetFpDirective();
233 bool parseSetPopDirective();
234 bool parseSetPushDirective();
236 bool parseSetAssignment();
238 bool parseDataDirective(unsigned Size, SMLoc L);
239 bool parseDirectiveGpWord();
240 bool parseDirectiveGpDWord();
241 bool parseDirectiveModule();
242 bool parseDirectiveModuleFP();
243 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
244 StringRef Directive);
246 bool parseInternalDirectiveReallowModule();
248 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
250 bool eatComma(StringRef ErrorStr);
252 int matchCPURegisterName(StringRef Symbol);
254 int matchHWRegsRegisterName(StringRef Symbol);
256 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
258 int matchFPURegisterName(StringRef Name);
260 int matchFCCRegisterName(StringRef Name);
262 int matchACRegisterName(StringRef Name);
264 int matchMSA128RegisterName(StringRef Name);
266 int matchMSA128CtrlRegisterName(StringRef Name);
268 unsigned getReg(int RC, int RegNo);
270 unsigned getGPR(int RegNo);
272 int getATReg(SMLoc Loc);
274 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
275 SmallVectorImpl<MCInst> &Instructions);
277 // Helper function that checks if the value of a vector index is within the
278 // boundaries of accepted values for each RegisterKind
279 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
280 bool validateMSAIndex(int Val, int RegKind);
282 // Selects a new architecture by updating the FeatureBits with the necessary
283 // info including implied dependencies.
284 // Internally, it clears all the feature bits related to *any* architecture
285 // and selects the new one using the ToggleFeature functionality of the
286 // MCSubtargetInfo object that handles implied dependencies. The reason we
287 // clear all the arch related bits manually is because ToggleFeature only
288 // clears the features that imply the feature being cleared and not the
289 // features implied by the feature being cleared. This is easier to see
291 // --------------------------------------------------
292 // | Feature | Implies |
293 // | -------------------------------------------------|
294 // | FeatureMips1 | None |
295 // | FeatureMips2 | FeatureMips1 |
296 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
297 // | FeatureMips4 | FeatureMips3 |
299 // --------------------------------------------------
301 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
302 // FeatureMipsGP64 | FeatureMips1)
303 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
304 void selectArch(StringRef ArchFeature) {
305 FeatureBitset FeatureBits = STI.getFeatureBits();
306 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
307 STI.setFeatureBits(FeatureBits);
308 setAvailableFeatures(
309 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
310 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
313 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
314 if (!(STI.getFeatureBits()[Feature])) {
315 setAvailableFeatures(
316 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
318 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
321 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
322 if (STI.getFeatureBits()[Feature]) {
323 setAvailableFeatures(
324 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
326 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
330 enum MipsMatchResultTy {
331 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
332 #define GET_OPERAND_DIAGNOSTIC_TYPES
333 #include "MipsGenAsmMatcher.inc"
334 #undef GET_OPERAND_DIAGNOSTIC_TYPES
338 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
339 const MCInstrInfo &MII, const MCTargetOptions &Options)
340 : MCTargetAsmParser(), STI(sti),
341 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
342 sti.getCPU(), Options)) {
343 MCAsmParserExtension::Initialize(parser);
345 // Initialize the set of available features.
346 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
348 // Remember the initial assembler options. The user can not modify these.
349 AssemblerOptions.push_back(
350 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
352 // Create an assembler options environment for the user to modify.
353 AssemblerOptions.push_back(
354 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
356 getTargetStreamer().updateABIInfo(*this);
358 if (!isABI_O32() && !useOddSPReg() != 0)
359 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
364 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
365 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
367 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
368 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
369 const MipsABIInfo &getABI() const { return ABI; }
370 bool isABI_N32() const { return ABI.IsN32(); }
371 bool isABI_N64() const { return ABI.IsN64(); }
372 bool isABI_O32() const { return ABI.IsO32(); }
373 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
375 bool useOddSPReg() const {
376 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
379 bool inMicroMipsMode() const {
380 return STI.getFeatureBits()[Mips::FeatureMicroMips];
382 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
383 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
384 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
385 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
386 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
387 bool hasMips32() const {
388 return STI.getFeatureBits()[Mips::FeatureMips32];
390 bool hasMips64() const {
391 return STI.getFeatureBits()[Mips::FeatureMips64];
393 bool hasMips32r2() const {
394 return STI.getFeatureBits()[Mips::FeatureMips32r2];
396 bool hasMips64r2() const {
397 return STI.getFeatureBits()[Mips::FeatureMips64r2];
399 bool hasMips32r3() const {
400 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
402 bool hasMips64r3() const {
403 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
405 bool hasMips32r5() const {
406 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
408 bool hasMips64r5() const {
409 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
411 bool hasMips32r6() const {
412 return STI.getFeatureBits()[Mips::FeatureMips32r6];
414 bool hasMips64r6() const {
415 return STI.getFeatureBits()[Mips::FeatureMips64r6];
418 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
419 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
420 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
421 bool hasCnMips() const {
422 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
425 bool inMips16Mode() const {
426 return STI.getFeatureBits()[Mips::FeatureMips16];
428 // TODO: see how can we get this info.
429 bool abiUsesSoftFloat() const { return false; }
431 /// Warn if RegNo is the current assembler temporary.
432 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
438 /// MipsOperand - Instances of this class represent a parsed Mips machine
440 class MipsOperand : public MCParsedAsmOperand {
442 /// Broad categories of register classes
443 /// The exact class is finalized by the render method.
445 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
446 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
448 RegKind_FCC = 4, /// FCC
449 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
450 RegKind_MSACtrl = 16, /// MSA control registers
451 RegKind_COP2 = 32, /// COP2
452 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
454 RegKind_CCR = 128, /// CCR
455 RegKind_HWRegs = 256, /// HWRegs
456 RegKind_COP3 = 512, /// COP3
458 /// Potentially any (e.g. $1)
459 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
460 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
461 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
466 k_Immediate, /// An immediate (possibly involving symbol references)
467 k_Memory, /// Base + Offset Memory Address
468 k_PhysRegister, /// A physical register from the Mips namespace
469 k_RegisterIndex, /// A register index in one or more RegKind.
470 k_Token, /// A simple token
471 k_RegList, /// A physical register list
472 k_RegPair /// A pair of physical register
476 MipsOperand(KindTy K, MipsAsmParser &Parser)
477 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
480 /// For diagnostics, and checking the assembler temporary
481 MipsAsmParser &AsmParser;
489 unsigned Num; /// Register Number
493 unsigned Index; /// Index into the register class
494 RegKind Kind; /// Bitfield of the kinds it could possibly be
495 const MCRegisterInfo *RegInfo;
508 SmallVector<unsigned, 10> *List;
513 struct PhysRegOp PhysReg;
514 struct RegIdxOp RegIdx;
517 struct RegListOp RegList;
520 SMLoc StartLoc, EndLoc;
522 /// Internal constructor for register kinds
523 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
524 const MCRegisterInfo *RegInfo,
526 MipsAsmParser &Parser) {
527 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
528 Op->RegIdx.Index = Index;
529 Op->RegIdx.RegInfo = RegInfo;
530 Op->RegIdx.Kind = RegKind;
537 /// Coerce the register to GPR32 and return the real register for the current
539 unsigned getGPR32Reg() const {
540 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
541 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
542 unsigned ClassID = Mips::GPR32RegClassID;
543 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
546 /// Coerce the register to GPR32 and return the real register for the current
548 unsigned getGPRMM16Reg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
550 unsigned ClassID = Mips::GPR32RegClassID;
551 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
554 /// Coerce the register to GPR64 and return the real register for the current
556 unsigned getGPR64Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
558 unsigned ClassID = Mips::GPR64RegClassID;
559 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
563 /// Coerce the register to AFGR64 and return the real register for the current
565 unsigned getAFGR64Reg() const {
566 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
567 if (RegIdx.Index % 2 != 0)
568 AsmParser.Warning(StartLoc, "Float register should be even.");
569 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
570 .getRegister(RegIdx.Index / 2);
573 /// Coerce the register to FGR64 and return the real register for the current
575 unsigned getFGR64Reg() const {
576 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
577 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
578 .getRegister(RegIdx.Index);
581 /// Coerce the register to FGR32 and return the real register for the current
583 unsigned getFGR32Reg() const {
584 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
585 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
586 .getRegister(RegIdx.Index);
589 /// Coerce the register to FGRH32 and return the real register for the current
591 unsigned getFGRH32Reg() const {
592 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
593 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
594 .getRegister(RegIdx.Index);
597 /// Coerce the register to FCC and return the real register for the current
599 unsigned getFCCReg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
601 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
602 .getRegister(RegIdx.Index);
605 /// Coerce the register to MSA128 and return the real register for the current
607 unsigned getMSA128Reg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
609 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
611 unsigned ClassID = Mips::MSA128BRegClassID;
612 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
615 /// Coerce the register to MSACtrl and return the real register for the
617 unsigned getMSACtrlReg() const {
618 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
619 unsigned ClassID = Mips::MSACtrlRegClassID;
620 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
623 /// Coerce the register to COP2 and return the real register for the
625 unsigned getCOP2Reg() const {
626 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
627 unsigned ClassID = Mips::COP2RegClassID;
628 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
631 /// Coerce the register to COP3 and return the real register for the
633 unsigned getCOP3Reg() const {
634 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
635 unsigned ClassID = Mips::COP3RegClassID;
636 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 /// Coerce the register to ACC64DSP and return the real register for the
641 unsigned getACC64DSPReg() const {
642 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
643 unsigned ClassID = Mips::ACC64DSPRegClassID;
644 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 /// Coerce the register to HI32DSP and return the real register for the
649 unsigned getHI32DSPReg() const {
650 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
651 unsigned ClassID = Mips::HI32DSPRegClassID;
652 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
655 /// Coerce the register to LO32DSP and return the real register for the
657 unsigned getLO32DSPReg() const {
658 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
659 unsigned ClassID = Mips::LO32DSPRegClassID;
660 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
663 /// Coerce the register to CCR and return the real register for the
665 unsigned getCCRReg() const {
666 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
667 unsigned ClassID = Mips::CCRRegClassID;
668 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
671 /// Coerce the register to HWRegs and return the real register for the
673 unsigned getHWRegsReg() const {
674 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
675 unsigned ClassID = Mips::HWRegsRegClassID;
676 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
680 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
681 // Add as immediate when possible. Null MCExpr = 0.
683 Inst.addOperand(MCOperand::CreateImm(0));
684 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
685 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
687 Inst.addOperand(MCOperand::CreateExpr(Expr));
690 void addRegOperands(MCInst &Inst, unsigned N) const {
691 llvm_unreachable("Use a custom parser instead");
694 /// Render the operand to an MCInst as a GPR32
695 /// Asserts if the wrong number of operands are requested, or the operand
696 /// is not a k_RegisterIndex compatible with RegKind_GPR
697 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
698 assert(N == 1 && "Invalid number of operands!");
699 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
702 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
703 assert(N == 1 && "Invalid number of operands!");
704 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
707 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
708 assert(N == 1 && "Invalid number of operands!");
709 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
712 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
713 assert(N == 1 && "Invalid number of operands!");
714 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
717 /// Render the operand to an MCInst as a GPR64
718 /// Asserts if the wrong number of operands are requested, or the operand
719 /// is not a k_RegisterIndex compatible with RegKind_GPR
720 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
725 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
726 assert(N == 1 && "Invalid number of operands!");
727 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
730 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
731 assert(N == 1 && "Invalid number of operands!");
732 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
735 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
736 assert(N == 1 && "Invalid number of operands!");
737 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
738 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
739 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
740 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
744 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
749 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
754 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
759 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
764 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
769 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
770 assert(N == 1 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
774 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
779 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
784 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
785 assert(N == 1 && "Invalid number of operands!");
786 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
789 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
794 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
799 void addImmOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 const MCExpr *Expr = getImm();
805 void addMemOperands(MCInst &Inst, unsigned N) const {
806 assert(N == 2 && "Invalid number of operands!");
808 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
810 const MCExpr *Expr = getMemOff();
814 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
815 assert(N == 2 && "Invalid number of operands!");
817 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
819 const MCExpr *Expr = getMemOff();
823 void addRegListOperands(MCInst &Inst, unsigned N) const {
824 assert(N == 1 && "Invalid number of operands!");
826 for (auto RegNo : getRegList())
827 Inst.addOperand(MCOperand::CreateReg(RegNo));
830 void addRegPairOperands(MCInst &Inst, unsigned N) const {
831 assert(N == 2 && "Invalid number of operands!");
832 unsigned RegNo = getRegPair();
833 Inst.addOperand(MCOperand::CreateReg(RegNo++));
834 Inst.addOperand(MCOperand::CreateReg(RegNo));
837 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 2 && "Invalid number of operands!");
839 for (auto RegNo : getRegList())
840 Inst.addOperand(MCOperand::CreateReg(RegNo));
843 bool isReg() const override {
844 // As a special case until we sort out the definition of div/divu, pretend
845 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
846 if (isGPRAsmReg() && RegIdx.Index == 0)
849 return Kind == k_PhysRegister;
851 bool isRegIdx() const { return Kind == k_RegisterIndex; }
852 bool isImm() const override { return Kind == k_Immediate; }
853 bool isConstantImm() const {
854 return isImm() && dyn_cast<MCConstantExpr>(getImm());
856 bool isToken() const override {
857 // Note: It's not possible to pretend that other operand kinds are tokens.
858 // The matcher emitter checks tokens first.
859 return Kind == k_Token;
861 bool isMem() const override { return Kind == k_Memory; }
862 bool isConstantMemOff() const {
863 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
865 template <unsigned Bits> bool isMemWithSimmOffset() const {
866 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
868 bool isMemWithGRPMM16Base() const {
869 return isMem() && getMemBase()->isMM16AsmReg();
871 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
872 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
873 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
875 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
876 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
877 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
878 && (getMemBase()->getGPR32Reg() == Mips::SP);
880 bool isRegList16() const {
884 int Size = RegList.List->size();
885 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
886 RegList.List->back() != Mips::RA)
889 int PrevReg = *RegList.List->begin();
890 for (int i = 1; i < Size - 1; i++) {
891 int Reg = (*(RegList.List))[i];
892 if ( Reg != PrevReg + 1)
899 bool isInvNum() const { return Kind == k_Immediate; }
900 bool isLSAImm() const {
901 if (!isConstantImm())
903 int64_t Val = getConstantImm();
904 return 1 <= Val && Val <= 4;
906 bool isRegList() const { return Kind == k_RegList; }
907 bool isMovePRegPair() const {
908 if (Kind != k_RegList || RegList.List->size() != 2)
911 unsigned R0 = RegList.List->front();
912 unsigned R1 = RegList.List->back();
914 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
915 (R0 == Mips::A1 && R1 == Mips::A3) ||
916 (R0 == Mips::A2 && R1 == Mips::A3) ||
917 (R0 == Mips::A0 && R1 == Mips::S5) ||
918 (R0 == Mips::A0 && R1 == Mips::S6) ||
919 (R0 == Mips::A0 && R1 == Mips::A1) ||
920 (R0 == Mips::A0 && R1 == Mips::A2) ||
921 (R0 == Mips::A0 && R1 == Mips::A3))
927 StringRef getToken() const {
928 assert(Kind == k_Token && "Invalid access!");
929 return StringRef(Tok.Data, Tok.Length);
931 bool isRegPair() const { return Kind == k_RegPair; }
933 unsigned getReg() const override {
934 // As a special case until we sort out the definition of div/divu, pretend
935 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
936 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
937 RegIdx.Kind & RegKind_GPR)
938 return getGPR32Reg(); // FIXME: GPR64 too
940 assert(Kind == k_PhysRegister && "Invalid access!");
944 const MCExpr *getImm() const {
945 assert((Kind == k_Immediate) && "Invalid access!");
949 int64_t getConstantImm() const {
950 const MCExpr *Val = getImm();
951 return static_cast<const MCConstantExpr *>(Val)->getValue();
954 MipsOperand *getMemBase() const {
955 assert((Kind == k_Memory) && "Invalid access!");
959 const MCExpr *getMemOff() const {
960 assert((Kind == k_Memory) && "Invalid access!");
964 int64_t getConstantMemOff() const {
965 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
968 const SmallVectorImpl<unsigned> &getRegList() const {
969 assert((Kind == k_RegList) && "Invalid access!");
970 return *(RegList.List);
973 unsigned getRegPair() const {
974 assert((Kind == k_RegPair) && "Invalid access!");
978 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
979 MipsAsmParser &Parser) {
980 auto Op = make_unique<MipsOperand>(k_Token, Parser);
981 Op->Tok.Data = Str.data();
982 Op->Tok.Length = Str.size();
988 /// Create a numeric register (e.g. $1). The exact register remains
989 /// unresolved until an instruction successfully matches
990 static std::unique_ptr<MipsOperand>
991 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
992 SMLoc E, MipsAsmParser &Parser) {
993 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
994 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
997 /// Create a register that is definitely a GPR.
998 /// This is typically only used for named registers such as $gp.
999 static std::unique_ptr<MipsOperand>
1000 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1001 MipsAsmParser &Parser) {
1002 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1005 /// Create a register that is definitely a FGR.
1006 /// This is typically only used for named registers such as $f0.
1007 static std::unique_ptr<MipsOperand>
1008 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1009 MipsAsmParser &Parser) {
1010 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1013 /// Create a register that is definitely a HWReg.
1014 /// This is typically only used for named registers such as $hwr_cpunum.
1015 static std::unique_ptr<MipsOperand>
1016 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1017 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1018 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1021 /// Create a register that is definitely an FCC.
1022 /// This is typically only used for named registers such as $fcc0.
1023 static std::unique_ptr<MipsOperand>
1024 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1025 MipsAsmParser &Parser) {
1026 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1029 /// Create a register that is definitely an ACC.
1030 /// This is typically only used for named registers such as $ac0.
1031 static std::unique_ptr<MipsOperand>
1032 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1033 MipsAsmParser &Parser) {
1034 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1037 /// Create a register that is definitely an MSA128.
1038 /// This is typically only used for named registers such as $w0.
1039 static std::unique_ptr<MipsOperand>
1040 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1041 SMLoc E, MipsAsmParser &Parser) {
1042 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1045 /// Create a register that is definitely an MSACtrl.
1046 /// This is typically only used for named registers such as $msaaccess.
1047 static std::unique_ptr<MipsOperand>
1048 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1049 SMLoc E, MipsAsmParser &Parser) {
1050 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1053 static std::unique_ptr<MipsOperand>
1054 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1055 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1062 static std::unique_ptr<MipsOperand>
1063 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1064 SMLoc E, MipsAsmParser &Parser) {
1065 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1066 Op->Mem.Base = Base.release();
1073 static std::unique_ptr<MipsOperand>
1074 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1075 MipsAsmParser &Parser) {
1076 assert (Regs.size() > 0 && "Empty list not allowed");
1078 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1079 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1080 Op->StartLoc = StartLoc;
1081 Op->EndLoc = EndLoc;
1085 static std::unique_ptr<MipsOperand>
1086 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1087 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1088 Op->RegIdx.Index = RegNo;
1094 bool isGPRAsmReg() const {
1095 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1097 bool isMM16AsmReg() const {
1098 if (!(isRegIdx() && RegIdx.Kind))
1100 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1101 || RegIdx.Index == 16 || RegIdx.Index == 17);
1103 bool isMM16AsmRegZero() const {
1104 if (!(isRegIdx() && RegIdx.Kind))
1106 return (RegIdx.Index == 0 ||
1107 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1108 RegIdx.Index == 17);
1110 bool isMM16AsmRegMoveP() const {
1111 if (!(isRegIdx() && RegIdx.Kind))
1113 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1114 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1116 bool isFGRAsmReg() const {
1117 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1118 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1120 bool isHWRegsAsmReg() const {
1121 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1123 bool isCCRAsmReg() const {
1124 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1126 bool isFCCAsmReg() const {
1127 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1129 if (!AsmParser.hasEightFccRegisters())
1130 return RegIdx.Index == 0;
1131 return RegIdx.Index <= 7;
1133 bool isACCAsmReg() const {
1134 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1136 bool isCOP2AsmReg() const {
1137 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1139 bool isCOP3AsmReg() const {
1140 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1142 bool isMSA128AsmReg() const {
1143 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1145 bool isMSACtrlAsmReg() const {
1146 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1149 /// getStartLoc - Get the location of the first token of this operand.
1150 SMLoc getStartLoc() const override { return StartLoc; }
1151 /// getEndLoc - Get the location of the last token of this operand.
1152 SMLoc getEndLoc() const override { return EndLoc; }
1154 virtual ~MipsOperand() {
1162 delete RegList.List;
1163 case k_PhysRegister:
1164 case k_RegisterIndex:
1171 void print(raw_ostream &OS) const override {
1180 Mem.Base->print(OS);
1185 case k_PhysRegister:
1186 OS << "PhysReg<" << PhysReg.Num << ">";
1188 case k_RegisterIndex:
1189 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1196 for (auto Reg : (*RegList.List))
1201 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1205 }; // class MipsOperand
1209 extern const MCInstrDesc MipsInsts[];
1211 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1212 return MipsInsts[Opcode];
1215 static bool hasShortDelaySlot(unsigned Opcode) {
1218 case Mips::JALRS_MM:
1219 case Mips::JALRS16_MM:
1220 case Mips::BGEZALS_MM:
1221 case Mips::BLTZALS_MM:
1228 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1229 SmallVectorImpl<MCInst> &Instructions) {
1230 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1234 if (MCID.isBranch() || MCID.isCall()) {
1235 const unsigned Opcode = Inst.getOpcode();
1245 assert(hasCnMips() && "instruction only valid for octeon cpus");
1252 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1253 Offset = Inst.getOperand(2);
1254 if (!Offset.isImm())
1255 break; // We'll deal with this situation later on when applying fixups.
1256 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1257 return Error(IDLoc, "branch target out of range");
1258 if (OffsetToAlignment(Offset.getImm(),
1259 1LL << (inMicroMipsMode() ? 1 : 2)))
1260 return Error(IDLoc, "branch to misaligned address");
1274 case Mips::BGEZAL_MM:
1275 case Mips::BLTZAL_MM:
1278 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1279 Offset = Inst.getOperand(1);
1280 if (!Offset.isImm())
1281 break; // We'll deal with this situation later on when applying fixups.
1282 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1283 return Error(IDLoc, "branch target out of range");
1284 if (OffsetToAlignment(Offset.getImm(),
1285 1LL << (inMicroMipsMode() ? 1 : 2)))
1286 return Error(IDLoc, "branch to misaligned address");
1288 case Mips::BEQZ16_MM:
1289 case Mips::BNEZ16_MM:
1290 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1291 Offset = Inst.getOperand(1);
1292 if (!Offset.isImm())
1293 break; // We'll deal with this situation later on when applying fixups.
1294 if (!isIntN(8, Offset.getImm()))
1295 return Error(IDLoc, "branch target out of range");
1296 if (OffsetToAlignment(Offset.getImm(), 2LL))
1297 return Error(IDLoc, "branch to misaligned address");
1302 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1303 // We still accept it but it is a normal nop.
1304 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1305 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1306 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1311 const unsigned Opcode = Inst.getOpcode();
1323 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1324 // The offset is handled above
1325 Opnd = Inst.getOperand(1);
1327 return Error(IDLoc, "expected immediate operand kind");
1328 Imm = Opnd.getImm();
1329 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1330 Opcode == Mips::BBIT1 ? 63 : 31))
1331 return Error(IDLoc, "immediate operand value out of range");
1333 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1335 Inst.getOperand(1).setImm(Imm - 32);
1343 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1345 Opnd = Inst.getOperand(3);
1347 return Error(IDLoc, "expected immediate operand kind");
1348 Imm = Opnd.getImm();
1349 if (Imm < 0 || Imm > 31)
1350 return Error(IDLoc, "immediate operand value out of range");
1352 Opnd = Inst.getOperand(2);
1354 return Error(IDLoc, "expected immediate operand kind");
1355 Imm = Opnd.getImm();
1356 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1357 Opcode == Mips::EXTS ? 63 : 31))
1358 return Error(IDLoc, "immediate operand value out of range");
1360 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1361 Inst.getOperand(2).setImm(Imm - 32);
1367 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1368 Opnd = Inst.getOperand(2);
1370 return Error(IDLoc, "expected immediate operand kind");
1371 Imm = Opnd.getImm();
1372 if (!isInt<10>(Imm))
1373 return Error(IDLoc, "immediate operand value out of range");
1378 // If this instruction has a delay slot and .set reorder is active,
1379 // emit a NOP after it.
1380 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1381 Instructions.push_back(Inst);
1382 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1386 if (MCID.mayLoad() || MCID.mayStore()) {
1387 // Check the offset of memory operand, if it is a symbol
1388 // reference or immediate we may have to expand instructions.
1389 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1390 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1391 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1392 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1393 MCOperand &Op = Inst.getOperand(i);
1395 int MemOffset = Op.getImm();
1396 if (MemOffset < -32768 || MemOffset > 32767) {
1397 // Offset can't exceed 16bit value.
1398 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1401 } else if (Op.isExpr()) {
1402 const MCExpr *Expr = Op.getExpr();
1403 if (Expr->getKind() == MCExpr::SymbolRef) {
1404 const MCSymbolRefExpr *SR =
1405 static_cast<const MCSymbolRefExpr *>(Expr);
1406 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1408 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1411 } else if (!isEvaluated(Expr)) {
1412 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1420 if (inMicroMipsMode()) {
1421 if (MCID.mayLoad()) {
1422 // Try to create 16-bit GP relative load instruction.
1423 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1424 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1425 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1426 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1427 MCOperand &Op = Inst.getOperand(i);
1429 int MemOffset = Op.getImm();
1430 MCOperand &DstReg = Inst.getOperand(0);
1431 MCOperand &BaseReg = Inst.getOperand(1);
1432 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1433 getContext().getRegisterInfo()->getRegClass(
1434 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1435 BaseReg.getReg() == Mips::GP) {
1437 TmpInst.setLoc(IDLoc);
1438 TmpInst.setOpcode(Mips::LWGP_MM);
1439 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1440 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1441 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1442 Instructions.push_back(TmpInst);
1450 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1455 switch (Inst.getOpcode()) {
1458 case Mips::ADDIUS5_MM:
1459 Opnd = Inst.getOperand(2);
1461 return Error(IDLoc, "expected immediate operand kind");
1462 Imm = Opnd.getImm();
1463 if (Imm < -8 || Imm > 7)
1464 return Error(IDLoc, "immediate operand value out of range");
1466 case Mips::ADDIUSP_MM:
1467 Opnd = Inst.getOperand(0);
1469 return Error(IDLoc, "expected immediate operand kind");
1470 Imm = Opnd.getImm();
1471 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1473 return Error(IDLoc, "immediate operand value out of range");
1475 case Mips::SLL16_MM:
1476 case Mips::SRL16_MM:
1477 Opnd = Inst.getOperand(2);
1479 return Error(IDLoc, "expected immediate operand kind");
1480 Imm = Opnd.getImm();
1481 if (Imm < 1 || Imm > 8)
1482 return Error(IDLoc, "immediate operand value out of range");
1485 Opnd = Inst.getOperand(1);
1487 return Error(IDLoc, "expected immediate operand kind");
1488 Imm = Opnd.getImm();
1489 if (Imm < -1 || Imm > 126)
1490 return Error(IDLoc, "immediate operand value out of range");
1492 case Mips::ADDIUR2_MM:
1493 Opnd = Inst.getOperand(2);
1495 return Error(IDLoc, "expected immediate operand kind");
1496 Imm = Opnd.getImm();
1497 if (!(Imm == 1 || Imm == -1 ||
1498 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1499 return Error(IDLoc, "immediate operand value out of range");
1501 case Mips::ADDIUR1SP_MM:
1502 Opnd = Inst.getOperand(1);
1504 return Error(IDLoc, "expected immediate operand kind");
1505 Imm = Opnd.getImm();
1506 if (OffsetToAlignment(Imm, 4LL))
1507 return Error(IDLoc, "misaligned immediate operand value");
1508 if (Imm < 0 || Imm > 255)
1509 return Error(IDLoc, "immediate operand value out of range");
1511 case Mips::ANDI16_MM:
1512 Opnd = Inst.getOperand(2);
1514 return Error(IDLoc, "expected immediate operand kind");
1515 Imm = Opnd.getImm();
1516 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1517 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1518 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1519 return Error(IDLoc, "immediate operand value out of range");
1521 case Mips::LBU16_MM:
1522 Opnd = Inst.getOperand(2);
1524 return Error(IDLoc, "expected immediate operand kind");
1525 Imm = Opnd.getImm();
1526 if (Imm < -1 || Imm > 14)
1527 return Error(IDLoc, "immediate operand value out of range");
1530 Opnd = Inst.getOperand(2);
1532 return Error(IDLoc, "expected immediate operand kind");
1533 Imm = Opnd.getImm();
1534 if (Imm < 0 || Imm > 15)
1535 return Error(IDLoc, "immediate operand value out of range");
1537 case Mips::LHU16_MM:
1539 Opnd = Inst.getOperand(2);
1541 return Error(IDLoc, "expected immediate operand kind");
1542 Imm = Opnd.getImm();
1543 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1544 return Error(IDLoc, "immediate operand value out of range");
1548 Opnd = Inst.getOperand(2);
1550 return Error(IDLoc, "expected immediate operand kind");
1551 Imm = Opnd.getImm();
1552 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1553 return Error(IDLoc, "immediate operand value out of range");
1557 Opnd = Inst.getOperand(2);
1559 return Error(IDLoc, "expected immediate operand kind");
1560 Imm = Opnd.getImm();
1561 if (!isUInt<5>(Imm))
1562 return Error(IDLoc, "immediate operand value out of range");
1564 case Mips::ADDIUPC_MM:
1565 MCOperand Opnd = Inst.getOperand(1);
1567 return Error(IDLoc, "expected immediate operand kind");
1568 int Imm = Opnd.getImm();
1569 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1570 return Error(IDLoc, "immediate operand value out of range");
1575 if (needsExpansion(Inst))
1576 return expandInstruction(Inst, IDLoc, Instructions);
1578 Instructions.push_back(Inst);
1583 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1585 switch (Inst.getOpcode()) {
1586 case Mips::LoadImm32:
1587 case Mips::LoadImm64:
1588 case Mips::LoadAddrImm32:
1589 case Mips::LoadAddrReg32:
1590 case Mips::B_MM_Pseudo:
1593 case Mips::JalOneReg:
1594 case Mips::JalTwoReg:
1601 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1602 SmallVectorImpl<MCInst> &Instructions) {
1603 switch (Inst.getOpcode()) {
1604 default: llvm_unreachable("unimplemented expansion");
1605 case Mips::LoadImm32:
1606 return expandLoadImm(Inst, IDLoc, Instructions);
1607 case Mips::LoadImm64:
1609 Error(IDLoc, "instruction requires a 64-bit architecture");
1612 return expandLoadImm(Inst, IDLoc, Instructions);
1613 case Mips::LoadAddrImm32:
1614 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1615 case Mips::LoadAddrReg32:
1616 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1617 case Mips::B_MM_Pseudo:
1618 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1621 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1622 case Mips::JalOneReg:
1623 case Mips::JalTwoReg:
1624 return expandJalWithRegs(Inst, IDLoc, Instructions);
1629 template <bool PerformShift>
1630 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1631 SmallVectorImpl<MCInst> &Instructions) {
1634 tmpInst.setOpcode(Mips::DSLL);
1635 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1636 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1637 tmpInst.addOperand(MCOperand::CreateImm(16));
1638 tmpInst.setLoc(IDLoc);
1639 Instructions.push_back(tmpInst);
1642 tmpInst.setOpcode(Mips::ORi);
1643 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1644 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1645 tmpInst.addOperand(Operand);
1646 tmpInst.setLoc(IDLoc);
1647 Instructions.push_back(tmpInst);
1650 template <int Shift, bool PerformShift>
1651 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1652 SmallVectorImpl<MCInst> &Instructions) {
1653 createShiftOr<PerformShift>(
1654 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1655 IDLoc, Instructions);
1659 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1660 SmallVectorImpl<MCInst> &Instructions) {
1661 // Create a JALR instruction which is going to replace the pseudo-JAL.
1663 JalrInst.setLoc(IDLoc);
1664 const MCOperand FirstRegOp = Inst.getOperand(0);
1665 const unsigned Opcode = Inst.getOpcode();
1667 if (Opcode == Mips::JalOneReg) {
1668 // jal $rs => jalr $rs
1669 if (inMicroMipsMode()) {
1670 JalrInst.setOpcode(Mips::JALR16_MM);
1671 JalrInst.addOperand(FirstRegOp);
1673 JalrInst.setOpcode(Mips::JALR);
1674 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1675 JalrInst.addOperand(FirstRegOp);
1677 } else if (Opcode == Mips::JalTwoReg) {
1678 // jal $rd, $rs => jalr $rd, $rs
1679 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1680 JalrInst.addOperand(FirstRegOp);
1681 const MCOperand SecondRegOp = Inst.getOperand(1);
1682 JalrInst.addOperand(SecondRegOp);
1684 Instructions.push_back(JalrInst);
1686 // If .set reorder is active, emit a NOP after it.
1687 if (AssemblerOptions.back()->isReorder()) {
1688 // This is a 32-bit NOP because these 2 pseudo-instructions
1689 // do not have a short delay slot.
1691 NopInst.setOpcode(Mips::SLL);
1692 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1693 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1694 NopInst.addOperand(MCOperand::CreateImm(0));
1695 Instructions.push_back(NopInst);
1701 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1702 SmallVectorImpl<MCInst> &Instructions) {
1704 const MCOperand &ImmOp = Inst.getOperand(1);
1705 assert(ImmOp.isImm() && "expected immediate operand kind");
1706 const MCOperand &RegOp = Inst.getOperand(0);
1707 assert(RegOp.isReg() && "expected register operand kind");
1709 int64_t ImmValue = ImmOp.getImm();
1710 tmpInst.setLoc(IDLoc);
1711 // FIXME: gas has a special case for values that are 000...1111, which
1712 // becomes a li -1 and then a dsrl
1713 if (0 <= ImmValue && ImmValue <= 65535) {
1714 // For 0 <= j <= 65535.
1715 // li d,j => ori d,$zero,j
1716 tmpInst.setOpcode(Mips::ORi);
1717 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1718 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1719 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1720 Instructions.push_back(tmpInst);
1721 } else if (ImmValue < 0 && ImmValue >= -32768) {
1722 // For -32768 <= j < 0.
1723 // li d,j => addiu d,$zero,j
1724 tmpInst.setOpcode(Mips::ADDiu);
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 & 0xffffffff) == ImmValue) {
1730 // For any value of j that is representable as a 32-bit integer, create
1732 // li d,j => lui d,hi16(j)
1734 tmpInst.setOpcode(Mips::LUi);
1735 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1736 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1737 Instructions.push_back(tmpInst);
1738 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1739 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1741 Error(IDLoc, "instruction requires a 64-bit architecture");
1745 // <------- lo32 ------>
1746 // <------- hi32 ------>
1747 // <- hi16 -> <- lo16 ->
1748 // _________________________________
1750 // | 16-bytes | 16-bytes | 16-bytes |
1751 // |__________|__________|__________|
1753 // For any value of j that is representable as a 48-bit integer, create
1755 // li d,j => lui d,hi16(j)
1756 // ori d,d,hi16(lo32(j))
1758 // ori d,d,lo16(lo32(j))
1759 tmpInst.setOpcode(Mips::LUi);
1760 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1762 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1763 Instructions.push_back(tmpInst);
1764 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1765 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1768 Error(IDLoc, "instruction requires a 64-bit architecture");
1772 // <------- hi32 ------> <------- lo32 ------>
1773 // <- hi16 -> <- lo16 ->
1774 // ___________________________________________
1776 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1777 // |__________|__________|__________|__________|
1779 // For any value of j that isn't representable as a 48-bit integer.
1780 // li d,j => lui d,hi16(j)
1781 // ori d,d,lo16(hi32(j))
1783 // ori d,d,hi16(lo32(j))
1785 // ori d,d,lo16(lo32(j))
1786 tmpInst.setOpcode(Mips::LUi);
1787 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1789 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1790 Instructions.push_back(tmpInst);
1791 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1792 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1793 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1799 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1800 SmallVectorImpl<MCInst> &Instructions) {
1802 const MCOperand &ImmOp = Inst.getOperand(2);
1803 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1804 "expected immediate operand kind");
1805 if (!ImmOp.isImm()) {
1806 expandLoadAddressSym(Inst, IDLoc, Instructions);
1809 const MCOperand &SrcRegOp = Inst.getOperand(1);
1810 assert(SrcRegOp.isReg() && "expected register operand kind");
1811 const MCOperand &DstRegOp = Inst.getOperand(0);
1812 assert(DstRegOp.isReg() && "expected register operand kind");
1813 int ImmValue = ImmOp.getImm();
1814 if (-32768 <= ImmValue && ImmValue <= 65535) {
1815 // For -32768 <= j <= 65535.
1816 // la d,j(s) => addiu d,s,j
1817 tmpInst.setOpcode(Mips::ADDiu);
1818 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1819 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1820 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1821 Instructions.push_back(tmpInst);
1823 // For any other value of j that is representable as a 32-bit integer.
1824 // la d,j(s) => lui d,hi16(j)
1827 tmpInst.setOpcode(Mips::LUi);
1828 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1829 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1830 Instructions.push_back(tmpInst);
1832 tmpInst.setOpcode(Mips::ORi);
1833 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1834 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1835 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1836 Instructions.push_back(tmpInst);
1838 tmpInst.setOpcode(Mips::ADDu);
1839 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1840 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1841 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1842 Instructions.push_back(tmpInst);
1848 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1849 SmallVectorImpl<MCInst> &Instructions) {
1851 const MCOperand &ImmOp = Inst.getOperand(1);
1852 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1853 "expected immediate operand kind");
1854 if (!ImmOp.isImm()) {
1855 expandLoadAddressSym(Inst, IDLoc, Instructions);
1858 const MCOperand &RegOp = Inst.getOperand(0);
1859 assert(RegOp.isReg() && "expected register operand kind");
1860 int ImmValue = ImmOp.getImm();
1861 if (-32768 <= ImmValue && ImmValue <= 65535) {
1862 // For -32768 <= j <= 65535.
1863 // la d,j => addiu d,$zero,j
1864 tmpInst.setOpcode(Mips::ADDiu);
1865 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1866 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1867 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1868 Instructions.push_back(tmpInst);
1870 // For any other value of j that is representable as a 32-bit integer.
1871 // la d,j => lui d,hi16(j)
1873 tmpInst.setOpcode(Mips::LUi);
1874 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1875 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1876 Instructions.push_back(tmpInst);
1878 tmpInst.setOpcode(Mips::ORi);
1879 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1880 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1881 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1882 Instructions.push_back(tmpInst);
1888 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1889 SmallVectorImpl<MCInst> &Instructions) {
1890 // FIXME: If we do have a valid at register to use, we should generate a
1891 // slightly shorter sequence here.
1893 int ExprOperandNo = 1;
1894 // Sometimes the assembly parser will get the immediate expression as
1895 // a $zero + an immediate.
1896 if (Inst.getNumOperands() == 3) {
1897 assert(Inst.getOperand(1).getReg() ==
1898 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1901 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1902 assert(SymOp.isExpr() && "expected symbol operand kind");
1903 const MCOperand &RegOp = Inst.getOperand(0);
1904 unsigned RegNo = RegOp.getReg();
1905 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1906 const MCSymbolRefExpr *HiExpr =
1907 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1908 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1909 const MCSymbolRefExpr *LoExpr =
1910 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1911 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1913 // If it's a 64-bit architecture, expand to:
1914 // la d,sym => lui d,highest(sym)
1915 // ori d,d,higher(sym)
1917 // ori d,d,hi16(sym)
1919 // ori d,d,lo16(sym)
1920 const MCSymbolRefExpr *HighestExpr =
1921 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1922 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1923 const MCSymbolRefExpr *HigherExpr =
1924 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1925 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1927 tmpInst.setOpcode(Mips::LUi);
1928 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1929 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1930 Instructions.push_back(tmpInst);
1932 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1934 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1936 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1939 // Otherwise, expand to:
1940 // la d,sym => lui d,hi16(sym)
1941 // ori d,d,lo16(sym)
1942 tmpInst.setOpcode(Mips::LUi);
1943 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1944 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1945 Instructions.push_back(tmpInst);
1947 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1952 bool MipsAsmParser::expandUncondBranchMMPseudo(
1953 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1954 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1955 "unexpected number of operands");
1957 MCOperand Offset = Inst.getOperand(0);
1958 if (Offset.isExpr()) {
1960 Inst.setOpcode(Mips::BEQ_MM);
1961 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1962 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1963 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1965 assert(Offset.isImm() && "expected immediate operand kind");
1966 if (isIntN(11, Offset.getImm())) {
1967 // If offset fits into 11 bits then this instruction becomes microMIPS
1968 // 16-bit unconditional branch instruction.
1969 Inst.setOpcode(Mips::B16_MM);
1971 if (!isIntN(17, Offset.getImm()))
1972 Error(IDLoc, "branch target out of range");
1973 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1974 Error(IDLoc, "branch to misaligned address");
1976 Inst.setOpcode(Mips::BEQ_MM);
1977 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1978 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1979 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1982 Instructions.push_back(Inst);
1984 // If .set reorder is active, emit a NOP after the branch instruction.
1985 if (AssemblerOptions.back()->isReorder())
1986 createNop(true, IDLoc, Instructions);
1991 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1992 SmallVectorImpl<MCInst> &Instructions,
1993 bool isLoad, bool isImmOpnd) {
1994 const MCSymbolRefExpr *SR;
1996 unsigned ImmOffset, HiOffset, LoOffset;
1997 const MCExpr *ExprOffset;
1999 // 1st operand is either the source or destination register.
2000 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2001 unsigned RegOpNum = Inst.getOperand(0).getReg();
2002 // 2nd operand is the base register.
2003 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2004 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2005 // 3rd operand is either an immediate or expression.
2007 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2008 ImmOffset = Inst.getOperand(2).getImm();
2009 LoOffset = ImmOffset & 0x0000ffff;
2010 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2011 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2012 if (LoOffset & 0x8000)
2015 ExprOffset = Inst.getOperand(2).getExpr();
2016 // All instructions will have the same location.
2017 TempInst.setLoc(IDLoc);
2018 // These are some of the types of expansions we perform here:
2019 // 1) lw $8, sym => lui $8, %hi(sym)
2020 // lw $8, %lo(sym)($8)
2021 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2023 // lw $8, %lo(offset)($9)
2024 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2026 // lw $8, %lo(offset)($at)
2027 // 4) sw $8, sym => lui $at, %hi(sym)
2028 // sw $8, %lo(sym)($at)
2029 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2031 // sw $8, %lo(offset)($at)
2032 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2033 // ldc1 $f0, %lo(sym)($at)
2035 // For load instructions we can use the destination register as a temporary
2036 // if base and dst are different (examples 1 and 2) and if the base register
2037 // is general purpose otherwise we must use $at (example 6) and error if it's
2038 // not available. For stores we must use $at (examples 4 and 5) because we
2039 // must not clobber the source register setting up the offset.
2040 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2041 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2042 unsigned RegClassIDOp0 =
2043 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2044 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2045 (RegClassIDOp0 == Mips::GPR64RegClassID);
2046 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2047 TmpRegNum = RegOpNum;
2049 int AT = getATReg(IDLoc);
2050 // At this point we need AT to perform the expansions and we exit if it is
2055 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
2058 TempInst.setOpcode(Mips::LUi);
2059 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2061 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2063 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2064 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2065 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2066 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2068 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2070 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2071 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2074 // Add the instruction to the list.
2075 Instructions.push_back(TempInst);
2076 // Prepare TempInst for next instruction.
2078 // Add temp register to base.
2079 TempInst.setOpcode(Mips::ADDu);
2080 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2081 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2082 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2083 Instructions.push_back(TempInst);
2085 // And finally, create original instruction with low part
2086 // of offset and new base.
2087 TempInst.setOpcode(Inst.getOpcode());
2088 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2089 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2091 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2093 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2094 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2095 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2097 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2099 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2100 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2103 Instructions.push_back(TempInst);
2108 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2109 SmallVectorImpl<MCInst> &Instructions) {
2110 unsigned OpNum = Inst.getNumOperands();
2111 unsigned Opcode = Inst.getOpcode();
2112 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2114 assert (Inst.getOperand(OpNum - 1).isImm() &&
2115 Inst.getOperand(OpNum - 2).isReg() &&
2116 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2118 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2119 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2120 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2121 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2122 // It can be implemented as SWM16 or LWM16 instruction.
2123 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2125 Inst.setOpcode(NewOpcode);
2126 Instructions.push_back(Inst);
2130 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2131 SmallVectorImpl<MCInst> &Instructions) {
2133 if (hasShortDelaySlot) {
2134 NopInst.setOpcode(Mips::MOVE16_MM);
2135 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2136 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2138 NopInst.setOpcode(Mips::SLL);
2139 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2140 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2141 NopInst.addOperand(MCOperand::CreateImm(0));
2143 Instructions.push_back(NopInst);
2146 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2147 // As described by the Mips32r2 spec, the registers Rd and Rs for
2148 // jalr.hb must be different.
2149 unsigned Opcode = Inst.getOpcode();
2151 if (Opcode == Mips::JALR_HB &&
2152 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2153 return Match_RequiresDifferentSrcAndDst;
2155 return Match_Success;
2158 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2159 OperandVector &Operands,
2161 uint64_t &ErrorInfo,
2162 bool MatchingInlineAsm) {
2165 SmallVector<MCInst, 8> Instructions;
2166 unsigned MatchResult =
2167 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2169 switch (MatchResult) {
2170 case Match_Success: {
2171 if (processInstruction(Inst, IDLoc, Instructions))
2173 for (unsigned i = 0; i < Instructions.size(); i++)
2174 Out.EmitInstruction(Instructions[i], STI);
2177 case Match_MissingFeature:
2178 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2180 case Match_InvalidOperand: {
2181 SMLoc ErrorLoc = IDLoc;
2182 if (ErrorInfo != ~0ULL) {
2183 if (ErrorInfo >= Operands.size())
2184 return Error(IDLoc, "too few operands for instruction");
2186 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2187 if (ErrorLoc == SMLoc())
2191 return Error(ErrorLoc, "invalid operand for instruction");
2193 case Match_MnemonicFail:
2194 return Error(IDLoc, "invalid instruction");
2195 case Match_RequiresDifferentSrcAndDst:
2196 return Error(IDLoc, "source and destination must be different");
2199 llvm_unreachable("Implement any new match types added!");
2202 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2203 if ((RegIndex != 0) &&
2204 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2206 Warning(Loc, "used $at without \".set noat\"");
2208 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2209 Twine(RegIndex) + "\"");
2214 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2215 SMRange Range, bool ShowColors) {
2216 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2217 Range, SMFixIt(Range, FixMsg),
2221 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2224 CC = StringSwitch<unsigned>(Name)
2260 if (!(isABI_N32() || isABI_N64()))
2263 if (12 <= CC && CC <= 15) {
2264 // Name is one of t4-t7
2265 AsmToken RegTok = getLexer().peekTok();
2266 SMRange RegRange = RegTok.getLocRange();
2268 StringRef FixedName = StringSwitch<StringRef>(Name)
2274 assert(FixedName != "" && "Register name is not one of t4-t7.");
2276 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2277 "Did you mean $" + FixedName + "?", RegRange);
2280 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2281 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2282 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2283 if (8 <= CC && CC <= 11)
2287 CC = StringSwitch<unsigned>(Name)
2299 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2302 CC = StringSwitch<unsigned>(Name)
2303 .Case("hwr_cpunum", 0)
2304 .Case("hwr_synci_step", 1)
2306 .Case("hwr_ccres", 3)
2307 .Case("hwr_ulr", 29)
2313 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2315 if (Name[0] == 'f') {
2316 StringRef NumString = Name.substr(1);
2318 if (NumString.getAsInteger(10, IntVal))
2319 return -1; // This is not an integer.
2320 if (IntVal > 31) // Maximum index for fpu register.
2327 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2329 if (Name.startswith("fcc")) {
2330 StringRef NumString = Name.substr(3);
2332 if (NumString.getAsInteger(10, IntVal))
2333 return -1; // This is not an integer.
2334 if (IntVal > 7) // There are only 8 fcc registers.
2341 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2343 if (Name.startswith("ac")) {
2344 StringRef NumString = Name.substr(2);
2346 if (NumString.getAsInteger(10, IntVal))
2347 return -1; // This is not an integer.
2348 if (IntVal > 3) // There are only 3 acc registers.
2355 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2358 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2367 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2370 CC = StringSwitch<unsigned>(Name)
2373 .Case("msaaccess", 2)
2375 .Case("msamodify", 4)
2376 .Case("msarequest", 5)
2378 .Case("msaunmap", 7)
2384 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2392 int MipsAsmParser::getATReg(SMLoc Loc) {
2393 int AT = AssemblerOptions.back()->getATRegNum();
2395 reportParseError(Loc,
2396 "pseudo-instruction requires $at, which is not available");
2400 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2401 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2404 unsigned MipsAsmParser::getGPR(int RegNo) {
2405 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2409 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2411 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2414 return getReg(RegClass, RegNum);
2417 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2418 MCAsmParser &Parser = getParser();
2419 DEBUG(dbgs() << "parseOperand\n");
2421 // Check if the current operand has a custom associated parser, if so, try to
2422 // custom parse the operand, or fallback to the general approach.
2423 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2424 if (ResTy == MatchOperand_Success)
2426 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2427 // there was a match, but an error occurred, in which case, just return that
2428 // the operand parsing failed.
2429 if (ResTy == MatchOperand_ParseFail)
2432 DEBUG(dbgs() << ".. Generic Parser\n");
2434 switch (getLexer().getKind()) {
2436 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2438 case AsmToken::Dollar: {
2439 // Parse the register.
2440 SMLoc S = Parser.getTok().getLoc();
2442 // Almost all registers have been parsed by custom parsers. There is only
2443 // one exception to this. $zero (and it's alias $0) will reach this point
2444 // for div, divu, and similar instructions because it is not an operand
2445 // to the instruction definition but an explicit register. Special case
2446 // this situation for now.
2447 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2450 // Maybe it is a symbol reference.
2451 StringRef Identifier;
2452 if (Parser.parseIdentifier(Identifier))
2455 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2456 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2457 // Otherwise create a symbol reference.
2459 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2461 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2464 // Else drop to expression parsing.
2465 case AsmToken::LParen:
2466 case AsmToken::Minus:
2467 case AsmToken::Plus:
2468 case AsmToken::Integer:
2469 case AsmToken::Tilde:
2470 case AsmToken::String: {
2471 DEBUG(dbgs() << ".. generic integer\n");
2472 OperandMatchResultTy ResTy = parseImm(Operands);
2473 return ResTy != MatchOperand_Success;
2475 case AsmToken::Percent: {
2476 // It is a symbol reference or constant expression.
2477 const MCExpr *IdVal;
2478 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2479 if (parseRelocOperand(IdVal))
2482 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2484 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2486 } // case AsmToken::Percent
2487 } // switch(getLexer().getKind())
2491 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2492 StringRef RelocStr) {
2494 // Check the type of the expression.
2495 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2496 // It's a constant, evaluate reloc value.
2498 switch (getVariantKind(RelocStr)) {
2499 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2500 // Get the 1st 16-bits.
2501 Val = MCE->getValue() & 0xffff;
2503 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2504 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2505 // 16 bits being negative.
2506 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2508 case MCSymbolRefExpr::VK_Mips_HIGHER:
2509 // Get the 3rd 16-bits.
2510 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2512 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2513 // Get the 4th 16-bits.
2514 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2517 report_fatal_error("unsupported reloc value");
2519 return MCConstantExpr::Create(Val, getContext());
2522 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2523 // It's a symbol, create a symbolic expression from the symbol.
2524 StringRef Symbol = MSRE->getSymbol().getName();
2525 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2526 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2530 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2531 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2533 // Try to create target expression.
2534 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2535 return MipsMCExpr::Create(VK, Expr, getContext());
2537 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2538 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2539 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2543 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2544 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2545 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2548 // Just return the original expression.
2552 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2554 switch (Expr->getKind()) {
2555 case MCExpr::Constant:
2557 case MCExpr::SymbolRef:
2558 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2559 case MCExpr::Binary:
2560 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2561 if (!isEvaluated(BE->getLHS()))
2563 return isEvaluated(BE->getRHS());
2566 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2567 case MCExpr::Target:
2573 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2574 MCAsmParser &Parser = getParser();
2575 Parser.Lex(); // Eat the % token.
2576 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2577 if (Tok.isNot(AsmToken::Identifier))
2580 std::string Str = Tok.getIdentifier().str();
2582 Parser.Lex(); // Eat the identifier.
2583 // Now make an expression from the rest of the operand.
2584 const MCExpr *IdVal;
2587 if (getLexer().getKind() == AsmToken::LParen) {
2589 Parser.Lex(); // Eat the '(' token.
2590 if (getLexer().getKind() == AsmToken::Percent) {
2591 Parser.Lex(); // Eat the % token.
2592 const AsmToken &nextTok = Parser.getTok();
2593 if (nextTok.isNot(AsmToken::Identifier))
2596 Str += nextTok.getIdentifier();
2597 Parser.Lex(); // Eat the identifier.
2598 if (getLexer().getKind() != AsmToken::LParen)
2603 if (getParser().parseParenExpression(IdVal, EndLoc))
2606 while (getLexer().getKind() == AsmToken::RParen)
2607 Parser.Lex(); // Eat the ')' token.
2610 return true; // Parenthesis must follow the relocation operand.
2612 Res = evaluateRelocExpr(IdVal, Str);
2616 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2618 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2619 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2620 if (ResTy == MatchOperand_Success) {
2621 assert(Operands.size() == 1);
2622 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2623 StartLoc = Operand.getStartLoc();
2624 EndLoc = Operand.getEndLoc();
2626 // AFAIK, we only support numeric registers and named GPR's in CFI
2628 // Don't worry about eating tokens before failing. Using an unrecognised
2629 // register is a parse error.
2630 if (Operand.isGPRAsmReg()) {
2631 // Resolve to GPR32 or GPR64 appropriately.
2632 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2635 return (RegNo == (unsigned)-1);
2638 assert(Operands.size() == 0);
2639 return (RegNo == (unsigned)-1);
2642 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2643 MCAsmParser &Parser = getParser();
2647 while (getLexer().getKind() == AsmToken::LParen)
2650 switch (getLexer().getKind()) {
2653 case AsmToken::Identifier:
2654 case AsmToken::LParen:
2655 case AsmToken::Integer:
2656 case AsmToken::Minus:
2657 case AsmToken::Plus:
2659 Result = getParser().parseParenExpression(Res, S);
2661 Result = (getParser().parseExpression(Res));
2662 while (getLexer().getKind() == AsmToken::RParen)
2665 case AsmToken::Percent:
2666 Result = parseRelocOperand(Res);
2671 MipsAsmParser::OperandMatchResultTy
2672 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2673 MCAsmParser &Parser = getParser();
2674 DEBUG(dbgs() << "parseMemOperand\n");
2675 const MCExpr *IdVal = nullptr;
2677 bool isParenExpr = false;
2678 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2679 // First operand is the offset.
2680 S = Parser.getTok().getLoc();
2682 if (getLexer().getKind() == AsmToken::LParen) {
2687 if (getLexer().getKind() != AsmToken::Dollar) {
2688 if (parseMemOffset(IdVal, isParenExpr))
2689 return MatchOperand_ParseFail;
2691 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2692 if (Tok.isNot(AsmToken::LParen)) {
2693 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2694 if (Mnemonic.getToken() == "la") {
2696 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2697 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2698 return MatchOperand_Success;
2700 if (Tok.is(AsmToken::EndOfStatement)) {
2702 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2704 // Zero register assumed, add a memory operand with ZERO as its base.
2705 // "Base" will be managed by k_Memory.
2706 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2709 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2710 return MatchOperand_Success;
2712 Error(Parser.getTok().getLoc(), "'(' expected");
2713 return MatchOperand_ParseFail;
2716 Parser.Lex(); // Eat the '(' token.
2719 Res = parseAnyRegister(Operands);
2720 if (Res != MatchOperand_Success)
2723 if (Parser.getTok().isNot(AsmToken::RParen)) {
2724 Error(Parser.getTok().getLoc(), "')' expected");
2725 return MatchOperand_ParseFail;
2728 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2730 Parser.Lex(); // Eat the ')' token.
2733 IdVal = MCConstantExpr::Create(0, getContext());
2735 // Replace the register operand with the memory operand.
2736 std::unique_ptr<MipsOperand> op(
2737 static_cast<MipsOperand *>(Operands.back().release()));
2738 // Remove the register from the operands.
2739 // "op" will be managed by k_Memory.
2740 Operands.pop_back();
2741 // Add the memory operand.
2742 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2744 if (IdVal->EvaluateAsAbsolute(Imm))
2745 IdVal = MCConstantExpr::Create(Imm, getContext());
2746 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2747 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2751 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2752 return MatchOperand_Success;
2755 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2756 MCAsmParser &Parser = getParser();
2757 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2759 SMLoc S = Parser.getTok().getLoc();
2761 if (Sym->isVariable())
2762 Expr = Sym->getVariableValue();
2765 if (Expr->getKind() == MCExpr::SymbolRef) {
2766 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2767 StringRef DefSymbol = Ref->getSymbol().getName();
2768 if (DefSymbol.startswith("$")) {
2769 OperandMatchResultTy ResTy =
2770 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2771 if (ResTy == MatchOperand_Success) {
2774 } else if (ResTy == MatchOperand_ParseFail)
2775 llvm_unreachable("Should never ParseFail");
2778 } else if (Expr->getKind() == MCExpr::Constant) {
2780 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2782 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2789 MipsAsmParser::OperandMatchResultTy
2790 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2791 StringRef Identifier,
2793 int Index = matchCPURegisterName(Identifier);
2795 Operands.push_back(MipsOperand::createGPRReg(
2796 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2797 return MatchOperand_Success;
2800 Index = matchHWRegsRegisterName(Identifier);
2802 Operands.push_back(MipsOperand::createHWRegsReg(
2803 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2804 return MatchOperand_Success;
2807 Index = matchFPURegisterName(Identifier);
2809 Operands.push_back(MipsOperand::createFGRReg(
2810 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2811 return MatchOperand_Success;
2814 Index = matchFCCRegisterName(Identifier);
2816 Operands.push_back(MipsOperand::createFCCReg(
2817 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2818 return MatchOperand_Success;
2821 Index = matchACRegisterName(Identifier);
2823 Operands.push_back(MipsOperand::createACCReg(
2824 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2825 return MatchOperand_Success;
2828 Index = matchMSA128RegisterName(Identifier);
2830 Operands.push_back(MipsOperand::createMSA128Reg(
2831 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2832 return MatchOperand_Success;
2835 Index = matchMSA128CtrlRegisterName(Identifier);
2837 Operands.push_back(MipsOperand::createMSACtrlReg(
2838 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2839 return MatchOperand_Success;
2842 return MatchOperand_NoMatch;
2845 MipsAsmParser::OperandMatchResultTy
2846 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2847 MCAsmParser &Parser = getParser();
2848 auto Token = Parser.getLexer().peekTok(false);
2850 if (Token.is(AsmToken::Identifier)) {
2851 DEBUG(dbgs() << ".. identifier\n");
2852 StringRef Identifier = Token.getIdentifier();
2853 OperandMatchResultTy ResTy =
2854 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2856 } else if (Token.is(AsmToken::Integer)) {
2857 DEBUG(dbgs() << ".. integer\n");
2858 Operands.push_back(MipsOperand::createNumericReg(
2859 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2861 return MatchOperand_Success;
2864 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2866 return MatchOperand_NoMatch;
2869 MipsAsmParser::OperandMatchResultTy
2870 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2871 MCAsmParser &Parser = getParser();
2872 DEBUG(dbgs() << "parseAnyRegister\n");
2874 auto Token = Parser.getTok();
2876 SMLoc S = Token.getLoc();
2878 if (Token.isNot(AsmToken::Dollar)) {
2879 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2880 if (Token.is(AsmToken::Identifier)) {
2881 if (searchSymbolAlias(Operands))
2882 return MatchOperand_Success;
2884 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2885 return MatchOperand_NoMatch;
2887 DEBUG(dbgs() << ".. $\n");
2889 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2890 if (ResTy == MatchOperand_Success) {
2892 Parser.Lex(); // identifier
2897 MipsAsmParser::OperandMatchResultTy
2898 MipsAsmParser::parseImm(OperandVector &Operands) {
2899 MCAsmParser &Parser = getParser();
2900 switch (getLexer().getKind()) {
2902 return MatchOperand_NoMatch;
2903 case AsmToken::LParen:
2904 case AsmToken::Minus:
2905 case AsmToken::Plus:
2906 case AsmToken::Integer:
2907 case AsmToken::Tilde:
2908 case AsmToken::String:
2912 const MCExpr *IdVal;
2913 SMLoc S = Parser.getTok().getLoc();
2914 if (getParser().parseExpression(IdVal))
2915 return MatchOperand_ParseFail;
2917 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2918 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2919 return MatchOperand_Success;
2922 MipsAsmParser::OperandMatchResultTy
2923 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2924 MCAsmParser &Parser = getParser();
2925 DEBUG(dbgs() << "parseJumpTarget\n");
2927 SMLoc S = getLexer().getLoc();
2929 // Integers and expressions are acceptable
2930 OperandMatchResultTy ResTy = parseImm(Operands);
2931 if (ResTy != MatchOperand_NoMatch)
2934 // Registers are a valid target and have priority over symbols.
2935 ResTy = parseAnyRegister(Operands);
2936 if (ResTy != MatchOperand_NoMatch)
2939 const MCExpr *Expr = nullptr;
2940 if (Parser.parseExpression(Expr)) {
2941 // We have no way of knowing if a symbol was consumed so we must ParseFail
2942 return MatchOperand_ParseFail;
2945 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2946 return MatchOperand_Success;
2949 MipsAsmParser::OperandMatchResultTy
2950 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2951 MCAsmParser &Parser = getParser();
2952 const MCExpr *IdVal;
2953 // If the first token is '$' we may have register operand.
2954 if (Parser.getTok().is(AsmToken::Dollar))
2955 return MatchOperand_NoMatch;
2956 SMLoc S = Parser.getTok().getLoc();
2957 if (getParser().parseExpression(IdVal))
2958 return MatchOperand_ParseFail;
2959 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2960 assert(MCE && "Unexpected MCExpr type.");
2961 int64_t Val = MCE->getValue();
2962 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2963 Operands.push_back(MipsOperand::CreateImm(
2964 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2965 return MatchOperand_Success;
2968 MipsAsmParser::OperandMatchResultTy
2969 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2970 MCAsmParser &Parser = getParser();
2971 switch (getLexer().getKind()) {
2973 return MatchOperand_NoMatch;
2974 case AsmToken::LParen:
2975 case AsmToken::Plus:
2976 case AsmToken::Minus:
2977 case AsmToken::Integer:
2982 SMLoc S = Parser.getTok().getLoc();
2984 if (getParser().parseExpression(Expr))
2985 return MatchOperand_ParseFail;
2988 if (!Expr->EvaluateAsAbsolute(Val)) {
2989 Error(S, "expected immediate value");
2990 return MatchOperand_ParseFail;
2993 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2994 // and because the CPU always adds one to the immediate field, the allowed
2995 // range becomes 1..4. We'll only check the range here and will deal
2996 // with the addition/subtraction when actually decoding/encoding
2998 if (Val < 1 || Val > 4) {
2999 Error(S, "immediate not in range (1..4)");
3000 return MatchOperand_ParseFail;
3004 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3005 return MatchOperand_Success;
3008 MipsAsmParser::OperandMatchResultTy
3009 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3010 MCAsmParser &Parser = getParser();
3011 SmallVector<unsigned, 10> Regs;
3013 unsigned PrevReg = Mips::NoRegister;
3014 bool RegRange = false;
3015 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3017 if (Parser.getTok().isNot(AsmToken::Dollar))
3018 return MatchOperand_ParseFail;
3020 SMLoc S = Parser.getTok().getLoc();
3021 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3022 SMLoc E = getLexer().getLoc();
3023 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3024 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3026 // Remove last register operand because registers from register range
3027 // should be inserted first.
3028 if (RegNo == Mips::RA) {
3029 Regs.push_back(RegNo);
3031 unsigned TmpReg = PrevReg + 1;
3032 while (TmpReg <= RegNo) {
3033 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3034 Error(E, "invalid register operand");
3035 return MatchOperand_ParseFail;
3039 Regs.push_back(TmpReg++);
3045 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3046 (RegNo != Mips::RA)) {
3047 Error(E, "$16 or $31 expected");
3048 return MatchOperand_ParseFail;
3049 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3050 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3051 Error(E, "invalid register operand");
3052 return MatchOperand_ParseFail;
3053 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3054 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3055 Error(E, "consecutive register numbers expected");
3056 return MatchOperand_ParseFail;
3059 Regs.push_back(RegNo);
3062 if (Parser.getTok().is(AsmToken::Minus))
3065 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3066 !Parser.getTok().isNot(AsmToken::Comma)) {
3067 Error(E, "',' or '-' expected");
3068 return MatchOperand_ParseFail;
3071 Lex(); // Consume comma or minus
3072 if (Parser.getTok().isNot(AsmToken::Dollar))
3078 SMLoc E = Parser.getTok().getLoc();
3079 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3080 parseMemOperand(Operands);
3081 return MatchOperand_Success;
3084 MipsAsmParser::OperandMatchResultTy
3085 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3086 MCAsmParser &Parser = getParser();
3088 SMLoc S = Parser.getTok().getLoc();
3089 if (parseAnyRegister(Operands) != MatchOperand_Success)
3090 return MatchOperand_ParseFail;
3092 SMLoc E = Parser.getTok().getLoc();
3093 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3094 unsigned Reg = Op.getGPR32Reg();
3095 Operands.pop_back();
3096 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3097 return MatchOperand_Success;
3100 MipsAsmParser::OperandMatchResultTy
3101 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3102 MCAsmParser &Parser = getParser();
3103 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3104 SmallVector<unsigned, 10> Regs;
3106 if (Parser.getTok().isNot(AsmToken::Dollar))
3107 return MatchOperand_ParseFail;
3109 SMLoc S = Parser.getTok().getLoc();
3111 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3112 return MatchOperand_ParseFail;
3114 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3115 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3116 Regs.push_back(RegNo);
3118 SMLoc E = Parser.getTok().getLoc();
3119 if (Parser.getTok().isNot(AsmToken::Comma)) {
3120 Error(E, "',' expected");
3121 return MatchOperand_ParseFail;
3127 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3128 return MatchOperand_ParseFail;
3130 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3131 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3132 Regs.push_back(RegNo);
3134 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3136 return MatchOperand_Success;
3139 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3141 MCSymbolRefExpr::VariantKind VK =
3142 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3143 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3144 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3145 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3146 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3147 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3148 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3149 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3150 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3151 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3152 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3153 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3154 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3155 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3156 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3157 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3158 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3159 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3160 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3161 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3162 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3163 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3164 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3165 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3166 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3167 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3168 .Default(MCSymbolRefExpr::VK_None);
3170 assert(VK != MCSymbolRefExpr::VK_None);
3175 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3177 /// ::= '(', register, ')'
3178 /// handle it before we iterate so we don't get tripped up by the lack of
3180 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3181 MCAsmParser &Parser = getParser();
3182 if (getLexer().is(AsmToken::LParen)) {
3184 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3186 if (parseOperand(Operands, Name)) {
3187 SMLoc Loc = getLexer().getLoc();
3188 Parser.eatToEndOfStatement();
3189 return Error(Loc, "unexpected token in argument list");
3191 if (Parser.getTok().isNot(AsmToken::RParen)) {
3192 SMLoc Loc = getLexer().getLoc();
3193 Parser.eatToEndOfStatement();
3194 return Error(Loc, "unexpected token, expected ')'");
3197 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3203 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3204 /// either one of these.
3205 /// ::= '[', register, ']'
3206 /// ::= '[', integer, ']'
3207 /// handle it before we iterate so we don't get tripped up by the lack of
3209 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3210 OperandVector &Operands) {
3211 MCAsmParser &Parser = getParser();
3212 if (getLexer().is(AsmToken::LBrac)) {
3214 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3216 if (parseOperand(Operands, Name)) {
3217 SMLoc Loc = getLexer().getLoc();
3218 Parser.eatToEndOfStatement();
3219 return Error(Loc, "unexpected token in argument list");
3221 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3222 SMLoc Loc = getLexer().getLoc();
3223 Parser.eatToEndOfStatement();
3224 return Error(Loc, "unexpected token, expected ']'");
3227 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3233 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3234 SMLoc NameLoc, OperandVector &Operands) {
3235 MCAsmParser &Parser = getParser();
3236 DEBUG(dbgs() << "ParseInstruction\n");
3238 // We have reached first instruction, module directive are now forbidden.
3239 getTargetStreamer().forbidModuleDirective();
3241 // Check if we have valid mnemonic
3242 if (!mnemonicIsValid(Name, 0)) {
3243 Parser.eatToEndOfStatement();
3244 return Error(NameLoc, "unknown instruction");
3246 // First operand in MCInst is instruction mnemonic.
3247 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3249 // Read the remaining operands.
3250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3251 // Read the first operand.
3252 if (parseOperand(Operands, Name)) {
3253 SMLoc Loc = getLexer().getLoc();
3254 Parser.eatToEndOfStatement();
3255 return Error(Loc, "unexpected token in argument list");
3257 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3259 // AFAIK, parenthesis suffixes are never on the first operand
3261 while (getLexer().is(AsmToken::Comma)) {
3262 Parser.Lex(); // Eat the comma.
3263 // Parse and remember the operand.
3264 if (parseOperand(Operands, Name)) {
3265 SMLoc Loc = getLexer().getLoc();
3266 Parser.eatToEndOfStatement();
3267 return Error(Loc, "unexpected token in argument list");
3269 // Parse bracket and parenthesis suffixes before we iterate
3270 if (getLexer().is(AsmToken::LBrac)) {
3271 if (parseBracketSuffix(Name, Operands))
3273 } else if (getLexer().is(AsmToken::LParen) &&
3274 parseParenSuffix(Name, Operands))
3278 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3279 SMLoc Loc = getLexer().getLoc();
3280 Parser.eatToEndOfStatement();
3281 return Error(Loc, "unexpected token in argument list");
3283 Parser.Lex(); // Consume the EndOfStatement.
3287 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3288 MCAsmParser &Parser = getParser();
3289 SMLoc Loc = getLexer().getLoc();
3290 Parser.eatToEndOfStatement();
3291 return Error(Loc, ErrorMsg);
3294 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3295 return Error(Loc, ErrorMsg);
3298 bool MipsAsmParser::parseSetNoAtDirective() {
3299 MCAsmParser &Parser = getParser();
3300 // Line should look like: ".set noat".
3302 // Set the $at register to $0.
3303 AssemblerOptions.back()->setATReg(0);
3305 Parser.Lex(); // Eat "noat".
3307 // If this is not the end of the statement, report an error.
3308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3309 reportParseError("unexpected token, expected end of statement");
3313 getTargetStreamer().emitDirectiveSetNoAt();
3314 Parser.Lex(); // Consume the EndOfStatement.
3318 bool MipsAsmParser::parseSetAtDirective() {
3319 // Line can be: ".set at", which sets $at to $1
3320 // or ".set at=$reg", which sets $at to $reg.
3321 MCAsmParser &Parser = getParser();
3322 Parser.Lex(); // Eat "at".
3324 if (getLexer().is(AsmToken::EndOfStatement)) {
3325 // No register was specified, so we set $at to $1.
3326 AssemblerOptions.back()->setATReg(1);
3328 getTargetStreamer().emitDirectiveSetAt();
3329 Parser.Lex(); // Consume the EndOfStatement.
3333 if (getLexer().isNot(AsmToken::Equal)) {
3334 reportParseError("unexpected token, expected equals sign");
3337 Parser.Lex(); // Eat "=".
3339 if (getLexer().isNot(AsmToken::Dollar)) {
3340 if (getLexer().is(AsmToken::EndOfStatement)) {
3341 reportParseError("no register specified");
3344 reportParseError("unexpected token, expected dollar sign '$'");
3348 Parser.Lex(); // Eat "$".
3350 // Find out what "reg" is.
3352 const AsmToken &Reg = Parser.getTok();
3353 if (Reg.is(AsmToken::Identifier)) {
3354 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3355 } else if (Reg.is(AsmToken::Integer)) {
3356 AtRegNo = Reg.getIntVal();
3358 reportParseError("unexpected token, expected identifier or integer");
3362 // Check if $reg is a valid register. If it is, set $at to $reg.
3363 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3364 reportParseError("invalid register");
3367 Parser.Lex(); // Eat "reg".
3369 // If this is not the end of the statement, report an error.
3370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3371 reportParseError("unexpected token, expected end of statement");
3375 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3377 Parser.Lex(); // Consume the EndOfStatement.
3381 bool MipsAsmParser::parseSetReorderDirective() {
3382 MCAsmParser &Parser = getParser();
3384 // If this is not the end of the statement, report an error.
3385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3386 reportParseError("unexpected token, expected end of statement");
3389 AssemblerOptions.back()->setReorder();
3390 getTargetStreamer().emitDirectiveSetReorder();
3391 Parser.Lex(); // Consume the EndOfStatement.
3395 bool MipsAsmParser::parseSetNoReorderDirective() {
3396 MCAsmParser &Parser = getParser();
3398 // If this is not the end of the statement, report an error.
3399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3400 reportParseError("unexpected token, expected end of statement");
3403 AssemblerOptions.back()->setNoReorder();
3404 getTargetStreamer().emitDirectiveSetNoReorder();
3405 Parser.Lex(); // Consume the EndOfStatement.
3409 bool MipsAsmParser::parseSetMacroDirective() {
3410 MCAsmParser &Parser = getParser();
3412 // If this is not the end of the statement, report an error.
3413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3414 reportParseError("unexpected token, expected end of statement");
3417 AssemblerOptions.back()->setMacro();
3418 Parser.Lex(); // Consume the EndOfStatement.
3422 bool MipsAsmParser::parseSetNoMacroDirective() {
3423 MCAsmParser &Parser = getParser();
3425 // If this is not the end of the statement, report an error.
3426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3427 reportParseError("unexpected token, expected end of statement");
3430 if (AssemblerOptions.back()->isReorder()) {
3431 reportParseError("`noreorder' must be set before `nomacro'");
3434 AssemblerOptions.back()->setNoMacro();
3435 Parser.Lex(); // Consume the EndOfStatement.
3439 bool MipsAsmParser::parseSetMsaDirective() {
3440 MCAsmParser &Parser = getParser();
3443 // If this is not the end of the statement, report an error.
3444 if (getLexer().isNot(AsmToken::EndOfStatement))
3445 return reportParseError("unexpected token, expected end of statement");
3447 setFeatureBits(Mips::FeatureMSA, "msa");
3448 getTargetStreamer().emitDirectiveSetMsa();
3452 bool MipsAsmParser::parseSetNoMsaDirective() {
3453 MCAsmParser &Parser = getParser();
3456 // If this is not the end of the statement, report an error.
3457 if (getLexer().isNot(AsmToken::EndOfStatement))
3458 return reportParseError("unexpected token, expected end of statement");
3460 clearFeatureBits(Mips::FeatureMSA, "msa");
3461 getTargetStreamer().emitDirectiveSetNoMsa();
3465 bool MipsAsmParser::parseSetNoDspDirective() {
3466 MCAsmParser &Parser = getParser();
3467 Parser.Lex(); // Eat "nodsp".
3469 // If this is not the end of the statement, report an error.
3470 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3471 reportParseError("unexpected token, expected end of statement");
3475 clearFeatureBits(Mips::FeatureDSP, "dsp");
3476 getTargetStreamer().emitDirectiveSetNoDsp();
3480 bool MipsAsmParser::parseSetMips16Directive() {
3481 MCAsmParser &Parser = getParser();
3482 Parser.Lex(); // Eat "mips16".
3484 // If this is not the end of the statement, report an error.
3485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3486 reportParseError("unexpected token, expected end of statement");
3490 setFeatureBits(Mips::FeatureMips16, "mips16");
3491 getTargetStreamer().emitDirectiveSetMips16();
3492 Parser.Lex(); // Consume the EndOfStatement.
3496 bool MipsAsmParser::parseSetNoMips16Directive() {
3497 MCAsmParser &Parser = getParser();
3498 Parser.Lex(); // Eat "nomips16".
3500 // If this is not the end of the statement, report an error.
3501 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3502 reportParseError("unexpected token, expected end of statement");
3506 clearFeatureBits(Mips::FeatureMips16, "mips16");
3507 getTargetStreamer().emitDirectiveSetNoMips16();
3508 Parser.Lex(); // Consume the EndOfStatement.
3512 bool MipsAsmParser::parseSetFpDirective() {
3513 MCAsmParser &Parser = getParser();
3514 MipsABIFlagsSection::FpABIKind FpAbiVal;
3515 // Line can be: .set fp=32
3518 Parser.Lex(); // Eat fp token
3519 AsmToken Tok = Parser.getTok();
3520 if (Tok.isNot(AsmToken::Equal)) {
3521 reportParseError("unexpected token, expected equals sign '='");
3524 Parser.Lex(); // Eat '=' token.
3525 Tok = Parser.getTok();
3527 if (!parseFpABIValue(FpAbiVal, ".set"))
3530 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3531 reportParseError("unexpected token, expected end of statement");
3534 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3535 Parser.Lex(); // Consume the EndOfStatement.
3539 bool MipsAsmParser::parseSetPopDirective() {
3540 MCAsmParser &Parser = getParser();
3541 SMLoc Loc = getLexer().getLoc();
3544 if (getLexer().isNot(AsmToken::EndOfStatement))
3545 return reportParseError("unexpected token, expected end of statement");
3547 // Always keep an element on the options "stack" to prevent the user
3548 // from changing the initial options. This is how we remember them.
3549 if (AssemblerOptions.size() == 2)
3550 return reportParseError(Loc, ".set pop with no .set push");
3552 AssemblerOptions.pop_back();
3553 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3555 getTargetStreamer().emitDirectiveSetPop();
3559 bool MipsAsmParser::parseSetPushDirective() {
3560 MCAsmParser &Parser = getParser();
3562 if (getLexer().isNot(AsmToken::EndOfStatement))
3563 return reportParseError("unexpected token, expected end of statement");
3565 // Create a copy of the current assembler options environment and push it.
3566 AssemblerOptions.push_back(
3567 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3569 getTargetStreamer().emitDirectiveSetPush();
3573 bool MipsAsmParser::parseSetAssignment() {
3575 const MCExpr *Value;
3576 MCAsmParser &Parser = getParser();
3578 if (Parser.parseIdentifier(Name))
3579 reportParseError("expected identifier after .set");
3581 if (getLexer().isNot(AsmToken::Comma))
3582 return reportParseError("unexpected token, expected comma");
3585 if (Parser.parseExpression(Value))
3586 return reportParseError("expected valid expression after comma");
3588 // Check if the Name already exists as a symbol.
3589 MCSymbol *Sym = getContext().LookupSymbol(Name);
3591 return reportParseError("symbol already defined");
3592 Sym = getContext().GetOrCreateSymbol(Name);
3593 Sym->setVariableValue(Value);
3598 bool MipsAsmParser::parseSetMips0Directive() {
3599 MCAsmParser &Parser = getParser();
3601 if (getLexer().isNot(AsmToken::EndOfStatement))
3602 return reportParseError("unexpected token, expected end of statement");
3604 // Reset assembler options to their initial values.
3605 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3606 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3608 getTargetStreamer().emitDirectiveSetMips0();
3612 bool MipsAsmParser::parseSetArchDirective() {
3613 MCAsmParser &Parser = getParser();
3615 if (getLexer().isNot(AsmToken::Equal))
3616 return reportParseError("unexpected token, expected equals sign");
3620 if (Parser.parseIdentifier(Arch))
3621 return reportParseError("expected arch identifier");
3623 StringRef ArchFeatureName =
3624 StringSwitch<StringRef>(Arch)
3625 .Case("mips1", "mips1")
3626 .Case("mips2", "mips2")
3627 .Case("mips3", "mips3")
3628 .Case("mips4", "mips4")
3629 .Case("mips5", "mips5")
3630 .Case("mips32", "mips32")
3631 .Case("mips32r2", "mips32r2")
3632 .Case("mips32r3", "mips32r3")
3633 .Case("mips32r5", "mips32r5")
3634 .Case("mips32r6", "mips32r6")
3635 .Case("mips64", "mips64")
3636 .Case("mips64r2", "mips64r2")
3637 .Case("mips64r3", "mips64r3")
3638 .Case("mips64r5", "mips64r5")
3639 .Case("mips64r6", "mips64r6")
3640 .Case("cnmips", "cnmips")
3641 .Case("r4000", "mips3") // This is an implementation of Mips3.
3644 if (ArchFeatureName.empty())
3645 return reportParseError("unsupported architecture");
3647 selectArch(ArchFeatureName);
3648 getTargetStreamer().emitDirectiveSetArch(Arch);
3652 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3653 MCAsmParser &Parser = getParser();
3655 if (getLexer().isNot(AsmToken::EndOfStatement))
3656 return reportParseError("unexpected token, expected end of statement");
3660 llvm_unreachable("Unimplemented feature");
3661 case Mips::FeatureDSP:
3662 setFeatureBits(Mips::FeatureDSP, "dsp");
3663 getTargetStreamer().emitDirectiveSetDsp();
3665 case Mips::FeatureMicroMips:
3666 getTargetStreamer().emitDirectiveSetMicroMips();
3668 case Mips::FeatureMips1:
3669 selectArch("mips1");
3670 getTargetStreamer().emitDirectiveSetMips1();
3672 case Mips::FeatureMips2:
3673 selectArch("mips2");
3674 getTargetStreamer().emitDirectiveSetMips2();
3676 case Mips::FeatureMips3:
3677 selectArch("mips3");
3678 getTargetStreamer().emitDirectiveSetMips3();
3680 case Mips::FeatureMips4:
3681 selectArch("mips4");
3682 getTargetStreamer().emitDirectiveSetMips4();
3684 case Mips::FeatureMips5:
3685 selectArch("mips5");
3686 getTargetStreamer().emitDirectiveSetMips5();
3688 case Mips::FeatureMips32:
3689 selectArch("mips32");
3690 getTargetStreamer().emitDirectiveSetMips32();
3692 case Mips::FeatureMips32r2:
3693 selectArch("mips32r2");
3694 getTargetStreamer().emitDirectiveSetMips32R2();
3696 case Mips::FeatureMips32r3:
3697 selectArch("mips32r3");
3698 getTargetStreamer().emitDirectiveSetMips32R3();
3700 case Mips::FeatureMips32r5:
3701 selectArch("mips32r5");
3702 getTargetStreamer().emitDirectiveSetMips32R5();
3704 case Mips::FeatureMips32r6:
3705 selectArch("mips32r6");
3706 getTargetStreamer().emitDirectiveSetMips32R6();
3708 case Mips::FeatureMips64:
3709 selectArch("mips64");
3710 getTargetStreamer().emitDirectiveSetMips64();
3712 case Mips::FeatureMips64r2:
3713 selectArch("mips64r2");
3714 getTargetStreamer().emitDirectiveSetMips64R2();
3716 case Mips::FeatureMips64r3:
3717 selectArch("mips64r3");
3718 getTargetStreamer().emitDirectiveSetMips64R3();
3720 case Mips::FeatureMips64r5:
3721 selectArch("mips64r5");
3722 getTargetStreamer().emitDirectiveSetMips64R5();
3724 case Mips::FeatureMips64r6:
3725 selectArch("mips64r6");
3726 getTargetStreamer().emitDirectiveSetMips64R6();
3732 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3733 MCAsmParser &Parser = getParser();
3734 if (getLexer().isNot(AsmToken::Comma)) {
3735 SMLoc Loc = getLexer().getLoc();
3736 Parser.eatToEndOfStatement();
3737 return Error(Loc, ErrorStr);
3740 Parser.Lex(); // Eat the comma.
3744 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3745 if (AssemblerOptions.back()->isReorder())
3746 Warning(Loc, ".cpload should be inside a noreorder section");
3748 if (inMips16Mode()) {
3749 reportParseError(".cpload is not supported in Mips16 mode");
3753 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3754 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3755 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3756 reportParseError("expected register containing function address");
3760 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3761 if (!RegOpnd.isGPRAsmReg()) {
3762 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3766 // If this is not the end of the statement, report an error.
3767 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3768 reportParseError("unexpected token, expected end of statement");
3772 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3776 bool MipsAsmParser::parseDirectiveCPSetup() {
3777 MCAsmParser &Parser = getParser();
3780 bool SaveIsReg = true;
3782 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3783 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3784 if (ResTy == MatchOperand_NoMatch) {
3785 reportParseError("expected register containing function address");
3786 Parser.eatToEndOfStatement();
3790 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3791 if (!FuncRegOpnd.isGPRAsmReg()) {
3792 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3793 Parser.eatToEndOfStatement();
3797 FuncReg = FuncRegOpnd.getGPR32Reg();
3800 if (!eatComma("unexpected token, expected comma"))
3803 ResTy = parseAnyRegister(TmpReg);
3804 if (ResTy == MatchOperand_NoMatch) {
3805 const AsmToken &Tok = Parser.getTok();
3806 if (Tok.is(AsmToken::Integer)) {
3807 Save = Tok.getIntVal();
3811 reportParseError("expected save register or stack offset");
3812 Parser.eatToEndOfStatement();
3816 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3817 if (!SaveOpnd.isGPRAsmReg()) {
3818 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3819 Parser.eatToEndOfStatement();
3822 Save = SaveOpnd.getGPR32Reg();
3825 if (!eatComma("unexpected token, expected comma"))
3829 if (Parser.parseExpression(Expr)) {
3830 reportParseError("expected expression");
3834 if (Expr->getKind() != MCExpr::SymbolRef) {
3835 reportParseError("expected symbol");
3838 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3840 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3845 bool MipsAsmParser::parseDirectiveNaN() {
3846 MCAsmParser &Parser = getParser();
3847 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3848 const AsmToken &Tok = Parser.getTok();
3850 if (Tok.getString() == "2008") {
3852 getTargetStreamer().emitDirectiveNaN2008();
3854 } else if (Tok.getString() == "legacy") {
3856 getTargetStreamer().emitDirectiveNaNLegacy();
3860 // If we don't recognize the option passed to the .nan
3861 // directive (e.g. no option or unknown option), emit an error.
3862 reportParseError("invalid option in .nan directive");
3866 bool MipsAsmParser::parseDirectiveSet() {
3867 MCAsmParser &Parser = getParser();
3868 // Get the next token.
3869 const AsmToken &Tok = Parser.getTok();
3871 if (Tok.getString() == "noat") {
3872 return parseSetNoAtDirective();
3873 } else if (Tok.getString() == "at") {
3874 return parseSetAtDirective();
3875 } else if (Tok.getString() == "arch") {
3876 return parseSetArchDirective();
3877 } else if (Tok.getString() == "fp") {
3878 return parseSetFpDirective();
3879 } else if (Tok.getString() == "pop") {
3880 return parseSetPopDirective();
3881 } else if (Tok.getString() == "push") {
3882 return parseSetPushDirective();
3883 } else if (Tok.getString() == "reorder") {
3884 return parseSetReorderDirective();
3885 } else if (Tok.getString() == "noreorder") {
3886 return parseSetNoReorderDirective();
3887 } else if (Tok.getString() == "macro") {
3888 return parseSetMacroDirective();
3889 } else if (Tok.getString() == "nomacro") {
3890 return parseSetNoMacroDirective();
3891 } else if (Tok.getString() == "mips16") {
3892 return parseSetMips16Directive();
3893 } else if (Tok.getString() == "nomips16") {
3894 return parseSetNoMips16Directive();
3895 } else if (Tok.getString() == "nomicromips") {
3896 getTargetStreamer().emitDirectiveSetNoMicroMips();
3897 Parser.eatToEndOfStatement();
3899 } else if (Tok.getString() == "micromips") {
3900 return parseSetFeature(Mips::FeatureMicroMips);
3901 } else if (Tok.getString() == "mips0") {
3902 return parseSetMips0Directive();
3903 } else if (Tok.getString() == "mips1") {
3904 return parseSetFeature(Mips::FeatureMips1);
3905 } else if (Tok.getString() == "mips2") {
3906 return parseSetFeature(Mips::FeatureMips2);
3907 } else if (Tok.getString() == "mips3") {
3908 return parseSetFeature(Mips::FeatureMips3);
3909 } else if (Tok.getString() == "mips4") {
3910 return parseSetFeature(Mips::FeatureMips4);
3911 } else if (Tok.getString() == "mips5") {
3912 return parseSetFeature(Mips::FeatureMips5);
3913 } else if (Tok.getString() == "mips32") {
3914 return parseSetFeature(Mips::FeatureMips32);
3915 } else if (Tok.getString() == "mips32r2") {
3916 return parseSetFeature(Mips::FeatureMips32r2);
3917 } else if (Tok.getString() == "mips32r3") {
3918 return parseSetFeature(Mips::FeatureMips32r3);
3919 } else if (Tok.getString() == "mips32r5") {
3920 return parseSetFeature(Mips::FeatureMips32r5);
3921 } else if (Tok.getString() == "mips32r6") {
3922 return parseSetFeature(Mips::FeatureMips32r6);
3923 } else if (Tok.getString() == "mips64") {
3924 return parseSetFeature(Mips::FeatureMips64);
3925 } else if (Tok.getString() == "mips64r2") {
3926 return parseSetFeature(Mips::FeatureMips64r2);
3927 } else if (Tok.getString() == "mips64r3") {
3928 return parseSetFeature(Mips::FeatureMips64r3);
3929 } else if (Tok.getString() == "mips64r5") {
3930 return parseSetFeature(Mips::FeatureMips64r5);
3931 } else if (Tok.getString() == "mips64r6") {
3932 return parseSetFeature(Mips::FeatureMips64r6);
3933 } else if (Tok.getString() == "dsp") {
3934 return parseSetFeature(Mips::FeatureDSP);
3935 } else if (Tok.getString() == "nodsp") {
3936 return parseSetNoDspDirective();
3937 } else if (Tok.getString() == "msa") {
3938 return parseSetMsaDirective();
3939 } else if (Tok.getString() == "nomsa") {
3940 return parseSetNoMsaDirective();
3942 // It is just an identifier, look for an assignment.
3943 parseSetAssignment();
3950 /// parseDataDirective
3951 /// ::= .word [ expression (, expression)* ]
3952 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3953 MCAsmParser &Parser = getParser();
3954 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3956 const MCExpr *Value;
3957 if (getParser().parseExpression(Value))
3960 getParser().getStreamer().EmitValue(Value, Size);
3962 if (getLexer().is(AsmToken::EndOfStatement))
3965 if (getLexer().isNot(AsmToken::Comma))
3966 return Error(L, "unexpected token, expected comma");
3975 /// parseDirectiveGpWord
3976 /// ::= .gpword local_sym
3977 bool MipsAsmParser::parseDirectiveGpWord() {
3978 MCAsmParser &Parser = getParser();
3979 const MCExpr *Value;
3980 // EmitGPRel32Value requires an expression, so we are using base class
3981 // method to evaluate the expression.
3982 if (getParser().parseExpression(Value))
3984 getParser().getStreamer().EmitGPRel32Value(Value);
3986 if (getLexer().isNot(AsmToken::EndOfStatement))
3987 return Error(getLexer().getLoc(),
3988 "unexpected token, expected end of statement");
3989 Parser.Lex(); // Eat EndOfStatement token.
3993 /// parseDirectiveGpDWord
3994 /// ::= .gpdword local_sym
3995 bool MipsAsmParser::parseDirectiveGpDWord() {
3996 MCAsmParser &Parser = getParser();
3997 const MCExpr *Value;
3998 // EmitGPRel64Value requires an expression, so we are using base class
3999 // method to evaluate the expression.
4000 if (getParser().parseExpression(Value))
4002 getParser().getStreamer().EmitGPRel64Value(Value);
4004 if (getLexer().isNot(AsmToken::EndOfStatement))
4005 return Error(getLexer().getLoc(),
4006 "unexpected token, expected end of statement");
4007 Parser.Lex(); // Eat EndOfStatement token.
4011 bool MipsAsmParser::parseDirectiveOption() {
4012 MCAsmParser &Parser = getParser();
4013 // Get the option token.
4014 AsmToken Tok = Parser.getTok();
4015 // At the moment only identifiers are supported.
4016 if (Tok.isNot(AsmToken::Identifier)) {
4017 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4018 Parser.eatToEndOfStatement();
4022 StringRef Option = Tok.getIdentifier();
4024 if (Option == "pic0") {
4025 getTargetStreamer().emitDirectiveOptionPic0();
4027 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4028 Error(Parser.getTok().getLoc(),
4029 "unexpected token, expected end of statement");
4030 Parser.eatToEndOfStatement();
4035 if (Option == "pic2") {
4036 getTargetStreamer().emitDirectiveOptionPic2();
4038 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4039 Error(Parser.getTok().getLoc(),
4040 "unexpected token, expected end of statement");
4041 Parser.eatToEndOfStatement();
4047 Warning(Parser.getTok().getLoc(),
4048 "unknown option, expected 'pic0' or 'pic2'");
4049 Parser.eatToEndOfStatement();
4053 /// parseDirectiveModule
4054 /// ::= .module oddspreg
4055 /// ::= .module nooddspreg
4056 /// ::= .module fp=value
4057 bool MipsAsmParser::parseDirectiveModule() {
4058 MCAsmParser &Parser = getParser();
4059 MCAsmLexer &Lexer = getLexer();
4060 SMLoc L = Lexer.getLoc();
4062 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4063 // TODO : get a better message.
4064 reportParseError(".module directive must appear before any code");
4069 if (Parser.parseIdentifier(Option)) {
4070 reportParseError("expected .module option identifier");
4074 if (Option == "oddspreg") {
4075 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4076 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4078 // If this is not the end of the statement, report an error.
4079 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4080 reportParseError("unexpected token, expected end of statement");
4084 return false; // parseDirectiveModule has finished successfully.
4085 } else if (Option == "nooddspreg") {
4087 Error(L, "'.module nooddspreg' requires the O32 ABI");
4091 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4092 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4094 // If this is not the end of the statement, report an error.
4095 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4096 reportParseError("unexpected token, expected end of statement");
4100 return false; // parseDirectiveModule has finished successfully.
4101 } else if (Option == "fp") {
4102 return parseDirectiveModuleFP();
4104 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4108 /// parseDirectiveModuleFP
4112 bool MipsAsmParser::parseDirectiveModuleFP() {
4113 MCAsmParser &Parser = getParser();
4114 MCAsmLexer &Lexer = getLexer();
4116 if (Lexer.isNot(AsmToken::Equal)) {
4117 reportParseError("unexpected token, expected equals sign '='");
4120 Parser.Lex(); // Eat '=' token.
4122 MipsABIFlagsSection::FpABIKind FpABI;
4123 if (!parseFpABIValue(FpABI, ".module"))
4126 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4127 reportParseError("unexpected token, expected end of statement");
4131 // Emit appropriate flags.
4132 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4133 Parser.Lex(); // Consume the EndOfStatement.
4137 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4138 StringRef Directive) {
4139 MCAsmParser &Parser = getParser();
4140 MCAsmLexer &Lexer = getLexer();
4142 if (Lexer.is(AsmToken::Identifier)) {
4143 StringRef Value = Parser.getTok().getString();
4146 if (Value != "xx") {
4147 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4152 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4156 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4160 if (Lexer.is(AsmToken::Integer)) {
4161 unsigned Value = Parser.getTok().getIntVal();
4164 if (Value != 32 && Value != 64) {
4165 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4171 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4175 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4177 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4185 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4186 MCAsmParser &Parser = getParser();
4187 StringRef IDVal = DirectiveID.getString();
4189 if (IDVal == ".cpload")
4190 return parseDirectiveCpLoad(DirectiveID.getLoc());
4191 if (IDVal == ".dword") {
4192 parseDataDirective(8, DirectiveID.getLoc());
4195 if (IDVal == ".ent") {
4196 StringRef SymbolName;
4198 if (Parser.parseIdentifier(SymbolName)) {
4199 reportParseError("expected identifier after .ent");
4203 // There's an undocumented extension that allows an integer to
4204 // follow the name of the procedure which AFAICS is ignored by GAS.
4205 // Example: .ent foo,2
4206 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4207 if (getLexer().isNot(AsmToken::Comma)) {
4208 // Even though we accept this undocumented extension for compatibility
4209 // reasons, the additional integer argument does not actually change
4210 // the behaviour of the '.ent' directive, so we would like to discourage
4211 // its use. We do this by not referring to the extended version in
4212 // error messages which are not directly related to its use.
4213 reportParseError("unexpected token, expected end of statement");
4216 Parser.Lex(); // Eat the comma.
4217 const MCExpr *DummyNumber;
4218 int64_t DummyNumberVal;
4219 // If the user was explicitly trying to use the extended version,
4220 // we still give helpful extension-related error messages.
4221 if (Parser.parseExpression(DummyNumber)) {
4222 reportParseError("expected number after comma");
4225 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4226 reportParseError("expected an absolute expression after comma");
4231 // If this is not the end of the statement, report an error.
4232 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4233 reportParseError("unexpected token, expected end of statement");
4237 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4239 getTargetStreamer().emitDirectiveEnt(*Sym);
4244 if (IDVal == ".end") {
4245 StringRef SymbolName;
4247 if (Parser.parseIdentifier(SymbolName)) {
4248 reportParseError("expected identifier after .end");
4252 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4253 reportParseError("unexpected token, expected end of statement");
4257 if (CurrentFn == nullptr) {
4258 reportParseError(".end used without .ent");
4262 if ((SymbolName != CurrentFn->getName())) {
4263 reportParseError(".end symbol does not match .ent symbol");
4267 getTargetStreamer().emitDirectiveEnd(SymbolName);
4268 CurrentFn = nullptr;
4272 if (IDVal == ".frame") {
4273 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4274 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4275 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4276 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4277 reportParseError("expected stack register");
4281 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4282 if (!StackRegOpnd.isGPRAsmReg()) {
4283 reportParseError(StackRegOpnd.getStartLoc(),
4284 "expected general purpose register");
4287 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4289 if (Parser.getTok().is(AsmToken::Comma))
4292 reportParseError("unexpected token, expected comma");
4296 // Parse the frame size.
4297 const MCExpr *FrameSize;
4298 int64_t FrameSizeVal;
4300 if (Parser.parseExpression(FrameSize)) {
4301 reportParseError("expected frame size value");
4305 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4306 reportParseError("frame size not an absolute expression");
4310 if (Parser.getTok().is(AsmToken::Comma))
4313 reportParseError("unexpected token, expected comma");
4317 // Parse the return register.
4319 ResTy = parseAnyRegister(TmpReg);
4320 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4321 reportParseError("expected return register");
4325 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4326 if (!ReturnRegOpnd.isGPRAsmReg()) {
4327 reportParseError(ReturnRegOpnd.getStartLoc(),
4328 "expected general purpose register");
4332 // If this is not the end of the statement, report an error.
4333 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4334 reportParseError("unexpected token, expected end of statement");
4338 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4339 ReturnRegOpnd.getGPR32Reg());
4343 if (IDVal == ".set") {
4344 return parseDirectiveSet();
4347 if (IDVal == ".mask" || IDVal == ".fmask") {
4348 // .mask bitmask, frame_offset
4349 // bitmask: One bit for each register used.
4350 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4351 // first register is expected to be saved.
4353 // .mask 0x80000000, -4
4354 // .fmask 0x80000000, -4
4357 // Parse the bitmask
4358 const MCExpr *BitMask;
4361 if (Parser.parseExpression(BitMask)) {
4362 reportParseError("expected bitmask value");
4366 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4367 reportParseError("bitmask not an absolute expression");
4371 if (Parser.getTok().is(AsmToken::Comma))
4374 reportParseError("unexpected token, expected comma");
4378 // Parse the frame_offset
4379 const MCExpr *FrameOffset;
4380 int64_t FrameOffsetVal;
4382 if (Parser.parseExpression(FrameOffset)) {
4383 reportParseError("expected frame offset value");
4387 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4388 reportParseError("frame offset not an absolute expression");
4392 // If this is not the end of the statement, report an error.
4393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4394 reportParseError("unexpected token, expected end of statement");
4398 if (IDVal == ".mask")
4399 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4401 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4405 if (IDVal == ".nan")
4406 return parseDirectiveNaN();
4408 if (IDVal == ".gpword") {
4409 parseDirectiveGpWord();
4413 if (IDVal == ".gpdword") {
4414 parseDirectiveGpDWord();
4418 if (IDVal == ".word") {
4419 parseDataDirective(4, DirectiveID.getLoc());
4423 if (IDVal == ".option")
4424 return parseDirectiveOption();
4426 if (IDVal == ".abicalls") {
4427 getTargetStreamer().emitDirectiveAbiCalls();
4428 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4429 Error(Parser.getTok().getLoc(),
4430 "unexpected token, expected end of statement");
4432 Parser.eatToEndOfStatement();
4437 if (IDVal == ".cpsetup")
4438 return parseDirectiveCPSetup();
4440 if (IDVal == ".module")
4441 return parseDirectiveModule();
4443 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4444 return parseInternalDirectiveReallowModule();
4449 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4450 // If this is not the end of the statement, report an error.
4451 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4452 reportParseError("unexpected token, expected end of statement");
4456 getTargetStreamer().reallowModuleDirective();
4458 getParser().Lex(); // Eat EndOfStatement token.
4462 extern "C" void LLVMInitializeMipsAsmParser() {
4463 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4464 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4465 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4466 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4469 #define GET_REGISTER_MATCHER
4470 #define GET_MATCHER_IMPLEMENTATION
4471 #include "MipsGenAsmMatcher.inc"