1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegNum();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegNum() const { return ATReg; }
57 bool setATReg(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
200 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool reportParseError(Twine ErrorMsg);
207 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
209 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
210 bool parseRelocOperand(const MCExpr *&Res);
212 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
214 bool isEvaluated(const MCExpr *Expr);
215 bool parseSetMips0Directive();
216 bool parseSetArchDirective();
217 bool parseSetFeature(uint64_t Feature);
218 bool parseDirectiveCpLoad(SMLoc Loc);
219 bool parseDirectiveCPSetup();
220 bool parseDirectiveNaN();
221 bool parseDirectiveSet();
222 bool parseDirectiveOption();
224 bool parseSetAtDirective();
225 bool parseSetNoAtDirective();
226 bool parseSetMacroDirective();
227 bool parseSetNoMacroDirective();
228 bool parseSetMsaDirective();
229 bool parseSetNoMsaDirective();
230 bool parseSetNoDspDirective();
231 bool parseSetReorderDirective();
232 bool parseSetNoReorderDirective();
233 bool parseSetMips16Directive();
234 bool parseSetNoMips16Directive();
235 bool parseSetFpDirective();
236 bool parseSetPopDirective();
237 bool parseSetPushDirective();
239 bool parseSetAssignment();
241 bool parseDataDirective(unsigned Size, SMLoc L);
242 bool parseDirectiveGpWord();
243 bool parseDirectiveGpDWord();
244 bool parseDirectiveModule();
245 bool parseDirectiveModuleFP();
246 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
247 StringRef Directive);
249 bool parseInternalDirectiveReallowModule();
251 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
253 bool eatComma(StringRef ErrorStr);
255 int matchCPURegisterName(StringRef Symbol);
257 int matchHWRegsRegisterName(StringRef Symbol);
259 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
261 int matchFPURegisterName(StringRef Name);
263 int matchFCCRegisterName(StringRef Name);
265 int matchACRegisterName(StringRef Name);
267 int matchMSA128RegisterName(StringRef Name);
269 int matchMSA128CtrlRegisterName(StringRef Name);
271 unsigned getReg(int RC, int RegNo);
273 unsigned getGPR(int RegNo);
275 /// Returns the internal register number for the current AT. Also checks if
276 /// the current AT is unavailable (set to $0) and gives an error if it is.
277 /// This should be used in pseudo-instruction expansions which need AT.
278 unsigned getATReg(SMLoc Loc);
280 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
281 SmallVectorImpl<MCInst> &Instructions);
283 // Helper function that checks if the value of a vector index is within the
284 // boundaries of accepted values for each RegisterKind
285 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
286 bool validateMSAIndex(int Val, int RegKind);
288 // Selects a new architecture by updating the FeatureBits with the necessary
289 // info including implied dependencies.
290 // Internally, it clears all the feature bits related to *any* architecture
291 // and selects the new one using the ToggleFeature functionality of the
292 // MCSubtargetInfo object that handles implied dependencies. The reason we
293 // clear all the arch related bits manually is because ToggleFeature only
294 // clears the features that imply the feature being cleared and not the
295 // features implied by the feature being cleared. This is easier to see
297 // --------------------------------------------------
298 // | Feature | Implies |
299 // | -------------------------------------------------|
300 // | FeatureMips1 | None |
301 // | FeatureMips2 | FeatureMips1 |
302 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
303 // | FeatureMips4 | FeatureMips3 |
305 // --------------------------------------------------
307 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
308 // FeatureMipsGP64 | FeatureMips1)
309 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
310 void selectArch(StringRef ArchFeature) {
311 uint64_t FeatureBits = STI.getFeatureBits();
312 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
313 STI.setFeatureBits(FeatureBits);
314 setAvailableFeatures(
315 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
316 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
319 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
320 if (!(STI.getFeatureBits() & Feature)) {
321 setAvailableFeatures(
322 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
324 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
327 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
328 if (STI.getFeatureBits() & Feature) {
329 setAvailableFeatures(
330 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
332 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
336 enum MipsMatchResultTy {
337 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
338 #define GET_OPERAND_DIAGNOSTIC_TYPES
339 #include "MipsGenAsmMatcher.inc"
340 #undef GET_OPERAND_DIAGNOSTIC_TYPES
344 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
345 const MCInstrInfo &MII, const MCTargetOptions &Options)
346 : MCTargetAsmParser(), STI(sti),
347 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
348 sti.getCPU(), Options)) {
349 MCAsmParserExtension::Initialize(parser);
351 // Initialize the set of available features.
352 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
354 // Remember the initial assembler options. The user can not modify these.
355 AssemblerOptions.push_back(
356 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
358 // Create an assembler options environment for the user to modify.
359 AssemblerOptions.push_back(
360 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
362 getTargetStreamer().updateABIInfo(*this);
364 if (!isABI_O32() && !useOddSPReg() != 0)
365 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
370 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
371 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
373 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
374 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
375 const MipsABIInfo &getABI() const { return ABI; }
376 bool isABI_N32() const { return ABI.IsN32(); }
377 bool isABI_N64() const { return ABI.IsN64(); }
378 bool isABI_O32() const { return ABI.IsO32(); }
379 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
381 bool useOddSPReg() const {
382 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
385 bool inMicroMipsMode() const {
386 return STI.getFeatureBits() & Mips::FeatureMicroMips;
388 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
389 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
390 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
391 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
392 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
393 bool hasMips32() const {
394 return (STI.getFeatureBits() & Mips::FeatureMips32);
396 bool hasMips64() const {
397 return (STI.getFeatureBits() & Mips::FeatureMips64);
399 bool hasMips32r2() const {
400 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
402 bool hasMips64r2() const {
403 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
405 bool hasMips32r3() const {
406 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
408 bool hasMips64r3() const {
409 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
411 bool hasMips32r5() const {
412 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
414 bool hasMips64r5() const {
415 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
417 bool hasMips32r6() const {
418 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
420 bool hasMips64r6() const {
421 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
423 bool hasCnMips() const {
424 return (STI.getFeatureBits() & Mips::FeatureCnMips);
426 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
427 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
428 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
430 bool inMips16Mode() const {
431 return STI.getFeatureBits() & Mips::FeatureMips16;
433 // TODO: see how can we get this info.
434 bool abiUsesSoftFloat() const { return false; }
436 /// Warn if RegNo is the current assembler temporary.
437 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
443 /// MipsOperand - Instances of this class represent a parsed Mips machine
445 class MipsOperand : public MCParsedAsmOperand {
447 /// Broad categories of register classes
448 /// The exact class is finalized by the render method.
450 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
451 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
453 RegKind_FCC = 4, /// FCC
454 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
455 RegKind_MSACtrl = 16, /// MSA control registers
456 RegKind_COP2 = 32, /// COP2
457 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
459 RegKind_CCR = 128, /// CCR
460 RegKind_HWRegs = 256, /// HWRegs
461 RegKind_COP3 = 512, /// COP3
463 /// Potentially any (e.g. $1)
464 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
465 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
466 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
471 k_Immediate, /// An immediate (possibly involving symbol references)
472 k_Memory, /// Base + Offset Memory Address
473 k_PhysRegister, /// A physical register from the Mips namespace
474 k_RegisterIndex, /// A register index in one or more RegKind.
475 k_Token, /// A simple token
476 k_RegList, /// A physical register list
477 k_RegPair /// A pair of physical register
481 MipsOperand(KindTy K, MipsAsmParser &Parser)
482 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
485 /// For diagnostics, and checking the assembler temporary
486 MipsAsmParser &AsmParser;
494 unsigned Num; /// Register Number
498 unsigned Index; /// Index into the register class
499 RegKind Kind; /// Bitfield of the kinds it could possibly be
500 const MCRegisterInfo *RegInfo;
513 SmallVector<unsigned, 10> *List;
518 struct PhysRegOp PhysReg;
519 struct RegIdxOp RegIdx;
522 struct RegListOp RegList;
525 SMLoc StartLoc, EndLoc;
527 /// Internal constructor for register kinds
528 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
529 const MCRegisterInfo *RegInfo,
531 MipsAsmParser &Parser) {
532 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
533 Op->RegIdx.Index = Index;
534 Op->RegIdx.RegInfo = RegInfo;
535 Op->RegIdx.Kind = RegKind;
542 /// Coerce the register to GPR32 and return the real register for the current
544 unsigned getGPR32Reg() const {
545 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
546 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
547 unsigned ClassID = Mips::GPR32RegClassID;
548 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
551 /// Coerce the register to GPR32 and return the real register for the current
553 unsigned getGPRMM16Reg() const {
554 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
555 unsigned ClassID = Mips::GPR32RegClassID;
556 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
559 /// Coerce the register to GPR64 and return the real register for the current
561 unsigned getGPR64Reg() const {
562 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
563 unsigned ClassID = Mips::GPR64RegClassID;
564 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
568 /// Coerce the register to AFGR64 and return the real register for the current
570 unsigned getAFGR64Reg() const {
571 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
572 if (RegIdx.Index % 2 != 0)
573 AsmParser.Warning(StartLoc, "Float register should be even.");
574 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
575 .getRegister(RegIdx.Index / 2);
578 /// Coerce the register to FGR64 and return the real register for the current
580 unsigned getFGR64Reg() const {
581 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
582 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
583 .getRegister(RegIdx.Index);
586 /// Coerce the register to FGR32 and return the real register for the current
588 unsigned getFGR32Reg() const {
589 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
590 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
591 .getRegister(RegIdx.Index);
594 /// Coerce the register to FGRH32 and return the real register for the current
596 unsigned getFGRH32Reg() const {
597 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
598 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
599 .getRegister(RegIdx.Index);
602 /// Coerce the register to FCC and return the real register for the current
604 unsigned getFCCReg() const {
605 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
606 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
607 .getRegister(RegIdx.Index);
610 /// Coerce the register to MSA128 and return the real register for the current
612 unsigned getMSA128Reg() const {
613 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
614 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
616 unsigned ClassID = Mips::MSA128BRegClassID;
617 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
620 /// Coerce the register to MSACtrl and return the real register for the
622 unsigned getMSACtrlReg() const {
623 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
624 unsigned ClassID = Mips::MSACtrlRegClassID;
625 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
628 /// Coerce the register to COP2 and return the real register for the
630 unsigned getCOP2Reg() const {
631 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
632 unsigned ClassID = Mips::COP2RegClassID;
633 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
636 /// Coerce the register to COP3 and return the real register for the
638 unsigned getCOP3Reg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
640 unsigned ClassID = Mips::COP3RegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
644 /// Coerce the register to ACC64DSP and return the real register for the
646 unsigned getACC64DSPReg() const {
647 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
648 unsigned ClassID = Mips::ACC64DSPRegClassID;
649 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
652 /// Coerce the register to HI32DSP and return the real register for the
654 unsigned getHI32DSPReg() const {
655 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
656 unsigned ClassID = Mips::HI32DSPRegClassID;
657 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
660 /// Coerce the register to LO32DSP and return the real register for the
662 unsigned getLO32DSPReg() const {
663 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
664 unsigned ClassID = Mips::LO32DSPRegClassID;
665 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
668 /// Coerce the register to CCR and return the real register for the
670 unsigned getCCRReg() const {
671 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
672 unsigned ClassID = Mips::CCRRegClassID;
673 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
676 /// Coerce the register to HWRegs and return the real register for the
678 unsigned getHWRegsReg() const {
679 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
680 unsigned ClassID = Mips::HWRegsRegClassID;
681 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
685 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
686 // Add as immediate when possible. Null MCExpr = 0.
688 Inst.addOperand(MCOperand::CreateImm(0));
689 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
690 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
692 Inst.addOperand(MCOperand::CreateExpr(Expr));
695 void addRegOperands(MCInst &Inst, unsigned N) const {
696 llvm_unreachable("Use a custom parser instead");
699 /// Render the operand to an MCInst as a GPR32
700 /// Asserts if the wrong number of operands are requested, or the operand
701 /// is not a k_RegisterIndex compatible with RegKind_GPR
702 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
703 assert(N == 1 && "Invalid number of operands!");
704 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
707 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
708 assert(N == 1 && "Invalid number of operands!");
709 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
712 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
713 assert(N == 1 && "Invalid number of operands!");
714 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
717 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
718 assert(N == 1 && "Invalid number of operands!");
719 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
722 /// Render the operand to an MCInst as a GPR64
723 /// Asserts if the wrong number of operands are requested, or the operand
724 /// is not a k_RegisterIndex compatible with RegKind_GPR
725 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
726 assert(N == 1 && "Invalid number of operands!");
727 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
730 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
731 assert(N == 1 && "Invalid number of operands!");
732 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
735 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
736 assert(N == 1 && "Invalid number of operands!");
737 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
740 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
741 assert(N == 1 && "Invalid number of operands!");
742 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
743 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
744 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
745 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
749 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
754 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
759 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
764 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
765 assert(N == 1 && "Invalid number of operands!");
766 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
769 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
770 assert(N == 1 && "Invalid number of operands!");
771 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
774 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 1 && "Invalid number of operands!");
776 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
779 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
780 assert(N == 1 && "Invalid number of operands!");
781 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
784 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
785 assert(N == 1 && "Invalid number of operands!");
786 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
789 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
790 assert(N == 1 && "Invalid number of operands!");
791 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
794 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
795 assert(N == 1 && "Invalid number of operands!");
796 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
799 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
800 assert(N == 1 && "Invalid number of operands!");
801 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
804 void addImmOperands(MCInst &Inst, unsigned N) const {
805 assert(N == 1 && "Invalid number of operands!");
806 const MCExpr *Expr = getImm();
810 void addMemOperands(MCInst &Inst, unsigned N) const {
811 assert(N == 2 && "Invalid number of operands!");
813 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
815 const MCExpr *Expr = getMemOff();
819 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
820 assert(N == 2 && "Invalid number of operands!");
822 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
824 const MCExpr *Expr = getMemOff();
828 void addRegListOperands(MCInst &Inst, unsigned N) const {
829 assert(N == 1 && "Invalid number of operands!");
831 for (auto RegNo : getRegList())
832 Inst.addOperand(MCOperand::CreateReg(RegNo));
835 void addRegPairOperands(MCInst &Inst, unsigned N) const {
836 assert(N == 2 && "Invalid number of operands!");
837 unsigned RegNo = getRegPair();
838 Inst.addOperand(MCOperand::CreateReg(RegNo++));
839 Inst.addOperand(MCOperand::CreateReg(RegNo));
842 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
843 assert(N == 2 && "Invalid number of operands!");
844 for (auto RegNo : getRegList())
845 Inst.addOperand(MCOperand::CreateReg(RegNo));
848 bool isReg() const override {
849 // As a special case until we sort out the definition of div/divu, pretend
850 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
851 if (isGPRAsmReg() && RegIdx.Index == 0)
854 return Kind == k_PhysRegister;
856 bool isRegIdx() const { return Kind == k_RegisterIndex; }
857 bool isImm() const override { return Kind == k_Immediate; }
858 bool isConstantImm() const {
859 return isImm() && dyn_cast<MCConstantExpr>(getImm());
861 bool isToken() const override {
862 // Note: It's not possible to pretend that other operand kinds are tokens.
863 // The matcher emitter checks tokens first.
864 return Kind == k_Token;
866 bool isMem() const override { return Kind == k_Memory; }
867 bool isConstantMemOff() const {
868 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
870 template <unsigned Bits> bool isMemWithSimmOffset() const {
871 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
873 bool isMemWithGRPMM16Base() const {
874 return isMem() && getMemBase()->isMM16AsmReg();
876 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
877 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
878 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
880 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
881 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
882 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
883 && (getMemBase()->getGPR32Reg() == Mips::SP);
885 bool isRegList16() const {
889 int Size = RegList.List->size();
890 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
891 RegList.List->back() != Mips::RA)
894 int PrevReg = *RegList.List->begin();
895 for (int i = 1; i < Size - 1; i++) {
896 int Reg = (*(RegList.List))[i];
897 if ( Reg != PrevReg + 1)
904 bool isInvNum() const { return Kind == k_Immediate; }
905 bool isLSAImm() const {
906 if (!isConstantImm())
908 int64_t Val = getConstantImm();
909 return 1 <= Val && Val <= 4;
911 bool isRegList() const { return Kind == k_RegList; }
912 bool isMovePRegPair() const {
913 if (Kind != k_RegList || RegList.List->size() != 2)
916 unsigned R0 = RegList.List->front();
917 unsigned R1 = RegList.List->back();
919 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
920 (R0 == Mips::A1 && R1 == Mips::A3) ||
921 (R0 == Mips::A2 && R1 == Mips::A3) ||
922 (R0 == Mips::A0 && R1 == Mips::S5) ||
923 (R0 == Mips::A0 && R1 == Mips::S6) ||
924 (R0 == Mips::A0 && R1 == Mips::A1) ||
925 (R0 == Mips::A0 && R1 == Mips::A2) ||
926 (R0 == Mips::A0 && R1 == Mips::A3))
932 StringRef getToken() const {
933 assert(Kind == k_Token && "Invalid access!");
934 return StringRef(Tok.Data, Tok.Length);
936 bool isRegPair() const { return Kind == k_RegPair; }
938 unsigned getReg() const override {
939 // As a special case until we sort out the definition of div/divu, pretend
940 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
941 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
942 RegIdx.Kind & RegKind_GPR)
943 return getGPR32Reg(); // FIXME: GPR64 too
945 assert(Kind == k_PhysRegister && "Invalid access!");
949 const MCExpr *getImm() const {
950 assert((Kind == k_Immediate) && "Invalid access!");
954 int64_t getConstantImm() const {
955 const MCExpr *Val = getImm();
956 return static_cast<const MCConstantExpr *>(Val)->getValue();
959 MipsOperand *getMemBase() const {
960 assert((Kind == k_Memory) && "Invalid access!");
964 const MCExpr *getMemOff() const {
965 assert((Kind == k_Memory) && "Invalid access!");
969 int64_t getConstantMemOff() const {
970 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
973 const SmallVectorImpl<unsigned> &getRegList() const {
974 assert((Kind == k_RegList) && "Invalid access!");
975 return *(RegList.List);
978 unsigned getRegPair() const {
979 assert((Kind == k_RegPair) && "Invalid access!");
983 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
984 MipsAsmParser &Parser) {
985 auto Op = make_unique<MipsOperand>(k_Token, Parser);
986 Op->Tok.Data = Str.data();
987 Op->Tok.Length = Str.size();
993 /// Create a numeric register (e.g. $1). The exact register remains
994 /// unresolved until an instruction successfully matches
995 static std::unique_ptr<MipsOperand>
996 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
997 SMLoc E, MipsAsmParser &Parser) {
998 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
999 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1002 /// Create a register that is definitely a GPR.
1003 /// This is typically only used for named registers such as $gp.
1004 static std::unique_ptr<MipsOperand>
1005 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1006 MipsAsmParser &Parser) {
1007 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1010 /// Create a register that is definitely a FGR.
1011 /// This is typically only used for named registers such as $f0.
1012 static std::unique_ptr<MipsOperand>
1013 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1014 MipsAsmParser &Parser) {
1015 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1018 /// Create a register that is definitely a HWReg.
1019 /// This is typically only used for named registers such as $hwr_cpunum.
1020 static std::unique_ptr<MipsOperand>
1021 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1022 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1023 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1026 /// Create a register that is definitely an FCC.
1027 /// This is typically only used for named registers such as $fcc0.
1028 static std::unique_ptr<MipsOperand>
1029 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1030 MipsAsmParser &Parser) {
1031 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1034 /// Create a register that is definitely an ACC.
1035 /// This is typically only used for named registers such as $ac0.
1036 static std::unique_ptr<MipsOperand>
1037 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1038 MipsAsmParser &Parser) {
1039 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1042 /// Create a register that is definitely an MSA128.
1043 /// This is typically only used for named registers such as $w0.
1044 static std::unique_ptr<MipsOperand>
1045 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1046 SMLoc E, MipsAsmParser &Parser) {
1047 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1050 /// Create a register that is definitely an MSACtrl.
1051 /// This is typically only used for named registers such as $msaaccess.
1052 static std::unique_ptr<MipsOperand>
1053 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1054 SMLoc E, MipsAsmParser &Parser) {
1055 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1058 static std::unique_ptr<MipsOperand>
1059 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1060 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1067 static std::unique_ptr<MipsOperand>
1068 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1069 SMLoc E, MipsAsmParser &Parser) {
1070 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1071 Op->Mem.Base = Base.release();
1078 static std::unique_ptr<MipsOperand>
1079 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1080 MipsAsmParser &Parser) {
1081 assert (Regs.size() > 0 && "Empty list not allowed");
1083 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1084 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1085 Op->StartLoc = StartLoc;
1086 Op->EndLoc = EndLoc;
1090 static std::unique_ptr<MipsOperand>
1091 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1092 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1093 Op->RegIdx.Index = RegNo;
1099 bool isGPRAsmReg() const {
1100 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1102 bool isMM16AsmReg() const {
1103 if (!(isRegIdx() && RegIdx.Kind))
1105 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1106 || RegIdx.Index == 16 || RegIdx.Index == 17);
1108 bool isMM16AsmRegZero() const {
1109 if (!(isRegIdx() && RegIdx.Kind))
1111 return (RegIdx.Index == 0 ||
1112 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1113 RegIdx.Index == 17);
1115 bool isMM16AsmRegMoveP() const {
1116 if (!(isRegIdx() && RegIdx.Kind))
1118 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1119 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1121 bool isFGRAsmReg() const {
1122 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1123 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1125 bool isHWRegsAsmReg() const {
1126 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1128 bool isCCRAsmReg() const {
1129 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1131 bool isFCCAsmReg() const {
1132 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1134 if (!AsmParser.hasEightFccRegisters())
1135 return RegIdx.Index == 0;
1136 return RegIdx.Index <= 7;
1138 bool isACCAsmReg() const {
1139 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1141 bool isCOP2AsmReg() const {
1142 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1144 bool isCOP3AsmReg() const {
1145 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1147 bool isMSA128AsmReg() const {
1148 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1150 bool isMSACtrlAsmReg() const {
1151 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1154 /// getStartLoc - Get the location of the first token of this operand.
1155 SMLoc getStartLoc() const override { return StartLoc; }
1156 /// getEndLoc - Get the location of the last token of this operand.
1157 SMLoc getEndLoc() const override { return EndLoc; }
1159 virtual ~MipsOperand() {
1167 delete RegList.List;
1168 case k_PhysRegister:
1169 case k_RegisterIndex:
1176 void print(raw_ostream &OS) const override {
1185 Mem.Base->print(OS);
1190 case k_PhysRegister:
1191 OS << "PhysReg<" << PhysReg.Num << ">";
1193 case k_RegisterIndex:
1194 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1201 for (auto Reg : (*RegList.List))
1206 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1210 }; // class MipsOperand
1214 extern const MCInstrDesc MipsInsts[];
1216 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1217 return MipsInsts[Opcode];
1220 static bool hasShortDelaySlot(unsigned Opcode) {
1223 case Mips::JALRS_MM:
1224 case Mips::JALRS16_MM:
1225 case Mips::BGEZALS_MM:
1226 case Mips::BLTZALS_MM:
1233 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1234 SmallVectorImpl<MCInst> &Instructions) {
1235 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1239 if (MCID.isBranch() || MCID.isCall()) {
1240 const unsigned Opcode = Inst.getOpcode();
1250 assert(hasCnMips() && "instruction only valid for octeon cpus");
1257 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1258 Offset = Inst.getOperand(2);
1259 if (!Offset.isImm())
1260 break; // We'll deal with this situation later on when applying fixups.
1261 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1262 return Error(IDLoc, "branch target out of range");
1263 if (OffsetToAlignment(Offset.getImm(),
1264 1LL << (inMicroMipsMode() ? 1 : 2)))
1265 return Error(IDLoc, "branch to misaligned address");
1279 case Mips::BGEZAL_MM:
1280 case Mips::BLTZAL_MM:
1283 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1284 Offset = Inst.getOperand(1);
1285 if (!Offset.isImm())
1286 break; // We'll deal with this situation later on when applying fixups.
1287 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1288 return Error(IDLoc, "branch target out of range");
1289 if (OffsetToAlignment(Offset.getImm(),
1290 1LL << (inMicroMipsMode() ? 1 : 2)))
1291 return Error(IDLoc, "branch to misaligned address");
1293 case Mips::BEQZ16_MM:
1294 case Mips::BNEZ16_MM:
1295 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1296 Offset = Inst.getOperand(1);
1297 if (!Offset.isImm())
1298 break; // We'll deal with this situation later on when applying fixups.
1299 if (!isIntN(8, Offset.getImm()))
1300 return Error(IDLoc, "branch target out of range");
1301 if (OffsetToAlignment(Offset.getImm(), 2LL))
1302 return Error(IDLoc, "branch to misaligned address");
1307 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1308 // We still accept it but it is a normal nop.
1309 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1310 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1311 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1316 const unsigned Opcode = Inst.getOpcode();
1328 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1329 // The offset is handled above
1330 Opnd = Inst.getOperand(1);
1332 return Error(IDLoc, "expected immediate operand kind");
1333 Imm = Opnd.getImm();
1334 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1335 Opcode == Mips::BBIT1 ? 63 : 31))
1336 return Error(IDLoc, "immediate operand value out of range");
1338 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1340 Inst.getOperand(1).setImm(Imm - 32);
1348 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1350 Opnd = Inst.getOperand(3);
1352 return Error(IDLoc, "expected immediate operand kind");
1353 Imm = Opnd.getImm();
1354 if (Imm < 0 || Imm > 31)
1355 return Error(IDLoc, "immediate operand value out of range");
1357 Opnd = Inst.getOperand(2);
1359 return Error(IDLoc, "expected immediate operand kind");
1360 Imm = Opnd.getImm();
1361 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1362 Opcode == Mips::EXTS ? 63 : 31))
1363 return Error(IDLoc, "immediate operand value out of range");
1365 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1366 Inst.getOperand(2).setImm(Imm - 32);
1372 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1373 Opnd = Inst.getOperand(2);
1375 return Error(IDLoc, "expected immediate operand kind");
1376 Imm = Opnd.getImm();
1377 if (!isInt<10>(Imm))
1378 return Error(IDLoc, "immediate operand value out of range");
1383 // If this instruction has a delay slot and .set reorder is active,
1384 // emit a NOP after it.
1385 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1386 Instructions.push_back(Inst);
1387 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1391 if (MCID.mayLoad() || MCID.mayStore()) {
1392 // Check the offset of memory operand, if it is a symbol
1393 // reference or immediate we may have to expand instructions.
1394 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1395 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1396 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1397 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1398 MCOperand &Op = Inst.getOperand(i);
1400 int MemOffset = Op.getImm();
1401 if (MemOffset < -32768 || MemOffset > 32767) {
1402 // Offset can't exceed 16bit value.
1403 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1406 } else if (Op.isExpr()) {
1407 const MCExpr *Expr = Op.getExpr();
1408 if (Expr->getKind() == MCExpr::SymbolRef) {
1409 const MCSymbolRefExpr *SR =
1410 static_cast<const MCSymbolRefExpr *>(Expr);
1411 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1413 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1416 } else if (!isEvaluated(Expr)) {
1417 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1425 if (inMicroMipsMode()) {
1426 if (MCID.mayLoad()) {
1427 // Try to create 16-bit GP relative load instruction.
1428 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1429 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1430 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1431 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1432 MCOperand &Op = Inst.getOperand(i);
1434 int MemOffset = Op.getImm();
1435 MCOperand &DstReg = Inst.getOperand(0);
1436 MCOperand &BaseReg = Inst.getOperand(1);
1437 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1438 getContext().getRegisterInfo()->getRegClass(
1439 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1440 BaseReg.getReg() == Mips::GP) {
1442 TmpInst.setLoc(IDLoc);
1443 TmpInst.setOpcode(Mips::LWGP_MM);
1444 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1445 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1446 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1447 Instructions.push_back(TmpInst);
1455 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1460 switch (Inst.getOpcode()) {
1463 case Mips::ADDIUS5_MM:
1464 Opnd = Inst.getOperand(2);
1466 return Error(IDLoc, "expected immediate operand kind");
1467 Imm = Opnd.getImm();
1468 if (Imm < -8 || Imm > 7)
1469 return Error(IDLoc, "immediate operand value out of range");
1471 case Mips::ADDIUSP_MM:
1472 Opnd = Inst.getOperand(0);
1474 return Error(IDLoc, "expected immediate operand kind");
1475 Imm = Opnd.getImm();
1476 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1478 return Error(IDLoc, "immediate operand value out of range");
1480 case Mips::SLL16_MM:
1481 case Mips::SRL16_MM:
1482 Opnd = Inst.getOperand(2);
1484 return Error(IDLoc, "expected immediate operand kind");
1485 Imm = Opnd.getImm();
1486 if (Imm < 1 || Imm > 8)
1487 return Error(IDLoc, "immediate operand value out of range");
1490 Opnd = Inst.getOperand(1);
1492 return Error(IDLoc, "expected immediate operand kind");
1493 Imm = Opnd.getImm();
1494 if (Imm < -1 || Imm > 126)
1495 return Error(IDLoc, "immediate operand value out of range");
1497 case Mips::ADDIUR2_MM:
1498 Opnd = Inst.getOperand(2);
1500 return Error(IDLoc, "expected immediate operand kind");
1501 Imm = Opnd.getImm();
1502 if (!(Imm == 1 || Imm == -1 ||
1503 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1504 return Error(IDLoc, "immediate operand value out of range");
1506 case Mips::ADDIUR1SP_MM:
1507 Opnd = Inst.getOperand(1);
1509 return Error(IDLoc, "expected immediate operand kind");
1510 Imm = Opnd.getImm();
1511 if (OffsetToAlignment(Imm, 4LL))
1512 return Error(IDLoc, "misaligned immediate operand value");
1513 if (Imm < 0 || Imm > 255)
1514 return Error(IDLoc, "immediate operand value out of range");
1516 case Mips::ANDI16_MM:
1517 Opnd = Inst.getOperand(2);
1519 return Error(IDLoc, "expected immediate operand kind");
1520 Imm = Opnd.getImm();
1521 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1522 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1523 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1524 return Error(IDLoc, "immediate operand value out of range");
1526 case Mips::LBU16_MM:
1527 Opnd = Inst.getOperand(2);
1529 return Error(IDLoc, "expected immediate operand kind");
1530 Imm = Opnd.getImm();
1531 if (Imm < -1 || Imm > 14)
1532 return Error(IDLoc, "immediate operand value out of range");
1535 Opnd = Inst.getOperand(2);
1537 return Error(IDLoc, "expected immediate operand kind");
1538 Imm = Opnd.getImm();
1539 if (Imm < 0 || Imm > 15)
1540 return Error(IDLoc, "immediate operand value out of range");
1542 case Mips::LHU16_MM:
1544 Opnd = Inst.getOperand(2);
1546 return Error(IDLoc, "expected immediate operand kind");
1547 Imm = Opnd.getImm();
1548 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1549 return Error(IDLoc, "immediate operand value out of range");
1553 Opnd = Inst.getOperand(2);
1555 return Error(IDLoc, "expected immediate operand kind");
1556 Imm = Opnd.getImm();
1557 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1558 return Error(IDLoc, "immediate operand value out of range");
1562 Opnd = Inst.getOperand(2);
1564 return Error(IDLoc, "expected immediate operand kind");
1565 Imm = Opnd.getImm();
1566 if (!isUInt<5>(Imm))
1567 return Error(IDLoc, "immediate operand value out of range");
1569 case Mips::ADDIUPC_MM:
1570 MCOperand Opnd = Inst.getOperand(1);
1572 return Error(IDLoc, "expected immediate operand kind");
1573 int Imm = Opnd.getImm();
1574 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1575 return Error(IDLoc, "immediate operand value out of range");
1580 if (needsExpansion(Inst))
1581 return expandInstruction(Inst, IDLoc, Instructions);
1583 Instructions.push_back(Inst);
1588 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1590 switch (Inst.getOpcode()) {
1591 case Mips::LoadImm32:
1592 case Mips::LoadImm64:
1593 case Mips::LoadAddrImm32:
1594 case Mips::LoadAddrReg32:
1595 case Mips::B_MM_Pseudo:
1598 case Mips::JalOneReg:
1599 case Mips::JalTwoReg:
1606 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1607 SmallVectorImpl<MCInst> &Instructions) {
1608 switch (Inst.getOpcode()) {
1609 default: llvm_unreachable("unimplemented expansion");
1610 case Mips::LoadImm32:
1611 return expandLoadImm(Inst, IDLoc, Instructions);
1612 case Mips::LoadImm64:
1614 Error(IDLoc, "instruction requires a 64-bit architecture");
1617 return expandLoadImm(Inst, IDLoc, Instructions);
1618 case Mips::LoadAddrImm32:
1619 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1620 case Mips::LoadAddrReg32:
1621 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1622 case Mips::B_MM_Pseudo:
1623 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1626 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1627 case Mips::JalOneReg:
1628 case Mips::JalTwoReg:
1629 return expandJalWithRegs(Inst, IDLoc, Instructions);
1634 template <bool PerformShift>
1635 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1636 SmallVectorImpl<MCInst> &Instructions) {
1639 tmpInst.setOpcode(Mips::DSLL);
1640 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1641 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1642 tmpInst.addOperand(MCOperand::CreateImm(16));
1643 tmpInst.setLoc(IDLoc);
1644 Instructions.push_back(tmpInst);
1647 tmpInst.setOpcode(Mips::ORi);
1648 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1649 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1650 tmpInst.addOperand(Operand);
1651 tmpInst.setLoc(IDLoc);
1652 Instructions.push_back(tmpInst);
1655 template <int Shift, bool PerformShift>
1656 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1657 SmallVectorImpl<MCInst> &Instructions) {
1658 createShiftOr<PerformShift>(
1659 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1660 IDLoc, Instructions);
1664 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1665 SmallVectorImpl<MCInst> &Instructions) {
1666 // Create a JALR instruction which is going to replace the pseudo-JAL.
1668 JalrInst.setLoc(IDLoc);
1669 const MCOperand FirstRegOp = Inst.getOperand(0);
1670 const unsigned Opcode = Inst.getOpcode();
1672 if (Opcode == Mips::JalOneReg) {
1673 // jal $rs => jalr $rs
1674 if (inMicroMipsMode()) {
1675 JalrInst.setOpcode(Mips::JALR16_MM);
1676 JalrInst.addOperand(FirstRegOp);
1678 JalrInst.setOpcode(Mips::JALR);
1679 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1680 JalrInst.addOperand(FirstRegOp);
1682 } else if (Opcode == Mips::JalTwoReg) {
1683 // jal $rd, $rs => jalr $rd, $rs
1684 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1685 JalrInst.addOperand(FirstRegOp);
1686 const MCOperand SecondRegOp = Inst.getOperand(1);
1687 JalrInst.addOperand(SecondRegOp);
1689 Instructions.push_back(JalrInst);
1691 // If .set reorder is active, emit a NOP after it.
1692 if (AssemblerOptions.back()->isReorder()) {
1693 // This is a 32-bit NOP because these 2 pseudo-instructions
1694 // do not have a short delay slot.
1696 NopInst.setOpcode(Mips::SLL);
1697 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1698 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1699 NopInst.addOperand(MCOperand::CreateImm(0));
1700 Instructions.push_back(NopInst);
1706 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1707 SmallVectorImpl<MCInst> &Instructions) {
1709 const MCOperand &ImmOp = Inst.getOperand(1);
1710 assert(ImmOp.isImm() && "expected immediate operand kind");
1711 const MCOperand &RegOp = Inst.getOperand(0);
1712 assert(RegOp.isReg() && "expected register operand kind");
1714 int64_t ImmValue = ImmOp.getImm();
1715 tmpInst.setLoc(IDLoc);
1716 // FIXME: gas has a special case for values that are 000...1111, which
1717 // becomes a li -1 and then a dsrl
1718 if (0 <= ImmValue && ImmValue <= 65535) {
1719 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1720 // li d,j => ori d,$zero,j
1721 tmpInst.setOpcode(Mips::ORi);
1722 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1723 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1724 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1725 Instructions.push_back(tmpInst);
1726 } else if (ImmValue < 0 && ImmValue >= -32768) {
1727 // For negative signed 16-bit values (-32768 <= j < 0):
1728 // li d,j => addiu d,$zero,j
1729 tmpInst.setOpcode(Mips::ADDiu);
1730 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1731 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1732 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1733 Instructions.push_back(tmpInst);
1734 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1735 // For all other values which are representable as a 32-bit integer:
1736 // li d,j => lui d,hi16(j)
1738 tmpInst.setOpcode(Mips::LUi);
1739 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1740 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1741 Instructions.push_back(tmpInst);
1742 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1743 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1745 Error(IDLoc, "instruction requires a 64-bit architecture");
1749 // <------- lo32 ------>
1750 // <------- hi32 ------>
1751 // <- hi16 -> <- lo16 ->
1752 // _________________________________
1754 // | 16-bytes | 16-bytes | 16-bytes |
1755 // |__________|__________|__________|
1757 // For any 64-bit value that is representable as a 48-bit integer:
1758 // li d,j => lui d,hi16(j)
1759 // ori d,d,hi16(lo32(j))
1761 // ori d,d,lo16(lo32(j))
1762 tmpInst.setOpcode(Mips::LUi);
1763 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1765 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1766 Instructions.push_back(tmpInst);
1767 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1768 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1771 Error(IDLoc, "instruction requires a 64-bit architecture");
1775 // <------- hi32 ------> <------- lo32 ------>
1776 // <- hi16 -> <- lo16 ->
1777 // ___________________________________________
1779 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1780 // |__________|__________|__________|__________|
1782 // For all other values which are representable as a 64-bit integer:
1783 // li d,j => lui d,hi16(j)
1784 // ori d,d,lo16(hi32(j))
1786 // ori d,d,hi16(lo32(j))
1788 // ori d,d,lo16(lo32(j))
1789 tmpInst.setOpcode(Mips::LUi);
1790 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1792 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1793 Instructions.push_back(tmpInst);
1794 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1795 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1796 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1802 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1803 SmallVectorImpl<MCInst> &Instructions) {
1805 const MCOperand &ImmOp = Inst.getOperand(2);
1806 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1807 "expected immediate operand kind");
1808 if (!ImmOp.isImm()) {
1809 expandLoadAddressSym(Inst, IDLoc, Instructions);
1812 const MCOperand &SrcRegOp = Inst.getOperand(1);
1813 assert(SrcRegOp.isReg() && "expected register operand kind");
1814 const MCOperand &DstRegOp = Inst.getOperand(0);
1815 assert(DstRegOp.isReg() && "expected register operand kind");
1816 int ImmValue = ImmOp.getImm();
1817 if (-32768 <= ImmValue && ImmValue <= 65535) {
1818 // For -32768 <= j <= 65535.
1819 // la d,j(s) => addiu d,s,j
1820 tmpInst.setOpcode(Mips::ADDiu);
1821 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1822 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1823 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1824 Instructions.push_back(tmpInst);
1826 // For any other value of j that is representable as a 32-bit integer.
1827 // la d,j(s) => lui d,hi16(j)
1830 tmpInst.setOpcode(Mips::LUi);
1831 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1832 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1833 Instructions.push_back(tmpInst);
1835 tmpInst.setOpcode(Mips::ORi);
1836 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1837 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1838 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1839 Instructions.push_back(tmpInst);
1841 tmpInst.setOpcode(Mips::ADDu);
1842 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1843 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1844 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1845 Instructions.push_back(tmpInst);
1851 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1852 SmallVectorImpl<MCInst> &Instructions) {
1854 const MCOperand &ImmOp = Inst.getOperand(1);
1855 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1856 "expected immediate operand kind");
1857 if (!ImmOp.isImm()) {
1858 expandLoadAddressSym(Inst, IDLoc, Instructions);
1861 const MCOperand &RegOp = Inst.getOperand(0);
1862 assert(RegOp.isReg() && "expected register operand kind");
1863 int ImmValue = ImmOp.getImm();
1864 if (-32768 <= ImmValue && ImmValue <= 65535) {
1865 // For -32768 <= j <= 65535.
1866 // la d,j => addiu d,$zero,j
1867 tmpInst.setOpcode(Mips::ADDiu);
1868 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1869 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1870 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1871 Instructions.push_back(tmpInst);
1873 // For any other value of j that is representable as a 32-bit integer.
1874 // la d,j => lui d,hi16(j)
1876 tmpInst.setOpcode(Mips::LUi);
1877 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1878 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1879 Instructions.push_back(tmpInst);
1881 tmpInst.setOpcode(Mips::ORi);
1882 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1883 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1884 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1885 Instructions.push_back(tmpInst);
1891 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1892 SmallVectorImpl<MCInst> &Instructions) {
1893 // FIXME: If we do have a valid at register to use, we should generate a
1894 // slightly shorter sequence here.
1896 int ExprOperandNo = 1;
1897 // Sometimes the assembly parser will get the immediate expression as
1898 // a $zero + an immediate.
1899 if (Inst.getNumOperands() == 3) {
1900 assert(Inst.getOperand(1).getReg() ==
1901 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1904 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1905 assert(SymOp.isExpr() && "expected symbol operand kind");
1906 const MCOperand &RegOp = Inst.getOperand(0);
1907 unsigned RegNo = RegOp.getReg();
1908 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1909 const MCSymbolRefExpr *HiExpr =
1910 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1911 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1912 const MCSymbolRefExpr *LoExpr =
1913 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1914 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1916 // If it's a 64-bit architecture, expand to:
1917 // la d,sym => lui d,highest(sym)
1918 // ori d,d,higher(sym)
1920 // ori d,d,hi16(sym)
1922 // ori d,d,lo16(sym)
1923 const MCSymbolRefExpr *HighestExpr =
1924 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1925 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1926 const MCSymbolRefExpr *HigherExpr =
1927 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1928 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1930 tmpInst.setOpcode(Mips::LUi);
1931 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1932 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1933 Instructions.push_back(tmpInst);
1935 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1937 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1939 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1942 // Otherwise, expand to:
1943 // la d,sym => lui d,hi16(sym)
1944 // ori d,d,lo16(sym)
1945 tmpInst.setOpcode(Mips::LUi);
1946 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1947 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1948 Instructions.push_back(tmpInst);
1950 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1955 bool MipsAsmParser::expandUncondBranchMMPseudo(
1956 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1957 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1958 "unexpected number of operands");
1960 MCOperand Offset = Inst.getOperand(0);
1961 if (Offset.isExpr()) {
1963 Inst.setOpcode(Mips::BEQ_MM);
1964 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1965 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1966 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1968 assert(Offset.isImm() && "expected immediate operand kind");
1969 if (isIntN(11, Offset.getImm())) {
1970 // If offset fits into 11 bits then this instruction becomes microMIPS
1971 // 16-bit unconditional branch instruction.
1972 Inst.setOpcode(Mips::B16_MM);
1974 if (!isIntN(17, Offset.getImm()))
1975 Error(IDLoc, "branch target out of range");
1976 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1977 Error(IDLoc, "branch to misaligned address");
1979 Inst.setOpcode(Mips::BEQ_MM);
1980 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1981 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1982 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1985 Instructions.push_back(Inst);
1987 // If .set reorder is active, emit a NOP after the branch instruction.
1988 if (AssemblerOptions.back()->isReorder())
1989 createNop(true, IDLoc, Instructions);
1994 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1995 SmallVectorImpl<MCInst> &Instructions,
1996 bool isLoad, bool isImmOpnd) {
1997 const MCSymbolRefExpr *SR;
1999 unsigned ImmOffset, HiOffset, LoOffset;
2000 const MCExpr *ExprOffset;
2002 // 1st operand is either the source or destination register.
2003 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2004 unsigned RegOpNum = Inst.getOperand(0).getReg();
2005 // 2nd operand is the base register.
2006 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2007 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2008 // 3rd operand is either an immediate or expression.
2010 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2011 ImmOffset = Inst.getOperand(2).getImm();
2012 LoOffset = ImmOffset & 0x0000ffff;
2013 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2014 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2015 if (LoOffset & 0x8000)
2018 ExprOffset = Inst.getOperand(2).getExpr();
2019 // All instructions will have the same location.
2020 TempInst.setLoc(IDLoc);
2021 // These are some of the types of expansions we perform here:
2022 // 1) lw $8, sym => lui $8, %hi(sym)
2023 // lw $8, %lo(sym)($8)
2024 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2026 // lw $8, %lo(offset)($9)
2027 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2029 // lw $8, %lo(offset)($at)
2030 // 4) sw $8, sym => lui $at, %hi(sym)
2031 // sw $8, %lo(sym)($at)
2032 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2034 // sw $8, %lo(offset)($at)
2035 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2036 // ldc1 $f0, %lo(sym)($at)
2038 // For load instructions we can use the destination register as a temporary
2039 // if base and dst are different (examples 1 and 2) and if the base register
2040 // is general purpose otherwise we must use $at (example 6) and error if it's
2041 // not available. For stores we must use $at (examples 4 and 5) because we
2042 // must not clobber the source register setting up the offset.
2043 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2044 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2045 unsigned RegClassIDOp0 =
2046 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2047 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2048 (RegClassIDOp0 == Mips::GPR64RegClassID);
2049 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2050 TmpRegNum = RegOpNum;
2052 // At this point we need AT to perform the expansions and we exit if it is
2054 TmpRegNum = getATReg(IDLoc);
2059 TempInst.setOpcode(Mips::LUi);
2060 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2062 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2064 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2065 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2066 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2067 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2069 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2071 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2072 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2075 // Add the instruction to the list.
2076 Instructions.push_back(TempInst);
2077 // Prepare TempInst for next instruction.
2079 // Add temp register to base.
2080 if (BaseRegNum != Mips::ZERO) {
2081 TempInst.setOpcode(Mips::ADDu);
2082 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2083 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2084 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2085 Instructions.push_back(TempInst);
2088 // And finally, create original instruction with low part
2089 // of offset and new base.
2090 TempInst.setOpcode(Inst.getOpcode());
2091 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2092 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2094 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2096 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2097 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2098 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2100 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2102 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2103 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2106 Instructions.push_back(TempInst);
2111 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2112 SmallVectorImpl<MCInst> &Instructions) {
2113 unsigned OpNum = Inst.getNumOperands();
2114 unsigned Opcode = Inst.getOpcode();
2115 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2117 assert (Inst.getOperand(OpNum - 1).isImm() &&
2118 Inst.getOperand(OpNum - 2).isReg() &&
2119 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2121 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2122 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2123 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2124 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2125 // It can be implemented as SWM16 or LWM16 instruction.
2126 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2128 Inst.setOpcode(NewOpcode);
2129 Instructions.push_back(Inst);
2133 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2134 SmallVectorImpl<MCInst> &Instructions) {
2136 if (hasShortDelaySlot) {
2137 NopInst.setOpcode(Mips::MOVE16_MM);
2138 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2139 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2141 NopInst.setOpcode(Mips::SLL);
2142 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2143 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2144 NopInst.addOperand(MCOperand::CreateImm(0));
2146 Instructions.push_back(NopInst);
2149 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2150 // As described by the Mips32r2 spec, the registers Rd and Rs for
2151 // jalr.hb must be different.
2152 unsigned Opcode = Inst.getOpcode();
2154 if (Opcode == Mips::JALR_HB &&
2155 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2156 return Match_RequiresDifferentSrcAndDst;
2158 return Match_Success;
2161 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2162 OperandVector &Operands,
2164 uint64_t &ErrorInfo,
2165 bool MatchingInlineAsm) {
2168 SmallVector<MCInst, 8> Instructions;
2169 unsigned MatchResult =
2170 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2172 switch (MatchResult) {
2173 case Match_Success: {
2174 if (processInstruction(Inst, IDLoc, Instructions))
2176 for (unsigned i = 0; i < Instructions.size(); i++)
2177 Out.EmitInstruction(Instructions[i], STI);
2180 case Match_MissingFeature:
2181 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2183 case Match_InvalidOperand: {
2184 SMLoc ErrorLoc = IDLoc;
2185 if (ErrorInfo != ~0ULL) {
2186 if (ErrorInfo >= Operands.size())
2187 return Error(IDLoc, "too few operands for instruction");
2189 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2190 if (ErrorLoc == SMLoc())
2194 return Error(ErrorLoc, "invalid operand for instruction");
2196 case Match_MnemonicFail:
2197 return Error(IDLoc, "invalid instruction");
2198 case Match_RequiresDifferentSrcAndDst:
2199 return Error(IDLoc, "source and destination must be different");
2202 llvm_unreachable("Implement any new match types added!");
2205 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2206 if ((RegIndex != 0) &&
2207 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2209 Warning(Loc, "used $at without \".set noat\"");
2211 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2212 Twine(RegIndex) + "\"");
2217 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2218 SMRange Range, bool ShowColors) {
2219 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2220 Range, SMFixIt(Range, FixMsg),
2224 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2227 CC = StringSwitch<unsigned>(Name)
2263 if (!(isABI_N32() || isABI_N64()))
2266 if (12 <= CC && CC <= 15) {
2267 // Name is one of t4-t7
2268 AsmToken RegTok = getLexer().peekTok();
2269 SMRange RegRange = RegTok.getLocRange();
2271 StringRef FixedName = StringSwitch<StringRef>(Name)
2277 assert(FixedName != "" && "Register name is not one of t4-t7.");
2279 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2280 "Did you mean $" + FixedName + "?", RegRange);
2283 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2284 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2285 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2286 if (8 <= CC && CC <= 11)
2290 CC = StringSwitch<unsigned>(Name)
2302 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2305 CC = StringSwitch<unsigned>(Name)
2306 .Case("hwr_cpunum", 0)
2307 .Case("hwr_synci_step", 1)
2309 .Case("hwr_ccres", 3)
2310 .Case("hwr_ulr", 29)
2316 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2318 if (Name[0] == 'f') {
2319 StringRef NumString = Name.substr(1);
2321 if (NumString.getAsInteger(10, IntVal))
2322 return -1; // This is not an integer.
2323 if (IntVal > 31) // Maximum index for fpu register.
2330 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2332 if (Name.startswith("fcc")) {
2333 StringRef NumString = Name.substr(3);
2335 if (NumString.getAsInteger(10, IntVal))
2336 return -1; // This is not an integer.
2337 if (IntVal > 7) // There are only 8 fcc registers.
2344 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2346 if (Name.startswith("ac")) {
2347 StringRef NumString = Name.substr(2);
2349 if (NumString.getAsInteger(10, IntVal))
2350 return -1; // This is not an integer.
2351 if (IntVal > 3) // There are only 3 acc registers.
2358 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2361 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2370 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2373 CC = StringSwitch<unsigned>(Name)
2376 .Case("msaaccess", 2)
2378 .Case("msamodify", 4)
2379 .Case("msarequest", 5)
2381 .Case("msaunmap", 7)
2387 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2388 unsigned ATIndex = AssemblerOptions.back()->getATRegNum();
2390 reportParseError(Loc,
2391 "pseudo-instruction requires $at, which is not available");
2394 unsigned AT = getReg(
2395 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2399 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2400 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2403 unsigned MipsAsmParser::getGPR(int RegNo) {
2404 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2408 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2410 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2413 return getReg(RegClass, RegNum);
2416 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2417 MCAsmParser &Parser = getParser();
2418 DEBUG(dbgs() << "parseOperand\n");
2420 // Check if the current operand has a custom associated parser, if so, try to
2421 // custom parse the operand, or fallback to the general approach.
2422 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2423 if (ResTy == MatchOperand_Success)
2425 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2426 // there was a match, but an error occurred, in which case, just return that
2427 // the operand parsing failed.
2428 if (ResTy == MatchOperand_ParseFail)
2431 DEBUG(dbgs() << ".. Generic Parser\n");
2433 switch (getLexer().getKind()) {
2435 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2437 case AsmToken::Dollar: {
2438 // Parse the register.
2439 SMLoc S = Parser.getTok().getLoc();
2441 // Almost all registers have been parsed by custom parsers. There is only
2442 // one exception to this. $zero (and it's alias $0) will reach this point
2443 // for div, divu, and similar instructions because it is not an operand
2444 // to the instruction definition but an explicit register. Special case
2445 // this situation for now.
2446 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2449 // Maybe it is a symbol reference.
2450 StringRef Identifier;
2451 if (Parser.parseIdentifier(Identifier))
2454 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2455 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2456 // Otherwise create a symbol reference.
2458 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2460 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2463 // Else drop to expression parsing.
2464 case AsmToken::LParen:
2465 case AsmToken::Minus:
2466 case AsmToken::Plus:
2467 case AsmToken::Integer:
2468 case AsmToken::Tilde:
2469 case AsmToken::String: {
2470 DEBUG(dbgs() << ".. generic integer\n");
2471 OperandMatchResultTy ResTy = parseImm(Operands);
2472 return ResTy != MatchOperand_Success;
2474 case AsmToken::Percent: {
2475 // It is a symbol reference or constant expression.
2476 const MCExpr *IdVal;
2477 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2478 if (parseRelocOperand(IdVal))
2481 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2483 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2485 } // case AsmToken::Percent
2486 } // switch(getLexer().getKind())
2490 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2491 StringRef RelocStr) {
2493 // Check the type of the expression.
2494 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2495 // It's a constant, evaluate reloc value.
2497 switch (getVariantKind(RelocStr)) {
2498 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2499 // Get the 1st 16-bits.
2500 Val = MCE->getValue() & 0xffff;
2502 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2503 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2504 // 16 bits being negative.
2505 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2507 case MCSymbolRefExpr::VK_Mips_HIGHER:
2508 // Get the 3rd 16-bits.
2509 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2511 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2512 // Get the 4th 16-bits.
2513 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2516 report_fatal_error("unsupported reloc value");
2518 return MCConstantExpr::Create(Val, getContext());
2521 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2522 // It's a symbol, create a symbolic expression from the symbol.
2523 StringRef Symbol = MSRE->getSymbol().getName();
2524 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2525 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2529 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2530 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2532 // Try to create target expression.
2533 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2534 return MipsMCExpr::Create(VK, Expr, getContext());
2536 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2537 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2538 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2542 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2543 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2544 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2547 // Just return the original expression.
2551 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2553 switch (Expr->getKind()) {
2554 case MCExpr::Constant:
2556 case MCExpr::SymbolRef:
2557 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2558 case MCExpr::Binary:
2559 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2560 if (!isEvaluated(BE->getLHS()))
2562 return isEvaluated(BE->getRHS());
2565 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2566 case MCExpr::Target:
2572 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2573 MCAsmParser &Parser = getParser();
2574 Parser.Lex(); // Eat the % token.
2575 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2576 if (Tok.isNot(AsmToken::Identifier))
2579 std::string Str = Tok.getIdentifier();
2581 Parser.Lex(); // Eat the identifier.
2582 // Now make an expression from the rest of the operand.
2583 const MCExpr *IdVal;
2586 if (getLexer().getKind() == AsmToken::LParen) {
2588 Parser.Lex(); // Eat the '(' token.
2589 if (getLexer().getKind() == AsmToken::Percent) {
2590 Parser.Lex(); // Eat the % token.
2591 const AsmToken &nextTok = Parser.getTok();
2592 if (nextTok.isNot(AsmToken::Identifier))
2595 Str += nextTok.getIdentifier();
2596 Parser.Lex(); // Eat the identifier.
2597 if (getLexer().getKind() != AsmToken::LParen)
2602 if (getParser().parseParenExpression(IdVal, EndLoc))
2605 while (getLexer().getKind() == AsmToken::RParen)
2606 Parser.Lex(); // Eat the ')' token.
2609 return true; // Parenthesis must follow the relocation operand.
2611 Res = evaluateRelocExpr(IdVal, Str);
2615 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2617 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2618 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2619 if (ResTy == MatchOperand_Success) {
2620 assert(Operands.size() == 1);
2621 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2622 StartLoc = Operand.getStartLoc();
2623 EndLoc = Operand.getEndLoc();
2625 // AFAIK, we only support numeric registers and named GPR's in CFI
2627 // Don't worry about eating tokens before failing. Using an unrecognised
2628 // register is a parse error.
2629 if (Operand.isGPRAsmReg()) {
2630 // Resolve to GPR32 or GPR64 appropriately.
2631 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2634 return (RegNo == (unsigned)-1);
2637 assert(Operands.size() == 0);
2638 return (RegNo == (unsigned)-1);
2641 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2642 MCAsmParser &Parser = getParser();
2646 while (getLexer().getKind() == AsmToken::LParen)
2649 switch (getLexer().getKind()) {
2652 case AsmToken::Identifier:
2653 case AsmToken::LParen:
2654 case AsmToken::Integer:
2655 case AsmToken::Minus:
2656 case AsmToken::Plus:
2658 Result = getParser().parseParenExpression(Res, S);
2660 Result = (getParser().parseExpression(Res));
2661 while (getLexer().getKind() == AsmToken::RParen)
2664 case AsmToken::Percent:
2665 Result = parseRelocOperand(Res);
2670 MipsAsmParser::OperandMatchResultTy
2671 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2672 MCAsmParser &Parser = getParser();
2673 DEBUG(dbgs() << "parseMemOperand\n");
2674 const MCExpr *IdVal = nullptr;
2676 bool isParenExpr = false;
2677 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2678 // First operand is the offset.
2679 S = Parser.getTok().getLoc();
2681 if (getLexer().getKind() == AsmToken::LParen) {
2686 if (getLexer().getKind() != AsmToken::Dollar) {
2687 if (parseMemOffset(IdVal, isParenExpr))
2688 return MatchOperand_ParseFail;
2690 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2691 if (Tok.isNot(AsmToken::LParen)) {
2692 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2693 if (Mnemonic.getToken() == "la") {
2695 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2696 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2697 return MatchOperand_Success;
2699 if (Tok.is(AsmToken::EndOfStatement)) {
2701 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2703 // Zero register assumed, add a memory operand with ZERO as its base.
2704 // "Base" will be managed by k_Memory.
2705 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2708 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2709 return MatchOperand_Success;
2711 Error(Parser.getTok().getLoc(), "'(' expected");
2712 return MatchOperand_ParseFail;
2715 Parser.Lex(); // Eat the '(' token.
2718 Res = parseAnyRegister(Operands);
2719 if (Res != MatchOperand_Success)
2722 if (Parser.getTok().isNot(AsmToken::RParen)) {
2723 Error(Parser.getTok().getLoc(), "')' expected");
2724 return MatchOperand_ParseFail;
2727 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2729 Parser.Lex(); // Eat the ')' token.
2732 IdVal = MCConstantExpr::Create(0, getContext());
2734 // Replace the register operand with the memory operand.
2735 std::unique_ptr<MipsOperand> op(
2736 static_cast<MipsOperand *>(Operands.back().release()));
2737 // Remove the register from the operands.
2738 // "op" will be managed by k_Memory.
2739 Operands.pop_back();
2740 // Add the memory operand.
2741 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2743 if (IdVal->EvaluateAsAbsolute(Imm))
2744 IdVal = MCConstantExpr::Create(Imm, getContext());
2745 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2746 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2750 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2751 return MatchOperand_Success;
2754 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2755 MCAsmParser &Parser = getParser();
2756 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2758 SMLoc S = Parser.getTok().getLoc();
2760 if (Sym->isVariable())
2761 Expr = Sym->getVariableValue();
2764 if (Expr->getKind() == MCExpr::SymbolRef) {
2765 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2766 StringRef DefSymbol = Ref->getSymbol().getName();
2767 if (DefSymbol.startswith("$")) {
2768 OperandMatchResultTy ResTy =
2769 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2770 if (ResTy == MatchOperand_Success) {
2773 } else if (ResTy == MatchOperand_ParseFail)
2774 llvm_unreachable("Should never ParseFail");
2777 } else if (Expr->getKind() == MCExpr::Constant) {
2779 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2781 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2788 MipsAsmParser::OperandMatchResultTy
2789 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2790 StringRef Identifier,
2792 int Index = matchCPURegisterName(Identifier);
2794 Operands.push_back(MipsOperand::createGPRReg(
2795 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2796 return MatchOperand_Success;
2799 Index = matchHWRegsRegisterName(Identifier);
2801 Operands.push_back(MipsOperand::createHWRegsReg(
2802 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2803 return MatchOperand_Success;
2806 Index = matchFPURegisterName(Identifier);
2808 Operands.push_back(MipsOperand::createFGRReg(
2809 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2810 return MatchOperand_Success;
2813 Index = matchFCCRegisterName(Identifier);
2815 Operands.push_back(MipsOperand::createFCCReg(
2816 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2817 return MatchOperand_Success;
2820 Index = matchACRegisterName(Identifier);
2822 Operands.push_back(MipsOperand::createACCReg(
2823 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2824 return MatchOperand_Success;
2827 Index = matchMSA128RegisterName(Identifier);
2829 Operands.push_back(MipsOperand::createMSA128Reg(
2830 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2831 return MatchOperand_Success;
2834 Index = matchMSA128CtrlRegisterName(Identifier);
2836 Operands.push_back(MipsOperand::createMSACtrlReg(
2837 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2838 return MatchOperand_Success;
2841 return MatchOperand_NoMatch;
2844 MipsAsmParser::OperandMatchResultTy
2845 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2846 MCAsmParser &Parser = getParser();
2847 auto Token = Parser.getLexer().peekTok(false);
2849 if (Token.is(AsmToken::Identifier)) {
2850 DEBUG(dbgs() << ".. identifier\n");
2851 StringRef Identifier = Token.getIdentifier();
2852 OperandMatchResultTy ResTy =
2853 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2855 } else if (Token.is(AsmToken::Integer)) {
2856 DEBUG(dbgs() << ".. integer\n");
2857 Operands.push_back(MipsOperand::createNumericReg(
2858 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2860 return MatchOperand_Success;
2863 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2865 return MatchOperand_NoMatch;
2868 MipsAsmParser::OperandMatchResultTy
2869 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2870 MCAsmParser &Parser = getParser();
2871 DEBUG(dbgs() << "parseAnyRegister\n");
2873 auto Token = Parser.getTok();
2875 SMLoc S = Token.getLoc();
2877 if (Token.isNot(AsmToken::Dollar)) {
2878 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2879 if (Token.is(AsmToken::Identifier)) {
2880 if (searchSymbolAlias(Operands))
2881 return MatchOperand_Success;
2883 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2884 return MatchOperand_NoMatch;
2886 DEBUG(dbgs() << ".. $\n");
2888 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2889 if (ResTy == MatchOperand_Success) {
2891 Parser.Lex(); // identifier
2896 MipsAsmParser::OperandMatchResultTy
2897 MipsAsmParser::parseImm(OperandVector &Operands) {
2898 MCAsmParser &Parser = getParser();
2899 switch (getLexer().getKind()) {
2901 return MatchOperand_NoMatch;
2902 case AsmToken::LParen:
2903 case AsmToken::Minus:
2904 case AsmToken::Plus:
2905 case AsmToken::Integer:
2906 case AsmToken::Tilde:
2907 case AsmToken::String:
2911 const MCExpr *IdVal;
2912 SMLoc S = Parser.getTok().getLoc();
2913 if (getParser().parseExpression(IdVal))
2914 return MatchOperand_ParseFail;
2916 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2917 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2918 return MatchOperand_Success;
2921 MipsAsmParser::OperandMatchResultTy
2922 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2923 MCAsmParser &Parser = getParser();
2924 DEBUG(dbgs() << "parseJumpTarget\n");
2926 SMLoc S = getLexer().getLoc();
2928 // Integers and expressions are acceptable
2929 OperandMatchResultTy ResTy = parseImm(Operands);
2930 if (ResTy != MatchOperand_NoMatch)
2933 // Registers are a valid target and have priority over symbols.
2934 ResTy = parseAnyRegister(Operands);
2935 if (ResTy != MatchOperand_NoMatch)
2938 const MCExpr *Expr = nullptr;
2939 if (Parser.parseExpression(Expr)) {
2940 // We have no way of knowing if a symbol was consumed so we must ParseFail
2941 return MatchOperand_ParseFail;
2944 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2945 return MatchOperand_Success;
2948 MipsAsmParser::OperandMatchResultTy
2949 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2950 MCAsmParser &Parser = getParser();
2951 const MCExpr *IdVal;
2952 // If the first token is '$' we may have register operand.
2953 if (Parser.getTok().is(AsmToken::Dollar))
2954 return MatchOperand_NoMatch;
2955 SMLoc S = Parser.getTok().getLoc();
2956 if (getParser().parseExpression(IdVal))
2957 return MatchOperand_ParseFail;
2958 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2959 assert(MCE && "Unexpected MCExpr type.");
2960 int64_t Val = MCE->getValue();
2961 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2962 Operands.push_back(MipsOperand::CreateImm(
2963 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2964 return MatchOperand_Success;
2967 MipsAsmParser::OperandMatchResultTy
2968 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2969 MCAsmParser &Parser = getParser();
2970 switch (getLexer().getKind()) {
2972 return MatchOperand_NoMatch;
2973 case AsmToken::LParen:
2974 case AsmToken::Plus:
2975 case AsmToken::Minus:
2976 case AsmToken::Integer:
2981 SMLoc S = Parser.getTok().getLoc();
2983 if (getParser().parseExpression(Expr))
2984 return MatchOperand_ParseFail;
2987 if (!Expr->EvaluateAsAbsolute(Val)) {
2988 Error(S, "expected immediate value");
2989 return MatchOperand_ParseFail;
2992 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2993 // and because the CPU always adds one to the immediate field, the allowed
2994 // range becomes 1..4. We'll only check the range here and will deal
2995 // with the addition/subtraction when actually decoding/encoding
2997 if (Val < 1 || Val > 4) {
2998 Error(S, "immediate not in range (1..4)");
2999 return MatchOperand_ParseFail;
3003 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3004 return MatchOperand_Success;
3007 MipsAsmParser::OperandMatchResultTy
3008 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3009 MCAsmParser &Parser = getParser();
3010 SmallVector<unsigned, 10> Regs;
3012 unsigned PrevReg = Mips::NoRegister;
3013 bool RegRange = false;
3014 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3016 if (Parser.getTok().isNot(AsmToken::Dollar))
3017 return MatchOperand_ParseFail;
3019 SMLoc S = Parser.getTok().getLoc();
3020 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3021 SMLoc E = getLexer().getLoc();
3022 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3023 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3025 // Remove last register operand because registers from register range
3026 // should be inserted first.
3027 if (RegNo == Mips::RA) {
3028 Regs.push_back(RegNo);
3030 unsigned TmpReg = PrevReg + 1;
3031 while (TmpReg <= RegNo) {
3032 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3033 Error(E, "invalid register operand");
3034 return MatchOperand_ParseFail;
3038 Regs.push_back(TmpReg++);
3044 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3045 (RegNo != Mips::RA)) {
3046 Error(E, "$16 or $31 expected");
3047 return MatchOperand_ParseFail;
3048 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3049 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3050 Error(E, "invalid register operand");
3051 return MatchOperand_ParseFail;
3052 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3053 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3054 Error(E, "consecutive register numbers expected");
3055 return MatchOperand_ParseFail;
3058 Regs.push_back(RegNo);
3061 if (Parser.getTok().is(AsmToken::Minus))
3064 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3065 !Parser.getTok().isNot(AsmToken::Comma)) {
3066 Error(E, "',' or '-' expected");
3067 return MatchOperand_ParseFail;
3070 Lex(); // Consume comma or minus
3071 if (Parser.getTok().isNot(AsmToken::Dollar))
3077 SMLoc E = Parser.getTok().getLoc();
3078 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3079 parseMemOperand(Operands);
3080 return MatchOperand_Success;
3083 MipsAsmParser::OperandMatchResultTy
3084 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3085 MCAsmParser &Parser = getParser();
3087 SMLoc S = Parser.getTok().getLoc();
3088 if (parseAnyRegister(Operands) != MatchOperand_Success)
3089 return MatchOperand_ParseFail;
3091 SMLoc E = Parser.getTok().getLoc();
3092 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3093 unsigned Reg = Op.getGPR32Reg();
3094 Operands.pop_back();
3095 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3096 return MatchOperand_Success;
3099 MipsAsmParser::OperandMatchResultTy
3100 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3101 MCAsmParser &Parser = getParser();
3102 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3103 SmallVector<unsigned, 10> Regs;
3105 if (Parser.getTok().isNot(AsmToken::Dollar))
3106 return MatchOperand_ParseFail;
3108 SMLoc S = Parser.getTok().getLoc();
3110 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3111 return MatchOperand_ParseFail;
3113 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3114 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3115 Regs.push_back(RegNo);
3117 SMLoc E = Parser.getTok().getLoc();
3118 if (Parser.getTok().isNot(AsmToken::Comma)) {
3119 Error(E, "',' expected");
3120 return MatchOperand_ParseFail;
3126 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3127 return MatchOperand_ParseFail;
3129 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3130 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3131 Regs.push_back(RegNo);
3133 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3135 return MatchOperand_Success;
3138 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3140 MCSymbolRefExpr::VariantKind VK =
3141 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3142 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3143 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3144 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3145 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3146 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3147 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3148 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3149 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3150 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3151 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3152 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3153 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3154 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3155 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3156 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3157 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3158 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3159 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3160 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3161 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3162 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3163 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3164 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3165 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3166 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3167 .Default(MCSymbolRefExpr::VK_None);
3169 assert(VK != MCSymbolRefExpr::VK_None);
3174 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3176 /// ::= '(', register, ')'
3177 /// handle it before we iterate so we don't get tripped up by the lack of
3179 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3180 MCAsmParser &Parser = getParser();
3181 if (getLexer().is(AsmToken::LParen)) {
3183 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3185 if (parseOperand(Operands, Name)) {
3186 SMLoc Loc = getLexer().getLoc();
3187 Parser.eatToEndOfStatement();
3188 return Error(Loc, "unexpected token in argument list");
3190 if (Parser.getTok().isNot(AsmToken::RParen)) {
3191 SMLoc Loc = getLexer().getLoc();
3192 Parser.eatToEndOfStatement();
3193 return Error(Loc, "unexpected token, expected ')'");
3196 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3202 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3203 /// either one of these.
3204 /// ::= '[', register, ']'
3205 /// ::= '[', integer, ']'
3206 /// handle it before we iterate so we don't get tripped up by the lack of
3208 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3209 OperandVector &Operands) {
3210 MCAsmParser &Parser = getParser();
3211 if (getLexer().is(AsmToken::LBrac)) {
3213 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3215 if (parseOperand(Operands, Name)) {
3216 SMLoc Loc = getLexer().getLoc();
3217 Parser.eatToEndOfStatement();
3218 return Error(Loc, "unexpected token in argument list");
3220 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3221 SMLoc Loc = getLexer().getLoc();
3222 Parser.eatToEndOfStatement();
3223 return Error(Loc, "unexpected token, expected ']'");
3226 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3232 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3233 SMLoc NameLoc, OperandVector &Operands) {
3234 MCAsmParser &Parser = getParser();
3235 DEBUG(dbgs() << "ParseInstruction\n");
3237 // We have reached first instruction, module directive are now forbidden.
3238 getTargetStreamer().forbidModuleDirective();
3240 // Check if we have valid mnemonic
3241 if (!mnemonicIsValid(Name, 0)) {
3242 Parser.eatToEndOfStatement();
3243 return Error(NameLoc, "unknown instruction");
3245 // First operand in MCInst is instruction mnemonic.
3246 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3248 // Read the remaining operands.
3249 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3250 // Read the first operand.
3251 if (parseOperand(Operands, Name)) {
3252 SMLoc Loc = getLexer().getLoc();
3253 Parser.eatToEndOfStatement();
3254 return Error(Loc, "unexpected token in argument list");
3256 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3258 // AFAIK, parenthesis suffixes are never on the first operand
3260 while (getLexer().is(AsmToken::Comma)) {
3261 Parser.Lex(); // Eat the comma.
3262 // Parse and remember the operand.
3263 if (parseOperand(Operands, Name)) {
3264 SMLoc Loc = getLexer().getLoc();
3265 Parser.eatToEndOfStatement();
3266 return Error(Loc, "unexpected token in argument list");
3268 // Parse bracket and parenthesis suffixes before we iterate
3269 if (getLexer().is(AsmToken::LBrac)) {
3270 if (parseBracketSuffix(Name, Operands))
3272 } else if (getLexer().is(AsmToken::LParen) &&
3273 parseParenSuffix(Name, Operands))
3277 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3278 SMLoc Loc = getLexer().getLoc();
3279 Parser.eatToEndOfStatement();
3280 return Error(Loc, "unexpected token in argument list");
3282 Parser.Lex(); // Consume the EndOfStatement.
3286 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3287 MCAsmParser &Parser = getParser();
3288 SMLoc Loc = getLexer().getLoc();
3289 Parser.eatToEndOfStatement();
3290 return Error(Loc, ErrorMsg);
3293 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3294 return Error(Loc, ErrorMsg);
3297 bool MipsAsmParser::parseSetNoAtDirective() {
3298 MCAsmParser &Parser = getParser();
3299 // Line should look like: ".set noat".
3301 // Set the $at register to $0.
3302 AssemblerOptions.back()->setATReg(0);
3304 Parser.Lex(); // Eat "noat".
3306 // If this is not the end of the statement, report an error.
3307 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3308 reportParseError("unexpected token, expected end of statement");
3312 getTargetStreamer().emitDirectiveSetNoAt();
3313 Parser.Lex(); // Consume the EndOfStatement.
3317 bool MipsAsmParser::parseSetAtDirective() {
3318 // Line can be: ".set at", which sets $at to $1
3319 // or ".set at=$reg", which sets $at to $reg.
3320 MCAsmParser &Parser = getParser();
3321 Parser.Lex(); // Eat "at".
3323 if (getLexer().is(AsmToken::EndOfStatement)) {
3324 // No register was specified, so we set $at to $1.
3325 AssemblerOptions.back()->setATReg(1);
3327 getTargetStreamer().emitDirectiveSetAt();
3328 Parser.Lex(); // Consume the EndOfStatement.
3332 if (getLexer().isNot(AsmToken::Equal)) {
3333 reportParseError("unexpected token, expected equals sign");
3336 Parser.Lex(); // Eat "=".
3338 if (getLexer().isNot(AsmToken::Dollar)) {
3339 if (getLexer().is(AsmToken::EndOfStatement)) {
3340 reportParseError("no register specified");
3343 reportParseError("unexpected token, expected dollar sign '$'");
3347 Parser.Lex(); // Eat "$".
3349 // Find out what "reg" is.
3351 const AsmToken &Reg = Parser.getTok();
3352 if (Reg.is(AsmToken::Identifier)) {
3353 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3354 } else if (Reg.is(AsmToken::Integer)) {
3355 AtRegNo = Reg.getIntVal();
3357 reportParseError("unexpected token, expected identifier or integer");
3361 // Check if $reg is a valid register. If it is, set $at to $reg.
3362 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3363 reportParseError("invalid register");
3366 Parser.Lex(); // Eat "reg".
3368 // If this is not the end of the statement, report an error.
3369 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3370 reportParseError("unexpected token, expected end of statement");
3374 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3376 Parser.Lex(); // Consume the EndOfStatement.
3380 bool MipsAsmParser::parseSetReorderDirective() {
3381 MCAsmParser &Parser = getParser();
3383 // If this is not the end of the statement, report an error.
3384 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3385 reportParseError("unexpected token, expected end of statement");
3388 AssemblerOptions.back()->setReorder();
3389 getTargetStreamer().emitDirectiveSetReorder();
3390 Parser.Lex(); // Consume the EndOfStatement.
3394 bool MipsAsmParser::parseSetNoReorderDirective() {
3395 MCAsmParser &Parser = getParser();
3397 // If this is not the end of the statement, report an error.
3398 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3399 reportParseError("unexpected token, expected end of statement");
3402 AssemblerOptions.back()->setNoReorder();
3403 getTargetStreamer().emitDirectiveSetNoReorder();
3404 Parser.Lex(); // Consume the EndOfStatement.
3408 bool MipsAsmParser::parseSetMacroDirective() {
3409 MCAsmParser &Parser = getParser();
3411 // If this is not the end of the statement, report an error.
3412 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3413 reportParseError("unexpected token, expected end of statement");
3416 AssemblerOptions.back()->setMacro();
3417 Parser.Lex(); // Consume the EndOfStatement.
3421 bool MipsAsmParser::parseSetNoMacroDirective() {
3422 MCAsmParser &Parser = getParser();
3424 // If this is not the end of the statement, report an error.
3425 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3426 reportParseError("unexpected token, expected end of statement");
3429 if (AssemblerOptions.back()->isReorder()) {
3430 reportParseError("`noreorder' must be set before `nomacro'");
3433 AssemblerOptions.back()->setNoMacro();
3434 Parser.Lex(); // Consume the EndOfStatement.
3438 bool MipsAsmParser::parseSetMsaDirective() {
3439 MCAsmParser &Parser = getParser();
3442 // If this is not the end of the statement, report an error.
3443 if (getLexer().isNot(AsmToken::EndOfStatement))
3444 return reportParseError("unexpected token, expected end of statement");
3446 setFeatureBits(Mips::FeatureMSA, "msa");
3447 getTargetStreamer().emitDirectiveSetMsa();
3451 bool MipsAsmParser::parseSetNoMsaDirective() {
3452 MCAsmParser &Parser = getParser();
3455 // If this is not the end of the statement, report an error.
3456 if (getLexer().isNot(AsmToken::EndOfStatement))
3457 return reportParseError("unexpected token, expected end of statement");
3459 clearFeatureBits(Mips::FeatureMSA, "msa");
3460 getTargetStreamer().emitDirectiveSetNoMsa();
3464 bool MipsAsmParser::parseSetNoDspDirective() {
3465 MCAsmParser &Parser = getParser();
3466 Parser.Lex(); // Eat "nodsp".
3468 // If this is not the end of the statement, report an error.
3469 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3470 reportParseError("unexpected token, expected end of statement");
3474 clearFeatureBits(Mips::FeatureDSP, "dsp");
3475 getTargetStreamer().emitDirectiveSetNoDsp();
3479 bool MipsAsmParser::parseSetMips16Directive() {
3480 MCAsmParser &Parser = getParser();
3481 Parser.Lex(); // Eat "mips16".
3483 // If this is not the end of the statement, report an error.
3484 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3485 reportParseError("unexpected token, expected end of statement");
3489 setFeatureBits(Mips::FeatureMips16, "mips16");
3490 getTargetStreamer().emitDirectiveSetMips16();
3491 Parser.Lex(); // Consume the EndOfStatement.
3495 bool MipsAsmParser::parseSetNoMips16Directive() {
3496 MCAsmParser &Parser = getParser();
3497 Parser.Lex(); // Eat "nomips16".
3499 // If this is not the end of the statement, report an error.
3500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3501 reportParseError("unexpected token, expected end of statement");
3505 clearFeatureBits(Mips::FeatureMips16, "mips16");
3506 getTargetStreamer().emitDirectiveSetNoMips16();
3507 Parser.Lex(); // Consume the EndOfStatement.
3511 bool MipsAsmParser::parseSetFpDirective() {
3512 MCAsmParser &Parser = getParser();
3513 MipsABIFlagsSection::FpABIKind FpAbiVal;
3514 // Line can be: .set fp=32
3517 Parser.Lex(); // Eat fp token
3518 AsmToken Tok = Parser.getTok();
3519 if (Tok.isNot(AsmToken::Equal)) {
3520 reportParseError("unexpected token, expected equals sign '='");
3523 Parser.Lex(); // Eat '=' token.
3524 Tok = Parser.getTok();
3526 if (!parseFpABIValue(FpAbiVal, ".set"))
3529 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3530 reportParseError("unexpected token, expected end of statement");
3533 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3534 Parser.Lex(); // Consume the EndOfStatement.
3538 bool MipsAsmParser::parseSetPopDirective() {
3539 MCAsmParser &Parser = getParser();
3540 SMLoc Loc = getLexer().getLoc();
3543 if (getLexer().isNot(AsmToken::EndOfStatement))
3544 return reportParseError("unexpected token, expected end of statement");
3546 // Always keep an element on the options "stack" to prevent the user
3547 // from changing the initial options. This is how we remember them.
3548 if (AssemblerOptions.size() == 2)
3549 return reportParseError(Loc, ".set pop with no .set push");
3551 AssemblerOptions.pop_back();
3552 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3554 getTargetStreamer().emitDirectiveSetPop();
3558 bool MipsAsmParser::parseSetPushDirective() {
3559 MCAsmParser &Parser = getParser();
3561 if (getLexer().isNot(AsmToken::EndOfStatement))
3562 return reportParseError("unexpected token, expected end of statement");
3564 // Create a copy of the current assembler options environment and push it.
3565 AssemblerOptions.push_back(
3566 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3568 getTargetStreamer().emitDirectiveSetPush();
3572 bool MipsAsmParser::parseSetAssignment() {
3574 const MCExpr *Value;
3575 MCAsmParser &Parser = getParser();
3577 if (Parser.parseIdentifier(Name))
3578 reportParseError("expected identifier after .set");
3580 if (getLexer().isNot(AsmToken::Comma))
3581 return reportParseError("unexpected token, expected comma");
3584 if (Parser.parseExpression(Value))
3585 return reportParseError("expected valid expression after comma");
3587 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3588 Sym->setVariableValue(Value);
3593 bool MipsAsmParser::parseSetMips0Directive() {
3594 MCAsmParser &Parser = getParser();
3596 if (getLexer().isNot(AsmToken::EndOfStatement))
3597 return reportParseError("unexpected token, expected end of statement");
3599 // Reset assembler options to their initial values.
3600 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3601 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3603 getTargetStreamer().emitDirectiveSetMips0();
3607 bool MipsAsmParser::parseSetArchDirective() {
3608 MCAsmParser &Parser = getParser();
3610 if (getLexer().isNot(AsmToken::Equal))
3611 return reportParseError("unexpected token, expected equals sign");
3615 if (Parser.parseIdentifier(Arch))
3616 return reportParseError("expected arch identifier");
3618 StringRef ArchFeatureName =
3619 StringSwitch<StringRef>(Arch)
3620 .Case("mips1", "mips1")
3621 .Case("mips2", "mips2")
3622 .Case("mips3", "mips3")
3623 .Case("mips4", "mips4")
3624 .Case("mips5", "mips5")
3625 .Case("mips32", "mips32")
3626 .Case("mips32r2", "mips32r2")
3627 .Case("mips32r3", "mips32r3")
3628 .Case("mips32r5", "mips32r5")
3629 .Case("mips32r6", "mips32r6")
3630 .Case("mips64", "mips64")
3631 .Case("mips64r2", "mips64r2")
3632 .Case("mips64r3", "mips64r3")
3633 .Case("mips64r5", "mips64r5")
3634 .Case("mips64r6", "mips64r6")
3635 .Case("cnmips", "cnmips")
3636 .Case("r4000", "mips3") // This is an implementation of Mips3.
3639 if (ArchFeatureName.empty())
3640 return reportParseError("unsupported architecture");
3642 selectArch(ArchFeatureName);
3643 getTargetStreamer().emitDirectiveSetArch(Arch);
3647 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3648 MCAsmParser &Parser = getParser();
3650 if (getLexer().isNot(AsmToken::EndOfStatement))
3651 return reportParseError("unexpected token, expected end of statement");
3655 llvm_unreachable("Unimplemented feature");
3656 case Mips::FeatureDSP:
3657 setFeatureBits(Mips::FeatureDSP, "dsp");
3658 getTargetStreamer().emitDirectiveSetDsp();
3660 case Mips::FeatureMicroMips:
3661 getTargetStreamer().emitDirectiveSetMicroMips();
3663 case Mips::FeatureMips1:
3664 selectArch("mips1");
3665 getTargetStreamer().emitDirectiveSetMips1();
3667 case Mips::FeatureMips2:
3668 selectArch("mips2");
3669 getTargetStreamer().emitDirectiveSetMips2();
3671 case Mips::FeatureMips3:
3672 selectArch("mips3");
3673 getTargetStreamer().emitDirectiveSetMips3();
3675 case Mips::FeatureMips4:
3676 selectArch("mips4");
3677 getTargetStreamer().emitDirectiveSetMips4();
3679 case Mips::FeatureMips5:
3680 selectArch("mips5");
3681 getTargetStreamer().emitDirectiveSetMips5();
3683 case Mips::FeatureMips32:
3684 selectArch("mips32");
3685 getTargetStreamer().emitDirectiveSetMips32();
3687 case Mips::FeatureMips32r2:
3688 selectArch("mips32r2");
3689 getTargetStreamer().emitDirectiveSetMips32R2();
3691 case Mips::FeatureMips32r3:
3692 selectArch("mips32r3");
3693 getTargetStreamer().emitDirectiveSetMips32R3();
3695 case Mips::FeatureMips32r5:
3696 selectArch("mips32r5");
3697 getTargetStreamer().emitDirectiveSetMips32R5();
3699 case Mips::FeatureMips32r6:
3700 selectArch("mips32r6");
3701 getTargetStreamer().emitDirectiveSetMips32R6();
3703 case Mips::FeatureMips64:
3704 selectArch("mips64");
3705 getTargetStreamer().emitDirectiveSetMips64();
3707 case Mips::FeatureMips64r2:
3708 selectArch("mips64r2");
3709 getTargetStreamer().emitDirectiveSetMips64R2();
3711 case Mips::FeatureMips64r3:
3712 selectArch("mips64r3");
3713 getTargetStreamer().emitDirectiveSetMips64R3();
3715 case Mips::FeatureMips64r5:
3716 selectArch("mips64r5");
3717 getTargetStreamer().emitDirectiveSetMips64R5();
3719 case Mips::FeatureMips64r6:
3720 selectArch("mips64r6");
3721 getTargetStreamer().emitDirectiveSetMips64R6();
3727 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3728 MCAsmParser &Parser = getParser();
3729 if (getLexer().isNot(AsmToken::Comma)) {
3730 SMLoc Loc = getLexer().getLoc();
3731 Parser.eatToEndOfStatement();
3732 return Error(Loc, ErrorStr);
3735 Parser.Lex(); // Eat the comma.
3739 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3740 if (AssemblerOptions.back()->isReorder())
3741 Warning(Loc, ".cpload should be inside a noreorder section");
3743 if (inMips16Mode()) {
3744 reportParseError(".cpload is not supported in Mips16 mode");
3748 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3749 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3750 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3751 reportParseError("expected register containing function address");
3755 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3756 if (!RegOpnd.isGPRAsmReg()) {
3757 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3761 // If this is not the end of the statement, report an error.
3762 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3763 reportParseError("unexpected token, expected end of statement");
3767 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3771 bool MipsAsmParser::parseDirectiveCPSetup() {
3772 MCAsmParser &Parser = getParser();
3775 bool SaveIsReg = true;
3777 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3778 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3779 if (ResTy == MatchOperand_NoMatch) {
3780 reportParseError("expected register containing function address");
3781 Parser.eatToEndOfStatement();
3785 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3786 if (!FuncRegOpnd.isGPRAsmReg()) {
3787 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3788 Parser.eatToEndOfStatement();
3792 FuncReg = FuncRegOpnd.getGPR32Reg();
3795 if (!eatComma("unexpected token, expected comma"))
3798 ResTy = parseAnyRegister(TmpReg);
3799 if (ResTy == MatchOperand_NoMatch) {
3800 const AsmToken &Tok = Parser.getTok();
3801 if (Tok.is(AsmToken::Integer)) {
3802 Save = Tok.getIntVal();
3806 reportParseError("expected save register or stack offset");
3807 Parser.eatToEndOfStatement();
3811 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3812 if (!SaveOpnd.isGPRAsmReg()) {
3813 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3814 Parser.eatToEndOfStatement();
3817 Save = SaveOpnd.getGPR32Reg();
3820 if (!eatComma("unexpected token, expected comma"))
3824 if (Parser.parseExpression(Expr)) {
3825 reportParseError("expected expression");
3829 if (Expr->getKind() != MCExpr::SymbolRef) {
3830 reportParseError("expected symbol");
3833 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3835 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3840 bool MipsAsmParser::parseDirectiveNaN() {
3841 MCAsmParser &Parser = getParser();
3842 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3843 const AsmToken &Tok = Parser.getTok();
3845 if (Tok.getString() == "2008") {
3847 getTargetStreamer().emitDirectiveNaN2008();
3849 } else if (Tok.getString() == "legacy") {
3851 getTargetStreamer().emitDirectiveNaNLegacy();
3855 // If we don't recognize the option passed to the .nan
3856 // directive (e.g. no option or unknown option), emit an error.
3857 reportParseError("invalid option in .nan directive");
3861 bool MipsAsmParser::parseDirectiveSet() {
3862 MCAsmParser &Parser = getParser();
3863 // Get the next token.
3864 const AsmToken &Tok = Parser.getTok();
3866 if (Tok.getString() == "noat") {
3867 return parseSetNoAtDirective();
3868 } else if (Tok.getString() == "at") {
3869 return parseSetAtDirective();
3870 } else if (Tok.getString() == "arch") {
3871 return parseSetArchDirective();
3872 } else if (Tok.getString() == "fp") {
3873 return parseSetFpDirective();
3874 } else if (Tok.getString() == "pop") {
3875 return parseSetPopDirective();
3876 } else if (Tok.getString() == "push") {
3877 return parseSetPushDirective();
3878 } else if (Tok.getString() == "reorder") {
3879 return parseSetReorderDirective();
3880 } else if (Tok.getString() == "noreorder") {
3881 return parseSetNoReorderDirective();
3882 } else if (Tok.getString() == "macro") {
3883 return parseSetMacroDirective();
3884 } else if (Tok.getString() == "nomacro") {
3885 return parseSetNoMacroDirective();
3886 } else if (Tok.getString() == "mips16") {
3887 return parseSetMips16Directive();
3888 } else if (Tok.getString() == "nomips16") {
3889 return parseSetNoMips16Directive();
3890 } else if (Tok.getString() == "nomicromips") {
3891 getTargetStreamer().emitDirectiveSetNoMicroMips();
3892 Parser.eatToEndOfStatement();
3894 } else if (Tok.getString() == "micromips") {
3895 return parseSetFeature(Mips::FeatureMicroMips);
3896 } else if (Tok.getString() == "mips0") {
3897 return parseSetMips0Directive();
3898 } else if (Tok.getString() == "mips1") {
3899 return parseSetFeature(Mips::FeatureMips1);
3900 } else if (Tok.getString() == "mips2") {
3901 return parseSetFeature(Mips::FeatureMips2);
3902 } else if (Tok.getString() == "mips3") {
3903 return parseSetFeature(Mips::FeatureMips3);
3904 } else if (Tok.getString() == "mips4") {
3905 return parseSetFeature(Mips::FeatureMips4);
3906 } else if (Tok.getString() == "mips5") {
3907 return parseSetFeature(Mips::FeatureMips5);
3908 } else if (Tok.getString() == "mips32") {
3909 return parseSetFeature(Mips::FeatureMips32);
3910 } else if (Tok.getString() == "mips32r2") {
3911 return parseSetFeature(Mips::FeatureMips32r2);
3912 } else if (Tok.getString() == "mips32r3") {
3913 return parseSetFeature(Mips::FeatureMips32r3);
3914 } else if (Tok.getString() == "mips32r5") {
3915 return parseSetFeature(Mips::FeatureMips32r5);
3916 } else if (Tok.getString() == "mips32r6") {
3917 return parseSetFeature(Mips::FeatureMips32r6);
3918 } else if (Tok.getString() == "mips64") {
3919 return parseSetFeature(Mips::FeatureMips64);
3920 } else if (Tok.getString() == "mips64r2") {
3921 return parseSetFeature(Mips::FeatureMips64r2);
3922 } else if (Tok.getString() == "mips64r3") {
3923 return parseSetFeature(Mips::FeatureMips64r3);
3924 } else if (Tok.getString() == "mips64r5") {
3925 return parseSetFeature(Mips::FeatureMips64r5);
3926 } else if (Tok.getString() == "mips64r6") {
3927 return parseSetFeature(Mips::FeatureMips64r6);
3928 } else if (Tok.getString() == "dsp") {
3929 return parseSetFeature(Mips::FeatureDSP);
3930 } else if (Tok.getString() == "nodsp") {
3931 return parseSetNoDspDirective();
3932 } else if (Tok.getString() == "msa") {
3933 return parseSetMsaDirective();
3934 } else if (Tok.getString() == "nomsa") {
3935 return parseSetNoMsaDirective();
3937 // It is just an identifier, look for an assignment.
3938 parseSetAssignment();
3945 /// parseDataDirective
3946 /// ::= .word [ expression (, expression)* ]
3947 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3948 MCAsmParser &Parser = getParser();
3949 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3951 const MCExpr *Value;
3952 if (getParser().parseExpression(Value))
3955 getParser().getStreamer().EmitValue(Value, Size);
3957 if (getLexer().is(AsmToken::EndOfStatement))
3960 if (getLexer().isNot(AsmToken::Comma))
3961 return Error(L, "unexpected token, expected comma");
3970 /// parseDirectiveGpWord
3971 /// ::= .gpword local_sym
3972 bool MipsAsmParser::parseDirectiveGpWord() {
3973 MCAsmParser &Parser = getParser();
3974 const MCExpr *Value;
3975 // EmitGPRel32Value requires an expression, so we are using base class
3976 // method to evaluate the expression.
3977 if (getParser().parseExpression(Value))
3979 getParser().getStreamer().EmitGPRel32Value(Value);
3981 if (getLexer().isNot(AsmToken::EndOfStatement))
3982 return Error(getLexer().getLoc(),
3983 "unexpected token, expected end of statement");
3984 Parser.Lex(); // Eat EndOfStatement token.
3988 /// parseDirectiveGpDWord
3989 /// ::= .gpdword local_sym
3990 bool MipsAsmParser::parseDirectiveGpDWord() {
3991 MCAsmParser &Parser = getParser();
3992 const MCExpr *Value;
3993 // EmitGPRel64Value requires an expression, so we are using base class
3994 // method to evaluate the expression.
3995 if (getParser().parseExpression(Value))
3997 getParser().getStreamer().EmitGPRel64Value(Value);
3999 if (getLexer().isNot(AsmToken::EndOfStatement))
4000 return Error(getLexer().getLoc(),
4001 "unexpected token, expected end of statement");
4002 Parser.Lex(); // Eat EndOfStatement token.
4006 bool MipsAsmParser::parseDirectiveOption() {
4007 MCAsmParser &Parser = getParser();
4008 // Get the option token.
4009 AsmToken Tok = Parser.getTok();
4010 // At the moment only identifiers are supported.
4011 if (Tok.isNot(AsmToken::Identifier)) {
4012 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4013 Parser.eatToEndOfStatement();
4017 StringRef Option = Tok.getIdentifier();
4019 if (Option == "pic0") {
4020 getTargetStreamer().emitDirectiveOptionPic0();
4022 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4023 Error(Parser.getTok().getLoc(),
4024 "unexpected token, expected end of statement");
4025 Parser.eatToEndOfStatement();
4030 if (Option == "pic2") {
4031 getTargetStreamer().emitDirectiveOptionPic2();
4033 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4034 Error(Parser.getTok().getLoc(),
4035 "unexpected token, expected end of statement");
4036 Parser.eatToEndOfStatement();
4042 Warning(Parser.getTok().getLoc(),
4043 "unknown option, expected 'pic0' or 'pic2'");
4044 Parser.eatToEndOfStatement();
4048 /// parseDirectiveModule
4049 /// ::= .module oddspreg
4050 /// ::= .module nooddspreg
4051 /// ::= .module fp=value
4052 bool MipsAsmParser::parseDirectiveModule() {
4053 MCAsmParser &Parser = getParser();
4054 MCAsmLexer &Lexer = getLexer();
4055 SMLoc L = Lexer.getLoc();
4057 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4058 // TODO : get a better message.
4059 reportParseError(".module directive must appear before any code");
4064 if (Parser.parseIdentifier(Option)) {
4065 reportParseError("expected .module option identifier");
4069 if (Option == "oddspreg") {
4070 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4071 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4073 // If this is not the end of the statement, report an error.
4074 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4075 reportParseError("unexpected token, expected end of statement");
4079 return false; // parseDirectiveModule has finished successfully.
4080 } else if (Option == "nooddspreg") {
4082 Error(L, "'.module nooddspreg' requires the O32 ABI");
4086 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4087 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4089 // If this is not the end of the statement, report an error.
4090 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4091 reportParseError("unexpected token, expected end of statement");
4095 return false; // parseDirectiveModule has finished successfully.
4096 } else if (Option == "fp") {
4097 return parseDirectiveModuleFP();
4099 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4103 /// parseDirectiveModuleFP
4107 bool MipsAsmParser::parseDirectiveModuleFP() {
4108 MCAsmParser &Parser = getParser();
4109 MCAsmLexer &Lexer = getLexer();
4111 if (Lexer.isNot(AsmToken::Equal)) {
4112 reportParseError("unexpected token, expected equals sign '='");
4115 Parser.Lex(); // Eat '=' token.
4117 MipsABIFlagsSection::FpABIKind FpABI;
4118 if (!parseFpABIValue(FpABI, ".module"))
4121 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4122 reportParseError("unexpected token, expected end of statement");
4126 // Emit appropriate flags.
4127 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4128 Parser.Lex(); // Consume the EndOfStatement.
4132 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4133 StringRef Directive) {
4134 MCAsmParser &Parser = getParser();
4135 MCAsmLexer &Lexer = getLexer();
4137 if (Lexer.is(AsmToken::Identifier)) {
4138 StringRef Value = Parser.getTok().getString();
4141 if (Value != "xx") {
4142 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4147 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4151 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4155 if (Lexer.is(AsmToken::Integer)) {
4156 unsigned Value = Parser.getTok().getIntVal();
4159 if (Value != 32 && Value != 64) {
4160 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4166 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4170 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4172 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4180 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4181 MCAsmParser &Parser = getParser();
4182 StringRef IDVal = DirectiveID.getString();
4184 if (IDVal == ".cpload")
4185 return parseDirectiveCpLoad(DirectiveID.getLoc());
4186 if (IDVal == ".dword") {
4187 parseDataDirective(8, DirectiveID.getLoc());
4190 if (IDVal == ".ent") {
4191 StringRef SymbolName;
4193 if (Parser.parseIdentifier(SymbolName)) {
4194 reportParseError("expected identifier after .ent");
4198 // There's an undocumented extension that allows an integer to
4199 // follow the name of the procedure which AFAICS is ignored by GAS.
4200 // Example: .ent foo,2
4201 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4202 if (getLexer().isNot(AsmToken::Comma)) {
4203 // Even though we accept this undocumented extension for compatibility
4204 // reasons, the additional integer argument does not actually change
4205 // the behaviour of the '.ent' directive, so we would like to discourage
4206 // its use. We do this by not referring to the extended version in
4207 // error messages which are not directly related to its use.
4208 reportParseError("unexpected token, expected end of statement");
4211 Parser.Lex(); // Eat the comma.
4212 const MCExpr *DummyNumber;
4213 int64_t DummyNumberVal;
4214 // If the user was explicitly trying to use the extended version,
4215 // we still give helpful extension-related error messages.
4216 if (Parser.parseExpression(DummyNumber)) {
4217 reportParseError("expected number after comma");
4220 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4221 reportParseError("expected an absolute expression after comma");
4226 // If this is not the end of the statement, report an error.
4227 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4228 reportParseError("unexpected token, expected end of statement");
4232 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4234 getTargetStreamer().emitDirectiveEnt(*Sym);
4239 if (IDVal == ".end") {
4240 StringRef SymbolName;
4242 if (Parser.parseIdentifier(SymbolName)) {
4243 reportParseError("expected identifier after .end");
4247 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4248 reportParseError("unexpected token, expected end of statement");
4252 if (CurrentFn == nullptr) {
4253 reportParseError(".end used without .ent");
4257 if ((SymbolName != CurrentFn->getName())) {
4258 reportParseError(".end symbol does not match .ent symbol");
4262 getTargetStreamer().emitDirectiveEnd(SymbolName);
4263 CurrentFn = nullptr;
4267 if (IDVal == ".frame") {
4268 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4269 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4270 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4271 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4272 reportParseError("expected stack register");
4276 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4277 if (!StackRegOpnd.isGPRAsmReg()) {
4278 reportParseError(StackRegOpnd.getStartLoc(),
4279 "expected general purpose register");
4282 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4284 if (Parser.getTok().is(AsmToken::Comma))
4287 reportParseError("unexpected token, expected comma");
4291 // Parse the frame size.
4292 const MCExpr *FrameSize;
4293 int64_t FrameSizeVal;
4295 if (Parser.parseExpression(FrameSize)) {
4296 reportParseError("expected frame size value");
4300 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4301 reportParseError("frame size not an absolute expression");
4305 if (Parser.getTok().is(AsmToken::Comma))
4308 reportParseError("unexpected token, expected comma");
4312 // Parse the return register.
4314 ResTy = parseAnyRegister(TmpReg);
4315 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4316 reportParseError("expected return register");
4320 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4321 if (!ReturnRegOpnd.isGPRAsmReg()) {
4322 reportParseError(ReturnRegOpnd.getStartLoc(),
4323 "expected general purpose register");
4327 // If this is not the end of the statement, report an error.
4328 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4329 reportParseError("unexpected token, expected end of statement");
4333 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4334 ReturnRegOpnd.getGPR32Reg());
4338 if (IDVal == ".set") {
4339 return parseDirectiveSet();
4342 if (IDVal == ".mask" || IDVal == ".fmask") {
4343 // .mask bitmask, frame_offset
4344 // bitmask: One bit for each register used.
4345 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4346 // first register is expected to be saved.
4348 // .mask 0x80000000, -4
4349 // .fmask 0x80000000, -4
4352 // Parse the bitmask
4353 const MCExpr *BitMask;
4356 if (Parser.parseExpression(BitMask)) {
4357 reportParseError("expected bitmask value");
4361 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4362 reportParseError("bitmask not an absolute expression");
4366 if (Parser.getTok().is(AsmToken::Comma))
4369 reportParseError("unexpected token, expected comma");
4373 // Parse the frame_offset
4374 const MCExpr *FrameOffset;
4375 int64_t FrameOffsetVal;
4377 if (Parser.parseExpression(FrameOffset)) {
4378 reportParseError("expected frame offset value");
4382 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4383 reportParseError("frame offset not an absolute expression");
4387 // If this is not the end of the statement, report an error.
4388 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4389 reportParseError("unexpected token, expected end of statement");
4393 if (IDVal == ".mask")
4394 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4396 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4400 if (IDVal == ".nan")
4401 return parseDirectiveNaN();
4403 if (IDVal == ".gpword") {
4404 parseDirectiveGpWord();
4408 if (IDVal == ".gpdword") {
4409 parseDirectiveGpDWord();
4413 if (IDVal == ".word") {
4414 parseDataDirective(4, DirectiveID.getLoc());
4418 if (IDVal == ".option")
4419 return parseDirectiveOption();
4421 if (IDVal == ".abicalls") {
4422 getTargetStreamer().emitDirectiveAbiCalls();
4423 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4424 Error(Parser.getTok().getLoc(),
4425 "unexpected token, expected end of statement");
4427 Parser.eatToEndOfStatement();
4432 if (IDVal == ".cpsetup")
4433 return parseDirectiveCPSetup();
4435 if (IDVal == ".module")
4436 return parseDirectiveModule();
4438 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4439 return parseInternalDirectiveReallowModule();
4444 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4445 // If this is not the end of the statement, report an error.
4446 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4447 reportParseError("unexpected token, expected end of statement");
4451 getTargetStreamer().reallowModuleDirective();
4453 getParser().Lex(); // Eat EndOfStatement token.
4457 extern "C" void LLVMInitializeMipsAsmParser() {
4458 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4459 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4460 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4461 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4464 #define GET_REGISTER_MATCHER
4465 #define GET_MATCHER_IMPLEMENTATION
4466 #include "MipsGenAsmMatcher.inc"