1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegIndex();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegIndex() const { return ATReg; }
57 bool setATRegIndex(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const FeatureBitset AllArchRelatedMask;
91 const FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
92 Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
93 Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
94 Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
95 Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
96 Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
97 Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
98 Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
99 Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
103 class MipsAsmParser : public MCTargetAsmParser {
104 MipsTargetStreamer &getTargetStreamer() {
105 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
106 return static_cast<MipsTargetStreamer &>(TS);
109 MCSubtargetInfo &STI;
111 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
112 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
113 // nullptr, which indicates that no function is currently
114 // selected. This usually happens after an '.end func'
117 // Print a warning along with its fix-it message at the given range.
118 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
119 SMRange Range, bool ShowColors = true);
121 #define GET_ASSEMBLER_HEADER
122 #include "MipsGenAsmMatcher.inc"
124 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
126 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
127 OperandVector &Operands, MCStreamer &Out,
129 bool MatchingInlineAsm) override;
131 /// Parse a register as used in CFI directives
132 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
134 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
136 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
138 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
139 SMLoc NameLoc, OperandVector &Operands) override;
141 bool ParseDirective(AsmToken DirectiveID) override;
143 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy
146 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
147 StringRef Identifier, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy
150 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
152 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
156 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
158 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
160 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseRegisterPair (OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseMovePRegPair(OperandVector &Operands);
168 MipsAsmParser::OperandMatchResultTy
169 parseRegisterList (OperandVector &Operands);
171 bool searchSymbolAlias(OperandVector &Operands);
173 bool parseOperand(OperandVector &, StringRef Mnemonic);
175 bool needsExpansion(MCInst &Inst);
177 // Expands assembly pseudo instructions.
178 // Returns false on success, true otherwise.
179 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
191 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
192 SmallVectorImpl<MCInst> &Instructions);
193 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions);
199 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
200 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
203 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
207 SmallVectorImpl<MCInst> &Instructions);
209 bool reportParseError(Twine ErrorMsg);
210 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
212 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
213 bool parseRelocOperand(const MCExpr *&Res);
215 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
217 bool isEvaluated(const MCExpr *Expr);
218 bool parseSetMips0Directive();
219 bool parseSetArchDirective();
220 bool parseSetFeature(uint64_t Feature);
221 bool parseDirectiveCpLoad(SMLoc Loc);
222 bool parseDirectiveCPSetup();
223 bool parseDirectiveNaN();
224 bool parseDirectiveSet();
225 bool parseDirectiveOption();
226 bool parseInsnDirective();
228 bool parseSetAtDirective();
229 bool parseSetNoAtDirective();
230 bool parseSetMacroDirective();
231 bool parseSetNoMacroDirective();
232 bool parseSetMsaDirective();
233 bool parseSetNoMsaDirective();
234 bool parseSetNoDspDirective();
235 bool parseSetReorderDirective();
236 bool parseSetNoReorderDirective();
237 bool parseSetMips16Directive();
238 bool parseSetNoMips16Directive();
239 bool parseSetFpDirective();
240 bool parseSetPopDirective();
241 bool parseSetPushDirective();
243 bool parseSetAssignment();
245 bool parseDataDirective(unsigned Size, SMLoc L);
246 bool parseDirectiveGpWord();
247 bool parseDirectiveGpDWord();
248 bool parseDirectiveModule();
249 bool parseDirectiveModuleFP();
250 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
251 StringRef Directive);
253 bool parseInternalDirectiveReallowModule();
255 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
257 bool eatComma(StringRef ErrorStr);
259 int matchCPURegisterName(StringRef Symbol);
261 int matchHWRegsRegisterName(StringRef Symbol);
263 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
265 int matchFPURegisterName(StringRef Name);
267 int matchFCCRegisterName(StringRef Name);
269 int matchACRegisterName(StringRef Name);
271 int matchMSA128RegisterName(StringRef Name);
273 int matchMSA128CtrlRegisterName(StringRef Name);
275 unsigned getReg(int RC, int RegNo);
277 unsigned getGPR(int RegNo);
279 /// Returns the internal register number for the current AT. Also checks if
280 /// the current AT is unavailable (set to $0) and gives an error if it is.
281 /// This should be used in pseudo-instruction expansions which need AT.
282 unsigned getATReg(SMLoc Loc);
284 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
285 SmallVectorImpl<MCInst> &Instructions);
287 // Helper function that checks if the value of a vector index is within the
288 // boundaries of accepted values for each RegisterKind
289 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
290 bool validateMSAIndex(int Val, int RegKind);
292 // Selects a new architecture by updating the FeatureBits with the necessary
293 // info including implied dependencies.
294 // Internally, it clears all the feature bits related to *any* architecture
295 // and selects the new one using the ToggleFeature functionality of the
296 // MCSubtargetInfo object that handles implied dependencies. The reason we
297 // clear all the arch related bits manually is because ToggleFeature only
298 // clears the features that imply the feature being cleared and not the
299 // features implied by the feature being cleared. This is easier to see
301 // --------------------------------------------------
302 // | Feature | Implies |
303 // | -------------------------------------------------|
304 // | FeatureMips1 | None |
305 // | FeatureMips2 | FeatureMips1 |
306 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
307 // | FeatureMips4 | FeatureMips3 |
309 // --------------------------------------------------
311 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
312 // FeatureMipsGP64 | FeatureMips1)
313 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
314 void selectArch(StringRef ArchFeature) {
315 FeatureBitset FeatureBits = STI.getFeatureBits();
316 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
317 STI.setFeatureBits(FeatureBits);
318 setAvailableFeatures(
319 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
320 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
323 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
324 if (!(STI.getFeatureBits()[Feature])) {
325 setAvailableFeatures(
326 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
328 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
331 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
332 if (STI.getFeatureBits()[Feature]) {
333 setAvailableFeatures(
334 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
336 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
340 enum MipsMatchResultTy {
341 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
342 #define GET_OPERAND_DIAGNOSTIC_TYPES
343 #include "MipsGenAsmMatcher.inc"
344 #undef GET_OPERAND_DIAGNOSTIC_TYPES
348 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
349 const MCInstrInfo &MII, const MCTargetOptions &Options)
350 : MCTargetAsmParser(), STI(sti),
351 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
352 sti.getCPU(), Options)) {
353 MCAsmParserExtension::Initialize(parser);
355 parser.addAliasForDirective(".asciiz", ".asciz");
357 // Initialize the set of available features.
358 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
360 // Remember the initial assembler options. The user can not modify these.
361 AssemblerOptions.push_back(
362 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
364 // Create an assembler options environment for the user to modify.
365 AssemblerOptions.push_back(
366 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
368 getTargetStreamer().updateABIInfo(*this);
370 if (!isABI_O32() && !useOddSPReg() != 0)
371 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
376 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
377 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
379 bool isGP64bit() const { return STI.getFeatureBits()[Mips::FeatureGP64Bit]; }
380 bool isFP64bit() const { return STI.getFeatureBits()[Mips::FeatureFP64Bit]; }
381 const MipsABIInfo &getABI() const { return ABI; }
382 bool isABI_N32() const { return ABI.IsN32(); }
383 bool isABI_N64() const { return ABI.IsN64(); }
384 bool isABI_O32() const { return ABI.IsO32(); }
385 bool isABI_FPXX() const { return STI.getFeatureBits()[Mips::FeatureFPXX]; }
387 bool useOddSPReg() const {
388 return !(STI.getFeatureBits()[Mips::FeatureNoOddSPReg]);
391 bool inMicroMipsMode() const {
392 return STI.getFeatureBits()[Mips::FeatureMicroMips];
394 bool hasMips1() const { return STI.getFeatureBits()[Mips::FeatureMips1]; }
395 bool hasMips2() const { return STI.getFeatureBits()[Mips::FeatureMips2]; }
396 bool hasMips3() const { return STI.getFeatureBits()[Mips::FeatureMips3]; }
397 bool hasMips4() const { return STI.getFeatureBits()[Mips::FeatureMips4]; }
398 bool hasMips5() const { return STI.getFeatureBits()[Mips::FeatureMips5]; }
399 bool hasMips32() const {
400 return STI.getFeatureBits()[Mips::FeatureMips32];
402 bool hasMips64() const {
403 return STI.getFeatureBits()[Mips::FeatureMips64];
405 bool hasMips32r2() const {
406 return STI.getFeatureBits()[Mips::FeatureMips32r2];
408 bool hasMips64r2() const {
409 return STI.getFeatureBits()[Mips::FeatureMips64r2];
411 bool hasMips32r3() const {
412 return (STI.getFeatureBits()[Mips::FeatureMips32r3]);
414 bool hasMips64r3() const {
415 return (STI.getFeatureBits()[Mips::FeatureMips64r3]);
417 bool hasMips32r5() const {
418 return (STI.getFeatureBits()[Mips::FeatureMips32r5]);
420 bool hasMips64r5() const {
421 return (STI.getFeatureBits()[Mips::FeatureMips64r5]);
423 bool hasMips32r6() const {
424 return STI.getFeatureBits()[Mips::FeatureMips32r6];
426 bool hasMips64r6() const {
427 return STI.getFeatureBits()[Mips::FeatureMips64r6];
430 bool hasDSP() const { return STI.getFeatureBits()[Mips::FeatureDSP]; }
431 bool hasDSPR2() const { return STI.getFeatureBits()[Mips::FeatureDSPR2]; }
432 bool hasMSA() const { return STI.getFeatureBits()[Mips::FeatureMSA]; }
433 bool hasCnMips() const {
434 return (STI.getFeatureBits()[Mips::FeatureCnMips]);
437 bool inMips16Mode() const {
438 return STI.getFeatureBits()[Mips::FeatureMips16];
441 bool useSoftFloat() const {
442 return STI.getFeatureBits()[Mips::FeatureSoftFloat];
445 /// Warn if RegIndex is the same as the current AT.
446 void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
452 /// MipsOperand - Instances of this class represent a parsed Mips machine
454 class MipsOperand : public MCParsedAsmOperand {
456 /// Broad categories of register classes
457 /// The exact class is finalized by the render method.
459 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
460 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
462 RegKind_FCC = 4, /// FCC
463 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
464 RegKind_MSACtrl = 16, /// MSA control registers
465 RegKind_COP2 = 32, /// COP2
466 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
468 RegKind_CCR = 128, /// CCR
469 RegKind_HWRegs = 256, /// HWRegs
470 RegKind_COP3 = 512, /// COP3
472 /// Potentially any (e.g. $1)
473 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
474 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
475 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
480 k_Immediate, /// An immediate (possibly involving symbol references)
481 k_Memory, /// Base + Offset Memory Address
482 k_PhysRegister, /// A physical register from the Mips namespace
483 k_RegisterIndex, /// A register index in one or more RegKind.
484 k_Token, /// A simple token
485 k_RegList, /// A physical register list
486 k_RegPair /// A pair of physical register
490 MipsOperand(KindTy K, MipsAsmParser &Parser)
491 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
494 /// For diagnostics, and checking the assembler temporary
495 MipsAsmParser &AsmParser;
503 unsigned Num; /// Register Number
507 unsigned Index; /// Index into the register class
508 RegKind Kind; /// Bitfield of the kinds it could possibly be
509 const MCRegisterInfo *RegInfo;
522 SmallVector<unsigned, 10> *List;
527 struct PhysRegOp PhysReg;
528 struct RegIdxOp RegIdx;
531 struct RegListOp RegList;
534 SMLoc StartLoc, EndLoc;
536 /// Internal constructor for register kinds
537 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
538 const MCRegisterInfo *RegInfo,
540 MipsAsmParser &Parser) {
541 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
542 Op->RegIdx.Index = Index;
543 Op->RegIdx.RegInfo = RegInfo;
544 Op->RegIdx.Kind = RegKind;
551 /// Coerce the register to GPR32 and return the real register for the current
553 unsigned getGPR32Reg() const {
554 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
555 AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
556 unsigned ClassID = Mips::GPR32RegClassID;
557 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
560 /// Coerce the register to GPR32 and return the real register for the current
562 unsigned getGPRMM16Reg() const {
563 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
564 unsigned ClassID = Mips::GPR32RegClassID;
565 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
568 /// Coerce the register to GPR64 and return the real register for the current
570 unsigned getGPR64Reg() const {
571 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
572 unsigned ClassID = Mips::GPR64RegClassID;
573 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
577 /// Coerce the register to AFGR64 and return the real register for the current
579 unsigned getAFGR64Reg() const {
580 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
581 if (RegIdx.Index % 2 != 0)
582 AsmParser.Warning(StartLoc, "Float register should be even.");
583 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
584 .getRegister(RegIdx.Index / 2);
587 /// Coerce the register to FGR64 and return the real register for the current
589 unsigned getFGR64Reg() const {
590 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
591 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
592 .getRegister(RegIdx.Index);
595 /// Coerce the register to FGR32 and return the real register for the current
597 unsigned getFGR32Reg() const {
598 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
599 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
600 .getRegister(RegIdx.Index);
603 /// Coerce the register to FGRH32 and return the real register for the current
605 unsigned getFGRH32Reg() const {
606 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
607 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
608 .getRegister(RegIdx.Index);
611 /// Coerce the register to FCC and return the real register for the current
613 unsigned getFCCReg() const {
614 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
615 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
616 .getRegister(RegIdx.Index);
619 /// Coerce the register to MSA128 and return the real register for the current
621 unsigned getMSA128Reg() const {
622 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
623 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
625 unsigned ClassID = Mips::MSA128BRegClassID;
626 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
629 /// Coerce the register to MSACtrl and return the real register for the
631 unsigned getMSACtrlReg() const {
632 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
633 unsigned ClassID = Mips::MSACtrlRegClassID;
634 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
637 /// Coerce the register to COP2 and return the real register for the
639 unsigned getCOP2Reg() const {
640 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
641 unsigned ClassID = Mips::COP2RegClassID;
642 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
645 /// Coerce the register to COP3 and return the real register for the
647 unsigned getCOP3Reg() const {
648 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
649 unsigned ClassID = Mips::COP3RegClassID;
650 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
653 /// Coerce the register to ACC64DSP and return the real register for the
655 unsigned getACC64DSPReg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
657 unsigned ClassID = Mips::ACC64DSPRegClassID;
658 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
661 /// Coerce the register to HI32DSP and return the real register for the
663 unsigned getHI32DSPReg() const {
664 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
665 unsigned ClassID = Mips::HI32DSPRegClassID;
666 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
669 /// Coerce the register to LO32DSP and return the real register for the
671 unsigned getLO32DSPReg() const {
672 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
673 unsigned ClassID = Mips::LO32DSPRegClassID;
674 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
677 /// Coerce the register to CCR and return the real register for the
679 unsigned getCCRReg() const {
680 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
681 unsigned ClassID = Mips::CCRRegClassID;
682 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
685 /// Coerce the register to HWRegs and return the real register for the
687 unsigned getHWRegsReg() const {
688 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
689 unsigned ClassID = Mips::HWRegsRegClassID;
690 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
694 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
695 // Add as immediate when possible. Null MCExpr = 0.
697 Inst.addOperand(MCOperand::CreateImm(0));
698 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
699 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
701 Inst.addOperand(MCOperand::CreateExpr(Expr));
704 void addRegOperands(MCInst &Inst, unsigned N) const {
705 llvm_unreachable("Use a custom parser instead");
708 /// Render the operand to an MCInst as a GPR32
709 /// Asserts if the wrong number of operands are requested, or the operand
710 /// is not a k_RegisterIndex compatible with RegKind_GPR
711 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
712 assert(N == 1 && "Invalid number of operands!");
713 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
716 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
717 assert(N == 1 && "Invalid number of operands!");
718 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
721 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
722 assert(N == 1 && "Invalid number of operands!");
723 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
726 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
731 /// Render the operand to an MCInst as a GPR64
732 /// Asserts if the wrong number of operands are requested, or the operand
733 /// is not a k_RegisterIndex compatible with RegKind_GPR
734 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
739 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
744 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
749 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
752 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
753 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
754 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
758 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
759 assert(N == 1 && "Invalid number of operands!");
760 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
763 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
764 assert(N == 1 && "Invalid number of operands!");
765 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
768 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 1 && "Invalid number of operands!");
770 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
773 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
774 assert(N == 1 && "Invalid number of operands!");
775 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
778 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
779 assert(N == 1 && "Invalid number of operands!");
780 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
783 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
785 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
788 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
789 assert(N == 1 && "Invalid number of operands!");
790 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
793 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
794 assert(N == 1 && "Invalid number of operands!");
795 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
798 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
799 assert(N == 1 && "Invalid number of operands!");
800 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
803 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
804 assert(N == 1 && "Invalid number of operands!");
805 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
808 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
809 assert(N == 1 && "Invalid number of operands!");
810 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
813 void addImmOperands(MCInst &Inst, unsigned N) const {
814 assert(N == 1 && "Invalid number of operands!");
815 const MCExpr *Expr = getImm();
819 void addMemOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 2 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
824 const MCExpr *Expr = getMemOff();
828 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 2 && "Invalid number of operands!");
831 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
833 const MCExpr *Expr = getMemOff();
837 void addRegListOperands(MCInst &Inst, unsigned N) const {
838 assert(N == 1 && "Invalid number of operands!");
840 for (auto RegNo : getRegList())
841 Inst.addOperand(MCOperand::CreateReg(RegNo));
844 void addRegPairOperands(MCInst &Inst, unsigned N) const {
845 assert(N == 2 && "Invalid number of operands!");
846 unsigned RegNo = getRegPair();
847 Inst.addOperand(MCOperand::CreateReg(RegNo++));
848 Inst.addOperand(MCOperand::CreateReg(RegNo));
851 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
852 assert(N == 2 && "Invalid number of operands!");
853 for (auto RegNo : getRegList())
854 Inst.addOperand(MCOperand::CreateReg(RegNo));
857 bool isReg() const override {
858 // As a special case until we sort out the definition of div/divu, pretend
859 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
860 if (isGPRAsmReg() && RegIdx.Index == 0)
863 return Kind == k_PhysRegister;
865 bool isRegIdx() const { return Kind == k_RegisterIndex; }
866 bool isImm() const override { return Kind == k_Immediate; }
867 bool isConstantImm() const {
868 return isImm() && dyn_cast<MCConstantExpr>(getImm());
870 bool isToken() const override {
871 // Note: It's not possible to pretend that other operand kinds are tokens.
872 // The matcher emitter checks tokens first.
873 return Kind == k_Token;
875 bool isMem() const override { return Kind == k_Memory; }
876 bool isConstantMemOff() const {
877 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
879 template <unsigned Bits> bool isMemWithSimmOffset() const {
880 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
882 bool isMemWithGRPMM16Base() const {
883 return isMem() && getMemBase()->isMM16AsmReg();
885 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
886 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
887 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
889 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
890 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
891 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
892 && (getMemBase()->getGPR32Reg() == Mips::SP);
894 bool isRegList16() const {
898 int Size = RegList.List->size();
899 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
900 RegList.List->back() != Mips::RA)
903 int PrevReg = *RegList.List->begin();
904 for (int i = 1; i < Size - 1; i++) {
905 int Reg = (*(RegList.List))[i];
906 if ( Reg != PrevReg + 1)
913 bool isInvNum() const { return Kind == k_Immediate; }
914 bool isLSAImm() const {
915 if (!isConstantImm())
917 int64_t Val = getConstantImm();
918 return 1 <= Val && Val <= 4;
920 bool isRegList() const { return Kind == k_RegList; }
921 bool isMovePRegPair() const {
922 if (Kind != k_RegList || RegList.List->size() != 2)
925 unsigned R0 = RegList.List->front();
926 unsigned R1 = RegList.List->back();
928 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
929 (R0 == Mips::A1 && R1 == Mips::A3) ||
930 (R0 == Mips::A2 && R1 == Mips::A3) ||
931 (R0 == Mips::A0 && R1 == Mips::S5) ||
932 (R0 == Mips::A0 && R1 == Mips::S6) ||
933 (R0 == Mips::A0 && R1 == Mips::A1) ||
934 (R0 == Mips::A0 && R1 == Mips::A2) ||
935 (R0 == Mips::A0 && R1 == Mips::A3))
941 StringRef getToken() const {
942 assert(Kind == k_Token && "Invalid access!");
943 return StringRef(Tok.Data, Tok.Length);
945 bool isRegPair() const { return Kind == k_RegPair; }
947 unsigned getReg() const override {
948 // As a special case until we sort out the definition of div/divu, pretend
949 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
950 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
951 RegIdx.Kind & RegKind_GPR)
952 return getGPR32Reg(); // FIXME: GPR64 too
954 assert(Kind == k_PhysRegister && "Invalid access!");
958 const MCExpr *getImm() const {
959 assert((Kind == k_Immediate) && "Invalid access!");
963 int64_t getConstantImm() const {
964 const MCExpr *Val = getImm();
965 return static_cast<const MCConstantExpr *>(Val)->getValue();
968 MipsOperand *getMemBase() const {
969 assert((Kind == k_Memory) && "Invalid access!");
973 const MCExpr *getMemOff() const {
974 assert((Kind == k_Memory) && "Invalid access!");
978 int64_t getConstantMemOff() const {
979 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
982 const SmallVectorImpl<unsigned> &getRegList() const {
983 assert((Kind == k_RegList) && "Invalid access!");
984 return *(RegList.List);
987 unsigned getRegPair() const {
988 assert((Kind == k_RegPair) && "Invalid access!");
992 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
993 MipsAsmParser &Parser) {
994 auto Op = make_unique<MipsOperand>(k_Token, Parser);
995 Op->Tok.Data = Str.data();
996 Op->Tok.Length = Str.size();
1002 /// Create a numeric register (e.g. $1). The exact register remains
1003 /// unresolved until an instruction successfully matches
1004 static std::unique_ptr<MipsOperand>
1005 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1006 SMLoc E, MipsAsmParser &Parser) {
1007 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1008 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1011 /// Create a register that is definitely a GPR.
1012 /// This is typically only used for named registers such as $gp.
1013 static std::unique_ptr<MipsOperand>
1014 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1015 MipsAsmParser &Parser) {
1016 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1019 /// Create a register that is definitely a FGR.
1020 /// This is typically only used for named registers such as $f0.
1021 static std::unique_ptr<MipsOperand>
1022 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1023 MipsAsmParser &Parser) {
1024 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1027 /// Create a register that is definitely a HWReg.
1028 /// This is typically only used for named registers such as $hwr_cpunum.
1029 static std::unique_ptr<MipsOperand>
1030 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1031 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1032 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1035 /// Create a register that is definitely an FCC.
1036 /// This is typically only used for named registers such as $fcc0.
1037 static std::unique_ptr<MipsOperand>
1038 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1039 MipsAsmParser &Parser) {
1040 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1043 /// Create a register that is definitely an ACC.
1044 /// This is typically only used for named registers such as $ac0.
1045 static std::unique_ptr<MipsOperand>
1046 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1047 MipsAsmParser &Parser) {
1048 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1051 /// Create a register that is definitely an MSA128.
1052 /// This is typically only used for named registers such as $w0.
1053 static std::unique_ptr<MipsOperand>
1054 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1055 SMLoc E, MipsAsmParser &Parser) {
1056 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1059 /// Create a register that is definitely an MSACtrl.
1060 /// This is typically only used for named registers such as $msaaccess.
1061 static std::unique_ptr<MipsOperand>
1062 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1063 SMLoc E, MipsAsmParser &Parser) {
1064 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1067 static std::unique_ptr<MipsOperand>
1068 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1069 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1076 static std::unique_ptr<MipsOperand>
1077 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1078 SMLoc E, MipsAsmParser &Parser) {
1079 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1080 Op->Mem.Base = Base.release();
1087 static std::unique_ptr<MipsOperand>
1088 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1089 MipsAsmParser &Parser) {
1090 assert (Regs.size() > 0 && "Empty list not allowed");
1092 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1093 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1094 Op->StartLoc = StartLoc;
1095 Op->EndLoc = EndLoc;
1099 static std::unique_ptr<MipsOperand>
1100 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1101 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1102 Op->RegIdx.Index = RegNo;
1108 bool isGPRAsmReg() const {
1109 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1111 bool isMM16AsmReg() const {
1112 if (!(isRegIdx() && RegIdx.Kind))
1114 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1115 || RegIdx.Index == 16 || RegIdx.Index == 17);
1117 bool isMM16AsmRegZero() const {
1118 if (!(isRegIdx() && RegIdx.Kind))
1120 return (RegIdx.Index == 0 ||
1121 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1122 RegIdx.Index == 17);
1124 bool isMM16AsmRegMoveP() const {
1125 if (!(isRegIdx() && RegIdx.Kind))
1127 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1128 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1130 bool isFGRAsmReg() const {
1131 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1132 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1134 bool isHWRegsAsmReg() const {
1135 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1137 bool isCCRAsmReg() const {
1138 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1140 bool isFCCAsmReg() const {
1141 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1143 if (!AsmParser.hasEightFccRegisters())
1144 return RegIdx.Index == 0;
1145 return RegIdx.Index <= 7;
1147 bool isACCAsmReg() const {
1148 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1150 bool isCOP2AsmReg() const {
1151 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1153 bool isCOP3AsmReg() const {
1154 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1156 bool isMSA128AsmReg() const {
1157 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1159 bool isMSACtrlAsmReg() const {
1160 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1163 /// getStartLoc - Get the location of the first token of this operand.
1164 SMLoc getStartLoc() const override { return StartLoc; }
1165 /// getEndLoc - Get the location of the last token of this operand.
1166 SMLoc getEndLoc() const override { return EndLoc; }
1168 virtual ~MipsOperand() {
1176 delete RegList.List;
1177 case k_PhysRegister:
1178 case k_RegisterIndex:
1185 void print(raw_ostream &OS) const override {
1194 Mem.Base->print(OS);
1199 case k_PhysRegister:
1200 OS << "PhysReg<" << PhysReg.Num << ">";
1202 case k_RegisterIndex:
1203 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1210 for (auto Reg : (*RegList.List))
1215 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1219 }; // class MipsOperand
1223 extern const MCInstrDesc MipsInsts[];
1225 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1226 return MipsInsts[Opcode];
1229 static bool hasShortDelaySlot(unsigned Opcode) {
1232 case Mips::JALRS_MM:
1233 case Mips::JALRS16_MM:
1234 case Mips::BGEZALS_MM:
1235 case Mips::BLTZALS_MM:
1242 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1243 SmallVectorImpl<MCInst> &Instructions) {
1244 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1248 if (MCID.isBranch() || MCID.isCall()) {
1249 const unsigned Opcode = Inst.getOpcode();
1259 assert(hasCnMips() && "instruction only valid for octeon cpus");
1266 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1267 Offset = Inst.getOperand(2);
1268 if (!Offset.isImm())
1269 break; // We'll deal with this situation later on when applying fixups.
1270 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1271 return Error(IDLoc, "branch target out of range");
1272 if (OffsetToAlignment(Offset.getImm(),
1273 1LL << (inMicroMipsMode() ? 1 : 2)))
1274 return Error(IDLoc, "branch to misaligned address");
1288 case Mips::BGEZAL_MM:
1289 case Mips::BLTZAL_MM:
1292 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1293 Offset = Inst.getOperand(1);
1294 if (!Offset.isImm())
1295 break; // We'll deal with this situation later on when applying fixups.
1296 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1297 return Error(IDLoc, "branch target out of range");
1298 if (OffsetToAlignment(Offset.getImm(),
1299 1LL << (inMicroMipsMode() ? 1 : 2)))
1300 return Error(IDLoc, "branch to misaligned address");
1302 case Mips::BEQZ16_MM:
1303 case Mips::BNEZ16_MM:
1304 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1305 Offset = Inst.getOperand(1);
1306 if (!Offset.isImm())
1307 break; // We'll deal with this situation later on when applying fixups.
1308 if (!isIntN(8, Offset.getImm()))
1309 return Error(IDLoc, "branch target out of range");
1310 if (OffsetToAlignment(Offset.getImm(), 2LL))
1311 return Error(IDLoc, "branch to misaligned address");
1316 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1317 // We still accept it but it is a normal nop.
1318 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1319 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1320 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1325 const unsigned Opcode = Inst.getOpcode();
1337 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1338 // The offset is handled above
1339 Opnd = Inst.getOperand(1);
1341 return Error(IDLoc, "expected immediate operand kind");
1342 Imm = Opnd.getImm();
1343 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1344 Opcode == Mips::BBIT1 ? 63 : 31))
1345 return Error(IDLoc, "immediate operand value out of range");
1347 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1349 Inst.getOperand(1).setImm(Imm - 32);
1357 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1359 Opnd = Inst.getOperand(3);
1361 return Error(IDLoc, "expected immediate operand kind");
1362 Imm = Opnd.getImm();
1363 if (Imm < 0 || Imm > 31)
1364 return Error(IDLoc, "immediate operand value out of range");
1366 Opnd = Inst.getOperand(2);
1368 return Error(IDLoc, "expected immediate operand kind");
1369 Imm = Opnd.getImm();
1370 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1371 Opcode == Mips::EXTS ? 63 : 31))
1372 return Error(IDLoc, "immediate operand value out of range");
1374 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1375 Inst.getOperand(2).setImm(Imm - 32);
1381 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1382 Opnd = Inst.getOperand(2);
1384 return Error(IDLoc, "expected immediate operand kind");
1385 Imm = Opnd.getImm();
1386 if (!isInt<10>(Imm))
1387 return Error(IDLoc, "immediate operand value out of range");
1392 if (MCID.mayLoad() || MCID.mayStore()) {
1393 // Check the offset of memory operand, if it is a symbol
1394 // reference or immediate we may have to expand instructions.
1395 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1396 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1397 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1398 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1399 MCOperand &Op = Inst.getOperand(i);
1401 int MemOffset = Op.getImm();
1402 if (MemOffset < -32768 || MemOffset > 32767) {
1403 // Offset can't exceed 16bit value.
1404 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1407 } else if (Op.isExpr()) {
1408 const MCExpr *Expr = Op.getExpr();
1409 if (Expr->getKind() == MCExpr::SymbolRef) {
1410 const MCSymbolRefExpr *SR =
1411 static_cast<const MCSymbolRefExpr *>(Expr);
1412 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1414 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1417 } else if (!isEvaluated(Expr)) {
1418 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1426 if (inMicroMipsMode()) {
1427 if (MCID.mayLoad()) {
1428 // Try to create 16-bit GP relative load instruction.
1429 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1430 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1431 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1432 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1433 MCOperand &Op = Inst.getOperand(i);
1435 int MemOffset = Op.getImm();
1436 MCOperand &DstReg = Inst.getOperand(0);
1437 MCOperand &BaseReg = Inst.getOperand(1);
1438 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1439 getContext().getRegisterInfo()->getRegClass(
1440 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1441 BaseReg.getReg() == Mips::GP) {
1443 TmpInst.setLoc(IDLoc);
1444 TmpInst.setOpcode(Mips::LWGP_MM);
1445 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1446 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1447 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1448 Instructions.push_back(TmpInst);
1456 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1461 switch (Inst.getOpcode()) {
1464 case Mips::ADDIUS5_MM:
1465 Opnd = Inst.getOperand(2);
1467 return Error(IDLoc, "expected immediate operand kind");
1468 Imm = Opnd.getImm();
1469 if (Imm < -8 || Imm > 7)
1470 return Error(IDLoc, "immediate operand value out of range");
1472 case Mips::ADDIUSP_MM:
1473 Opnd = Inst.getOperand(0);
1475 return Error(IDLoc, "expected immediate operand kind");
1476 Imm = Opnd.getImm();
1477 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1479 return Error(IDLoc, "immediate operand value out of range");
1481 case Mips::SLL16_MM:
1482 case Mips::SRL16_MM:
1483 Opnd = Inst.getOperand(2);
1485 return Error(IDLoc, "expected immediate operand kind");
1486 Imm = Opnd.getImm();
1487 if (Imm < 1 || Imm > 8)
1488 return Error(IDLoc, "immediate operand value out of range");
1491 Opnd = Inst.getOperand(1);
1493 return Error(IDLoc, "expected immediate operand kind");
1494 Imm = Opnd.getImm();
1495 if (Imm < -1 || Imm > 126)
1496 return Error(IDLoc, "immediate operand value out of range");
1498 case Mips::ADDIUR2_MM:
1499 Opnd = Inst.getOperand(2);
1501 return Error(IDLoc, "expected immediate operand kind");
1502 Imm = Opnd.getImm();
1503 if (!(Imm == 1 || Imm == -1 ||
1504 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1505 return Error(IDLoc, "immediate operand value out of range");
1507 case Mips::ADDIUR1SP_MM:
1508 Opnd = Inst.getOperand(1);
1510 return Error(IDLoc, "expected immediate operand kind");
1511 Imm = Opnd.getImm();
1512 if (OffsetToAlignment(Imm, 4LL))
1513 return Error(IDLoc, "misaligned immediate operand value");
1514 if (Imm < 0 || Imm > 255)
1515 return Error(IDLoc, "immediate operand value out of range");
1517 case Mips::ANDI16_MM:
1518 Opnd = Inst.getOperand(2);
1520 return Error(IDLoc, "expected immediate operand kind");
1521 Imm = Opnd.getImm();
1522 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1523 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1524 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1525 return Error(IDLoc, "immediate operand value out of range");
1527 case Mips::LBU16_MM:
1528 Opnd = Inst.getOperand(2);
1530 return Error(IDLoc, "expected immediate operand kind");
1531 Imm = Opnd.getImm();
1532 if (Imm < -1 || Imm > 14)
1533 return Error(IDLoc, "immediate operand value out of range");
1536 Opnd = Inst.getOperand(2);
1538 return Error(IDLoc, "expected immediate operand kind");
1539 Imm = Opnd.getImm();
1540 if (Imm < 0 || Imm > 15)
1541 return Error(IDLoc, "immediate operand value out of range");
1543 case Mips::LHU16_MM:
1545 Opnd = Inst.getOperand(2);
1547 return Error(IDLoc, "expected immediate operand kind");
1548 Imm = Opnd.getImm();
1549 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1550 return Error(IDLoc, "immediate operand value out of range");
1554 Opnd = Inst.getOperand(2);
1556 return Error(IDLoc, "expected immediate operand kind");
1557 Imm = Opnd.getImm();
1558 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1559 return Error(IDLoc, "immediate operand value out of range");
1563 Opnd = Inst.getOperand(2);
1565 return Error(IDLoc, "expected immediate operand kind");
1566 Imm = Opnd.getImm();
1567 if (!isUInt<5>(Imm))
1568 return Error(IDLoc, "immediate operand value out of range");
1570 case Mips::ADDIUPC_MM:
1571 MCOperand Opnd = Inst.getOperand(1);
1573 return Error(IDLoc, "expected immediate operand kind");
1574 int Imm = Opnd.getImm();
1575 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1576 return Error(IDLoc, "immediate operand value out of range");
1581 if (needsExpansion(Inst)) {
1582 if (expandInstruction(Inst, IDLoc, Instructions))
1585 Instructions.push_back(Inst);
1587 // If this instruction has a delay slot and .set reorder is active,
1588 // emit a NOP after it.
1589 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
1590 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1595 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1597 switch (Inst.getOpcode()) {
1598 case Mips::LoadImm32:
1599 case Mips::LoadImm64:
1600 case Mips::LoadAddrImm32:
1601 case Mips::LoadAddrReg32:
1602 case Mips::B_MM_Pseudo:
1605 case Mips::JalOneReg:
1606 case Mips::JalTwoReg:
1613 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1614 SmallVectorImpl<MCInst> &Instructions) {
1615 switch (Inst.getOpcode()) {
1616 default: llvm_unreachable("unimplemented expansion");
1617 case Mips::LoadImm32:
1618 return expandLoadImm(Inst, true, IDLoc, Instructions);
1619 case Mips::LoadImm64:
1620 return expandLoadImm(Inst, false, IDLoc, Instructions);
1621 case Mips::LoadAddrImm32:
1622 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1623 case Mips::LoadAddrReg32:
1624 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1625 case Mips::B_MM_Pseudo:
1626 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1629 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1630 case Mips::JalOneReg:
1631 case Mips::JalTwoReg:
1632 return expandJalWithRegs(Inst, IDLoc, Instructions);
1637 template <unsigned ShiftAmount>
1638 void createLShiftOri(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1639 SmallVectorImpl<MCInst> &Instructions) {
1641 if (ShiftAmount >= 32) {
1642 tmpInst.setOpcode(Mips::DSLL32);
1643 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1644 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1645 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount - 32));
1646 tmpInst.setLoc(IDLoc);
1647 Instructions.push_back(tmpInst);
1649 } else if (ShiftAmount > 0) {
1650 tmpInst.setOpcode(Mips::DSLL);
1651 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1652 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1653 tmpInst.addOperand(MCOperand::CreateImm(ShiftAmount));
1654 tmpInst.setLoc(IDLoc);
1655 Instructions.push_back(tmpInst);
1658 // There's no need for an ORi if the immediate is 0.
1659 if (Operand.isImm() && Operand.getImm() == 0)
1662 tmpInst.setOpcode(Mips::ORi);
1663 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1664 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1665 tmpInst.addOperand(Operand);
1666 tmpInst.setLoc(IDLoc);
1667 Instructions.push_back(tmpInst);
1670 template <unsigned ShiftAmount>
1671 void createLShiftOri(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1672 SmallVectorImpl<MCInst> &Instructions) {
1673 createLShiftOri<ShiftAmount>(MCOperand::CreateImm(Value), RegNo, IDLoc,
1678 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1679 SmallVectorImpl<MCInst> &Instructions) {
1680 // Create a JALR instruction which is going to replace the pseudo-JAL.
1682 JalrInst.setLoc(IDLoc);
1683 const MCOperand FirstRegOp = Inst.getOperand(0);
1684 const unsigned Opcode = Inst.getOpcode();
1686 if (Opcode == Mips::JalOneReg) {
1687 // jal $rs => jalr $rs
1688 if (inMicroMipsMode()) {
1689 JalrInst.setOpcode(Mips::JALR16_MM);
1690 JalrInst.addOperand(FirstRegOp);
1692 JalrInst.setOpcode(Mips::JALR);
1693 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1694 JalrInst.addOperand(FirstRegOp);
1696 } else if (Opcode == Mips::JalTwoReg) {
1697 // jal $rd, $rs => jalr $rd, $rs
1698 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1699 JalrInst.addOperand(FirstRegOp);
1700 const MCOperand SecondRegOp = Inst.getOperand(1);
1701 JalrInst.addOperand(SecondRegOp);
1703 Instructions.push_back(JalrInst);
1705 // If .set reorder is active, emit a NOP after it.
1706 if (AssemblerOptions.back()->isReorder()) {
1707 // This is a 32-bit NOP because these 2 pseudo-instructions
1708 // do not have a short delay slot.
1710 NopInst.setOpcode(Mips::SLL);
1711 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1712 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1713 NopInst.addOperand(MCOperand::CreateImm(0));
1714 Instructions.push_back(NopInst);
1720 bool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
1721 SmallVectorImpl<MCInst> &Instructions) {
1722 if (!Is32BitImm && !isGP64bit()) {
1723 Error(IDLoc, "instruction requires a 64-bit architecture");
1728 const MCOperand &ImmOp = Inst.getOperand(1);
1729 assert(ImmOp.isImm() && "expected immediate operand kind");
1730 const MCOperand &RegOp = Inst.getOperand(0);
1731 assert(RegOp.isReg() && "expected register operand kind");
1733 int64_t ImmValue = ImmOp.getImm();
1734 unsigned Reg = RegOp.getReg();
1735 tmpInst.setLoc(IDLoc);
1736 // FIXME: gas has a special case for values that are 000...1111, which
1737 // becomes a li -1 and then a dsrl
1738 if (0 <= ImmValue && ImmValue <= 65535) {
1739 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1740 // li d,j => ori d,$zero,j
1741 tmpInst.setOpcode(Mips::ORi);
1742 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1743 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1744 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1745 Instructions.push_back(tmpInst);
1746 } else if (ImmValue < 0 && ImmValue >= -32768) {
1747 // For negative signed 16-bit values (-32768 <= j < 0):
1748 // li d,j => addiu d,$zero,j
1749 tmpInst.setOpcode(Mips::ADDiu);
1750 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1751 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1752 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1753 Instructions.push_back(tmpInst);
1754 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1755 // For all other values which are representable as a 32-bit integer:
1756 // li d,j => lui d,hi16(j)
1758 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1759 uint16_t Bits15To0 = ImmValue & 0xffff;
1761 tmpInst.setOpcode(Mips::LUi);
1762 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1763 tmpInst.addOperand(MCOperand::CreateImm(Bits31To16));
1764 Instructions.push_back(tmpInst);
1765 createLShiftOri<0>(Bits15To0, Reg, IDLoc, Instructions);
1766 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1768 Error(IDLoc, "instruction requires a 32-bit immediate");
1772 // <------- lo32 ------>
1773 // <------- hi32 ------>
1774 // <- hi16 -> <- lo16 ->
1775 // _________________________________
1777 // | 16-bits | 16-bits | 16-bits |
1778 // |__________|__________|__________|
1780 // For any 64-bit value that is representable as a 48-bit integer:
1781 // li d,j => lui d,hi16(j)
1782 // ori d,d,hi16(lo32(j))
1784 // ori d,d,lo16(lo32(j))
1785 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1786 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1787 uint16_t Bits15To0 = ImmValue & 0xffff;
1789 tmpInst.setOpcode(Mips::LUi);
1790 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1791 tmpInst.addOperand(MCOperand::CreateImm(Bits47To32));
1792 Instructions.push_back(tmpInst);
1793 createLShiftOri<0>(Bits31To16, Reg, IDLoc, Instructions);
1794 createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
1797 Error(IDLoc, "instruction requires a 32-bit immediate");
1801 // <------- hi32 ------> <------- lo32 ------>
1802 // <- hi16 -> <- lo16 ->
1803 // ___________________________________________
1805 // | 16-bits | 16-bits | 16-bits | 16-bits |
1806 // |__________|__________|__________|__________|
1808 // For all other values which are representable as a 64-bit integer:
1809 // li d,j => lui d,hi16(j)
1810 // ori d,d,lo16(hi32(j))
1812 // ori d,d,hi16(lo32(j))
1814 // ori d,d,lo16(lo32(j))
1815 uint16_t Bits63To48 = (ImmValue >> 48) & 0xffff;
1816 uint16_t Bits47To32 = (ImmValue >> 32) & 0xffff;
1817 uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
1818 uint16_t Bits15To0 = ImmValue & 0xffff;
1820 tmpInst.setOpcode(Mips::LUi);
1821 tmpInst.addOperand(MCOperand::CreateReg(Reg));
1822 tmpInst.addOperand(MCOperand::CreateImm(Bits63To48));
1823 Instructions.push_back(tmpInst);
1824 createLShiftOri<0>(Bits47To32, Reg, IDLoc, Instructions);
1826 // When Bits31To16 is 0, do a left shift of 32 bits instead of doing
1827 // two left shifts of 16 bits.
1828 if (Bits31To16 == 0) {
1829 createLShiftOri<32>(Bits15To0, Reg, IDLoc, Instructions);
1831 createLShiftOri<16>(Bits31To16, Reg, IDLoc, Instructions);
1832 createLShiftOri<16>(Bits15To0, Reg, IDLoc, Instructions);
1839 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1840 SmallVectorImpl<MCInst> &Instructions) {
1842 const MCOperand &ImmOp = Inst.getOperand(2);
1843 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1844 "expected immediate operand kind");
1845 if (!ImmOp.isImm()) {
1846 expandLoadAddressSym(Inst, IDLoc, Instructions);
1849 const MCOperand &SrcRegOp = Inst.getOperand(1);
1850 assert(SrcRegOp.isReg() && "expected register operand kind");
1851 const MCOperand &DstRegOp = Inst.getOperand(0);
1852 assert(DstRegOp.isReg() && "expected register operand kind");
1853 int ImmValue = ImmOp.getImm();
1854 if (-32768 <= ImmValue && ImmValue <= 65535) {
1855 // For -32768 <= j <= 65535.
1856 // la d,j(s) => addiu d,s,j
1857 tmpInst.setOpcode(Mips::ADDiu);
1858 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1859 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1860 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1861 Instructions.push_back(tmpInst);
1863 // For any other value of j that is representable as a 32-bit integer.
1864 // la d,j(s) => lui d,hi16(j)
1867 tmpInst.setOpcode(Mips::LUi);
1868 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1869 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1870 Instructions.push_back(tmpInst);
1872 tmpInst.setOpcode(Mips::ORi);
1873 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1874 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1875 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1876 Instructions.push_back(tmpInst);
1878 tmpInst.setOpcode(Mips::ADDu);
1879 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1880 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1881 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1882 Instructions.push_back(tmpInst);
1888 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1889 SmallVectorImpl<MCInst> &Instructions) {
1891 const MCOperand &ImmOp = Inst.getOperand(1);
1892 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1893 "expected immediate operand kind");
1894 if (!ImmOp.isImm()) {
1895 expandLoadAddressSym(Inst, IDLoc, Instructions);
1898 const MCOperand &RegOp = Inst.getOperand(0);
1899 assert(RegOp.isReg() && "expected register operand kind");
1900 int ImmValue = ImmOp.getImm();
1901 if (-32768 <= ImmValue && ImmValue <= 65535) {
1902 // For -32768 <= j <= 65535.
1903 // la d,j => addiu d,$zero,j
1904 tmpInst.setOpcode(Mips::ADDiu);
1905 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1906 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1907 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1908 Instructions.push_back(tmpInst);
1910 // For any other value of j that is representable as a 32-bit integer.
1911 // la d,j => lui d,hi16(j)
1913 tmpInst.setOpcode(Mips::LUi);
1914 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1915 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1916 Instructions.push_back(tmpInst);
1918 tmpInst.setOpcode(Mips::ORi);
1919 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1920 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1921 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1922 Instructions.push_back(tmpInst);
1928 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1929 SmallVectorImpl<MCInst> &Instructions) {
1930 // FIXME: If we do have a valid at register to use, we should generate a
1931 // slightly shorter sequence here.
1933 int ExprOperandNo = 1;
1934 // Sometimes the assembly parser will get the immediate expression as
1935 // a $zero + an immediate.
1936 if (Inst.getNumOperands() == 3) {
1937 assert(Inst.getOperand(1).getReg() ==
1938 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1941 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1942 assert(SymOp.isExpr() && "expected symbol operand kind");
1943 const MCOperand &RegOp = Inst.getOperand(0);
1944 unsigned RegNo = RegOp.getReg();
1945 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1946 const MCSymbolRefExpr *HiExpr =
1947 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1948 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1949 const MCSymbolRefExpr *LoExpr =
1950 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1951 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1953 // If it's a 64-bit architecture, expand to:
1954 // la d,sym => lui d,highest(sym)
1955 // ori d,d,higher(sym)
1957 // ori d,d,hi16(sym)
1959 // ori d,d,lo16(sym)
1960 const MCSymbolRefExpr *HighestExpr =
1961 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1962 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1963 const MCSymbolRefExpr *HigherExpr =
1964 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1965 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1967 tmpInst.setOpcode(Mips::LUi);
1968 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1969 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1970 Instructions.push_back(tmpInst);
1972 createLShiftOri<0>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1974 createLShiftOri<16>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1976 createLShiftOri<16>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1979 // Otherwise, expand to:
1980 // la d,sym => lui d,hi16(sym)
1981 // ori d,d,lo16(sym)
1982 tmpInst.setOpcode(Mips::LUi);
1983 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1984 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1985 Instructions.push_back(tmpInst);
1987 createLShiftOri<0>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1992 bool MipsAsmParser::expandUncondBranchMMPseudo(
1993 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1994 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1995 "unexpected number of operands");
1997 MCOperand Offset = Inst.getOperand(0);
1998 if (Offset.isExpr()) {
2000 Inst.setOpcode(Mips::BEQ_MM);
2001 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2002 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2003 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
2005 assert(Offset.isImm() && "expected immediate operand kind");
2006 if (isIntN(11, Offset.getImm())) {
2007 // If offset fits into 11 bits then this instruction becomes microMIPS
2008 // 16-bit unconditional branch instruction.
2009 Inst.setOpcode(Mips::B16_MM);
2011 if (!isIntN(17, Offset.getImm()))
2012 Error(IDLoc, "branch target out of range");
2013 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2014 Error(IDLoc, "branch to misaligned address");
2016 Inst.setOpcode(Mips::BEQ_MM);
2017 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2018 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2019 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
2022 Instructions.push_back(Inst);
2024 // If .set reorder is active, emit a NOP after the branch instruction.
2025 if (AssemblerOptions.back()->isReorder())
2026 createNop(true, IDLoc, Instructions);
2031 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
2032 SmallVectorImpl<MCInst> &Instructions,
2033 bool isLoad, bool isImmOpnd) {
2034 const MCSymbolRefExpr *SR;
2036 unsigned ImmOffset, HiOffset, LoOffset;
2037 const MCExpr *ExprOffset;
2039 // 1st operand is either the source or destination register.
2040 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2041 unsigned RegOpNum = Inst.getOperand(0).getReg();
2042 // 2nd operand is the base register.
2043 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2044 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2045 // 3rd operand is either an immediate or expression.
2047 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2048 ImmOffset = Inst.getOperand(2).getImm();
2049 LoOffset = ImmOffset & 0x0000ffff;
2050 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2051 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2052 if (LoOffset & 0x8000)
2055 ExprOffset = Inst.getOperand(2).getExpr();
2056 // All instructions will have the same location.
2057 TempInst.setLoc(IDLoc);
2058 // These are some of the types of expansions we perform here:
2059 // 1) lw $8, sym => lui $8, %hi(sym)
2060 // lw $8, %lo(sym)($8)
2061 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2063 // lw $8, %lo(offset)($9)
2064 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2066 // lw $8, %lo(offset)($at)
2067 // 4) sw $8, sym => lui $at, %hi(sym)
2068 // sw $8, %lo(sym)($at)
2069 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2071 // sw $8, %lo(offset)($at)
2072 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2073 // ldc1 $f0, %lo(sym)($at)
2075 // For load instructions we can use the destination register as a temporary
2076 // if base and dst are different (examples 1 and 2) and if the base register
2077 // is general purpose otherwise we must use $at (example 6) and error if it's
2078 // not available. For stores we must use $at (examples 4 and 5) because we
2079 // must not clobber the source register setting up the offset.
2080 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2081 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2082 unsigned RegClassIDOp0 =
2083 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2084 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2085 (RegClassIDOp0 == Mips::GPR64RegClassID);
2086 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2087 TmpRegNum = RegOpNum;
2089 // At this point we need AT to perform the expansions and we exit if it is
2091 TmpRegNum = getATReg(IDLoc);
2096 TempInst.setOpcode(Mips::LUi);
2097 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2099 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2101 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2102 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2103 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2104 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2106 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2108 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2109 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2112 // Add the instruction to the list.
2113 Instructions.push_back(TempInst);
2114 // Prepare TempInst for next instruction.
2116 // Add temp register to base.
2117 if (BaseRegNum != Mips::ZERO) {
2118 TempInst.setOpcode(Mips::ADDu);
2119 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2120 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2121 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2122 Instructions.push_back(TempInst);
2125 // And finally, create original instruction with low part
2126 // of offset and new base.
2127 TempInst.setOpcode(Inst.getOpcode());
2128 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2129 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2131 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2133 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2134 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2135 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2137 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2139 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2140 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2143 Instructions.push_back(TempInst);
2148 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2149 SmallVectorImpl<MCInst> &Instructions) {
2150 unsigned OpNum = Inst.getNumOperands();
2151 unsigned Opcode = Inst.getOpcode();
2152 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2154 assert (Inst.getOperand(OpNum - 1).isImm() &&
2155 Inst.getOperand(OpNum - 2).isReg() &&
2156 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2158 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2159 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2160 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2161 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2162 // It can be implemented as SWM16 or LWM16 instruction.
2163 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2165 Inst.setOpcode(NewOpcode);
2166 Instructions.push_back(Inst);
2170 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2171 SmallVectorImpl<MCInst> &Instructions) {
2173 if (hasShortDelaySlot) {
2174 NopInst.setOpcode(Mips::MOVE16_MM);
2175 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2176 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2178 NopInst.setOpcode(Mips::SLL);
2179 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2180 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2181 NopInst.addOperand(MCOperand::CreateImm(0));
2183 Instructions.push_back(NopInst);
2186 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2187 // As described by the Mips32r2 spec, the registers Rd and Rs for
2188 // jalr.hb must be different.
2189 unsigned Opcode = Inst.getOpcode();
2191 if (Opcode == Mips::JALR_HB &&
2192 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2193 return Match_RequiresDifferentSrcAndDst;
2195 return Match_Success;
2198 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2199 OperandVector &Operands,
2201 uint64_t &ErrorInfo,
2202 bool MatchingInlineAsm) {
2205 SmallVector<MCInst, 8> Instructions;
2206 unsigned MatchResult =
2207 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2209 switch (MatchResult) {
2210 case Match_Success: {
2211 if (processInstruction(Inst, IDLoc, Instructions))
2213 for (unsigned i = 0; i < Instructions.size(); i++)
2214 Out.EmitInstruction(Instructions[i], STI);
2217 case Match_MissingFeature:
2218 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2220 case Match_InvalidOperand: {
2221 SMLoc ErrorLoc = IDLoc;
2222 if (ErrorInfo != ~0ULL) {
2223 if (ErrorInfo >= Operands.size())
2224 return Error(IDLoc, "too few operands for instruction");
2226 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2227 if (ErrorLoc == SMLoc())
2231 return Error(ErrorLoc, "invalid operand for instruction");
2233 case Match_MnemonicFail:
2234 return Error(IDLoc, "invalid instruction");
2235 case Match_RequiresDifferentSrcAndDst:
2236 return Error(IDLoc, "source and destination must be different");
2239 llvm_unreachable("Implement any new match types added!");
2242 void MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
2243 if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
2244 Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
2245 ") without \".set noat\"");
2249 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2250 SMRange Range, bool ShowColors) {
2251 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2252 Range, SMFixIt(Range, FixMsg),
2256 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2259 CC = StringSwitch<unsigned>(Name)
2295 if (!(isABI_N32() || isABI_N64()))
2298 if (12 <= CC && CC <= 15) {
2299 // Name is one of t4-t7
2300 AsmToken RegTok = getLexer().peekTok();
2301 SMRange RegRange = RegTok.getLocRange();
2303 StringRef FixedName = StringSwitch<StringRef>(Name)
2309 assert(FixedName != "" && "Register name is not one of t4-t7.");
2311 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2312 "Did you mean $" + FixedName + "?", RegRange);
2315 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2316 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2317 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2318 if (8 <= CC && CC <= 11)
2322 CC = StringSwitch<unsigned>(Name)
2334 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2337 CC = StringSwitch<unsigned>(Name)
2338 .Case("hwr_cpunum", 0)
2339 .Case("hwr_synci_step", 1)
2341 .Case("hwr_ccres", 3)
2342 .Case("hwr_ulr", 29)
2348 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2350 if (Name[0] == 'f') {
2351 StringRef NumString = Name.substr(1);
2353 if (NumString.getAsInteger(10, IntVal))
2354 return -1; // This is not an integer.
2355 if (IntVal > 31) // Maximum index for fpu register.
2362 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2364 if (Name.startswith("fcc")) {
2365 StringRef NumString = Name.substr(3);
2367 if (NumString.getAsInteger(10, IntVal))
2368 return -1; // This is not an integer.
2369 if (IntVal > 7) // There are only 8 fcc registers.
2376 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2378 if (Name.startswith("ac")) {
2379 StringRef NumString = Name.substr(2);
2381 if (NumString.getAsInteger(10, IntVal))
2382 return -1; // This is not an integer.
2383 if (IntVal > 3) // There are only 3 acc registers.
2390 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2393 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2402 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2405 CC = StringSwitch<unsigned>(Name)
2408 .Case("msaaccess", 2)
2410 .Case("msamodify", 4)
2411 .Case("msarequest", 5)
2413 .Case("msaunmap", 7)
2419 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2420 unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
2422 reportParseError(Loc,
2423 "pseudo-instruction requires $at, which is not available");
2426 unsigned AT = getReg(
2427 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2431 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2432 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2435 unsigned MipsAsmParser::getGPR(int RegNo) {
2436 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2440 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2442 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2445 return getReg(RegClass, RegNum);
2448 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2449 MCAsmParser &Parser = getParser();
2450 DEBUG(dbgs() << "parseOperand\n");
2452 // Check if the current operand has a custom associated parser, if so, try to
2453 // custom parse the operand, or fallback to the general approach.
2454 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2455 if (ResTy == MatchOperand_Success)
2457 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2458 // there was a match, but an error occurred, in which case, just return that
2459 // the operand parsing failed.
2460 if (ResTy == MatchOperand_ParseFail)
2463 DEBUG(dbgs() << ".. Generic Parser\n");
2465 switch (getLexer().getKind()) {
2467 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2469 case AsmToken::Dollar: {
2470 // Parse the register.
2471 SMLoc S = Parser.getTok().getLoc();
2473 // Almost all registers have been parsed by custom parsers. There is only
2474 // one exception to this. $zero (and it's alias $0) will reach this point
2475 // for div, divu, and similar instructions because it is not an operand
2476 // to the instruction definition but an explicit register. Special case
2477 // this situation for now.
2478 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2481 // Maybe it is a symbol reference.
2482 StringRef Identifier;
2483 if (Parser.parseIdentifier(Identifier))
2486 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2487 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2488 // Otherwise create a symbol reference.
2490 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2492 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2495 // Else drop to expression parsing.
2496 case AsmToken::LParen:
2497 case AsmToken::Minus:
2498 case AsmToken::Plus:
2499 case AsmToken::Integer:
2500 case AsmToken::Tilde:
2501 case AsmToken::String: {
2502 DEBUG(dbgs() << ".. generic integer\n");
2503 OperandMatchResultTy ResTy = parseImm(Operands);
2504 return ResTy != MatchOperand_Success;
2506 case AsmToken::Percent: {
2507 // It is a symbol reference or constant expression.
2508 const MCExpr *IdVal;
2509 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2510 if (parseRelocOperand(IdVal))
2513 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2515 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2517 } // case AsmToken::Percent
2518 } // switch(getLexer().getKind())
2522 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2523 StringRef RelocStr) {
2525 // Check the type of the expression.
2526 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2527 // It's a constant, evaluate reloc value.
2529 switch (getVariantKind(RelocStr)) {
2530 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2531 // Get the 1st 16-bits.
2532 Val = MCE->getValue() & 0xffff;
2534 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2535 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2536 // 16 bits being negative.
2537 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2539 case MCSymbolRefExpr::VK_Mips_HIGHER:
2540 // Get the 3rd 16-bits.
2541 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2543 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2544 // Get the 4th 16-bits.
2545 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2548 report_fatal_error("unsupported reloc value");
2550 return MCConstantExpr::Create(Val, getContext());
2553 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2554 // It's a symbol, create a symbolic expression from the symbol.
2555 StringRef Symbol = MSRE->getSymbol().getName();
2556 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2557 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2561 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2562 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2564 // Try to create target expression.
2565 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2566 return MipsMCExpr::Create(VK, Expr, getContext());
2568 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2569 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2570 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2574 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2575 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2576 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2579 // Just return the original expression.
2583 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2585 switch (Expr->getKind()) {
2586 case MCExpr::Constant:
2588 case MCExpr::SymbolRef:
2589 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2590 case MCExpr::Binary:
2591 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2592 if (!isEvaluated(BE->getLHS()))
2594 return isEvaluated(BE->getRHS());
2597 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2598 case MCExpr::Target:
2604 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2605 MCAsmParser &Parser = getParser();
2606 Parser.Lex(); // Eat the % token.
2607 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2608 if (Tok.isNot(AsmToken::Identifier))
2611 std::string Str = Tok.getIdentifier();
2613 Parser.Lex(); // Eat the identifier.
2614 // Now make an expression from the rest of the operand.
2615 const MCExpr *IdVal;
2618 if (getLexer().getKind() == AsmToken::LParen) {
2620 Parser.Lex(); // Eat the '(' token.
2621 if (getLexer().getKind() == AsmToken::Percent) {
2622 Parser.Lex(); // Eat the % token.
2623 const AsmToken &nextTok = Parser.getTok();
2624 if (nextTok.isNot(AsmToken::Identifier))
2627 Str += nextTok.getIdentifier();
2628 Parser.Lex(); // Eat the identifier.
2629 if (getLexer().getKind() != AsmToken::LParen)
2634 if (getParser().parseParenExpression(IdVal, EndLoc))
2637 while (getLexer().getKind() == AsmToken::RParen)
2638 Parser.Lex(); // Eat the ')' token.
2641 return true; // Parenthesis must follow the relocation operand.
2643 Res = evaluateRelocExpr(IdVal, Str);
2647 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2649 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2650 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2651 if (ResTy == MatchOperand_Success) {
2652 assert(Operands.size() == 1);
2653 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2654 StartLoc = Operand.getStartLoc();
2655 EndLoc = Operand.getEndLoc();
2657 // AFAIK, we only support numeric registers and named GPR's in CFI
2659 // Don't worry about eating tokens before failing. Using an unrecognised
2660 // register is a parse error.
2661 if (Operand.isGPRAsmReg()) {
2662 // Resolve to GPR32 or GPR64 appropriately.
2663 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2666 return (RegNo == (unsigned)-1);
2669 assert(Operands.size() == 0);
2670 return (RegNo == (unsigned)-1);
2673 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2674 MCAsmParser &Parser = getParser();
2678 while (getLexer().getKind() == AsmToken::LParen)
2681 switch (getLexer().getKind()) {
2684 case AsmToken::Identifier:
2685 case AsmToken::LParen:
2686 case AsmToken::Integer:
2687 case AsmToken::Minus:
2688 case AsmToken::Plus:
2690 Result = getParser().parseParenExpression(Res, S);
2692 Result = (getParser().parseExpression(Res));
2693 while (getLexer().getKind() == AsmToken::RParen)
2696 case AsmToken::Percent:
2697 Result = parseRelocOperand(Res);
2702 MipsAsmParser::OperandMatchResultTy
2703 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2704 MCAsmParser &Parser = getParser();
2705 DEBUG(dbgs() << "parseMemOperand\n");
2706 const MCExpr *IdVal = nullptr;
2708 bool isParenExpr = false;
2709 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2710 // First operand is the offset.
2711 S = Parser.getTok().getLoc();
2713 if (getLexer().getKind() == AsmToken::LParen) {
2718 if (getLexer().getKind() != AsmToken::Dollar) {
2719 if (parseMemOffset(IdVal, isParenExpr))
2720 return MatchOperand_ParseFail;
2722 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2723 if (Tok.isNot(AsmToken::LParen)) {
2724 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2725 if (Mnemonic.getToken() == "la") {
2727 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2728 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2729 return MatchOperand_Success;
2731 if (Tok.is(AsmToken::EndOfStatement)) {
2733 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2735 // Zero register assumed, add a memory operand with ZERO as its base.
2736 // "Base" will be managed by k_Memory.
2737 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2740 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2741 return MatchOperand_Success;
2743 Error(Parser.getTok().getLoc(), "'(' expected");
2744 return MatchOperand_ParseFail;
2747 Parser.Lex(); // Eat the '(' token.
2750 Res = parseAnyRegister(Operands);
2751 if (Res != MatchOperand_Success)
2754 if (Parser.getTok().isNot(AsmToken::RParen)) {
2755 Error(Parser.getTok().getLoc(), "')' expected");
2756 return MatchOperand_ParseFail;
2759 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2761 Parser.Lex(); // Eat the ')' token.
2764 IdVal = MCConstantExpr::Create(0, getContext());
2766 // Replace the register operand with the memory operand.
2767 std::unique_ptr<MipsOperand> op(
2768 static_cast<MipsOperand *>(Operands.back().release()));
2769 // Remove the register from the operands.
2770 // "op" will be managed by k_Memory.
2771 Operands.pop_back();
2772 // Add the memory operand.
2773 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2775 if (IdVal->EvaluateAsAbsolute(Imm))
2776 IdVal = MCConstantExpr::Create(Imm, getContext());
2777 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2778 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2782 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2783 return MatchOperand_Success;
2786 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2787 MCAsmParser &Parser = getParser();
2788 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2790 SMLoc S = Parser.getTok().getLoc();
2792 if (Sym->isVariable())
2793 Expr = Sym->getVariableValue();
2796 if (Expr->getKind() == MCExpr::SymbolRef) {
2797 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2798 StringRef DefSymbol = Ref->getSymbol().getName();
2799 if (DefSymbol.startswith("$")) {
2800 OperandMatchResultTy ResTy =
2801 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2802 if (ResTy == MatchOperand_Success) {
2805 } else if (ResTy == MatchOperand_ParseFail)
2806 llvm_unreachable("Should never ParseFail");
2809 } else if (Expr->getKind() == MCExpr::Constant) {
2811 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2813 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2820 MipsAsmParser::OperandMatchResultTy
2821 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2822 StringRef Identifier,
2824 int Index = matchCPURegisterName(Identifier);
2826 Operands.push_back(MipsOperand::createGPRReg(
2827 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2828 return MatchOperand_Success;
2831 Index = matchHWRegsRegisterName(Identifier);
2833 Operands.push_back(MipsOperand::createHWRegsReg(
2834 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2835 return MatchOperand_Success;
2838 Index = matchFPURegisterName(Identifier);
2840 Operands.push_back(MipsOperand::createFGRReg(
2841 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2842 return MatchOperand_Success;
2845 Index = matchFCCRegisterName(Identifier);
2847 Operands.push_back(MipsOperand::createFCCReg(
2848 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2849 return MatchOperand_Success;
2852 Index = matchACRegisterName(Identifier);
2854 Operands.push_back(MipsOperand::createACCReg(
2855 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2856 return MatchOperand_Success;
2859 Index = matchMSA128RegisterName(Identifier);
2861 Operands.push_back(MipsOperand::createMSA128Reg(
2862 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2863 return MatchOperand_Success;
2866 Index = matchMSA128CtrlRegisterName(Identifier);
2868 Operands.push_back(MipsOperand::createMSACtrlReg(
2869 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2870 return MatchOperand_Success;
2873 return MatchOperand_NoMatch;
2876 MipsAsmParser::OperandMatchResultTy
2877 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2878 MCAsmParser &Parser = getParser();
2879 auto Token = Parser.getLexer().peekTok(false);
2881 if (Token.is(AsmToken::Identifier)) {
2882 DEBUG(dbgs() << ".. identifier\n");
2883 StringRef Identifier = Token.getIdentifier();
2884 OperandMatchResultTy ResTy =
2885 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2887 } else if (Token.is(AsmToken::Integer)) {
2888 DEBUG(dbgs() << ".. integer\n");
2889 Operands.push_back(MipsOperand::createNumericReg(
2890 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2892 return MatchOperand_Success;
2895 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2897 return MatchOperand_NoMatch;
2900 MipsAsmParser::OperandMatchResultTy
2901 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2902 MCAsmParser &Parser = getParser();
2903 DEBUG(dbgs() << "parseAnyRegister\n");
2905 auto Token = Parser.getTok();
2907 SMLoc S = Token.getLoc();
2909 if (Token.isNot(AsmToken::Dollar)) {
2910 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2911 if (Token.is(AsmToken::Identifier)) {
2912 if (searchSymbolAlias(Operands))
2913 return MatchOperand_Success;
2915 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2916 return MatchOperand_NoMatch;
2918 DEBUG(dbgs() << ".. $\n");
2920 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2921 if (ResTy == MatchOperand_Success) {
2923 Parser.Lex(); // identifier
2928 MipsAsmParser::OperandMatchResultTy
2929 MipsAsmParser::parseImm(OperandVector &Operands) {
2930 MCAsmParser &Parser = getParser();
2931 switch (getLexer().getKind()) {
2933 return MatchOperand_NoMatch;
2934 case AsmToken::LParen:
2935 case AsmToken::Minus:
2936 case AsmToken::Plus:
2937 case AsmToken::Integer:
2938 case AsmToken::Tilde:
2939 case AsmToken::String:
2943 const MCExpr *IdVal;
2944 SMLoc S = Parser.getTok().getLoc();
2945 if (getParser().parseExpression(IdVal))
2946 return MatchOperand_ParseFail;
2948 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2949 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2950 return MatchOperand_Success;
2953 MipsAsmParser::OperandMatchResultTy
2954 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2955 MCAsmParser &Parser = getParser();
2956 DEBUG(dbgs() << "parseJumpTarget\n");
2958 SMLoc S = getLexer().getLoc();
2960 // Integers and expressions are acceptable
2961 OperandMatchResultTy ResTy = parseImm(Operands);
2962 if (ResTy != MatchOperand_NoMatch)
2965 // Registers are a valid target and have priority over symbols.
2966 ResTy = parseAnyRegister(Operands);
2967 if (ResTy != MatchOperand_NoMatch)
2970 const MCExpr *Expr = nullptr;
2971 if (Parser.parseExpression(Expr)) {
2972 // We have no way of knowing if a symbol was consumed so we must ParseFail
2973 return MatchOperand_ParseFail;
2976 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2977 return MatchOperand_Success;
2980 MipsAsmParser::OperandMatchResultTy
2981 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2982 MCAsmParser &Parser = getParser();
2983 const MCExpr *IdVal;
2984 // If the first token is '$' we may have register operand.
2985 if (Parser.getTok().is(AsmToken::Dollar))
2986 return MatchOperand_NoMatch;
2987 SMLoc S = Parser.getTok().getLoc();
2988 if (getParser().parseExpression(IdVal))
2989 return MatchOperand_ParseFail;
2990 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2991 assert(MCE && "Unexpected MCExpr type.");
2992 int64_t Val = MCE->getValue();
2993 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2994 Operands.push_back(MipsOperand::CreateImm(
2995 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2996 return MatchOperand_Success;
2999 MipsAsmParser::OperandMatchResultTy
3000 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
3001 MCAsmParser &Parser = getParser();
3002 switch (getLexer().getKind()) {
3004 return MatchOperand_NoMatch;
3005 case AsmToken::LParen:
3006 case AsmToken::Plus:
3007 case AsmToken::Minus:
3008 case AsmToken::Integer:
3013 SMLoc S = Parser.getTok().getLoc();
3015 if (getParser().parseExpression(Expr))
3016 return MatchOperand_ParseFail;
3019 if (!Expr->EvaluateAsAbsolute(Val)) {
3020 Error(S, "expected immediate value");
3021 return MatchOperand_ParseFail;
3024 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
3025 // and because the CPU always adds one to the immediate field, the allowed
3026 // range becomes 1..4. We'll only check the range here and will deal
3027 // with the addition/subtraction when actually decoding/encoding
3029 if (Val < 1 || Val > 4) {
3030 Error(S, "immediate not in range (1..4)");
3031 return MatchOperand_ParseFail;
3035 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3036 return MatchOperand_Success;
3039 MipsAsmParser::OperandMatchResultTy
3040 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3041 MCAsmParser &Parser = getParser();
3042 SmallVector<unsigned, 10> Regs;
3044 unsigned PrevReg = Mips::NoRegister;
3045 bool RegRange = false;
3046 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3048 if (Parser.getTok().isNot(AsmToken::Dollar))
3049 return MatchOperand_ParseFail;
3051 SMLoc S = Parser.getTok().getLoc();
3052 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3053 SMLoc E = getLexer().getLoc();
3054 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3055 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3057 // Remove last register operand because registers from register range
3058 // should be inserted first.
3059 if (RegNo == Mips::RA) {
3060 Regs.push_back(RegNo);
3062 unsigned TmpReg = PrevReg + 1;
3063 while (TmpReg <= RegNo) {
3064 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3065 Error(E, "invalid register operand");
3066 return MatchOperand_ParseFail;
3070 Regs.push_back(TmpReg++);
3076 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3077 (RegNo != Mips::RA)) {
3078 Error(E, "$16 or $31 expected");
3079 return MatchOperand_ParseFail;
3080 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3081 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3082 Error(E, "invalid register operand");
3083 return MatchOperand_ParseFail;
3084 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3085 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3086 Error(E, "consecutive register numbers expected");
3087 return MatchOperand_ParseFail;
3090 Regs.push_back(RegNo);
3093 if (Parser.getTok().is(AsmToken::Minus))
3096 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3097 !Parser.getTok().isNot(AsmToken::Comma)) {
3098 Error(E, "',' or '-' expected");
3099 return MatchOperand_ParseFail;
3102 Lex(); // Consume comma or minus
3103 if (Parser.getTok().isNot(AsmToken::Dollar))
3109 SMLoc E = Parser.getTok().getLoc();
3110 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3111 parseMemOperand(Operands);
3112 return MatchOperand_Success;
3115 MipsAsmParser::OperandMatchResultTy
3116 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3117 MCAsmParser &Parser = getParser();
3119 SMLoc S = Parser.getTok().getLoc();
3120 if (parseAnyRegister(Operands) != MatchOperand_Success)
3121 return MatchOperand_ParseFail;
3123 SMLoc E = Parser.getTok().getLoc();
3124 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3125 unsigned Reg = Op.getGPR32Reg();
3126 Operands.pop_back();
3127 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3128 return MatchOperand_Success;
3131 MipsAsmParser::OperandMatchResultTy
3132 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3133 MCAsmParser &Parser = getParser();
3134 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3135 SmallVector<unsigned, 10> Regs;
3137 if (Parser.getTok().isNot(AsmToken::Dollar))
3138 return MatchOperand_ParseFail;
3140 SMLoc S = Parser.getTok().getLoc();
3142 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3143 return MatchOperand_ParseFail;
3145 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3146 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3147 Regs.push_back(RegNo);
3149 SMLoc E = Parser.getTok().getLoc();
3150 if (Parser.getTok().isNot(AsmToken::Comma)) {
3151 Error(E, "',' expected");
3152 return MatchOperand_ParseFail;
3158 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3159 return MatchOperand_ParseFail;
3161 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3162 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3163 Regs.push_back(RegNo);
3165 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3167 return MatchOperand_Success;
3170 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3172 MCSymbolRefExpr::VariantKind VK =
3173 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3174 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3175 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3176 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3177 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3178 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3179 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3180 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3181 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3182 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3183 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3184 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3185 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3186 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3187 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3188 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3189 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3190 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3191 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3192 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3193 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3194 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3195 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3196 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3197 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3198 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3199 .Default(MCSymbolRefExpr::VK_None);
3201 assert(VK != MCSymbolRefExpr::VK_None);
3206 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3208 /// ::= '(', register, ')'
3209 /// handle it before we iterate so we don't get tripped up by the lack of
3211 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3212 MCAsmParser &Parser = getParser();
3213 if (getLexer().is(AsmToken::LParen)) {
3215 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3217 if (parseOperand(Operands, Name)) {
3218 SMLoc Loc = getLexer().getLoc();
3219 Parser.eatToEndOfStatement();
3220 return Error(Loc, "unexpected token in argument list");
3222 if (Parser.getTok().isNot(AsmToken::RParen)) {
3223 SMLoc Loc = getLexer().getLoc();
3224 Parser.eatToEndOfStatement();
3225 return Error(Loc, "unexpected token, expected ')'");
3228 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3234 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3235 /// either one of these.
3236 /// ::= '[', register, ']'
3237 /// ::= '[', integer, ']'
3238 /// handle it before we iterate so we don't get tripped up by the lack of
3240 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3241 OperandVector &Operands) {
3242 MCAsmParser &Parser = getParser();
3243 if (getLexer().is(AsmToken::LBrac)) {
3245 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3247 if (parseOperand(Operands, Name)) {
3248 SMLoc Loc = getLexer().getLoc();
3249 Parser.eatToEndOfStatement();
3250 return Error(Loc, "unexpected token in argument list");
3252 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3253 SMLoc Loc = getLexer().getLoc();
3254 Parser.eatToEndOfStatement();
3255 return Error(Loc, "unexpected token, expected ']'");
3258 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3264 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3265 SMLoc NameLoc, OperandVector &Operands) {
3266 MCAsmParser &Parser = getParser();
3267 DEBUG(dbgs() << "ParseInstruction\n");
3269 // We have reached first instruction, module directive are now forbidden.
3270 getTargetStreamer().forbidModuleDirective();
3272 // Check if we have valid mnemonic
3273 if (!mnemonicIsValid(Name, 0)) {
3274 Parser.eatToEndOfStatement();
3275 return Error(NameLoc, "unknown instruction");
3277 // First operand in MCInst is instruction mnemonic.
3278 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3280 // Read the remaining operands.
3281 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3282 // Read the first operand.
3283 if (parseOperand(Operands, Name)) {
3284 SMLoc Loc = getLexer().getLoc();
3285 Parser.eatToEndOfStatement();
3286 return Error(Loc, "unexpected token in argument list");
3288 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3290 // AFAIK, parenthesis suffixes are never on the first operand
3292 while (getLexer().is(AsmToken::Comma)) {
3293 Parser.Lex(); // Eat the comma.
3294 // Parse and remember the operand.
3295 if (parseOperand(Operands, Name)) {
3296 SMLoc Loc = getLexer().getLoc();
3297 Parser.eatToEndOfStatement();
3298 return Error(Loc, "unexpected token in argument list");
3300 // Parse bracket and parenthesis suffixes before we iterate
3301 if (getLexer().is(AsmToken::LBrac)) {
3302 if (parseBracketSuffix(Name, Operands))
3304 } else if (getLexer().is(AsmToken::LParen) &&
3305 parseParenSuffix(Name, Operands))
3309 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3310 SMLoc Loc = getLexer().getLoc();
3311 Parser.eatToEndOfStatement();
3312 return Error(Loc, "unexpected token in argument list");
3314 Parser.Lex(); // Consume the EndOfStatement.
3318 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3319 MCAsmParser &Parser = getParser();
3320 SMLoc Loc = getLexer().getLoc();
3321 Parser.eatToEndOfStatement();
3322 return Error(Loc, ErrorMsg);
3325 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3326 return Error(Loc, ErrorMsg);
3329 bool MipsAsmParser::parseSetNoAtDirective() {
3330 MCAsmParser &Parser = getParser();
3331 // Line should look like: ".set noat".
3333 // Set the $at register to $0.
3334 AssemblerOptions.back()->setATRegIndex(0);
3336 Parser.Lex(); // Eat "noat".
3338 // If this is not the end of the statement, report an error.
3339 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3340 reportParseError("unexpected token, expected end of statement");
3344 getTargetStreamer().emitDirectiveSetNoAt();
3345 Parser.Lex(); // Consume the EndOfStatement.
3349 bool MipsAsmParser::parseSetAtDirective() {
3350 // Line can be: ".set at", which sets $at to $1
3351 // or ".set at=$reg", which sets $at to $reg.
3352 MCAsmParser &Parser = getParser();
3353 Parser.Lex(); // Eat "at".
3355 if (getLexer().is(AsmToken::EndOfStatement)) {
3356 // No register was specified, so we set $at to $1.
3357 AssemblerOptions.back()->setATRegIndex(1);
3359 getTargetStreamer().emitDirectiveSetAt();
3360 Parser.Lex(); // Consume the EndOfStatement.
3364 if (getLexer().isNot(AsmToken::Equal)) {
3365 reportParseError("unexpected token, expected equals sign");
3368 Parser.Lex(); // Eat "=".
3370 if (getLexer().isNot(AsmToken::Dollar)) {
3371 if (getLexer().is(AsmToken::EndOfStatement)) {
3372 reportParseError("no register specified");
3375 reportParseError("unexpected token, expected dollar sign '$'");
3379 Parser.Lex(); // Eat "$".
3381 // Find out what "reg" is.
3383 const AsmToken &Reg = Parser.getTok();
3384 if (Reg.is(AsmToken::Identifier)) {
3385 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3386 } else if (Reg.is(AsmToken::Integer)) {
3387 AtRegNo = Reg.getIntVal();
3389 reportParseError("unexpected token, expected identifier or integer");
3393 // Check if $reg is a valid register. If it is, set $at to $reg.
3394 if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
3395 reportParseError("invalid register");
3398 Parser.Lex(); // Eat "reg".
3400 // If this is not the end of the statement, report an error.
3401 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3402 reportParseError("unexpected token, expected end of statement");
3406 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3408 Parser.Lex(); // Consume the EndOfStatement.
3412 bool MipsAsmParser::parseSetReorderDirective() {
3413 MCAsmParser &Parser = getParser();
3415 // If this is not the end of the statement, report an error.
3416 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3417 reportParseError("unexpected token, expected end of statement");
3420 AssemblerOptions.back()->setReorder();
3421 getTargetStreamer().emitDirectiveSetReorder();
3422 Parser.Lex(); // Consume the EndOfStatement.
3426 bool MipsAsmParser::parseSetNoReorderDirective() {
3427 MCAsmParser &Parser = getParser();
3429 // If this is not the end of the statement, report an error.
3430 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3431 reportParseError("unexpected token, expected end of statement");
3434 AssemblerOptions.back()->setNoReorder();
3435 getTargetStreamer().emitDirectiveSetNoReorder();
3436 Parser.Lex(); // Consume the EndOfStatement.
3440 bool MipsAsmParser::parseSetMacroDirective() {
3441 MCAsmParser &Parser = getParser();
3443 // If this is not the end of the statement, report an error.
3444 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3445 reportParseError("unexpected token, expected end of statement");
3448 AssemblerOptions.back()->setMacro();
3449 Parser.Lex(); // Consume the EndOfStatement.
3453 bool MipsAsmParser::parseSetNoMacroDirective() {
3454 MCAsmParser &Parser = getParser();
3456 // If this is not the end of the statement, report an error.
3457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3458 reportParseError("unexpected token, expected end of statement");
3461 if (AssemblerOptions.back()->isReorder()) {
3462 reportParseError("`noreorder' must be set before `nomacro'");
3465 AssemblerOptions.back()->setNoMacro();
3466 Parser.Lex(); // Consume the EndOfStatement.
3470 bool MipsAsmParser::parseSetMsaDirective() {
3471 MCAsmParser &Parser = getParser();
3474 // If this is not the end of the statement, report an error.
3475 if (getLexer().isNot(AsmToken::EndOfStatement))
3476 return reportParseError("unexpected token, expected end of statement");
3478 setFeatureBits(Mips::FeatureMSA, "msa");
3479 getTargetStreamer().emitDirectiveSetMsa();
3483 bool MipsAsmParser::parseSetNoMsaDirective() {
3484 MCAsmParser &Parser = getParser();
3487 // If this is not the end of the statement, report an error.
3488 if (getLexer().isNot(AsmToken::EndOfStatement))
3489 return reportParseError("unexpected token, expected end of statement");
3491 clearFeatureBits(Mips::FeatureMSA, "msa");
3492 getTargetStreamer().emitDirectiveSetNoMsa();
3496 bool MipsAsmParser::parseSetNoDspDirective() {
3497 MCAsmParser &Parser = getParser();
3498 Parser.Lex(); // Eat "nodsp".
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::FeatureDSP, "dsp");
3507 getTargetStreamer().emitDirectiveSetNoDsp();
3511 bool MipsAsmParser::parseSetMips16Directive() {
3512 MCAsmParser &Parser = getParser();
3513 Parser.Lex(); // Eat "mips16".
3515 // If this is not the end of the statement, report an error.
3516 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3517 reportParseError("unexpected token, expected end of statement");
3521 setFeatureBits(Mips::FeatureMips16, "mips16");
3522 getTargetStreamer().emitDirectiveSetMips16();
3523 Parser.Lex(); // Consume the EndOfStatement.
3527 bool MipsAsmParser::parseSetNoMips16Directive() {
3528 MCAsmParser &Parser = getParser();
3529 Parser.Lex(); // Eat "nomips16".
3531 // If this is not the end of the statement, report an error.
3532 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3533 reportParseError("unexpected token, expected end of statement");
3537 clearFeatureBits(Mips::FeatureMips16, "mips16");
3538 getTargetStreamer().emitDirectiveSetNoMips16();
3539 Parser.Lex(); // Consume the EndOfStatement.
3543 bool MipsAsmParser::parseSetFpDirective() {
3544 MCAsmParser &Parser = getParser();
3545 MipsABIFlagsSection::FpABIKind FpAbiVal;
3546 // Line can be: .set fp=32
3549 Parser.Lex(); // Eat fp token
3550 AsmToken Tok = Parser.getTok();
3551 if (Tok.isNot(AsmToken::Equal)) {
3552 reportParseError("unexpected token, expected equals sign '='");
3555 Parser.Lex(); // Eat '=' token.
3556 Tok = Parser.getTok();
3558 if (!parseFpABIValue(FpAbiVal, ".set"))
3561 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3562 reportParseError("unexpected token, expected end of statement");
3565 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3566 Parser.Lex(); // Consume the EndOfStatement.
3570 bool MipsAsmParser::parseSetPopDirective() {
3571 MCAsmParser &Parser = getParser();
3572 SMLoc Loc = getLexer().getLoc();
3575 if (getLexer().isNot(AsmToken::EndOfStatement))
3576 return reportParseError("unexpected token, expected end of statement");
3578 // Always keep an element on the options "stack" to prevent the user
3579 // from changing the initial options. This is how we remember them.
3580 if (AssemblerOptions.size() == 2)
3581 return reportParseError(Loc, ".set pop with no .set push");
3583 AssemblerOptions.pop_back();
3584 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3586 getTargetStreamer().emitDirectiveSetPop();
3590 bool MipsAsmParser::parseSetPushDirective() {
3591 MCAsmParser &Parser = getParser();
3593 if (getLexer().isNot(AsmToken::EndOfStatement))
3594 return reportParseError("unexpected token, expected end of statement");
3596 // Create a copy of the current assembler options environment and push it.
3597 AssemblerOptions.push_back(
3598 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3600 getTargetStreamer().emitDirectiveSetPush();
3604 bool MipsAsmParser::parseSetAssignment() {
3606 const MCExpr *Value;
3607 MCAsmParser &Parser = getParser();
3609 if (Parser.parseIdentifier(Name))
3610 reportParseError("expected identifier after .set");
3612 if (getLexer().isNot(AsmToken::Comma))
3613 return reportParseError("unexpected token, expected comma");
3616 if (Parser.parseExpression(Value))
3617 return reportParseError("expected valid expression after comma");
3619 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3620 Sym->setVariableValue(Value);
3625 bool MipsAsmParser::parseSetMips0Directive() {
3626 MCAsmParser &Parser = getParser();
3628 if (getLexer().isNot(AsmToken::EndOfStatement))
3629 return reportParseError("unexpected token, expected end of statement");
3631 // Reset assembler options to their initial values.
3632 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3633 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3635 getTargetStreamer().emitDirectiveSetMips0();
3639 bool MipsAsmParser::parseSetArchDirective() {
3640 MCAsmParser &Parser = getParser();
3642 if (getLexer().isNot(AsmToken::Equal))
3643 return reportParseError("unexpected token, expected equals sign");
3647 if (Parser.parseIdentifier(Arch))
3648 return reportParseError("expected arch identifier");
3650 StringRef ArchFeatureName =
3651 StringSwitch<StringRef>(Arch)
3652 .Case("mips1", "mips1")
3653 .Case("mips2", "mips2")
3654 .Case("mips3", "mips3")
3655 .Case("mips4", "mips4")
3656 .Case("mips5", "mips5")
3657 .Case("mips32", "mips32")
3658 .Case("mips32r2", "mips32r2")
3659 .Case("mips32r3", "mips32r3")
3660 .Case("mips32r5", "mips32r5")
3661 .Case("mips32r6", "mips32r6")
3662 .Case("mips64", "mips64")
3663 .Case("mips64r2", "mips64r2")
3664 .Case("mips64r3", "mips64r3")
3665 .Case("mips64r5", "mips64r5")
3666 .Case("mips64r6", "mips64r6")
3667 .Case("cnmips", "cnmips")
3668 .Case("r4000", "mips3") // This is an implementation of Mips3.
3671 if (ArchFeatureName.empty())
3672 return reportParseError("unsupported architecture");
3674 selectArch(ArchFeatureName);
3675 getTargetStreamer().emitDirectiveSetArch(Arch);
3679 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3680 MCAsmParser &Parser = getParser();
3682 if (getLexer().isNot(AsmToken::EndOfStatement))
3683 return reportParseError("unexpected token, expected end of statement");
3687 llvm_unreachable("Unimplemented feature");
3688 case Mips::FeatureDSP:
3689 setFeatureBits(Mips::FeatureDSP, "dsp");
3690 getTargetStreamer().emitDirectiveSetDsp();
3692 case Mips::FeatureMicroMips:
3693 getTargetStreamer().emitDirectiveSetMicroMips();
3695 case Mips::FeatureMips1:
3696 selectArch("mips1");
3697 getTargetStreamer().emitDirectiveSetMips1();
3699 case Mips::FeatureMips2:
3700 selectArch("mips2");
3701 getTargetStreamer().emitDirectiveSetMips2();
3703 case Mips::FeatureMips3:
3704 selectArch("mips3");
3705 getTargetStreamer().emitDirectiveSetMips3();
3707 case Mips::FeatureMips4:
3708 selectArch("mips4");
3709 getTargetStreamer().emitDirectiveSetMips4();
3711 case Mips::FeatureMips5:
3712 selectArch("mips5");
3713 getTargetStreamer().emitDirectiveSetMips5();
3715 case Mips::FeatureMips32:
3716 selectArch("mips32");
3717 getTargetStreamer().emitDirectiveSetMips32();
3719 case Mips::FeatureMips32r2:
3720 selectArch("mips32r2");
3721 getTargetStreamer().emitDirectiveSetMips32R2();
3723 case Mips::FeatureMips32r3:
3724 selectArch("mips32r3");
3725 getTargetStreamer().emitDirectiveSetMips32R3();
3727 case Mips::FeatureMips32r5:
3728 selectArch("mips32r5");
3729 getTargetStreamer().emitDirectiveSetMips32R5();
3731 case Mips::FeatureMips32r6:
3732 selectArch("mips32r6");
3733 getTargetStreamer().emitDirectiveSetMips32R6();
3735 case Mips::FeatureMips64:
3736 selectArch("mips64");
3737 getTargetStreamer().emitDirectiveSetMips64();
3739 case Mips::FeatureMips64r2:
3740 selectArch("mips64r2");
3741 getTargetStreamer().emitDirectiveSetMips64R2();
3743 case Mips::FeatureMips64r3:
3744 selectArch("mips64r3");
3745 getTargetStreamer().emitDirectiveSetMips64R3();
3747 case Mips::FeatureMips64r5:
3748 selectArch("mips64r5");
3749 getTargetStreamer().emitDirectiveSetMips64R5();
3751 case Mips::FeatureMips64r6:
3752 selectArch("mips64r6");
3753 getTargetStreamer().emitDirectiveSetMips64R6();
3759 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3760 MCAsmParser &Parser = getParser();
3761 if (getLexer().isNot(AsmToken::Comma)) {
3762 SMLoc Loc = getLexer().getLoc();
3763 Parser.eatToEndOfStatement();
3764 return Error(Loc, ErrorStr);
3767 Parser.Lex(); // Eat the comma.
3771 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3772 if (AssemblerOptions.back()->isReorder())
3773 Warning(Loc, ".cpload should be inside a noreorder section");
3775 if (inMips16Mode()) {
3776 reportParseError(".cpload is not supported in Mips16 mode");
3780 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3781 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3782 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3783 reportParseError("expected register containing function address");
3787 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3788 if (!RegOpnd.isGPRAsmReg()) {
3789 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3793 // If this is not the end of the statement, report an error.
3794 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3795 reportParseError("unexpected token, expected end of statement");
3799 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3803 bool MipsAsmParser::parseDirectiveCPSetup() {
3804 MCAsmParser &Parser = getParser();
3807 bool SaveIsReg = true;
3809 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3810 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3811 if (ResTy == MatchOperand_NoMatch) {
3812 reportParseError("expected register containing function address");
3813 Parser.eatToEndOfStatement();
3817 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3818 if (!FuncRegOpnd.isGPRAsmReg()) {
3819 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3820 Parser.eatToEndOfStatement();
3824 FuncReg = FuncRegOpnd.getGPR32Reg();
3827 if (!eatComma("unexpected token, expected comma"))
3830 ResTy = parseAnyRegister(TmpReg);
3831 if (ResTy == MatchOperand_NoMatch) {
3832 const AsmToken &Tok = Parser.getTok();
3833 if (Tok.is(AsmToken::Integer)) {
3834 Save = Tok.getIntVal();
3838 reportParseError("expected save register or stack offset");
3839 Parser.eatToEndOfStatement();
3843 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3844 if (!SaveOpnd.isGPRAsmReg()) {
3845 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3846 Parser.eatToEndOfStatement();
3849 Save = SaveOpnd.getGPR32Reg();
3852 if (!eatComma("unexpected token, expected comma"))
3856 if (Parser.parseExpression(Expr)) {
3857 reportParseError("expected expression");
3861 if (Expr->getKind() != MCExpr::SymbolRef) {
3862 reportParseError("expected symbol");
3865 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3867 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3872 bool MipsAsmParser::parseDirectiveNaN() {
3873 MCAsmParser &Parser = getParser();
3874 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3875 const AsmToken &Tok = Parser.getTok();
3877 if (Tok.getString() == "2008") {
3879 getTargetStreamer().emitDirectiveNaN2008();
3881 } else if (Tok.getString() == "legacy") {
3883 getTargetStreamer().emitDirectiveNaNLegacy();
3887 // If we don't recognize the option passed to the .nan
3888 // directive (e.g. no option or unknown option), emit an error.
3889 reportParseError("invalid option in .nan directive");
3893 bool MipsAsmParser::parseDirectiveSet() {
3894 MCAsmParser &Parser = getParser();
3895 // Get the next token.
3896 const AsmToken &Tok = Parser.getTok();
3898 if (Tok.getString() == "noat") {
3899 return parseSetNoAtDirective();
3900 } else if (Tok.getString() == "at") {
3901 return parseSetAtDirective();
3902 } else if (Tok.getString() == "arch") {
3903 return parseSetArchDirective();
3904 } else if (Tok.getString() == "fp") {
3905 return parseSetFpDirective();
3906 } else if (Tok.getString() == "pop") {
3907 return parseSetPopDirective();
3908 } else if (Tok.getString() == "push") {
3909 return parseSetPushDirective();
3910 } else if (Tok.getString() == "reorder") {
3911 return parseSetReorderDirective();
3912 } else if (Tok.getString() == "noreorder") {
3913 return parseSetNoReorderDirective();
3914 } else if (Tok.getString() == "macro") {
3915 return parseSetMacroDirective();
3916 } else if (Tok.getString() == "nomacro") {
3917 return parseSetNoMacroDirective();
3918 } else if (Tok.getString() == "mips16") {
3919 return parseSetMips16Directive();
3920 } else if (Tok.getString() == "nomips16") {
3921 return parseSetNoMips16Directive();
3922 } else if (Tok.getString() == "nomicromips") {
3923 getTargetStreamer().emitDirectiveSetNoMicroMips();
3924 Parser.eatToEndOfStatement();
3926 } else if (Tok.getString() == "micromips") {
3927 return parseSetFeature(Mips::FeatureMicroMips);
3928 } else if (Tok.getString() == "mips0") {
3929 return parseSetMips0Directive();
3930 } else if (Tok.getString() == "mips1") {
3931 return parseSetFeature(Mips::FeatureMips1);
3932 } else if (Tok.getString() == "mips2") {
3933 return parseSetFeature(Mips::FeatureMips2);
3934 } else if (Tok.getString() == "mips3") {
3935 return parseSetFeature(Mips::FeatureMips3);
3936 } else if (Tok.getString() == "mips4") {
3937 return parseSetFeature(Mips::FeatureMips4);
3938 } else if (Tok.getString() == "mips5") {
3939 return parseSetFeature(Mips::FeatureMips5);
3940 } else if (Tok.getString() == "mips32") {
3941 return parseSetFeature(Mips::FeatureMips32);
3942 } else if (Tok.getString() == "mips32r2") {
3943 return parseSetFeature(Mips::FeatureMips32r2);
3944 } else if (Tok.getString() == "mips32r3") {
3945 return parseSetFeature(Mips::FeatureMips32r3);
3946 } else if (Tok.getString() == "mips32r5") {
3947 return parseSetFeature(Mips::FeatureMips32r5);
3948 } else if (Tok.getString() == "mips32r6") {
3949 return parseSetFeature(Mips::FeatureMips32r6);
3950 } else if (Tok.getString() == "mips64") {
3951 return parseSetFeature(Mips::FeatureMips64);
3952 } else if (Tok.getString() == "mips64r2") {
3953 return parseSetFeature(Mips::FeatureMips64r2);
3954 } else if (Tok.getString() == "mips64r3") {
3955 return parseSetFeature(Mips::FeatureMips64r3);
3956 } else if (Tok.getString() == "mips64r5") {
3957 return parseSetFeature(Mips::FeatureMips64r5);
3958 } else if (Tok.getString() == "mips64r6") {
3959 return parseSetFeature(Mips::FeatureMips64r6);
3960 } else if (Tok.getString() == "dsp") {
3961 return parseSetFeature(Mips::FeatureDSP);
3962 } else if (Tok.getString() == "nodsp") {
3963 return parseSetNoDspDirective();
3964 } else if (Tok.getString() == "msa") {
3965 return parseSetMsaDirective();
3966 } else if (Tok.getString() == "nomsa") {
3967 return parseSetNoMsaDirective();
3969 // It is just an identifier, look for an assignment.
3970 parseSetAssignment();
3977 /// parseDataDirective
3978 /// ::= .word [ expression (, expression)* ]
3979 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3980 MCAsmParser &Parser = getParser();
3981 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3983 const MCExpr *Value;
3984 if (getParser().parseExpression(Value))
3987 getParser().getStreamer().EmitValue(Value, Size);
3989 if (getLexer().is(AsmToken::EndOfStatement))
3992 if (getLexer().isNot(AsmToken::Comma))
3993 return Error(L, "unexpected token, expected comma");
4002 /// parseDirectiveGpWord
4003 /// ::= .gpword local_sym
4004 bool MipsAsmParser::parseDirectiveGpWord() {
4005 MCAsmParser &Parser = getParser();
4006 const MCExpr *Value;
4007 // EmitGPRel32Value requires an expression, so we are using base class
4008 // method to evaluate the expression.
4009 if (getParser().parseExpression(Value))
4011 getParser().getStreamer().EmitGPRel32Value(Value);
4013 if (getLexer().isNot(AsmToken::EndOfStatement))
4014 return Error(getLexer().getLoc(),
4015 "unexpected token, expected end of statement");
4016 Parser.Lex(); // Eat EndOfStatement token.
4020 /// parseDirectiveGpDWord
4021 /// ::= .gpdword local_sym
4022 bool MipsAsmParser::parseDirectiveGpDWord() {
4023 MCAsmParser &Parser = getParser();
4024 const MCExpr *Value;
4025 // EmitGPRel64Value requires an expression, so we are using base class
4026 // method to evaluate the expression.
4027 if (getParser().parseExpression(Value))
4029 getParser().getStreamer().EmitGPRel64Value(Value);
4031 if (getLexer().isNot(AsmToken::EndOfStatement))
4032 return Error(getLexer().getLoc(),
4033 "unexpected token, expected end of statement");
4034 Parser.Lex(); // Eat EndOfStatement token.
4038 bool MipsAsmParser::parseDirectiveOption() {
4039 MCAsmParser &Parser = getParser();
4040 // Get the option token.
4041 AsmToken Tok = Parser.getTok();
4042 // At the moment only identifiers are supported.
4043 if (Tok.isNot(AsmToken::Identifier)) {
4044 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4045 Parser.eatToEndOfStatement();
4049 StringRef Option = Tok.getIdentifier();
4051 if (Option == "pic0") {
4052 getTargetStreamer().emitDirectiveOptionPic0();
4054 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4055 Error(Parser.getTok().getLoc(),
4056 "unexpected token, expected end of statement");
4057 Parser.eatToEndOfStatement();
4062 if (Option == "pic2") {
4063 getTargetStreamer().emitDirectiveOptionPic2();
4065 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4066 Error(Parser.getTok().getLoc(),
4067 "unexpected token, expected end of statement");
4068 Parser.eatToEndOfStatement();
4074 Warning(Parser.getTok().getLoc(),
4075 "unknown option, expected 'pic0' or 'pic2'");
4076 Parser.eatToEndOfStatement();
4080 /// parseInsnDirective
4082 bool MipsAsmParser::parseInsnDirective() {
4083 // If this is not the end of the statement, report an error.
4084 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4085 reportParseError("unexpected token, expected end of statement");
4089 // The actual label marking happens in
4090 // MipsELFStreamer::createPendingLabelRelocs().
4091 getTargetStreamer().emitDirectiveInsn();
4093 getParser().Lex(); // Eat EndOfStatement token.
4097 /// parseDirectiveModule
4098 /// ::= .module oddspreg
4099 /// ::= .module nooddspreg
4100 /// ::= .module fp=value
4101 bool MipsAsmParser::parseDirectiveModule() {
4102 MCAsmParser &Parser = getParser();
4103 MCAsmLexer &Lexer = getLexer();
4104 SMLoc L = Lexer.getLoc();
4106 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4107 // TODO : get a better message.
4108 reportParseError(".module directive must appear before any code");
4113 if (Parser.parseIdentifier(Option)) {
4114 reportParseError("expected .module option identifier");
4118 if (Option == "oddspreg") {
4119 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4120 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4122 // If this is not the end of the statement, report an error.
4123 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4124 reportParseError("unexpected token, expected end of statement");
4128 return false; // parseDirectiveModule has finished successfully.
4129 } else if (Option == "nooddspreg") {
4131 Error(L, "'.module nooddspreg' requires the O32 ABI");
4135 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4136 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4138 // If this is not the end of the statement, report an error.
4139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4140 reportParseError("unexpected token, expected end of statement");
4144 return false; // parseDirectiveModule has finished successfully.
4145 } else if (Option == "fp") {
4146 return parseDirectiveModuleFP();
4148 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4152 /// parseDirectiveModuleFP
4156 bool MipsAsmParser::parseDirectiveModuleFP() {
4157 MCAsmParser &Parser = getParser();
4158 MCAsmLexer &Lexer = getLexer();
4160 if (Lexer.isNot(AsmToken::Equal)) {
4161 reportParseError("unexpected token, expected equals sign '='");
4164 Parser.Lex(); // Eat '=' token.
4166 MipsABIFlagsSection::FpABIKind FpABI;
4167 if (!parseFpABIValue(FpABI, ".module"))
4170 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4171 reportParseError("unexpected token, expected end of statement");
4175 // Emit appropriate flags.
4176 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4177 Parser.Lex(); // Consume the EndOfStatement.
4181 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4182 StringRef Directive) {
4183 MCAsmParser &Parser = getParser();
4184 MCAsmLexer &Lexer = getLexer();
4186 if (Lexer.is(AsmToken::Identifier)) {
4187 StringRef Value = Parser.getTok().getString();
4190 if (Value != "xx") {
4191 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4196 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4200 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4204 if (Lexer.is(AsmToken::Integer)) {
4205 unsigned Value = Parser.getTok().getIntVal();
4208 if (Value != 32 && Value != 64) {
4209 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4215 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4219 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4221 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4229 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4230 MCAsmParser &Parser = getParser();
4231 StringRef IDVal = DirectiveID.getString();
4233 if (IDVal == ".cpload")
4234 return parseDirectiveCpLoad(DirectiveID.getLoc());
4235 if (IDVal == ".dword") {
4236 parseDataDirective(8, DirectiveID.getLoc());
4239 if (IDVal == ".ent") {
4240 StringRef SymbolName;
4242 if (Parser.parseIdentifier(SymbolName)) {
4243 reportParseError("expected identifier after .ent");
4247 // There's an undocumented extension that allows an integer to
4248 // follow the name of the procedure which AFAICS is ignored by GAS.
4249 // Example: .ent foo,2
4250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4251 if (getLexer().isNot(AsmToken::Comma)) {
4252 // Even though we accept this undocumented extension for compatibility
4253 // reasons, the additional integer argument does not actually change
4254 // the behaviour of the '.ent' directive, so we would like to discourage
4255 // its use. We do this by not referring to the extended version in
4256 // error messages which are not directly related to its use.
4257 reportParseError("unexpected token, expected end of statement");
4260 Parser.Lex(); // Eat the comma.
4261 const MCExpr *DummyNumber;
4262 int64_t DummyNumberVal;
4263 // If the user was explicitly trying to use the extended version,
4264 // we still give helpful extension-related error messages.
4265 if (Parser.parseExpression(DummyNumber)) {
4266 reportParseError("expected number after comma");
4269 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4270 reportParseError("expected an absolute expression after comma");
4275 // If this is not the end of the statement, report an error.
4276 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4277 reportParseError("unexpected token, expected end of statement");
4281 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4283 getTargetStreamer().emitDirectiveEnt(*Sym);
4288 if (IDVal == ".end") {
4289 StringRef SymbolName;
4291 if (Parser.parseIdentifier(SymbolName)) {
4292 reportParseError("expected identifier after .end");
4296 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4297 reportParseError("unexpected token, expected end of statement");
4301 if (CurrentFn == nullptr) {
4302 reportParseError(".end used without .ent");
4306 if ((SymbolName != CurrentFn->getName())) {
4307 reportParseError(".end symbol does not match .ent symbol");
4311 getTargetStreamer().emitDirectiveEnd(SymbolName);
4312 CurrentFn = nullptr;
4316 if (IDVal == ".frame") {
4317 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4318 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4319 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4320 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4321 reportParseError("expected stack register");
4325 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4326 if (!StackRegOpnd.isGPRAsmReg()) {
4327 reportParseError(StackRegOpnd.getStartLoc(),
4328 "expected general purpose register");
4331 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4333 if (Parser.getTok().is(AsmToken::Comma))
4336 reportParseError("unexpected token, expected comma");
4340 // Parse the frame size.
4341 const MCExpr *FrameSize;
4342 int64_t FrameSizeVal;
4344 if (Parser.parseExpression(FrameSize)) {
4345 reportParseError("expected frame size value");
4349 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4350 reportParseError("frame size not an absolute expression");
4354 if (Parser.getTok().is(AsmToken::Comma))
4357 reportParseError("unexpected token, expected comma");
4361 // Parse the return register.
4363 ResTy = parseAnyRegister(TmpReg);
4364 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4365 reportParseError("expected return register");
4369 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4370 if (!ReturnRegOpnd.isGPRAsmReg()) {
4371 reportParseError(ReturnRegOpnd.getStartLoc(),
4372 "expected general purpose register");
4376 // If this is not the end of the statement, report an error.
4377 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4378 reportParseError("unexpected token, expected end of statement");
4382 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4383 ReturnRegOpnd.getGPR32Reg());
4387 if (IDVal == ".set") {
4388 return parseDirectiveSet();
4391 if (IDVal == ".mask" || IDVal == ".fmask") {
4392 // .mask bitmask, frame_offset
4393 // bitmask: One bit for each register used.
4394 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4395 // first register is expected to be saved.
4397 // .mask 0x80000000, -4
4398 // .fmask 0x80000000, -4
4401 // Parse the bitmask
4402 const MCExpr *BitMask;
4405 if (Parser.parseExpression(BitMask)) {
4406 reportParseError("expected bitmask value");
4410 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4411 reportParseError("bitmask not an absolute expression");
4415 if (Parser.getTok().is(AsmToken::Comma))
4418 reportParseError("unexpected token, expected comma");
4422 // Parse the frame_offset
4423 const MCExpr *FrameOffset;
4424 int64_t FrameOffsetVal;
4426 if (Parser.parseExpression(FrameOffset)) {
4427 reportParseError("expected frame offset value");
4431 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4432 reportParseError("frame offset not an absolute expression");
4436 // If this is not the end of the statement, report an error.
4437 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4438 reportParseError("unexpected token, expected end of statement");
4442 if (IDVal == ".mask")
4443 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4445 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4449 if (IDVal == ".nan")
4450 return parseDirectiveNaN();
4452 if (IDVal == ".gpword") {
4453 parseDirectiveGpWord();
4457 if (IDVal == ".gpdword") {
4458 parseDirectiveGpDWord();
4462 if (IDVal == ".word") {
4463 parseDataDirective(4, DirectiveID.getLoc());
4467 if (IDVal == ".option")
4468 return parseDirectiveOption();
4470 if (IDVal == ".abicalls") {
4471 getTargetStreamer().emitDirectiveAbiCalls();
4472 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4473 Error(Parser.getTok().getLoc(),
4474 "unexpected token, expected end of statement");
4476 Parser.eatToEndOfStatement();
4481 if (IDVal == ".cpsetup")
4482 return parseDirectiveCPSetup();
4484 if (IDVal == ".module")
4485 return parseDirectiveModule();
4487 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4488 return parseInternalDirectiveReallowModule();
4490 if (IDVal == ".insn")
4491 return parseInsnDirective();
4496 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4497 // If this is not the end of the statement, report an error.
4498 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4499 reportParseError("unexpected token, expected end of statement");
4503 getTargetStreamer().reallowModuleDirective();
4505 getParser().Lex(); // Eat EndOfStatement token.
4509 extern "C" void LLVMInitializeMipsAsmParser() {
4510 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4511 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4512 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4513 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4516 #define GET_REGISTER_MATCHER
4517 #define GET_MATCHER_IMPLEMENTATION
4518 #include "MipsGenAsmMatcher.inc"