1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsABIInfo.h"
11 #include "MCTargetDesc/MipsMCExpr.h"
12 #include "MCTargetDesc/MipsMCTargetDesc.h"
13 #include "MipsRegisterInfo.h"
14 #include "MipsTargetStreamer.h"
15 #include "llvm/ADT/APInt.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/ADT/StringSwitch.h"
18 #include "llvm/MC/MCContext.h"
19 #include "llvm/MC/MCExpr.h"
20 #include "llvm/MC/MCInst.h"
21 #include "llvm/MC/MCInstBuilder.h"
22 #include "llvm/MC/MCParser/MCAsmLexer.h"
23 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24 #include "llvm/MC/MCStreamer.h"
25 #include "llvm/MC/MCSubtargetInfo.h"
26 #include "llvm/MC/MCSymbol.h"
27 #include "llvm/MC/MCTargetAsmParser.h"
28 #include "llvm/Support/Debug.h"
29 #include "llvm/Support/MathExtras.h"
30 #include "llvm/Support/SourceMgr.h"
31 #include "llvm/Support/TargetRegistry.h"
32 #include "llvm/Support/raw_ostream.h"
37 #define DEBUG_TYPE "mips-asm-parser"
44 class MipsAssemblerOptions {
46 MipsAssemblerOptions(uint64_t Features_) :
47 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
49 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
50 ATReg = Opts->getATRegNum();
51 Reorder = Opts->isReorder();
52 Macro = Opts->isMacro();
53 Features = Opts->getFeatures();
56 unsigned getATRegNum() const { return ATReg; }
57 bool setATReg(unsigned Reg) {
65 bool isReorder() const { return Reorder; }
66 void setReorder() { Reorder = true; }
67 void setNoReorder() { Reorder = false; }
69 bool isMacro() const { return Macro; }
70 void setMacro() { Macro = true; }
71 void setNoMacro() { Macro = false; }
73 uint64_t getFeatures() const { return Features; }
74 void setFeatures(uint64_t Features_) { Features = Features_; }
76 // Set of features that are either architecture features or referenced
77 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
78 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
79 // The reason we need this mask is explained in the selectArch function.
80 // FIXME: Ideally we would like TableGen to generate this information.
81 static const uint64_t AllArchRelatedMask =
82 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
83 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
84 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
85 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
86 Mips::FeatureMips32r3 | Mips::FeatureMips32r5 | Mips::FeatureMips32r6 |
87 Mips::FeatureMips64 | Mips::FeatureMips64r2 | Mips::FeatureMips64r3 |
88 Mips::FeatureMips64r5 | Mips::FeatureMips64r6 | Mips::FeatureCnMips |
89 Mips::FeatureFP64Bit | Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
100 class MipsAsmParser : public MCTargetAsmParser {
101 MipsTargetStreamer &getTargetStreamer() {
102 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
103 return static_cast<MipsTargetStreamer &>(TS);
106 MCSubtargetInfo &STI;
108 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
109 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
110 // nullptr, which indicates that no function is currently
111 // selected. This usually happens after an '.end func'
114 // Print a warning along with its fix-it message at the given range.
115 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
116 SMRange Range, bool ShowColors = true);
118 #define GET_ASSEMBLER_HEADER
119 #include "MipsGenAsmMatcher.inc"
121 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
123 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
124 OperandVector &Operands, MCStreamer &Out,
126 bool MatchingInlineAsm) override;
128 /// Parse a register as used in CFI directives
129 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
131 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
133 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
135 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
136 SMLoc NameLoc, OperandVector &Operands) override;
138 bool ParseDirective(AsmToken DirectiveID) override;
140 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy
143 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
144 StringRef Identifier, SMLoc S);
146 MipsAsmParser::OperandMatchResultTy
147 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
149 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
153 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
155 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
157 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
159 MipsAsmParser::OperandMatchResultTy
160 parseRegisterPair (OperandVector &Operands);
162 MipsAsmParser::OperandMatchResultTy
163 parseMovePRegPair(OperandVector &Operands);
165 MipsAsmParser::OperandMatchResultTy
166 parseRegisterList (OperandVector &Operands);
168 bool searchSymbolAlias(OperandVector &Operands);
170 bool parseOperand(OperandVector &, StringRef Mnemonic);
172 bool needsExpansion(MCInst &Inst);
174 // Expands assembly pseudo instructions.
175 // Returns false on success, true otherwise.
176 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions);
185 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
186 SmallVectorImpl<MCInst> &Instructions);
188 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
189 SmallVectorImpl<MCInst> &Instructions);
190 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
191 SmallVectorImpl<MCInst> &Instructions);
193 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
194 SmallVectorImpl<MCInst> &Instructions);
196 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
197 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
200 bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
201 SmallVectorImpl<MCInst> &Instructions);
203 void createNop(bool hasShortDelaySlot, SMLoc IDLoc,
204 SmallVectorImpl<MCInst> &Instructions);
206 bool reportParseError(Twine ErrorMsg);
207 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
209 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
210 bool parseRelocOperand(const MCExpr *&Res);
212 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
214 bool isEvaluated(const MCExpr *Expr);
215 bool parseSetMips0Directive();
216 bool parseSetArchDirective();
217 bool parseSetFeature(uint64_t Feature);
218 bool parseDirectiveCpLoad(SMLoc Loc);
219 bool parseDirectiveCPSetup();
220 bool parseDirectiveNaN();
221 bool parseDirectiveSet();
222 bool parseDirectiveOption();
223 bool parseInsnDirective();
225 bool parseSetAtDirective();
226 bool parseSetNoAtDirective();
227 bool parseSetMacroDirective();
228 bool parseSetNoMacroDirective();
229 bool parseSetMsaDirective();
230 bool parseSetNoMsaDirective();
231 bool parseSetNoDspDirective();
232 bool parseSetReorderDirective();
233 bool parseSetNoReorderDirective();
234 bool parseSetMips16Directive();
235 bool parseSetNoMips16Directive();
236 bool parseSetFpDirective();
237 bool parseSetPopDirective();
238 bool parseSetPushDirective();
240 bool parseSetAssignment();
242 bool parseDataDirective(unsigned Size, SMLoc L);
243 bool parseDirectiveGpWord();
244 bool parseDirectiveGpDWord();
245 bool parseDirectiveModule();
246 bool parseDirectiveModuleFP();
247 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
248 StringRef Directive);
250 bool parseInternalDirectiveReallowModule();
252 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
254 bool eatComma(StringRef ErrorStr);
256 int matchCPURegisterName(StringRef Symbol);
258 int matchHWRegsRegisterName(StringRef Symbol);
260 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
262 int matchFPURegisterName(StringRef Name);
264 int matchFCCRegisterName(StringRef Name);
266 int matchACRegisterName(StringRef Name);
268 int matchMSA128RegisterName(StringRef Name);
270 int matchMSA128CtrlRegisterName(StringRef Name);
272 unsigned getReg(int RC, int RegNo);
274 unsigned getGPR(int RegNo);
276 /// Returns the internal register number for the current AT. Also checks if
277 /// the current AT is unavailable (set to $0) and gives an error if it is.
278 /// This should be used in pseudo-instruction expansions which need AT.
279 unsigned getATReg(SMLoc Loc);
281 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
282 SmallVectorImpl<MCInst> &Instructions);
284 // Helper function that checks if the value of a vector index is within the
285 // boundaries of accepted values for each RegisterKind
286 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
287 bool validateMSAIndex(int Val, int RegKind);
289 // Selects a new architecture by updating the FeatureBits with the necessary
290 // info including implied dependencies.
291 // Internally, it clears all the feature bits related to *any* architecture
292 // and selects the new one using the ToggleFeature functionality of the
293 // MCSubtargetInfo object that handles implied dependencies. The reason we
294 // clear all the arch related bits manually is because ToggleFeature only
295 // clears the features that imply the feature being cleared and not the
296 // features implied by the feature being cleared. This is easier to see
298 // --------------------------------------------------
299 // | Feature | Implies |
300 // | -------------------------------------------------|
301 // | FeatureMips1 | None |
302 // | FeatureMips2 | FeatureMips1 |
303 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
304 // | FeatureMips4 | FeatureMips3 |
306 // --------------------------------------------------
308 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
309 // FeatureMipsGP64 | FeatureMips1)
310 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
311 void selectArch(StringRef ArchFeature) {
312 uint64_t FeatureBits = STI.getFeatureBits();
313 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
314 STI.setFeatureBits(FeatureBits);
315 setAvailableFeatures(
316 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
317 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
320 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
321 if (!(STI.getFeatureBits() & Feature)) {
322 setAvailableFeatures(
323 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
325 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
328 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
329 if (STI.getFeatureBits() & Feature) {
330 setAvailableFeatures(
331 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
333 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
337 enum MipsMatchResultTy {
338 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
339 #define GET_OPERAND_DIAGNOSTIC_TYPES
340 #include "MipsGenAsmMatcher.inc"
341 #undef GET_OPERAND_DIAGNOSTIC_TYPES
345 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
346 const MCInstrInfo &MII, const MCTargetOptions &Options)
347 : MCTargetAsmParser(), STI(sti),
348 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
349 sti.getCPU(), Options)) {
350 MCAsmParserExtension::Initialize(parser);
352 // Initialize the set of available features.
353 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
355 // Remember the initial assembler options. The user can not modify these.
356 AssemblerOptions.push_back(
357 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
359 // Create an assembler options environment for the user to modify.
360 AssemblerOptions.push_back(
361 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
363 getTargetStreamer().updateABIInfo(*this);
365 if (!isABI_O32() && !useOddSPReg() != 0)
366 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
371 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
372 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
374 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
375 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
376 const MipsABIInfo &getABI() const { return ABI; }
377 bool isABI_N32() const { return ABI.IsN32(); }
378 bool isABI_N64() const { return ABI.IsN64(); }
379 bool isABI_O32() const { return ABI.IsO32(); }
380 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
382 bool useOddSPReg() const {
383 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
386 bool inMicroMipsMode() const {
387 return STI.getFeatureBits() & Mips::FeatureMicroMips;
389 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
390 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
391 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
392 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
393 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
394 bool hasMips32() const {
395 return (STI.getFeatureBits() & Mips::FeatureMips32);
397 bool hasMips64() const {
398 return (STI.getFeatureBits() & Mips::FeatureMips64);
400 bool hasMips32r2() const {
401 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
403 bool hasMips64r2() const {
404 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
406 bool hasMips32r3() const {
407 return (STI.getFeatureBits() & Mips::FeatureMips32r3);
409 bool hasMips64r3() const {
410 return (STI.getFeatureBits() & Mips::FeatureMips64r3);
412 bool hasMips32r5() const {
413 return (STI.getFeatureBits() & Mips::FeatureMips32r5);
415 bool hasMips64r5() const {
416 return (STI.getFeatureBits() & Mips::FeatureMips64r5);
418 bool hasMips32r6() const {
419 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
421 bool hasMips64r6() const {
422 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
424 bool hasCnMips() const {
425 return (STI.getFeatureBits() & Mips::FeatureCnMips);
427 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
428 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
429 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
431 bool inMips16Mode() const {
432 return STI.getFeatureBits() & Mips::FeatureMips16;
434 // TODO: see how can we get this info.
435 bool abiUsesSoftFloat() const { return false; }
437 /// Warn if RegNo is the current assembler temporary.
438 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
444 /// MipsOperand - Instances of this class represent a parsed Mips machine
446 class MipsOperand : public MCParsedAsmOperand {
448 /// Broad categories of register classes
449 /// The exact class is finalized by the render method.
451 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
452 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
454 RegKind_FCC = 4, /// FCC
455 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
456 RegKind_MSACtrl = 16, /// MSA control registers
457 RegKind_COP2 = 32, /// COP2
458 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
460 RegKind_CCR = 128, /// CCR
461 RegKind_HWRegs = 256, /// HWRegs
462 RegKind_COP3 = 512, /// COP3
464 /// Potentially any (e.g. $1)
465 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
466 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
467 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
472 k_Immediate, /// An immediate (possibly involving symbol references)
473 k_Memory, /// Base + Offset Memory Address
474 k_PhysRegister, /// A physical register from the Mips namespace
475 k_RegisterIndex, /// A register index in one or more RegKind.
476 k_Token, /// A simple token
477 k_RegList, /// A physical register list
478 k_RegPair /// A pair of physical register
482 MipsOperand(KindTy K, MipsAsmParser &Parser)
483 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
486 /// For diagnostics, and checking the assembler temporary
487 MipsAsmParser &AsmParser;
495 unsigned Num; /// Register Number
499 unsigned Index; /// Index into the register class
500 RegKind Kind; /// Bitfield of the kinds it could possibly be
501 const MCRegisterInfo *RegInfo;
514 SmallVector<unsigned, 10> *List;
519 struct PhysRegOp PhysReg;
520 struct RegIdxOp RegIdx;
523 struct RegListOp RegList;
526 SMLoc StartLoc, EndLoc;
528 /// Internal constructor for register kinds
529 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
530 const MCRegisterInfo *RegInfo,
532 MipsAsmParser &Parser) {
533 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
534 Op->RegIdx.Index = Index;
535 Op->RegIdx.RegInfo = RegInfo;
536 Op->RegIdx.Kind = RegKind;
543 /// Coerce the register to GPR32 and return the real register for the current
545 unsigned getGPR32Reg() const {
546 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
547 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
548 unsigned ClassID = Mips::GPR32RegClassID;
549 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
552 /// Coerce the register to GPR32 and return the real register for the current
554 unsigned getGPRMM16Reg() const {
555 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
556 unsigned ClassID = Mips::GPR32RegClassID;
557 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
560 /// Coerce the register to GPR64 and return the real register for the current
562 unsigned getGPR64Reg() const {
563 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
564 unsigned ClassID = Mips::GPR64RegClassID;
565 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
569 /// Coerce the register to AFGR64 and return the real register for the current
571 unsigned getAFGR64Reg() const {
572 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
573 if (RegIdx.Index % 2 != 0)
574 AsmParser.Warning(StartLoc, "Float register should be even.");
575 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
576 .getRegister(RegIdx.Index / 2);
579 /// Coerce the register to FGR64 and return the real register for the current
581 unsigned getFGR64Reg() const {
582 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
583 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
584 .getRegister(RegIdx.Index);
587 /// Coerce the register to FGR32 and return the real register for the current
589 unsigned getFGR32Reg() const {
590 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
591 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
592 .getRegister(RegIdx.Index);
595 /// Coerce the register to FGRH32 and return the real register for the current
597 unsigned getFGRH32Reg() const {
598 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
599 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
600 .getRegister(RegIdx.Index);
603 /// Coerce the register to FCC and return the real register for the current
605 unsigned getFCCReg() const {
606 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
607 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
608 .getRegister(RegIdx.Index);
611 /// Coerce the register to MSA128 and return the real register for the current
613 unsigned getMSA128Reg() const {
614 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
615 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
617 unsigned ClassID = Mips::MSA128BRegClassID;
618 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
621 /// Coerce the register to MSACtrl and return the real register for the
623 unsigned getMSACtrlReg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
625 unsigned ClassID = Mips::MSACtrlRegClassID;
626 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
629 /// Coerce the register to COP2 and return the real register for the
631 unsigned getCOP2Reg() const {
632 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
633 unsigned ClassID = Mips::COP2RegClassID;
634 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
637 /// Coerce the register to COP3 and return the real register for the
639 unsigned getCOP3Reg() const {
640 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
641 unsigned ClassID = Mips::COP3RegClassID;
642 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
645 /// Coerce the register to ACC64DSP and return the real register for the
647 unsigned getACC64DSPReg() const {
648 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
649 unsigned ClassID = Mips::ACC64DSPRegClassID;
650 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
653 /// Coerce the register to HI32DSP and return the real register for the
655 unsigned getHI32DSPReg() const {
656 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
657 unsigned ClassID = Mips::HI32DSPRegClassID;
658 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
661 /// Coerce the register to LO32DSP and return the real register for the
663 unsigned getLO32DSPReg() const {
664 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
665 unsigned ClassID = Mips::LO32DSPRegClassID;
666 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
669 /// Coerce the register to CCR and return the real register for the
671 unsigned getCCRReg() const {
672 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
673 unsigned ClassID = Mips::CCRRegClassID;
674 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
677 /// Coerce the register to HWRegs and return the real register for the
679 unsigned getHWRegsReg() const {
680 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
681 unsigned ClassID = Mips::HWRegsRegClassID;
682 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
686 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
687 // Add as immediate when possible. Null MCExpr = 0.
689 Inst.addOperand(MCOperand::CreateImm(0));
690 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
691 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
693 Inst.addOperand(MCOperand::CreateExpr(Expr));
696 void addRegOperands(MCInst &Inst, unsigned N) const {
697 llvm_unreachable("Use a custom parser instead");
700 /// Render the operand to an MCInst as a GPR32
701 /// Asserts if the wrong number of operands are requested, or the operand
702 /// is not a k_RegisterIndex compatible with RegKind_GPR
703 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
708 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
709 assert(N == 1 && "Invalid number of operands!");
710 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
713 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
714 assert(N == 1 && "Invalid number of operands!");
715 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
718 void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
719 assert(N == 1 && "Invalid number of operands!");
720 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
723 /// Render the operand to an MCInst as a GPR64
724 /// Asserts if the wrong number of operands are requested, or the operand
725 /// is not a k_RegisterIndex compatible with RegKind_GPR
726 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
731 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
736 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
737 assert(N == 1 && "Invalid number of operands!");
738 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
741 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
742 assert(N == 1 && "Invalid number of operands!");
743 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
744 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
745 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
746 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
750 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
751 assert(N == 1 && "Invalid number of operands!");
752 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
755 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
756 assert(N == 1 && "Invalid number of operands!");
757 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
760 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
761 assert(N == 1 && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
765 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 1 && "Invalid number of operands!");
767 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
770 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
771 assert(N == 1 && "Invalid number of operands!");
772 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
775 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
776 assert(N == 1 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
780 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
781 assert(N == 1 && "Invalid number of operands!");
782 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
785 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
787 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
790 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 1 && "Invalid number of operands!");
792 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
795 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
796 assert(N == 1 && "Invalid number of operands!");
797 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
800 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
801 assert(N == 1 && "Invalid number of operands!");
802 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
805 void addImmOperands(MCInst &Inst, unsigned N) const {
806 assert(N == 1 && "Invalid number of operands!");
807 const MCExpr *Expr = getImm();
811 void addMemOperands(MCInst &Inst, unsigned N) const {
812 assert(N == 2 && "Invalid number of operands!");
814 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
816 const MCExpr *Expr = getMemOff();
820 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
821 assert(N == 2 && "Invalid number of operands!");
823 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
825 const MCExpr *Expr = getMemOff();
829 void addRegListOperands(MCInst &Inst, unsigned N) const {
830 assert(N == 1 && "Invalid number of operands!");
832 for (auto RegNo : getRegList())
833 Inst.addOperand(MCOperand::CreateReg(RegNo));
836 void addRegPairOperands(MCInst &Inst, unsigned N) const {
837 assert(N == 2 && "Invalid number of operands!");
838 unsigned RegNo = getRegPair();
839 Inst.addOperand(MCOperand::CreateReg(RegNo++));
840 Inst.addOperand(MCOperand::CreateReg(RegNo));
843 void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
844 assert(N == 2 && "Invalid number of operands!");
845 for (auto RegNo : getRegList())
846 Inst.addOperand(MCOperand::CreateReg(RegNo));
849 bool isReg() const override {
850 // As a special case until we sort out the definition of div/divu, pretend
851 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
852 if (isGPRAsmReg() && RegIdx.Index == 0)
855 return Kind == k_PhysRegister;
857 bool isRegIdx() const { return Kind == k_RegisterIndex; }
858 bool isImm() const override { return Kind == k_Immediate; }
859 bool isConstantImm() const {
860 return isImm() && dyn_cast<MCConstantExpr>(getImm());
862 bool isToken() const override {
863 // Note: It's not possible to pretend that other operand kinds are tokens.
864 // The matcher emitter checks tokens first.
865 return Kind == k_Token;
867 bool isMem() const override { return Kind == k_Memory; }
868 bool isConstantMemOff() const {
869 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
871 template <unsigned Bits> bool isMemWithSimmOffset() const {
872 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
874 bool isMemWithGRPMM16Base() const {
875 return isMem() && getMemBase()->isMM16AsmReg();
877 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
878 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
879 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
881 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
882 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
883 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
884 && (getMemBase()->getGPR32Reg() == Mips::SP);
886 bool isRegList16() const {
890 int Size = RegList.List->size();
891 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
892 RegList.List->back() != Mips::RA)
895 int PrevReg = *RegList.List->begin();
896 for (int i = 1; i < Size - 1; i++) {
897 int Reg = (*(RegList.List))[i];
898 if ( Reg != PrevReg + 1)
905 bool isInvNum() const { return Kind == k_Immediate; }
906 bool isLSAImm() const {
907 if (!isConstantImm())
909 int64_t Val = getConstantImm();
910 return 1 <= Val && Val <= 4;
912 bool isRegList() const { return Kind == k_RegList; }
913 bool isMovePRegPair() const {
914 if (Kind != k_RegList || RegList.List->size() != 2)
917 unsigned R0 = RegList.List->front();
918 unsigned R1 = RegList.List->back();
920 if ((R0 == Mips::A1 && R1 == Mips::A2) ||
921 (R0 == Mips::A1 && R1 == Mips::A3) ||
922 (R0 == Mips::A2 && R1 == Mips::A3) ||
923 (R0 == Mips::A0 && R1 == Mips::S5) ||
924 (R0 == Mips::A0 && R1 == Mips::S6) ||
925 (R0 == Mips::A0 && R1 == Mips::A1) ||
926 (R0 == Mips::A0 && R1 == Mips::A2) ||
927 (R0 == Mips::A0 && R1 == Mips::A3))
933 StringRef getToken() const {
934 assert(Kind == k_Token && "Invalid access!");
935 return StringRef(Tok.Data, Tok.Length);
937 bool isRegPair() const { return Kind == k_RegPair; }
939 unsigned getReg() const override {
940 // As a special case until we sort out the definition of div/divu, pretend
941 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
942 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
943 RegIdx.Kind & RegKind_GPR)
944 return getGPR32Reg(); // FIXME: GPR64 too
946 assert(Kind == k_PhysRegister && "Invalid access!");
950 const MCExpr *getImm() const {
951 assert((Kind == k_Immediate) && "Invalid access!");
955 int64_t getConstantImm() const {
956 const MCExpr *Val = getImm();
957 return static_cast<const MCConstantExpr *>(Val)->getValue();
960 MipsOperand *getMemBase() const {
961 assert((Kind == k_Memory) && "Invalid access!");
965 const MCExpr *getMemOff() const {
966 assert((Kind == k_Memory) && "Invalid access!");
970 int64_t getConstantMemOff() const {
971 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
974 const SmallVectorImpl<unsigned> &getRegList() const {
975 assert((Kind == k_RegList) && "Invalid access!");
976 return *(RegList.List);
979 unsigned getRegPair() const {
980 assert((Kind == k_RegPair) && "Invalid access!");
984 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
985 MipsAsmParser &Parser) {
986 auto Op = make_unique<MipsOperand>(k_Token, Parser);
987 Op->Tok.Data = Str.data();
988 Op->Tok.Length = Str.size();
994 /// Create a numeric register (e.g. $1). The exact register remains
995 /// unresolved until an instruction successfully matches
996 static std::unique_ptr<MipsOperand>
997 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
998 SMLoc E, MipsAsmParser &Parser) {
999 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
1000 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1003 /// Create a register that is definitely a GPR.
1004 /// This is typically only used for named registers such as $gp.
1005 static std::unique_ptr<MipsOperand>
1006 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1007 MipsAsmParser &Parser) {
1008 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1011 /// Create a register that is definitely a FGR.
1012 /// This is typically only used for named registers such as $f0.
1013 static std::unique_ptr<MipsOperand>
1014 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1015 MipsAsmParser &Parser) {
1016 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
1019 /// Create a register that is definitely a HWReg.
1020 /// This is typically only used for named registers such as $hwr_cpunum.
1021 static std::unique_ptr<MipsOperand>
1022 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
1023 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1024 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
1027 /// Create a register that is definitely an FCC.
1028 /// This is typically only used for named registers such as $fcc0.
1029 static std::unique_ptr<MipsOperand>
1030 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1031 MipsAsmParser &Parser) {
1032 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
1035 /// Create a register that is definitely an ACC.
1036 /// This is typically only used for named registers such as $ac0.
1037 static std::unique_ptr<MipsOperand>
1038 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1039 MipsAsmParser &Parser) {
1040 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
1043 /// Create a register that is definitely an MSA128.
1044 /// This is typically only used for named registers such as $w0.
1045 static std::unique_ptr<MipsOperand>
1046 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1047 SMLoc E, MipsAsmParser &Parser) {
1048 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
1051 /// Create a register that is definitely an MSACtrl.
1052 /// This is typically only used for named registers such as $msaaccess.
1053 static std::unique_ptr<MipsOperand>
1054 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1055 SMLoc E, MipsAsmParser &Parser) {
1056 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
1059 static std::unique_ptr<MipsOperand>
1060 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1061 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
1068 static std::unique_ptr<MipsOperand>
1069 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1070 SMLoc E, MipsAsmParser &Parser) {
1071 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1072 Op->Mem.Base = Base.release();
1079 static std::unique_ptr<MipsOperand>
1080 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1081 MipsAsmParser &Parser) {
1082 assert (Regs.size() > 0 && "Empty list not allowed");
1084 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1085 Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
1086 Op->StartLoc = StartLoc;
1087 Op->EndLoc = EndLoc;
1091 static std::unique_ptr<MipsOperand>
1092 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1093 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1094 Op->RegIdx.Index = RegNo;
1100 bool isGPRAsmReg() const {
1101 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1103 bool isMM16AsmReg() const {
1104 if (!(isRegIdx() && RegIdx.Kind))
1106 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1107 || RegIdx.Index == 16 || RegIdx.Index == 17);
1109 bool isMM16AsmRegZero() const {
1110 if (!(isRegIdx() && RegIdx.Kind))
1112 return (RegIdx.Index == 0 ||
1113 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1114 RegIdx.Index == 17);
1116 bool isMM16AsmRegMoveP() const {
1117 if (!(isRegIdx() && RegIdx.Kind))
1119 return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1120 (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1122 bool isFGRAsmReg() const {
1123 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1124 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1126 bool isHWRegsAsmReg() const {
1127 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1129 bool isCCRAsmReg() const {
1130 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1132 bool isFCCAsmReg() const {
1133 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1135 if (!AsmParser.hasEightFccRegisters())
1136 return RegIdx.Index == 0;
1137 return RegIdx.Index <= 7;
1139 bool isACCAsmReg() const {
1140 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1142 bool isCOP2AsmReg() const {
1143 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1145 bool isCOP3AsmReg() const {
1146 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1148 bool isMSA128AsmReg() const {
1149 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1151 bool isMSACtrlAsmReg() const {
1152 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1155 /// getStartLoc - Get the location of the first token of this operand.
1156 SMLoc getStartLoc() const override { return StartLoc; }
1157 /// getEndLoc - Get the location of the last token of this operand.
1158 SMLoc getEndLoc() const override { return EndLoc; }
1160 virtual ~MipsOperand() {
1168 delete RegList.List;
1169 case k_PhysRegister:
1170 case k_RegisterIndex:
1177 void print(raw_ostream &OS) const override {
1186 Mem.Base->print(OS);
1191 case k_PhysRegister:
1192 OS << "PhysReg<" << PhysReg.Num << ">";
1194 case k_RegisterIndex:
1195 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1202 for (auto Reg : (*RegList.List))
1207 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1211 }; // class MipsOperand
1215 extern const MCInstrDesc MipsInsts[];
1217 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1218 return MipsInsts[Opcode];
1221 static bool hasShortDelaySlot(unsigned Opcode) {
1224 case Mips::JALRS_MM:
1225 case Mips::JALRS16_MM:
1226 case Mips::BGEZALS_MM:
1227 case Mips::BLTZALS_MM:
1234 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1235 SmallVectorImpl<MCInst> &Instructions) {
1236 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1240 if (MCID.isBranch() || MCID.isCall()) {
1241 const unsigned Opcode = Inst.getOpcode();
1251 assert(hasCnMips() && "instruction only valid for octeon cpus");
1258 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1259 Offset = Inst.getOperand(2);
1260 if (!Offset.isImm())
1261 break; // We'll deal with this situation later on when applying fixups.
1262 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1263 return Error(IDLoc, "branch target out of range");
1264 if (OffsetToAlignment(Offset.getImm(),
1265 1LL << (inMicroMipsMode() ? 1 : 2)))
1266 return Error(IDLoc, "branch to misaligned address");
1280 case Mips::BGEZAL_MM:
1281 case Mips::BLTZAL_MM:
1284 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1285 Offset = Inst.getOperand(1);
1286 if (!Offset.isImm())
1287 break; // We'll deal with this situation later on when applying fixups.
1288 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1289 return Error(IDLoc, "branch target out of range");
1290 if (OffsetToAlignment(Offset.getImm(),
1291 1LL << (inMicroMipsMode() ? 1 : 2)))
1292 return Error(IDLoc, "branch to misaligned address");
1294 case Mips::BEQZ16_MM:
1295 case Mips::BNEZ16_MM:
1296 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1297 Offset = Inst.getOperand(1);
1298 if (!Offset.isImm())
1299 break; // We'll deal with this situation later on when applying fixups.
1300 if (!isIntN(8, Offset.getImm()))
1301 return Error(IDLoc, "branch target out of range");
1302 if (OffsetToAlignment(Offset.getImm(), 2LL))
1303 return Error(IDLoc, "branch to misaligned address");
1308 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1309 // We still accept it but it is a normal nop.
1310 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1311 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1312 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1317 const unsigned Opcode = Inst.getOpcode();
1329 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1330 // The offset is handled above
1331 Opnd = Inst.getOperand(1);
1333 return Error(IDLoc, "expected immediate operand kind");
1334 Imm = Opnd.getImm();
1335 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1336 Opcode == Mips::BBIT1 ? 63 : 31))
1337 return Error(IDLoc, "immediate operand value out of range");
1339 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1341 Inst.getOperand(1).setImm(Imm - 32);
1349 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1351 Opnd = Inst.getOperand(3);
1353 return Error(IDLoc, "expected immediate operand kind");
1354 Imm = Opnd.getImm();
1355 if (Imm < 0 || Imm > 31)
1356 return Error(IDLoc, "immediate operand value out of range");
1358 Opnd = Inst.getOperand(2);
1360 return Error(IDLoc, "expected immediate operand kind");
1361 Imm = Opnd.getImm();
1362 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1363 Opcode == Mips::EXTS ? 63 : 31))
1364 return Error(IDLoc, "immediate operand value out of range");
1366 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1367 Inst.getOperand(2).setImm(Imm - 32);
1373 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1374 Opnd = Inst.getOperand(2);
1376 return Error(IDLoc, "expected immediate operand kind");
1377 Imm = Opnd.getImm();
1378 if (!isInt<10>(Imm))
1379 return Error(IDLoc, "immediate operand value out of range");
1384 // If this instruction has a delay slot and .set reorder is active,
1385 // emit a NOP after it.
1386 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1387 Instructions.push_back(Inst);
1388 createNop(hasShortDelaySlot(Inst.getOpcode()), IDLoc, Instructions);
1392 if (MCID.mayLoad() || MCID.mayStore()) {
1393 // Check the offset of memory operand, if it is a symbol
1394 // reference or immediate we may have to expand instructions.
1395 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1396 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1397 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1398 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1399 MCOperand &Op = Inst.getOperand(i);
1401 int MemOffset = Op.getImm();
1402 if (MemOffset < -32768 || MemOffset > 32767) {
1403 // Offset can't exceed 16bit value.
1404 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1407 } else if (Op.isExpr()) {
1408 const MCExpr *Expr = Op.getExpr();
1409 if (Expr->getKind() == MCExpr::SymbolRef) {
1410 const MCSymbolRefExpr *SR =
1411 static_cast<const MCSymbolRefExpr *>(Expr);
1412 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1414 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1417 } else if (!isEvaluated(Expr)) {
1418 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1426 if (inMicroMipsMode()) {
1427 if (MCID.mayLoad()) {
1428 // Try to create 16-bit GP relative load instruction.
1429 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1430 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1431 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1432 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1433 MCOperand &Op = Inst.getOperand(i);
1435 int MemOffset = Op.getImm();
1436 MCOperand &DstReg = Inst.getOperand(0);
1437 MCOperand &BaseReg = Inst.getOperand(1);
1438 if (isIntN(9, MemOffset) && (MemOffset % 4 == 0) &&
1439 getContext().getRegisterInfo()->getRegClass(
1440 Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1441 BaseReg.getReg() == Mips::GP) {
1443 TmpInst.setLoc(IDLoc);
1444 TmpInst.setOpcode(Mips::LWGP_MM);
1445 TmpInst.addOperand(MCOperand::CreateReg(DstReg.getReg()));
1446 TmpInst.addOperand(MCOperand::CreateReg(Mips::GP));
1447 TmpInst.addOperand(MCOperand::CreateImm(MemOffset));
1448 Instructions.push_back(TmpInst);
1456 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1461 switch (Inst.getOpcode()) {
1464 case Mips::ADDIUS5_MM:
1465 Opnd = Inst.getOperand(2);
1467 return Error(IDLoc, "expected immediate operand kind");
1468 Imm = Opnd.getImm();
1469 if (Imm < -8 || Imm > 7)
1470 return Error(IDLoc, "immediate operand value out of range");
1472 case Mips::ADDIUSP_MM:
1473 Opnd = Inst.getOperand(0);
1475 return Error(IDLoc, "expected immediate operand kind");
1476 Imm = Opnd.getImm();
1477 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1479 return Error(IDLoc, "immediate operand value out of range");
1481 case Mips::SLL16_MM:
1482 case Mips::SRL16_MM:
1483 Opnd = Inst.getOperand(2);
1485 return Error(IDLoc, "expected immediate operand kind");
1486 Imm = Opnd.getImm();
1487 if (Imm < 1 || Imm > 8)
1488 return Error(IDLoc, "immediate operand value out of range");
1491 Opnd = Inst.getOperand(1);
1493 return Error(IDLoc, "expected immediate operand kind");
1494 Imm = Opnd.getImm();
1495 if (Imm < -1 || Imm > 126)
1496 return Error(IDLoc, "immediate operand value out of range");
1498 case Mips::ADDIUR2_MM:
1499 Opnd = Inst.getOperand(2);
1501 return Error(IDLoc, "expected immediate operand kind");
1502 Imm = Opnd.getImm();
1503 if (!(Imm == 1 || Imm == -1 ||
1504 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1505 return Error(IDLoc, "immediate operand value out of range");
1507 case Mips::ADDIUR1SP_MM:
1508 Opnd = Inst.getOperand(1);
1510 return Error(IDLoc, "expected immediate operand kind");
1511 Imm = Opnd.getImm();
1512 if (OffsetToAlignment(Imm, 4LL))
1513 return Error(IDLoc, "misaligned immediate operand value");
1514 if (Imm < 0 || Imm > 255)
1515 return Error(IDLoc, "immediate operand value out of range");
1517 case Mips::ANDI16_MM:
1518 Opnd = Inst.getOperand(2);
1520 return Error(IDLoc, "expected immediate operand kind");
1521 Imm = Opnd.getImm();
1522 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1523 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1524 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1525 return Error(IDLoc, "immediate operand value out of range");
1527 case Mips::LBU16_MM:
1528 Opnd = Inst.getOperand(2);
1530 return Error(IDLoc, "expected immediate operand kind");
1531 Imm = Opnd.getImm();
1532 if (Imm < -1 || Imm > 14)
1533 return Error(IDLoc, "immediate operand value out of range");
1536 Opnd = Inst.getOperand(2);
1538 return Error(IDLoc, "expected immediate operand kind");
1539 Imm = Opnd.getImm();
1540 if (Imm < 0 || Imm > 15)
1541 return Error(IDLoc, "immediate operand value out of range");
1543 case Mips::LHU16_MM:
1545 Opnd = Inst.getOperand(2);
1547 return Error(IDLoc, "expected immediate operand kind");
1548 Imm = Opnd.getImm();
1549 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1550 return Error(IDLoc, "immediate operand value out of range");
1554 Opnd = Inst.getOperand(2);
1556 return Error(IDLoc, "expected immediate operand kind");
1557 Imm = Opnd.getImm();
1558 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1559 return Error(IDLoc, "immediate operand value out of range");
1563 Opnd = Inst.getOperand(2);
1565 return Error(IDLoc, "expected immediate operand kind");
1566 Imm = Opnd.getImm();
1567 if (!isUInt<5>(Imm))
1568 return Error(IDLoc, "immediate operand value out of range");
1570 case Mips::ADDIUPC_MM:
1571 MCOperand Opnd = Inst.getOperand(1);
1573 return Error(IDLoc, "expected immediate operand kind");
1574 int Imm = Opnd.getImm();
1575 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1576 return Error(IDLoc, "immediate operand value out of range");
1581 if (needsExpansion(Inst))
1582 return expandInstruction(Inst, IDLoc, Instructions);
1584 Instructions.push_back(Inst);
1589 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1591 switch (Inst.getOpcode()) {
1592 case Mips::LoadImm32:
1593 case Mips::LoadImm64:
1594 case Mips::LoadAddrImm32:
1595 case Mips::LoadAddrReg32:
1596 case Mips::B_MM_Pseudo:
1599 case Mips::JalOneReg:
1600 case Mips::JalTwoReg:
1607 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1608 SmallVectorImpl<MCInst> &Instructions) {
1609 switch (Inst.getOpcode()) {
1610 default: llvm_unreachable("unimplemented expansion");
1611 case Mips::LoadImm32:
1612 return expandLoadImm(Inst, IDLoc, Instructions);
1613 case Mips::LoadImm64:
1615 Error(IDLoc, "instruction requires a 64-bit architecture");
1618 return expandLoadImm(Inst, IDLoc, Instructions);
1619 case Mips::LoadAddrImm32:
1620 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1621 case Mips::LoadAddrReg32:
1622 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1623 case Mips::B_MM_Pseudo:
1624 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1627 return expandLoadStoreMultiple(Inst, IDLoc, Instructions);
1628 case Mips::JalOneReg:
1629 case Mips::JalTwoReg:
1630 return expandJalWithRegs(Inst, IDLoc, Instructions);
1635 template <bool PerformShift>
1636 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1637 SmallVectorImpl<MCInst> &Instructions) {
1640 tmpInst.setOpcode(Mips::DSLL);
1641 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1642 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1643 tmpInst.addOperand(MCOperand::CreateImm(16));
1644 tmpInst.setLoc(IDLoc);
1645 Instructions.push_back(tmpInst);
1648 tmpInst.setOpcode(Mips::ORi);
1649 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1650 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1651 tmpInst.addOperand(Operand);
1652 tmpInst.setLoc(IDLoc);
1653 Instructions.push_back(tmpInst);
1656 template <int Shift, bool PerformShift>
1657 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1658 SmallVectorImpl<MCInst> &Instructions) {
1659 createShiftOr<PerformShift>(
1660 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1661 IDLoc, Instructions);
1665 bool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
1666 SmallVectorImpl<MCInst> &Instructions) {
1667 // Create a JALR instruction which is going to replace the pseudo-JAL.
1669 JalrInst.setLoc(IDLoc);
1670 const MCOperand FirstRegOp = Inst.getOperand(0);
1671 const unsigned Opcode = Inst.getOpcode();
1673 if (Opcode == Mips::JalOneReg) {
1674 // jal $rs => jalr $rs
1675 if (inMicroMipsMode()) {
1676 JalrInst.setOpcode(Mips::JALR16_MM);
1677 JalrInst.addOperand(FirstRegOp);
1679 JalrInst.setOpcode(Mips::JALR);
1680 JalrInst.addOperand(MCOperand::CreateReg(Mips::RA));
1681 JalrInst.addOperand(FirstRegOp);
1683 } else if (Opcode == Mips::JalTwoReg) {
1684 // jal $rd, $rs => jalr $rd, $rs
1685 JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1686 JalrInst.addOperand(FirstRegOp);
1687 const MCOperand SecondRegOp = Inst.getOperand(1);
1688 JalrInst.addOperand(SecondRegOp);
1690 Instructions.push_back(JalrInst);
1692 // If .set reorder is active, emit a NOP after it.
1693 if (AssemblerOptions.back()->isReorder()) {
1694 // This is a 32-bit NOP because these 2 pseudo-instructions
1695 // do not have a short delay slot.
1697 NopInst.setOpcode(Mips::SLL);
1698 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1699 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1700 NopInst.addOperand(MCOperand::CreateImm(0));
1701 Instructions.push_back(NopInst);
1707 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1708 SmallVectorImpl<MCInst> &Instructions) {
1710 const MCOperand &ImmOp = Inst.getOperand(1);
1711 assert(ImmOp.isImm() && "expected immediate operand kind");
1712 const MCOperand &RegOp = Inst.getOperand(0);
1713 assert(RegOp.isReg() && "expected register operand kind");
1715 int64_t ImmValue = ImmOp.getImm();
1716 tmpInst.setLoc(IDLoc);
1717 // FIXME: gas has a special case for values that are 000...1111, which
1718 // becomes a li -1 and then a dsrl
1719 if (0 <= ImmValue && ImmValue <= 65535) {
1720 // For unsigned and positive signed 16-bit values (0 <= j <= 65535):
1721 // li d,j => ori d,$zero,j
1722 tmpInst.setOpcode(Mips::ORi);
1723 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1724 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1725 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1726 Instructions.push_back(tmpInst);
1727 } else if (ImmValue < 0 && ImmValue >= -32768) {
1728 // For negative signed 16-bit values (-32768 <= j < 0):
1729 // li d,j => addiu d,$zero,j
1730 tmpInst.setOpcode(Mips::ADDiu);
1731 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1732 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1733 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1734 Instructions.push_back(tmpInst);
1735 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1736 // For all other values which are representable as a 32-bit integer:
1737 // li d,j => lui d,hi16(j)
1739 tmpInst.setOpcode(Mips::LUi);
1740 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1741 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1742 Instructions.push_back(tmpInst);
1743 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1744 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1746 Error(IDLoc, "instruction requires a 64-bit architecture");
1750 // <------- lo32 ------>
1751 // <------- hi32 ------>
1752 // <- hi16 -> <- lo16 ->
1753 // _________________________________
1755 // | 16-bytes | 16-bytes | 16-bytes |
1756 // |__________|__________|__________|
1758 // For any 64-bit value that is representable as a 48-bit integer:
1759 // li d,j => lui d,hi16(j)
1760 // ori d,d,hi16(lo32(j))
1762 // ori d,d,lo16(lo32(j))
1763 tmpInst.setOpcode(Mips::LUi);
1764 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1766 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1767 Instructions.push_back(tmpInst);
1768 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1769 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1772 Error(IDLoc, "instruction requires a 64-bit architecture");
1776 // <------- hi32 ------> <------- lo32 ------>
1777 // <- hi16 -> <- lo16 ->
1778 // ___________________________________________
1780 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1781 // |__________|__________|__________|__________|
1783 // For all other values which are representable as a 64-bit integer:
1784 // li d,j => lui d,hi16(j)
1785 // ori d,d,lo16(hi32(j))
1787 // ori d,d,hi16(lo32(j))
1789 // ori d,d,lo16(lo32(j))
1790 tmpInst.setOpcode(Mips::LUi);
1791 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1793 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1794 Instructions.push_back(tmpInst);
1795 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1796 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1797 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1803 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1804 SmallVectorImpl<MCInst> &Instructions) {
1806 const MCOperand &ImmOp = Inst.getOperand(2);
1807 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1808 "expected immediate operand kind");
1809 if (!ImmOp.isImm()) {
1810 expandLoadAddressSym(Inst, IDLoc, Instructions);
1813 const MCOperand &SrcRegOp = Inst.getOperand(1);
1814 assert(SrcRegOp.isReg() && "expected register operand kind");
1815 const MCOperand &DstRegOp = Inst.getOperand(0);
1816 assert(DstRegOp.isReg() && "expected register operand kind");
1817 int ImmValue = ImmOp.getImm();
1818 if (-32768 <= ImmValue && ImmValue <= 65535) {
1819 // For -32768 <= j <= 65535.
1820 // la d,j(s) => addiu d,s,j
1821 tmpInst.setOpcode(Mips::ADDiu);
1822 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1823 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1824 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1825 Instructions.push_back(tmpInst);
1827 // For any other value of j that is representable as a 32-bit integer.
1828 // la d,j(s) => lui d,hi16(j)
1831 tmpInst.setOpcode(Mips::LUi);
1832 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1833 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1834 Instructions.push_back(tmpInst);
1836 tmpInst.setOpcode(Mips::ORi);
1837 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1838 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1839 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1840 Instructions.push_back(tmpInst);
1842 tmpInst.setOpcode(Mips::ADDu);
1843 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1844 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1845 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1846 Instructions.push_back(tmpInst);
1852 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1853 SmallVectorImpl<MCInst> &Instructions) {
1855 const MCOperand &ImmOp = Inst.getOperand(1);
1856 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1857 "expected immediate operand kind");
1858 if (!ImmOp.isImm()) {
1859 expandLoadAddressSym(Inst, IDLoc, Instructions);
1862 const MCOperand &RegOp = Inst.getOperand(0);
1863 assert(RegOp.isReg() && "expected register operand kind");
1864 int ImmValue = ImmOp.getImm();
1865 if (-32768 <= ImmValue && ImmValue <= 65535) {
1866 // For -32768 <= j <= 65535.
1867 // la d,j => addiu d,$zero,j
1868 tmpInst.setOpcode(Mips::ADDiu);
1869 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1870 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1871 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1872 Instructions.push_back(tmpInst);
1874 // For any other value of j that is representable as a 32-bit integer.
1875 // la d,j => lui d,hi16(j)
1877 tmpInst.setOpcode(Mips::LUi);
1878 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1879 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1880 Instructions.push_back(tmpInst);
1882 tmpInst.setOpcode(Mips::ORi);
1883 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1884 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1885 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1886 Instructions.push_back(tmpInst);
1892 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1893 SmallVectorImpl<MCInst> &Instructions) {
1894 // FIXME: If we do have a valid at register to use, we should generate a
1895 // slightly shorter sequence here.
1897 int ExprOperandNo = 1;
1898 // Sometimes the assembly parser will get the immediate expression as
1899 // a $zero + an immediate.
1900 if (Inst.getNumOperands() == 3) {
1901 assert(Inst.getOperand(1).getReg() ==
1902 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1905 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1906 assert(SymOp.isExpr() && "expected symbol operand kind");
1907 const MCOperand &RegOp = Inst.getOperand(0);
1908 unsigned RegNo = RegOp.getReg();
1909 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1910 const MCSymbolRefExpr *HiExpr =
1911 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1912 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1913 const MCSymbolRefExpr *LoExpr =
1914 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1915 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1917 // If it's a 64-bit architecture, expand to:
1918 // la d,sym => lui d,highest(sym)
1919 // ori d,d,higher(sym)
1921 // ori d,d,hi16(sym)
1923 // ori d,d,lo16(sym)
1924 const MCSymbolRefExpr *HighestExpr =
1925 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1926 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1927 const MCSymbolRefExpr *HigherExpr =
1928 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1929 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1931 tmpInst.setOpcode(Mips::LUi);
1932 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1933 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1934 Instructions.push_back(tmpInst);
1936 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1938 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1940 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1943 // Otherwise, expand to:
1944 // la d,sym => lui d,hi16(sym)
1945 // ori d,d,lo16(sym)
1946 tmpInst.setOpcode(Mips::LUi);
1947 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1948 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1949 Instructions.push_back(tmpInst);
1951 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1956 bool MipsAsmParser::expandUncondBranchMMPseudo(
1957 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1958 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1959 "unexpected number of operands");
1961 MCOperand Offset = Inst.getOperand(0);
1962 if (Offset.isExpr()) {
1964 Inst.setOpcode(Mips::BEQ_MM);
1965 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1966 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1967 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1969 assert(Offset.isImm() && "expected immediate operand kind");
1970 if (isIntN(11, Offset.getImm())) {
1971 // If offset fits into 11 bits then this instruction becomes microMIPS
1972 // 16-bit unconditional branch instruction.
1973 Inst.setOpcode(Mips::B16_MM);
1975 if (!isIntN(17, Offset.getImm()))
1976 Error(IDLoc, "branch target out of range");
1977 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1978 Error(IDLoc, "branch to misaligned address");
1980 Inst.setOpcode(Mips::BEQ_MM);
1981 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1982 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1983 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1986 Instructions.push_back(Inst);
1988 // If .set reorder is active, emit a NOP after the branch instruction.
1989 if (AssemblerOptions.back()->isReorder())
1990 createNop(true, IDLoc, Instructions);
1995 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1996 SmallVectorImpl<MCInst> &Instructions,
1997 bool isLoad, bool isImmOpnd) {
1998 const MCSymbolRefExpr *SR;
2000 unsigned ImmOffset, HiOffset, LoOffset;
2001 const MCExpr *ExprOffset;
2003 // 1st operand is either the source or destination register.
2004 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
2005 unsigned RegOpNum = Inst.getOperand(0).getReg();
2006 // 2nd operand is the base register.
2007 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
2008 unsigned BaseRegNum = Inst.getOperand(1).getReg();
2009 // 3rd operand is either an immediate or expression.
2011 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
2012 ImmOffset = Inst.getOperand(2).getImm();
2013 LoOffset = ImmOffset & 0x0000ffff;
2014 HiOffset = (ImmOffset & 0xffff0000) >> 16;
2015 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
2016 if (LoOffset & 0x8000)
2019 ExprOffset = Inst.getOperand(2).getExpr();
2020 // All instructions will have the same location.
2021 TempInst.setLoc(IDLoc);
2022 // These are some of the types of expansions we perform here:
2023 // 1) lw $8, sym => lui $8, %hi(sym)
2024 // lw $8, %lo(sym)($8)
2025 // 2) lw $8, offset($9) => lui $8, %hi(offset)
2027 // lw $8, %lo(offset)($9)
2028 // 3) lw $8, offset($8) => lui $at, %hi(offset)
2030 // lw $8, %lo(offset)($at)
2031 // 4) sw $8, sym => lui $at, %hi(sym)
2032 // sw $8, %lo(sym)($at)
2033 // 5) sw $8, offset($8) => lui $at, %hi(offset)
2035 // sw $8, %lo(offset)($at)
2036 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
2037 // ldc1 $f0, %lo(sym)($at)
2039 // For load instructions we can use the destination register as a temporary
2040 // if base and dst are different (examples 1 and 2) and if the base register
2041 // is general purpose otherwise we must use $at (example 6) and error if it's
2042 // not available. For stores we must use $at (examples 4 and 5) because we
2043 // must not clobber the source register setting up the offset.
2044 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2045 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
2046 unsigned RegClassIDOp0 =
2047 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
2048 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
2049 (RegClassIDOp0 == Mips::GPR64RegClassID);
2050 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
2051 TmpRegNum = RegOpNum;
2053 // At this point we need AT to perform the expansions and we exit if it is
2055 TmpRegNum = getATReg(IDLoc);
2060 TempInst.setOpcode(Mips::LUi);
2061 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2063 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
2065 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2066 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
2067 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
2068 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
2070 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2072 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
2073 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
2076 // Add the instruction to the list.
2077 Instructions.push_back(TempInst);
2078 // Prepare TempInst for next instruction.
2080 // Add temp register to base.
2081 if (BaseRegNum != Mips::ZERO) {
2082 TempInst.setOpcode(Mips::ADDu);
2083 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2084 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2085 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
2086 Instructions.push_back(TempInst);
2089 // And finally, create original instruction with low part
2090 // of offset and new base.
2091 TempInst.setOpcode(Inst.getOpcode());
2092 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
2093 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
2095 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
2097 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
2098 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
2099 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
2101 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2103 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
2104 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
2107 Instructions.push_back(TempInst);
2112 MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2113 SmallVectorImpl<MCInst> &Instructions) {
2114 unsigned OpNum = Inst.getNumOperands();
2115 unsigned Opcode = Inst.getOpcode();
2116 unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2118 assert (Inst.getOperand(OpNum - 1).isImm() &&
2119 Inst.getOperand(OpNum - 2).isReg() &&
2120 Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2122 if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2123 Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2124 Inst.getOperand(OpNum - 2).getReg() == Mips::SP &&
2125 Inst.getOperand(OpNum - 3).getReg() == Mips::RA)
2126 // It can be implemented as SWM16 or LWM16 instruction.
2127 NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2129 Inst.setOpcode(NewOpcode);
2130 Instructions.push_back(Inst);
2134 void MipsAsmParser::createNop(bool hasShortDelaySlot, SMLoc IDLoc,
2135 SmallVectorImpl<MCInst> &Instructions) {
2137 if (hasShortDelaySlot) {
2138 NopInst.setOpcode(Mips::MOVE16_MM);
2139 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2140 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2142 NopInst.setOpcode(Mips::SLL);
2143 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2144 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
2145 NopInst.addOperand(MCOperand::CreateImm(0));
2147 Instructions.push_back(NopInst);
2150 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
2151 // As described by the Mips32r2 spec, the registers Rd and Rs for
2152 // jalr.hb must be different.
2153 unsigned Opcode = Inst.getOpcode();
2155 if (Opcode == Mips::JALR_HB &&
2156 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
2157 return Match_RequiresDifferentSrcAndDst;
2159 return Match_Success;
2162 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
2163 OperandVector &Operands,
2165 uint64_t &ErrorInfo,
2166 bool MatchingInlineAsm) {
2169 SmallVector<MCInst, 8> Instructions;
2170 unsigned MatchResult =
2171 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
2173 switch (MatchResult) {
2174 case Match_Success: {
2175 if (processInstruction(Inst, IDLoc, Instructions))
2177 for (unsigned i = 0; i < Instructions.size(); i++)
2178 Out.EmitInstruction(Instructions[i], STI);
2181 case Match_MissingFeature:
2182 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2184 case Match_InvalidOperand: {
2185 SMLoc ErrorLoc = IDLoc;
2186 if (ErrorInfo != ~0ULL) {
2187 if (ErrorInfo >= Operands.size())
2188 return Error(IDLoc, "too few operands for instruction");
2190 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2191 if (ErrorLoc == SMLoc())
2195 return Error(ErrorLoc, "invalid operand for instruction");
2197 case Match_MnemonicFail:
2198 return Error(IDLoc, "invalid instruction");
2199 case Match_RequiresDifferentSrcAndDst:
2200 return Error(IDLoc, "source and destination must be different");
2203 llvm_unreachable("Implement any new match types added!");
2206 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2207 if ((RegIndex != 0) &&
2208 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2210 Warning(Loc, "used $at without \".set noat\"");
2212 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2213 Twine(RegIndex) + "\"");
2218 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2219 SMRange Range, bool ShowColors) {
2220 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2221 Range, SMFixIt(Range, FixMsg),
2225 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2228 CC = StringSwitch<unsigned>(Name)
2264 if (!(isABI_N32() || isABI_N64()))
2267 if (12 <= CC && CC <= 15) {
2268 // Name is one of t4-t7
2269 AsmToken RegTok = getLexer().peekTok();
2270 SMRange RegRange = RegTok.getLocRange();
2272 StringRef FixedName = StringSwitch<StringRef>(Name)
2278 assert(FixedName != "" && "Register name is not one of t4-t7.");
2280 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2281 "Did you mean $" + FixedName + "?", RegRange);
2284 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2285 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2286 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2287 if (8 <= CC && CC <= 11)
2291 CC = StringSwitch<unsigned>(Name)
2303 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2306 CC = StringSwitch<unsigned>(Name)
2307 .Case("hwr_cpunum", 0)
2308 .Case("hwr_synci_step", 1)
2310 .Case("hwr_ccres", 3)
2311 .Case("hwr_ulr", 29)
2317 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2319 if (Name[0] == 'f') {
2320 StringRef NumString = Name.substr(1);
2322 if (NumString.getAsInteger(10, IntVal))
2323 return -1; // This is not an integer.
2324 if (IntVal > 31) // Maximum index for fpu register.
2331 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2333 if (Name.startswith("fcc")) {
2334 StringRef NumString = Name.substr(3);
2336 if (NumString.getAsInteger(10, IntVal))
2337 return -1; // This is not an integer.
2338 if (IntVal > 7) // There are only 8 fcc registers.
2345 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2347 if (Name.startswith("ac")) {
2348 StringRef NumString = Name.substr(2);
2350 if (NumString.getAsInteger(10, IntVal))
2351 return -1; // This is not an integer.
2352 if (IntVal > 3) // There are only 3 acc registers.
2359 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2362 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2371 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2374 CC = StringSwitch<unsigned>(Name)
2377 .Case("msaaccess", 2)
2379 .Case("msamodify", 4)
2380 .Case("msarequest", 5)
2382 .Case("msaunmap", 7)
2388 unsigned MipsAsmParser::getATReg(SMLoc Loc) {
2389 unsigned ATIndex = AssemblerOptions.back()->getATRegNum();
2391 reportParseError(Loc,
2392 "pseudo-instruction requires $at, which is not available");
2395 unsigned AT = getReg(
2396 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
2400 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2401 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2404 unsigned MipsAsmParser::getGPR(int RegNo) {
2405 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2409 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2411 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2414 return getReg(RegClass, RegNum);
2417 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2418 MCAsmParser &Parser = getParser();
2419 DEBUG(dbgs() << "parseOperand\n");
2421 // Check if the current operand has a custom associated parser, if so, try to
2422 // custom parse the operand, or fallback to the general approach.
2423 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2424 if (ResTy == MatchOperand_Success)
2426 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2427 // there was a match, but an error occurred, in which case, just return that
2428 // the operand parsing failed.
2429 if (ResTy == MatchOperand_ParseFail)
2432 DEBUG(dbgs() << ".. Generic Parser\n");
2434 switch (getLexer().getKind()) {
2436 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2438 case AsmToken::Dollar: {
2439 // Parse the register.
2440 SMLoc S = Parser.getTok().getLoc();
2442 // Almost all registers have been parsed by custom parsers. There is only
2443 // one exception to this. $zero (and it's alias $0) will reach this point
2444 // for div, divu, and similar instructions because it is not an operand
2445 // to the instruction definition but an explicit register. Special case
2446 // this situation for now.
2447 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2450 // Maybe it is a symbol reference.
2451 StringRef Identifier;
2452 if (Parser.parseIdentifier(Identifier))
2455 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2456 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2457 // Otherwise create a symbol reference.
2459 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2461 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2464 // Else drop to expression parsing.
2465 case AsmToken::LParen:
2466 case AsmToken::Minus:
2467 case AsmToken::Plus:
2468 case AsmToken::Integer:
2469 case AsmToken::Tilde:
2470 case AsmToken::String: {
2471 DEBUG(dbgs() << ".. generic integer\n");
2472 OperandMatchResultTy ResTy = parseImm(Operands);
2473 return ResTy != MatchOperand_Success;
2475 case AsmToken::Percent: {
2476 // It is a symbol reference or constant expression.
2477 const MCExpr *IdVal;
2478 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2479 if (parseRelocOperand(IdVal))
2482 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2484 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2486 } // case AsmToken::Percent
2487 } // switch(getLexer().getKind())
2491 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2492 StringRef RelocStr) {
2494 // Check the type of the expression.
2495 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2496 // It's a constant, evaluate reloc value.
2498 switch (getVariantKind(RelocStr)) {
2499 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2500 // Get the 1st 16-bits.
2501 Val = MCE->getValue() & 0xffff;
2503 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2504 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2505 // 16 bits being negative.
2506 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2508 case MCSymbolRefExpr::VK_Mips_HIGHER:
2509 // Get the 3rd 16-bits.
2510 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2512 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2513 // Get the 4th 16-bits.
2514 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2517 report_fatal_error("unsupported reloc value");
2519 return MCConstantExpr::Create(Val, getContext());
2522 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2523 // It's a symbol, create a symbolic expression from the symbol.
2524 StringRef Symbol = MSRE->getSymbol().getName();
2525 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2526 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2530 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2531 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2533 // Try to create target expression.
2534 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2535 return MipsMCExpr::Create(VK, Expr, getContext());
2537 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2538 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2539 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2543 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2544 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2545 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2548 // Just return the original expression.
2552 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2554 switch (Expr->getKind()) {
2555 case MCExpr::Constant:
2557 case MCExpr::SymbolRef:
2558 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2559 case MCExpr::Binary:
2560 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2561 if (!isEvaluated(BE->getLHS()))
2563 return isEvaluated(BE->getRHS());
2566 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2567 case MCExpr::Target:
2573 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2574 MCAsmParser &Parser = getParser();
2575 Parser.Lex(); // Eat the % token.
2576 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2577 if (Tok.isNot(AsmToken::Identifier))
2580 std::string Str = Tok.getIdentifier();
2582 Parser.Lex(); // Eat the identifier.
2583 // Now make an expression from the rest of the operand.
2584 const MCExpr *IdVal;
2587 if (getLexer().getKind() == AsmToken::LParen) {
2589 Parser.Lex(); // Eat the '(' token.
2590 if (getLexer().getKind() == AsmToken::Percent) {
2591 Parser.Lex(); // Eat the % token.
2592 const AsmToken &nextTok = Parser.getTok();
2593 if (nextTok.isNot(AsmToken::Identifier))
2596 Str += nextTok.getIdentifier();
2597 Parser.Lex(); // Eat the identifier.
2598 if (getLexer().getKind() != AsmToken::LParen)
2603 if (getParser().parseParenExpression(IdVal, EndLoc))
2606 while (getLexer().getKind() == AsmToken::RParen)
2607 Parser.Lex(); // Eat the ')' token.
2610 return true; // Parenthesis must follow the relocation operand.
2612 Res = evaluateRelocExpr(IdVal, Str);
2616 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2618 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2619 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2620 if (ResTy == MatchOperand_Success) {
2621 assert(Operands.size() == 1);
2622 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2623 StartLoc = Operand.getStartLoc();
2624 EndLoc = Operand.getEndLoc();
2626 // AFAIK, we only support numeric registers and named GPR's in CFI
2628 // Don't worry about eating tokens before failing. Using an unrecognised
2629 // register is a parse error.
2630 if (Operand.isGPRAsmReg()) {
2631 // Resolve to GPR32 or GPR64 appropriately.
2632 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2635 return (RegNo == (unsigned)-1);
2638 assert(Operands.size() == 0);
2639 return (RegNo == (unsigned)-1);
2642 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2643 MCAsmParser &Parser = getParser();
2647 while (getLexer().getKind() == AsmToken::LParen)
2650 switch (getLexer().getKind()) {
2653 case AsmToken::Identifier:
2654 case AsmToken::LParen:
2655 case AsmToken::Integer:
2656 case AsmToken::Minus:
2657 case AsmToken::Plus:
2659 Result = getParser().parseParenExpression(Res, S);
2661 Result = (getParser().parseExpression(Res));
2662 while (getLexer().getKind() == AsmToken::RParen)
2665 case AsmToken::Percent:
2666 Result = parseRelocOperand(Res);
2671 MipsAsmParser::OperandMatchResultTy
2672 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2673 MCAsmParser &Parser = getParser();
2674 DEBUG(dbgs() << "parseMemOperand\n");
2675 const MCExpr *IdVal = nullptr;
2677 bool isParenExpr = false;
2678 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2679 // First operand is the offset.
2680 S = Parser.getTok().getLoc();
2682 if (getLexer().getKind() == AsmToken::LParen) {
2687 if (getLexer().getKind() != AsmToken::Dollar) {
2688 if (parseMemOffset(IdVal, isParenExpr))
2689 return MatchOperand_ParseFail;
2691 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2692 if (Tok.isNot(AsmToken::LParen)) {
2693 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2694 if (Mnemonic.getToken() == "la") {
2696 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2697 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2698 return MatchOperand_Success;
2700 if (Tok.is(AsmToken::EndOfStatement)) {
2702 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2704 // Zero register assumed, add a memory operand with ZERO as its base.
2705 // "Base" will be managed by k_Memory.
2706 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2709 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2710 return MatchOperand_Success;
2712 Error(Parser.getTok().getLoc(), "'(' expected");
2713 return MatchOperand_ParseFail;
2716 Parser.Lex(); // Eat the '(' token.
2719 Res = parseAnyRegister(Operands);
2720 if (Res != MatchOperand_Success)
2723 if (Parser.getTok().isNot(AsmToken::RParen)) {
2724 Error(Parser.getTok().getLoc(), "')' expected");
2725 return MatchOperand_ParseFail;
2728 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2730 Parser.Lex(); // Eat the ')' token.
2733 IdVal = MCConstantExpr::Create(0, getContext());
2735 // Replace the register operand with the memory operand.
2736 std::unique_ptr<MipsOperand> op(
2737 static_cast<MipsOperand *>(Operands.back().release()));
2738 // Remove the register from the operands.
2739 // "op" will be managed by k_Memory.
2740 Operands.pop_back();
2741 // Add the memory operand.
2742 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2744 if (IdVal->EvaluateAsAbsolute(Imm))
2745 IdVal = MCConstantExpr::Create(Imm, getContext());
2746 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2747 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2751 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2752 return MatchOperand_Success;
2755 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2756 MCAsmParser &Parser = getParser();
2757 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2759 SMLoc S = Parser.getTok().getLoc();
2761 if (Sym->isVariable())
2762 Expr = Sym->getVariableValue();
2765 if (Expr->getKind() == MCExpr::SymbolRef) {
2766 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2767 StringRef DefSymbol = Ref->getSymbol().getName();
2768 if (DefSymbol.startswith("$")) {
2769 OperandMatchResultTy ResTy =
2770 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2771 if (ResTy == MatchOperand_Success) {
2774 } else if (ResTy == MatchOperand_ParseFail)
2775 llvm_unreachable("Should never ParseFail");
2778 } else if (Expr->getKind() == MCExpr::Constant) {
2780 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2782 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2789 MipsAsmParser::OperandMatchResultTy
2790 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2791 StringRef Identifier,
2793 int Index = matchCPURegisterName(Identifier);
2795 Operands.push_back(MipsOperand::createGPRReg(
2796 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2797 return MatchOperand_Success;
2800 Index = matchHWRegsRegisterName(Identifier);
2802 Operands.push_back(MipsOperand::createHWRegsReg(
2803 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2804 return MatchOperand_Success;
2807 Index = matchFPURegisterName(Identifier);
2809 Operands.push_back(MipsOperand::createFGRReg(
2810 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2811 return MatchOperand_Success;
2814 Index = matchFCCRegisterName(Identifier);
2816 Operands.push_back(MipsOperand::createFCCReg(
2817 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2818 return MatchOperand_Success;
2821 Index = matchACRegisterName(Identifier);
2823 Operands.push_back(MipsOperand::createACCReg(
2824 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2825 return MatchOperand_Success;
2828 Index = matchMSA128RegisterName(Identifier);
2830 Operands.push_back(MipsOperand::createMSA128Reg(
2831 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2832 return MatchOperand_Success;
2835 Index = matchMSA128CtrlRegisterName(Identifier);
2837 Operands.push_back(MipsOperand::createMSACtrlReg(
2838 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2839 return MatchOperand_Success;
2842 return MatchOperand_NoMatch;
2845 MipsAsmParser::OperandMatchResultTy
2846 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2847 MCAsmParser &Parser = getParser();
2848 auto Token = Parser.getLexer().peekTok(false);
2850 if (Token.is(AsmToken::Identifier)) {
2851 DEBUG(dbgs() << ".. identifier\n");
2852 StringRef Identifier = Token.getIdentifier();
2853 OperandMatchResultTy ResTy =
2854 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2856 } else if (Token.is(AsmToken::Integer)) {
2857 DEBUG(dbgs() << ".. integer\n");
2858 Operands.push_back(MipsOperand::createNumericReg(
2859 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2861 return MatchOperand_Success;
2864 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2866 return MatchOperand_NoMatch;
2869 MipsAsmParser::OperandMatchResultTy
2870 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2871 MCAsmParser &Parser = getParser();
2872 DEBUG(dbgs() << "parseAnyRegister\n");
2874 auto Token = Parser.getTok();
2876 SMLoc S = Token.getLoc();
2878 if (Token.isNot(AsmToken::Dollar)) {
2879 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2880 if (Token.is(AsmToken::Identifier)) {
2881 if (searchSymbolAlias(Operands))
2882 return MatchOperand_Success;
2884 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2885 return MatchOperand_NoMatch;
2887 DEBUG(dbgs() << ".. $\n");
2889 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2890 if (ResTy == MatchOperand_Success) {
2892 Parser.Lex(); // identifier
2897 MipsAsmParser::OperandMatchResultTy
2898 MipsAsmParser::parseImm(OperandVector &Operands) {
2899 MCAsmParser &Parser = getParser();
2900 switch (getLexer().getKind()) {
2902 return MatchOperand_NoMatch;
2903 case AsmToken::LParen:
2904 case AsmToken::Minus:
2905 case AsmToken::Plus:
2906 case AsmToken::Integer:
2907 case AsmToken::Tilde:
2908 case AsmToken::String:
2912 const MCExpr *IdVal;
2913 SMLoc S = Parser.getTok().getLoc();
2914 if (getParser().parseExpression(IdVal))
2915 return MatchOperand_ParseFail;
2917 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2918 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2919 return MatchOperand_Success;
2922 MipsAsmParser::OperandMatchResultTy
2923 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2924 MCAsmParser &Parser = getParser();
2925 DEBUG(dbgs() << "parseJumpTarget\n");
2927 SMLoc S = getLexer().getLoc();
2929 // Integers and expressions are acceptable
2930 OperandMatchResultTy ResTy = parseImm(Operands);
2931 if (ResTy != MatchOperand_NoMatch)
2934 // Registers are a valid target and have priority over symbols.
2935 ResTy = parseAnyRegister(Operands);
2936 if (ResTy != MatchOperand_NoMatch)
2939 const MCExpr *Expr = nullptr;
2940 if (Parser.parseExpression(Expr)) {
2941 // We have no way of knowing if a symbol was consumed so we must ParseFail
2942 return MatchOperand_ParseFail;
2945 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2946 return MatchOperand_Success;
2949 MipsAsmParser::OperandMatchResultTy
2950 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2951 MCAsmParser &Parser = getParser();
2952 const MCExpr *IdVal;
2953 // If the first token is '$' we may have register operand.
2954 if (Parser.getTok().is(AsmToken::Dollar))
2955 return MatchOperand_NoMatch;
2956 SMLoc S = Parser.getTok().getLoc();
2957 if (getParser().parseExpression(IdVal))
2958 return MatchOperand_ParseFail;
2959 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2960 assert(MCE && "Unexpected MCExpr type.");
2961 int64_t Val = MCE->getValue();
2962 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2963 Operands.push_back(MipsOperand::CreateImm(
2964 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2965 return MatchOperand_Success;
2968 MipsAsmParser::OperandMatchResultTy
2969 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2970 MCAsmParser &Parser = getParser();
2971 switch (getLexer().getKind()) {
2973 return MatchOperand_NoMatch;
2974 case AsmToken::LParen:
2975 case AsmToken::Plus:
2976 case AsmToken::Minus:
2977 case AsmToken::Integer:
2982 SMLoc S = Parser.getTok().getLoc();
2984 if (getParser().parseExpression(Expr))
2985 return MatchOperand_ParseFail;
2988 if (!Expr->EvaluateAsAbsolute(Val)) {
2989 Error(S, "expected immediate value");
2990 return MatchOperand_ParseFail;
2993 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2994 // and because the CPU always adds one to the immediate field, the allowed
2995 // range becomes 1..4. We'll only check the range here and will deal
2996 // with the addition/subtraction when actually decoding/encoding
2998 if (Val < 1 || Val > 4) {
2999 Error(S, "immediate not in range (1..4)");
3000 return MatchOperand_ParseFail;
3004 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
3005 return MatchOperand_Success;
3008 MipsAsmParser::OperandMatchResultTy
3009 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
3010 MCAsmParser &Parser = getParser();
3011 SmallVector<unsigned, 10> Regs;
3013 unsigned PrevReg = Mips::NoRegister;
3014 bool RegRange = false;
3015 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3017 if (Parser.getTok().isNot(AsmToken::Dollar))
3018 return MatchOperand_ParseFail;
3020 SMLoc S = Parser.getTok().getLoc();
3021 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
3022 SMLoc E = getLexer().getLoc();
3023 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
3024 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
3026 // Remove last register operand because registers from register range
3027 // should be inserted first.
3028 if (RegNo == Mips::RA) {
3029 Regs.push_back(RegNo);
3031 unsigned TmpReg = PrevReg + 1;
3032 while (TmpReg <= RegNo) {
3033 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
3034 Error(E, "invalid register operand");
3035 return MatchOperand_ParseFail;
3039 Regs.push_back(TmpReg++);
3045 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
3046 (RegNo != Mips::RA)) {
3047 Error(E, "$16 or $31 expected");
3048 return MatchOperand_ParseFail;
3049 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
3050 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3051 Error(E, "invalid register operand");
3052 return MatchOperand_ParseFail;
3053 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
3054 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
3055 Error(E, "consecutive register numbers expected");
3056 return MatchOperand_ParseFail;
3059 Regs.push_back(RegNo);
3062 if (Parser.getTok().is(AsmToken::Minus))
3065 if (!Parser.getTok().isNot(AsmToken::Minus) &&
3066 !Parser.getTok().isNot(AsmToken::Comma)) {
3067 Error(E, "',' or '-' expected");
3068 return MatchOperand_ParseFail;
3071 Lex(); // Consume comma or minus
3072 if (Parser.getTok().isNot(AsmToken::Dollar))
3078 SMLoc E = Parser.getTok().getLoc();
3079 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3080 parseMemOperand(Operands);
3081 return MatchOperand_Success;
3084 MipsAsmParser::OperandMatchResultTy
3085 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
3086 MCAsmParser &Parser = getParser();
3088 SMLoc S = Parser.getTok().getLoc();
3089 if (parseAnyRegister(Operands) != MatchOperand_Success)
3090 return MatchOperand_ParseFail;
3092 SMLoc E = Parser.getTok().getLoc();
3093 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
3094 unsigned Reg = Op.getGPR32Reg();
3095 Operands.pop_back();
3096 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
3097 return MatchOperand_Success;
3100 MipsAsmParser::OperandMatchResultTy
3101 MipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
3102 MCAsmParser &Parser = getParser();
3103 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
3104 SmallVector<unsigned, 10> Regs;
3106 if (Parser.getTok().isNot(AsmToken::Dollar))
3107 return MatchOperand_ParseFail;
3109 SMLoc S = Parser.getTok().getLoc();
3111 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3112 return MatchOperand_ParseFail;
3114 MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3115 unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3116 Regs.push_back(RegNo);
3118 SMLoc E = Parser.getTok().getLoc();
3119 if (Parser.getTok().isNot(AsmToken::Comma)) {
3120 Error(E, "',' expected");
3121 return MatchOperand_ParseFail;
3127 if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
3128 return MatchOperand_ParseFail;
3130 Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
3131 RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
3132 Regs.push_back(RegNo);
3134 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
3136 return MatchOperand_Success;
3139 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
3141 MCSymbolRefExpr::VariantKind VK =
3142 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
3143 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
3144 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
3145 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
3146 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
3147 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
3148 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
3149 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
3150 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
3151 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
3152 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
3153 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
3154 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
3155 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
3156 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
3157 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
3158 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
3159 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
3160 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
3161 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
3162 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
3163 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
3164 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
3165 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
3166 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
3167 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
3168 .Default(MCSymbolRefExpr::VK_None);
3170 assert(VK != MCSymbolRefExpr::VK_None);
3175 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
3177 /// ::= '(', register, ')'
3178 /// handle it before we iterate so we don't get tripped up by the lack of
3180 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
3181 MCAsmParser &Parser = getParser();
3182 if (getLexer().is(AsmToken::LParen)) {
3184 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
3186 if (parseOperand(Operands, Name)) {
3187 SMLoc Loc = getLexer().getLoc();
3188 Parser.eatToEndOfStatement();
3189 return Error(Loc, "unexpected token in argument list");
3191 if (Parser.getTok().isNot(AsmToken::RParen)) {
3192 SMLoc Loc = getLexer().getLoc();
3193 Parser.eatToEndOfStatement();
3194 return Error(Loc, "unexpected token, expected ')'");
3197 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
3203 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
3204 /// either one of these.
3205 /// ::= '[', register, ']'
3206 /// ::= '[', integer, ']'
3207 /// handle it before we iterate so we don't get tripped up by the lack of
3209 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
3210 OperandVector &Operands) {
3211 MCAsmParser &Parser = getParser();
3212 if (getLexer().is(AsmToken::LBrac)) {
3214 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3216 if (parseOperand(Operands, Name)) {
3217 SMLoc Loc = getLexer().getLoc();
3218 Parser.eatToEndOfStatement();
3219 return Error(Loc, "unexpected token in argument list");
3221 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3222 SMLoc Loc = getLexer().getLoc();
3223 Parser.eatToEndOfStatement();
3224 return Error(Loc, "unexpected token, expected ']'");
3227 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3233 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3234 SMLoc NameLoc, OperandVector &Operands) {
3235 MCAsmParser &Parser = getParser();
3236 DEBUG(dbgs() << "ParseInstruction\n");
3238 // We have reached first instruction, module directive are now forbidden.
3239 getTargetStreamer().forbidModuleDirective();
3241 // Check if we have valid mnemonic
3242 if (!mnemonicIsValid(Name, 0)) {
3243 Parser.eatToEndOfStatement();
3244 return Error(NameLoc, "unknown instruction");
3246 // First operand in MCInst is instruction mnemonic.
3247 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3249 // Read the remaining operands.
3250 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3251 // Read the first operand.
3252 if (parseOperand(Operands, Name)) {
3253 SMLoc Loc = getLexer().getLoc();
3254 Parser.eatToEndOfStatement();
3255 return Error(Loc, "unexpected token in argument list");
3257 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3259 // AFAIK, parenthesis suffixes are never on the first operand
3261 while (getLexer().is(AsmToken::Comma)) {
3262 Parser.Lex(); // Eat the comma.
3263 // Parse and remember the operand.
3264 if (parseOperand(Operands, Name)) {
3265 SMLoc Loc = getLexer().getLoc();
3266 Parser.eatToEndOfStatement();
3267 return Error(Loc, "unexpected token in argument list");
3269 // Parse bracket and parenthesis suffixes before we iterate
3270 if (getLexer().is(AsmToken::LBrac)) {
3271 if (parseBracketSuffix(Name, Operands))
3273 } else if (getLexer().is(AsmToken::LParen) &&
3274 parseParenSuffix(Name, Operands))
3278 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3279 SMLoc Loc = getLexer().getLoc();
3280 Parser.eatToEndOfStatement();
3281 return Error(Loc, "unexpected token in argument list");
3283 Parser.Lex(); // Consume the EndOfStatement.
3287 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3288 MCAsmParser &Parser = getParser();
3289 SMLoc Loc = getLexer().getLoc();
3290 Parser.eatToEndOfStatement();
3291 return Error(Loc, ErrorMsg);
3294 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3295 return Error(Loc, ErrorMsg);
3298 bool MipsAsmParser::parseSetNoAtDirective() {
3299 MCAsmParser &Parser = getParser();
3300 // Line should look like: ".set noat".
3302 // Set the $at register to $0.
3303 AssemblerOptions.back()->setATReg(0);
3305 Parser.Lex(); // Eat "noat".
3307 // If this is not the end of the statement, report an error.
3308 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3309 reportParseError("unexpected token, expected end of statement");
3313 getTargetStreamer().emitDirectiveSetNoAt();
3314 Parser.Lex(); // Consume the EndOfStatement.
3318 bool MipsAsmParser::parseSetAtDirective() {
3319 // Line can be: ".set at", which sets $at to $1
3320 // or ".set at=$reg", which sets $at to $reg.
3321 MCAsmParser &Parser = getParser();
3322 Parser.Lex(); // Eat "at".
3324 if (getLexer().is(AsmToken::EndOfStatement)) {
3325 // No register was specified, so we set $at to $1.
3326 AssemblerOptions.back()->setATReg(1);
3328 getTargetStreamer().emitDirectiveSetAt();
3329 Parser.Lex(); // Consume the EndOfStatement.
3333 if (getLexer().isNot(AsmToken::Equal)) {
3334 reportParseError("unexpected token, expected equals sign");
3337 Parser.Lex(); // Eat "=".
3339 if (getLexer().isNot(AsmToken::Dollar)) {
3340 if (getLexer().is(AsmToken::EndOfStatement)) {
3341 reportParseError("no register specified");
3344 reportParseError("unexpected token, expected dollar sign '$'");
3348 Parser.Lex(); // Eat "$".
3350 // Find out what "reg" is.
3352 const AsmToken &Reg = Parser.getTok();
3353 if (Reg.is(AsmToken::Identifier)) {
3354 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3355 } else if (Reg.is(AsmToken::Integer)) {
3356 AtRegNo = Reg.getIntVal();
3358 reportParseError("unexpected token, expected identifier or integer");
3362 // Check if $reg is a valid register. If it is, set $at to $reg.
3363 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3364 reportParseError("invalid register");
3367 Parser.Lex(); // Eat "reg".
3369 // If this is not the end of the statement, report an error.
3370 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3371 reportParseError("unexpected token, expected end of statement");
3375 getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
3377 Parser.Lex(); // Consume the EndOfStatement.
3381 bool MipsAsmParser::parseSetReorderDirective() {
3382 MCAsmParser &Parser = getParser();
3384 // If this is not the end of the statement, report an error.
3385 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3386 reportParseError("unexpected token, expected end of statement");
3389 AssemblerOptions.back()->setReorder();
3390 getTargetStreamer().emitDirectiveSetReorder();
3391 Parser.Lex(); // Consume the EndOfStatement.
3395 bool MipsAsmParser::parseSetNoReorderDirective() {
3396 MCAsmParser &Parser = getParser();
3398 // If this is not the end of the statement, report an error.
3399 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3400 reportParseError("unexpected token, expected end of statement");
3403 AssemblerOptions.back()->setNoReorder();
3404 getTargetStreamer().emitDirectiveSetNoReorder();
3405 Parser.Lex(); // Consume the EndOfStatement.
3409 bool MipsAsmParser::parseSetMacroDirective() {
3410 MCAsmParser &Parser = getParser();
3412 // If this is not the end of the statement, report an error.
3413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3414 reportParseError("unexpected token, expected end of statement");
3417 AssemblerOptions.back()->setMacro();
3418 Parser.Lex(); // Consume the EndOfStatement.
3422 bool MipsAsmParser::parseSetNoMacroDirective() {
3423 MCAsmParser &Parser = getParser();
3425 // If this is not the end of the statement, report an error.
3426 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3427 reportParseError("unexpected token, expected end of statement");
3430 if (AssemblerOptions.back()->isReorder()) {
3431 reportParseError("`noreorder' must be set before `nomacro'");
3434 AssemblerOptions.back()->setNoMacro();
3435 Parser.Lex(); // Consume the EndOfStatement.
3439 bool MipsAsmParser::parseSetMsaDirective() {
3440 MCAsmParser &Parser = getParser();
3443 // If this is not the end of the statement, report an error.
3444 if (getLexer().isNot(AsmToken::EndOfStatement))
3445 return reportParseError("unexpected token, expected end of statement");
3447 setFeatureBits(Mips::FeatureMSA, "msa");
3448 getTargetStreamer().emitDirectiveSetMsa();
3452 bool MipsAsmParser::parseSetNoMsaDirective() {
3453 MCAsmParser &Parser = getParser();
3456 // If this is not the end of the statement, report an error.
3457 if (getLexer().isNot(AsmToken::EndOfStatement))
3458 return reportParseError("unexpected token, expected end of statement");
3460 clearFeatureBits(Mips::FeatureMSA, "msa");
3461 getTargetStreamer().emitDirectiveSetNoMsa();
3465 bool MipsAsmParser::parseSetNoDspDirective() {
3466 MCAsmParser &Parser = getParser();
3467 Parser.Lex(); // Eat "nodsp".
3469 // If this is not the end of the statement, report an error.
3470 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3471 reportParseError("unexpected token, expected end of statement");
3475 clearFeatureBits(Mips::FeatureDSP, "dsp");
3476 getTargetStreamer().emitDirectiveSetNoDsp();
3480 bool MipsAsmParser::parseSetMips16Directive() {
3481 MCAsmParser &Parser = getParser();
3482 Parser.Lex(); // Eat "mips16".
3484 // If this is not the end of the statement, report an error.
3485 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3486 reportParseError("unexpected token, expected end of statement");
3490 setFeatureBits(Mips::FeatureMips16, "mips16");
3491 getTargetStreamer().emitDirectiveSetMips16();
3492 Parser.Lex(); // Consume the EndOfStatement.
3496 bool MipsAsmParser::parseSetNoMips16Directive() {
3497 MCAsmParser &Parser = getParser();
3498 Parser.Lex(); // Eat "nomips16".
3500 // If this is not the end of the statement, report an error.
3501 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3502 reportParseError("unexpected token, expected end of statement");
3506 clearFeatureBits(Mips::FeatureMips16, "mips16");
3507 getTargetStreamer().emitDirectiveSetNoMips16();
3508 Parser.Lex(); // Consume the EndOfStatement.
3512 bool MipsAsmParser::parseSetFpDirective() {
3513 MCAsmParser &Parser = getParser();
3514 MipsABIFlagsSection::FpABIKind FpAbiVal;
3515 // Line can be: .set fp=32
3518 Parser.Lex(); // Eat fp token
3519 AsmToken Tok = Parser.getTok();
3520 if (Tok.isNot(AsmToken::Equal)) {
3521 reportParseError("unexpected token, expected equals sign '='");
3524 Parser.Lex(); // Eat '=' token.
3525 Tok = Parser.getTok();
3527 if (!parseFpABIValue(FpAbiVal, ".set"))
3530 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3531 reportParseError("unexpected token, expected end of statement");
3534 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3535 Parser.Lex(); // Consume the EndOfStatement.
3539 bool MipsAsmParser::parseSetPopDirective() {
3540 MCAsmParser &Parser = getParser();
3541 SMLoc Loc = getLexer().getLoc();
3544 if (getLexer().isNot(AsmToken::EndOfStatement))
3545 return reportParseError("unexpected token, expected end of statement");
3547 // Always keep an element on the options "stack" to prevent the user
3548 // from changing the initial options. This is how we remember them.
3549 if (AssemblerOptions.size() == 2)
3550 return reportParseError(Loc, ".set pop with no .set push");
3552 AssemblerOptions.pop_back();
3553 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3555 getTargetStreamer().emitDirectiveSetPop();
3559 bool MipsAsmParser::parseSetPushDirective() {
3560 MCAsmParser &Parser = getParser();
3562 if (getLexer().isNot(AsmToken::EndOfStatement))
3563 return reportParseError("unexpected token, expected end of statement");
3565 // Create a copy of the current assembler options environment and push it.
3566 AssemblerOptions.push_back(
3567 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3569 getTargetStreamer().emitDirectiveSetPush();
3573 bool MipsAsmParser::parseSetAssignment() {
3575 const MCExpr *Value;
3576 MCAsmParser &Parser = getParser();
3578 if (Parser.parseIdentifier(Name))
3579 reportParseError("expected identifier after .set");
3581 if (getLexer().isNot(AsmToken::Comma))
3582 return reportParseError("unexpected token, expected comma");
3585 if (Parser.parseExpression(Value))
3586 return reportParseError("expected valid expression after comma");
3588 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3589 Sym->setVariableValue(Value);
3594 bool MipsAsmParser::parseSetMips0Directive() {
3595 MCAsmParser &Parser = getParser();
3597 if (getLexer().isNot(AsmToken::EndOfStatement))
3598 return reportParseError("unexpected token, expected end of statement");
3600 // Reset assembler options to their initial values.
3601 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3602 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3604 getTargetStreamer().emitDirectiveSetMips0();
3608 bool MipsAsmParser::parseSetArchDirective() {
3609 MCAsmParser &Parser = getParser();
3611 if (getLexer().isNot(AsmToken::Equal))
3612 return reportParseError("unexpected token, expected equals sign");
3616 if (Parser.parseIdentifier(Arch))
3617 return reportParseError("expected arch identifier");
3619 StringRef ArchFeatureName =
3620 StringSwitch<StringRef>(Arch)
3621 .Case("mips1", "mips1")
3622 .Case("mips2", "mips2")
3623 .Case("mips3", "mips3")
3624 .Case("mips4", "mips4")
3625 .Case("mips5", "mips5")
3626 .Case("mips32", "mips32")
3627 .Case("mips32r2", "mips32r2")
3628 .Case("mips32r3", "mips32r3")
3629 .Case("mips32r5", "mips32r5")
3630 .Case("mips32r6", "mips32r6")
3631 .Case("mips64", "mips64")
3632 .Case("mips64r2", "mips64r2")
3633 .Case("mips64r3", "mips64r3")
3634 .Case("mips64r5", "mips64r5")
3635 .Case("mips64r6", "mips64r6")
3636 .Case("cnmips", "cnmips")
3637 .Case("r4000", "mips3") // This is an implementation of Mips3.
3640 if (ArchFeatureName.empty())
3641 return reportParseError("unsupported architecture");
3643 selectArch(ArchFeatureName);
3644 getTargetStreamer().emitDirectiveSetArch(Arch);
3648 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3649 MCAsmParser &Parser = getParser();
3651 if (getLexer().isNot(AsmToken::EndOfStatement))
3652 return reportParseError("unexpected token, expected end of statement");
3656 llvm_unreachable("Unimplemented feature");
3657 case Mips::FeatureDSP:
3658 setFeatureBits(Mips::FeatureDSP, "dsp");
3659 getTargetStreamer().emitDirectiveSetDsp();
3661 case Mips::FeatureMicroMips:
3662 getTargetStreamer().emitDirectiveSetMicroMips();
3664 case Mips::FeatureMips1:
3665 selectArch("mips1");
3666 getTargetStreamer().emitDirectiveSetMips1();
3668 case Mips::FeatureMips2:
3669 selectArch("mips2");
3670 getTargetStreamer().emitDirectiveSetMips2();
3672 case Mips::FeatureMips3:
3673 selectArch("mips3");
3674 getTargetStreamer().emitDirectiveSetMips3();
3676 case Mips::FeatureMips4:
3677 selectArch("mips4");
3678 getTargetStreamer().emitDirectiveSetMips4();
3680 case Mips::FeatureMips5:
3681 selectArch("mips5");
3682 getTargetStreamer().emitDirectiveSetMips5();
3684 case Mips::FeatureMips32:
3685 selectArch("mips32");
3686 getTargetStreamer().emitDirectiveSetMips32();
3688 case Mips::FeatureMips32r2:
3689 selectArch("mips32r2");
3690 getTargetStreamer().emitDirectiveSetMips32R2();
3692 case Mips::FeatureMips32r3:
3693 selectArch("mips32r3");
3694 getTargetStreamer().emitDirectiveSetMips32R3();
3696 case Mips::FeatureMips32r5:
3697 selectArch("mips32r5");
3698 getTargetStreamer().emitDirectiveSetMips32R5();
3700 case Mips::FeatureMips32r6:
3701 selectArch("mips32r6");
3702 getTargetStreamer().emitDirectiveSetMips32R6();
3704 case Mips::FeatureMips64:
3705 selectArch("mips64");
3706 getTargetStreamer().emitDirectiveSetMips64();
3708 case Mips::FeatureMips64r2:
3709 selectArch("mips64r2");
3710 getTargetStreamer().emitDirectiveSetMips64R2();
3712 case Mips::FeatureMips64r3:
3713 selectArch("mips64r3");
3714 getTargetStreamer().emitDirectiveSetMips64R3();
3716 case Mips::FeatureMips64r5:
3717 selectArch("mips64r5");
3718 getTargetStreamer().emitDirectiveSetMips64R5();
3720 case Mips::FeatureMips64r6:
3721 selectArch("mips64r6");
3722 getTargetStreamer().emitDirectiveSetMips64R6();
3728 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3729 MCAsmParser &Parser = getParser();
3730 if (getLexer().isNot(AsmToken::Comma)) {
3731 SMLoc Loc = getLexer().getLoc();
3732 Parser.eatToEndOfStatement();
3733 return Error(Loc, ErrorStr);
3736 Parser.Lex(); // Eat the comma.
3740 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3741 if (AssemblerOptions.back()->isReorder())
3742 Warning(Loc, ".cpload should be inside a noreorder section");
3744 if (inMips16Mode()) {
3745 reportParseError(".cpload is not supported in Mips16 mode");
3749 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3750 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3751 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3752 reportParseError("expected register containing function address");
3756 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3757 if (!RegOpnd.isGPRAsmReg()) {
3758 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3762 // If this is not the end of the statement, report an error.
3763 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3764 reportParseError("unexpected token, expected end of statement");
3768 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3772 bool MipsAsmParser::parseDirectiveCPSetup() {
3773 MCAsmParser &Parser = getParser();
3776 bool SaveIsReg = true;
3778 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3779 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3780 if (ResTy == MatchOperand_NoMatch) {
3781 reportParseError("expected register containing function address");
3782 Parser.eatToEndOfStatement();
3786 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3787 if (!FuncRegOpnd.isGPRAsmReg()) {
3788 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3789 Parser.eatToEndOfStatement();
3793 FuncReg = FuncRegOpnd.getGPR32Reg();
3796 if (!eatComma("unexpected token, expected comma"))
3799 ResTy = parseAnyRegister(TmpReg);
3800 if (ResTy == MatchOperand_NoMatch) {
3801 const AsmToken &Tok = Parser.getTok();
3802 if (Tok.is(AsmToken::Integer)) {
3803 Save = Tok.getIntVal();
3807 reportParseError("expected save register or stack offset");
3808 Parser.eatToEndOfStatement();
3812 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3813 if (!SaveOpnd.isGPRAsmReg()) {
3814 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3815 Parser.eatToEndOfStatement();
3818 Save = SaveOpnd.getGPR32Reg();
3821 if (!eatComma("unexpected token, expected comma"))
3825 if (Parser.parseExpression(Expr)) {
3826 reportParseError("expected expression");
3830 if (Expr->getKind() != MCExpr::SymbolRef) {
3831 reportParseError("expected symbol");
3834 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
3836 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
3841 bool MipsAsmParser::parseDirectiveNaN() {
3842 MCAsmParser &Parser = getParser();
3843 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3844 const AsmToken &Tok = Parser.getTok();
3846 if (Tok.getString() == "2008") {
3848 getTargetStreamer().emitDirectiveNaN2008();
3850 } else if (Tok.getString() == "legacy") {
3852 getTargetStreamer().emitDirectiveNaNLegacy();
3856 // If we don't recognize the option passed to the .nan
3857 // directive (e.g. no option or unknown option), emit an error.
3858 reportParseError("invalid option in .nan directive");
3862 bool MipsAsmParser::parseDirectiveSet() {
3863 MCAsmParser &Parser = getParser();
3864 // Get the next token.
3865 const AsmToken &Tok = Parser.getTok();
3867 if (Tok.getString() == "noat") {
3868 return parseSetNoAtDirective();
3869 } else if (Tok.getString() == "at") {
3870 return parseSetAtDirective();
3871 } else if (Tok.getString() == "arch") {
3872 return parseSetArchDirective();
3873 } else if (Tok.getString() == "fp") {
3874 return parseSetFpDirective();
3875 } else if (Tok.getString() == "pop") {
3876 return parseSetPopDirective();
3877 } else if (Tok.getString() == "push") {
3878 return parseSetPushDirective();
3879 } else if (Tok.getString() == "reorder") {
3880 return parseSetReorderDirective();
3881 } else if (Tok.getString() == "noreorder") {
3882 return parseSetNoReorderDirective();
3883 } else if (Tok.getString() == "macro") {
3884 return parseSetMacroDirective();
3885 } else if (Tok.getString() == "nomacro") {
3886 return parseSetNoMacroDirective();
3887 } else if (Tok.getString() == "mips16") {
3888 return parseSetMips16Directive();
3889 } else if (Tok.getString() == "nomips16") {
3890 return parseSetNoMips16Directive();
3891 } else if (Tok.getString() == "nomicromips") {
3892 getTargetStreamer().emitDirectiveSetNoMicroMips();
3893 Parser.eatToEndOfStatement();
3895 } else if (Tok.getString() == "micromips") {
3896 return parseSetFeature(Mips::FeatureMicroMips);
3897 } else if (Tok.getString() == "mips0") {
3898 return parseSetMips0Directive();
3899 } else if (Tok.getString() == "mips1") {
3900 return parseSetFeature(Mips::FeatureMips1);
3901 } else if (Tok.getString() == "mips2") {
3902 return parseSetFeature(Mips::FeatureMips2);
3903 } else if (Tok.getString() == "mips3") {
3904 return parseSetFeature(Mips::FeatureMips3);
3905 } else if (Tok.getString() == "mips4") {
3906 return parseSetFeature(Mips::FeatureMips4);
3907 } else if (Tok.getString() == "mips5") {
3908 return parseSetFeature(Mips::FeatureMips5);
3909 } else if (Tok.getString() == "mips32") {
3910 return parseSetFeature(Mips::FeatureMips32);
3911 } else if (Tok.getString() == "mips32r2") {
3912 return parseSetFeature(Mips::FeatureMips32r2);
3913 } else if (Tok.getString() == "mips32r3") {
3914 return parseSetFeature(Mips::FeatureMips32r3);
3915 } else if (Tok.getString() == "mips32r5") {
3916 return parseSetFeature(Mips::FeatureMips32r5);
3917 } else if (Tok.getString() == "mips32r6") {
3918 return parseSetFeature(Mips::FeatureMips32r6);
3919 } else if (Tok.getString() == "mips64") {
3920 return parseSetFeature(Mips::FeatureMips64);
3921 } else if (Tok.getString() == "mips64r2") {
3922 return parseSetFeature(Mips::FeatureMips64r2);
3923 } else if (Tok.getString() == "mips64r3") {
3924 return parseSetFeature(Mips::FeatureMips64r3);
3925 } else if (Tok.getString() == "mips64r5") {
3926 return parseSetFeature(Mips::FeatureMips64r5);
3927 } else if (Tok.getString() == "mips64r6") {
3928 return parseSetFeature(Mips::FeatureMips64r6);
3929 } else if (Tok.getString() == "dsp") {
3930 return parseSetFeature(Mips::FeatureDSP);
3931 } else if (Tok.getString() == "nodsp") {
3932 return parseSetNoDspDirective();
3933 } else if (Tok.getString() == "msa") {
3934 return parseSetMsaDirective();
3935 } else if (Tok.getString() == "nomsa") {
3936 return parseSetNoMsaDirective();
3938 // It is just an identifier, look for an assignment.
3939 parseSetAssignment();
3946 /// parseDataDirective
3947 /// ::= .word [ expression (, expression)* ]
3948 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3949 MCAsmParser &Parser = getParser();
3950 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3952 const MCExpr *Value;
3953 if (getParser().parseExpression(Value))
3956 getParser().getStreamer().EmitValue(Value, Size);
3958 if (getLexer().is(AsmToken::EndOfStatement))
3961 if (getLexer().isNot(AsmToken::Comma))
3962 return Error(L, "unexpected token, expected comma");
3971 /// parseDirectiveGpWord
3972 /// ::= .gpword local_sym
3973 bool MipsAsmParser::parseDirectiveGpWord() {
3974 MCAsmParser &Parser = getParser();
3975 const MCExpr *Value;
3976 // EmitGPRel32Value requires an expression, so we are using base class
3977 // method to evaluate the expression.
3978 if (getParser().parseExpression(Value))
3980 getParser().getStreamer().EmitGPRel32Value(Value);
3982 if (getLexer().isNot(AsmToken::EndOfStatement))
3983 return Error(getLexer().getLoc(),
3984 "unexpected token, expected end of statement");
3985 Parser.Lex(); // Eat EndOfStatement token.
3989 /// parseDirectiveGpDWord
3990 /// ::= .gpdword local_sym
3991 bool MipsAsmParser::parseDirectiveGpDWord() {
3992 MCAsmParser &Parser = getParser();
3993 const MCExpr *Value;
3994 // EmitGPRel64Value requires an expression, so we are using base class
3995 // method to evaluate the expression.
3996 if (getParser().parseExpression(Value))
3998 getParser().getStreamer().EmitGPRel64Value(Value);
4000 if (getLexer().isNot(AsmToken::EndOfStatement))
4001 return Error(getLexer().getLoc(),
4002 "unexpected token, expected end of statement");
4003 Parser.Lex(); // Eat EndOfStatement token.
4007 bool MipsAsmParser::parseDirectiveOption() {
4008 MCAsmParser &Parser = getParser();
4009 // Get the option token.
4010 AsmToken Tok = Parser.getTok();
4011 // At the moment only identifiers are supported.
4012 if (Tok.isNot(AsmToken::Identifier)) {
4013 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
4014 Parser.eatToEndOfStatement();
4018 StringRef Option = Tok.getIdentifier();
4020 if (Option == "pic0") {
4021 getTargetStreamer().emitDirectiveOptionPic0();
4023 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4024 Error(Parser.getTok().getLoc(),
4025 "unexpected token, expected end of statement");
4026 Parser.eatToEndOfStatement();
4031 if (Option == "pic2") {
4032 getTargetStreamer().emitDirectiveOptionPic2();
4034 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4035 Error(Parser.getTok().getLoc(),
4036 "unexpected token, expected end of statement");
4037 Parser.eatToEndOfStatement();
4043 Warning(Parser.getTok().getLoc(),
4044 "unknown option, expected 'pic0' or 'pic2'");
4045 Parser.eatToEndOfStatement();
4049 /// parseInsnDirective
4051 bool MipsAsmParser::parseInsnDirective() {
4052 // If this is not the end of the statement, report an error.
4053 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4054 reportParseError("unexpected token, expected end of statement");
4058 // The actual label marking happens in
4059 // MipsELFStreamer::createPendingLabelRelocs().
4060 getTargetStreamer().emitDirectiveInsn();
4062 getParser().Lex(); // Eat EndOfStatement token.
4066 /// parseDirectiveModule
4067 /// ::= .module oddspreg
4068 /// ::= .module nooddspreg
4069 /// ::= .module fp=value
4070 bool MipsAsmParser::parseDirectiveModule() {
4071 MCAsmParser &Parser = getParser();
4072 MCAsmLexer &Lexer = getLexer();
4073 SMLoc L = Lexer.getLoc();
4075 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
4076 // TODO : get a better message.
4077 reportParseError(".module directive must appear before any code");
4082 if (Parser.parseIdentifier(Option)) {
4083 reportParseError("expected .module option identifier");
4087 if (Option == "oddspreg") {
4088 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
4089 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4091 // If this is not the end of the statement, report an error.
4092 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4093 reportParseError("unexpected token, expected end of statement");
4097 return false; // parseDirectiveModule has finished successfully.
4098 } else if (Option == "nooddspreg") {
4100 Error(L, "'.module nooddspreg' requires the O32 ABI");
4104 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
4105 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
4107 // If this is not the end of the statement, report an error.
4108 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4109 reportParseError("unexpected token, expected end of statement");
4113 return false; // parseDirectiveModule has finished successfully.
4114 } else if (Option == "fp") {
4115 return parseDirectiveModuleFP();
4117 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
4121 /// parseDirectiveModuleFP
4125 bool MipsAsmParser::parseDirectiveModuleFP() {
4126 MCAsmParser &Parser = getParser();
4127 MCAsmLexer &Lexer = getLexer();
4129 if (Lexer.isNot(AsmToken::Equal)) {
4130 reportParseError("unexpected token, expected equals sign '='");
4133 Parser.Lex(); // Eat '=' token.
4135 MipsABIFlagsSection::FpABIKind FpABI;
4136 if (!parseFpABIValue(FpABI, ".module"))
4139 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4140 reportParseError("unexpected token, expected end of statement");
4144 // Emit appropriate flags.
4145 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
4146 Parser.Lex(); // Consume the EndOfStatement.
4150 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
4151 StringRef Directive) {
4152 MCAsmParser &Parser = getParser();
4153 MCAsmLexer &Lexer = getLexer();
4155 if (Lexer.is(AsmToken::Identifier)) {
4156 StringRef Value = Parser.getTok().getString();
4159 if (Value != "xx") {
4160 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4165 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
4169 FpABI = MipsABIFlagsSection::FpABIKind::XX;
4173 if (Lexer.is(AsmToken::Integer)) {
4174 unsigned Value = Parser.getTok().getIntVal();
4177 if (Value != 32 && Value != 64) {
4178 reportParseError("unsupported value, expected 'xx', '32' or '64'");
4184 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
4188 FpABI = MipsABIFlagsSection::FpABIKind::S32;
4190 FpABI = MipsABIFlagsSection::FpABIKind::S64;
4198 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
4199 MCAsmParser &Parser = getParser();
4200 StringRef IDVal = DirectiveID.getString();
4202 if (IDVal == ".cpload")
4203 return parseDirectiveCpLoad(DirectiveID.getLoc());
4204 if (IDVal == ".dword") {
4205 parseDataDirective(8, DirectiveID.getLoc());
4208 if (IDVal == ".ent") {
4209 StringRef SymbolName;
4211 if (Parser.parseIdentifier(SymbolName)) {
4212 reportParseError("expected identifier after .ent");
4216 // There's an undocumented extension that allows an integer to
4217 // follow the name of the procedure which AFAICS is ignored by GAS.
4218 // Example: .ent foo,2
4219 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4220 if (getLexer().isNot(AsmToken::Comma)) {
4221 // Even though we accept this undocumented extension for compatibility
4222 // reasons, the additional integer argument does not actually change
4223 // the behaviour of the '.ent' directive, so we would like to discourage
4224 // its use. We do this by not referring to the extended version in
4225 // error messages which are not directly related to its use.
4226 reportParseError("unexpected token, expected end of statement");
4229 Parser.Lex(); // Eat the comma.
4230 const MCExpr *DummyNumber;
4231 int64_t DummyNumberVal;
4232 // If the user was explicitly trying to use the extended version,
4233 // we still give helpful extension-related error messages.
4234 if (Parser.parseExpression(DummyNumber)) {
4235 reportParseError("expected number after comma");
4238 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
4239 reportParseError("expected an absolute expression after comma");
4244 // If this is not the end of the statement, report an error.
4245 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4246 reportParseError("unexpected token, expected end of statement");
4250 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
4252 getTargetStreamer().emitDirectiveEnt(*Sym);
4257 if (IDVal == ".end") {
4258 StringRef SymbolName;
4260 if (Parser.parseIdentifier(SymbolName)) {
4261 reportParseError("expected identifier after .end");
4265 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4266 reportParseError("unexpected token, expected end of statement");
4270 if (CurrentFn == nullptr) {
4271 reportParseError(".end used without .ent");
4275 if ((SymbolName != CurrentFn->getName())) {
4276 reportParseError(".end symbol does not match .ent symbol");
4280 getTargetStreamer().emitDirectiveEnd(SymbolName);
4281 CurrentFn = nullptr;
4285 if (IDVal == ".frame") {
4286 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4287 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4288 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4289 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4290 reportParseError("expected stack register");
4294 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4295 if (!StackRegOpnd.isGPRAsmReg()) {
4296 reportParseError(StackRegOpnd.getStartLoc(),
4297 "expected general purpose register");
4300 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4302 if (Parser.getTok().is(AsmToken::Comma))
4305 reportParseError("unexpected token, expected comma");
4309 // Parse the frame size.
4310 const MCExpr *FrameSize;
4311 int64_t FrameSizeVal;
4313 if (Parser.parseExpression(FrameSize)) {
4314 reportParseError("expected frame size value");
4318 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4319 reportParseError("frame size not an absolute expression");
4323 if (Parser.getTok().is(AsmToken::Comma))
4326 reportParseError("unexpected token, expected comma");
4330 // Parse the return register.
4332 ResTy = parseAnyRegister(TmpReg);
4333 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4334 reportParseError("expected return register");
4338 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4339 if (!ReturnRegOpnd.isGPRAsmReg()) {
4340 reportParseError(ReturnRegOpnd.getStartLoc(),
4341 "expected general purpose register");
4345 // If this is not the end of the statement, report an error.
4346 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4347 reportParseError("unexpected token, expected end of statement");
4351 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4352 ReturnRegOpnd.getGPR32Reg());
4356 if (IDVal == ".set") {
4357 return parseDirectiveSet();
4360 if (IDVal == ".mask" || IDVal == ".fmask") {
4361 // .mask bitmask, frame_offset
4362 // bitmask: One bit for each register used.
4363 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4364 // first register is expected to be saved.
4366 // .mask 0x80000000, -4
4367 // .fmask 0x80000000, -4
4370 // Parse the bitmask
4371 const MCExpr *BitMask;
4374 if (Parser.parseExpression(BitMask)) {
4375 reportParseError("expected bitmask value");
4379 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4380 reportParseError("bitmask not an absolute expression");
4384 if (Parser.getTok().is(AsmToken::Comma))
4387 reportParseError("unexpected token, expected comma");
4391 // Parse the frame_offset
4392 const MCExpr *FrameOffset;
4393 int64_t FrameOffsetVal;
4395 if (Parser.parseExpression(FrameOffset)) {
4396 reportParseError("expected frame offset value");
4400 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4401 reportParseError("frame offset not an absolute expression");
4405 // If this is not the end of the statement, report an error.
4406 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4407 reportParseError("unexpected token, expected end of statement");
4411 if (IDVal == ".mask")
4412 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4414 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4418 if (IDVal == ".nan")
4419 return parseDirectiveNaN();
4421 if (IDVal == ".gpword") {
4422 parseDirectiveGpWord();
4426 if (IDVal == ".gpdword") {
4427 parseDirectiveGpDWord();
4431 if (IDVal == ".word") {
4432 parseDataDirective(4, DirectiveID.getLoc());
4436 if (IDVal == ".option")
4437 return parseDirectiveOption();
4439 if (IDVal == ".abicalls") {
4440 getTargetStreamer().emitDirectiveAbiCalls();
4441 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4442 Error(Parser.getTok().getLoc(),
4443 "unexpected token, expected end of statement");
4445 Parser.eatToEndOfStatement();
4450 if (IDVal == ".cpsetup")
4451 return parseDirectiveCPSetup();
4453 if (IDVal == ".module")
4454 return parseDirectiveModule();
4456 if (IDVal == ".llvm_internal_mips_reallow_module_directive")
4457 return parseInternalDirectiveReallowModule();
4459 if (IDVal == ".insn")
4460 return parseInsnDirective();
4465 bool MipsAsmParser::parseInternalDirectiveReallowModule() {
4466 // If this is not the end of the statement, report an error.
4467 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4468 reportParseError("unexpected token, expected end of statement");
4472 getTargetStreamer().reallowModuleDirective();
4474 getParser().Lex(); // Eat EndOfStatement token.
4478 extern "C" void LLVMInitializeMipsAsmParser() {
4479 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4480 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4481 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4482 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4485 #define GET_REGISTER_MATCHER
4486 #define GET_MATCHER_IMPLEMENTATION
4487 #include "MipsGenAsmMatcher.inc"