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"
36 #define DEBUG_TYPE "mips-asm-parser"
43 class MipsAssemblerOptions {
45 MipsAssemblerOptions(uint64_t Features_) :
46 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
48 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
49 ATReg = Opts->getATRegNum();
50 Reorder = Opts->isReorder();
51 Macro = Opts->isMacro();
52 Features = Opts->getFeatures();
55 unsigned getATRegNum() const { return ATReg; }
56 bool setATReg(unsigned Reg);
58 bool isReorder() const { return Reorder; }
59 void setReorder() { Reorder = true; }
60 void setNoReorder() { Reorder = false; }
62 bool isMacro() const { return Macro; }
63 void setMacro() { Macro = true; }
64 void setNoMacro() { Macro = false; }
66 uint64_t getFeatures() const { return Features; }
67 void setFeatures(uint64_t Features_) { Features = Features_; }
69 // Set of features that are either architecture features or referenced
70 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
71 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
72 // The reason we need this mask is explained in the selectArch function.
73 // FIXME: Ideally we would like TableGen to generate this information.
74 static const uint64_t AllArchRelatedMask =
75 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
76 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
77 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
78 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
79 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
80 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
81 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
92 class MipsAsmParser : public MCTargetAsmParser {
93 MipsTargetStreamer &getTargetStreamer() {
94 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
95 return static_cast<MipsTargetStreamer &>(TS);
100 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
101 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
102 // nullptr, which indicates that no function is currently
103 // selected. This usually happens after an '.end func'
106 // Print a warning along with its fix-it message at the given range.
107 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
108 SMRange Range, bool ShowColors = true);
110 #define GET_ASSEMBLER_HEADER
111 #include "MipsGenAsmMatcher.inc"
113 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
115 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
116 OperandVector &Operands, MCStreamer &Out,
118 bool MatchingInlineAsm) override;
120 /// Parse a register as used in CFI directives
121 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
123 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
125 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
127 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
128 SMLoc NameLoc, OperandVector &Operands) override;
130 bool ParseDirective(AsmToken DirectiveID) override;
132 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
134 MipsAsmParser::OperandMatchResultTy
135 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
136 StringRef Identifier, SMLoc S);
138 MipsAsmParser::OperandMatchResultTy
139 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
141 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
151 MipsAsmParser::OperandMatchResultTy
152 parseRegisterPair (OperandVector &Operands);
154 MipsAsmParser::OperandMatchResultTy
155 parseRegisterList (OperandVector &Operands);
157 bool searchSymbolAlias(OperandVector &Operands);
159 bool parseOperand(OperandVector &, StringRef Mnemonic);
161 bool needsExpansion(MCInst &Inst);
163 // Expands assembly pseudo instructions.
164 // Returns false on success, true otherwise.
165 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
166 SmallVectorImpl<MCInst> &Instructions);
168 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
169 SmallVectorImpl<MCInst> &Instructions);
171 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
172 SmallVectorImpl<MCInst> &Instructions);
174 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
176 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
177 SmallVectorImpl<MCInst> &Instructions);
179 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
180 SmallVectorImpl<MCInst> &Instructions);
182 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
183 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
185 bool reportParseError(Twine ErrorMsg);
186 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
188 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
189 bool parseRelocOperand(const MCExpr *&Res);
191 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
193 bool isEvaluated(const MCExpr *Expr);
194 bool parseSetMips0Directive();
195 bool parseSetArchDirective();
196 bool parseSetFeature(uint64_t Feature);
197 bool parseDirectiveCpLoad(SMLoc Loc);
198 bool parseDirectiveCPSetup();
199 bool parseDirectiveNaN();
200 bool parseDirectiveSet();
201 bool parseDirectiveOption();
203 bool parseSetAtDirective();
204 bool parseSetNoAtDirective();
205 bool parseSetMacroDirective();
206 bool parseSetNoMacroDirective();
207 bool parseSetMsaDirective();
208 bool parseSetNoMsaDirective();
209 bool parseSetNoDspDirective();
210 bool parseSetReorderDirective();
211 bool parseSetNoReorderDirective();
212 bool parseSetMips16Directive();
213 bool parseSetNoMips16Directive();
214 bool parseSetFpDirective();
215 bool parseSetPopDirective();
216 bool parseSetPushDirective();
218 bool parseSetAssignment();
220 bool parseDataDirective(unsigned Size, SMLoc L);
221 bool parseDirectiveGpWord();
222 bool parseDirectiveGpDWord();
223 bool parseDirectiveModule();
224 bool parseDirectiveModuleFP();
225 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
226 StringRef Directive);
228 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
230 bool eatComma(StringRef ErrorStr);
232 int matchCPURegisterName(StringRef Symbol);
234 int matchHWRegsRegisterName(StringRef Symbol);
236 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
238 int matchFPURegisterName(StringRef Name);
240 int matchFCCRegisterName(StringRef Name);
242 int matchACRegisterName(StringRef Name);
244 int matchMSA128RegisterName(StringRef Name);
246 int matchMSA128CtrlRegisterName(StringRef Name);
248 unsigned getReg(int RC, int RegNo);
250 unsigned getGPR(int RegNo);
252 int getATReg(SMLoc Loc);
254 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
255 SmallVectorImpl<MCInst> &Instructions);
257 // Helper function that checks if the value of a vector index is within the
258 // boundaries of accepted values for each RegisterKind
259 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
260 bool validateMSAIndex(int Val, int RegKind);
262 // Selects a new architecture by updating the FeatureBits with the necessary
263 // info including implied dependencies.
264 // Internally, it clears all the feature bits related to *any* architecture
265 // and selects the new one using the ToggleFeature functionality of the
266 // MCSubtargetInfo object that handles implied dependencies. The reason we
267 // clear all the arch related bits manually is because ToggleFeature only
268 // clears the features that imply the feature being cleared and not the
269 // features implied by the feature being cleared. This is easier to see
271 // --------------------------------------------------
272 // | Feature | Implies |
273 // | -------------------------------------------------|
274 // | FeatureMips1 | None |
275 // | FeatureMips2 | FeatureMips1 |
276 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
277 // | FeatureMips4 | FeatureMips3 |
279 // --------------------------------------------------
281 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
282 // FeatureMipsGP64 | FeatureMips1)
283 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
284 void selectArch(StringRef ArchFeature) {
285 uint64_t FeatureBits = STI.getFeatureBits();
286 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
287 STI.setFeatureBits(FeatureBits);
288 setAvailableFeatures(
289 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
290 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
293 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
294 if (!(STI.getFeatureBits() & Feature)) {
295 setAvailableFeatures(
296 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
298 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
301 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
302 if (STI.getFeatureBits() & Feature) {
303 setAvailableFeatures(
304 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
306 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
310 enum MipsMatchResultTy {
311 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
312 #define GET_OPERAND_DIAGNOSTIC_TYPES
313 #include "MipsGenAsmMatcher.inc"
314 #undef GET_OPERAND_DIAGNOSTIC_TYPES
318 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
319 const MCInstrInfo &MII, const MCTargetOptions &Options)
320 : MCTargetAsmParser(), STI(sti),
321 ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
322 sti.getCPU(), Options)) {
323 MCAsmParserExtension::Initialize(parser);
325 // Initialize the set of available features.
326 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
328 // Remember the initial assembler options. The user can not modify these.
329 AssemblerOptions.push_back(
330 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
332 // Create an assembler options environment for the user to modify.
333 AssemblerOptions.push_back(
334 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
336 getTargetStreamer().updateABIInfo(*this);
338 if (!isABI_O32() && !useOddSPReg() != 0)
339 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
344 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
345 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
347 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
348 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
349 const MipsABIInfo &getABI() const { return ABI; }
350 bool isABI_N32() const { return ABI.IsN32(); }
351 bool isABI_N64() const { return ABI.IsN64(); }
352 bool isABI_O32() const { return ABI.IsO32(); }
353 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
355 bool useOddSPReg() const {
356 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
359 bool inMicroMipsMode() const {
360 return STI.getFeatureBits() & Mips::FeatureMicroMips;
362 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
363 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
364 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
365 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
366 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
367 bool hasMips32() const {
368 return (STI.getFeatureBits() & Mips::FeatureMips32);
370 bool hasMips64() const {
371 return (STI.getFeatureBits() & Mips::FeatureMips64);
373 bool hasMips32r2() const {
374 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
376 bool hasMips64r2() const {
377 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
379 bool hasMips32r6() const {
380 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
382 bool hasMips64r6() const {
383 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
385 bool hasCnMips() const {
386 return (STI.getFeatureBits() & Mips::FeatureCnMips);
388 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
389 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
390 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
392 bool inMips16Mode() const {
393 return STI.getFeatureBits() & Mips::FeatureMips16;
395 // TODO: see how can we get this info.
396 bool abiUsesSoftFloat() const { return false; }
398 /// Warn if RegNo is the current assembler temporary.
399 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
405 /// MipsOperand - Instances of this class represent a parsed Mips machine
407 class MipsOperand : public MCParsedAsmOperand {
409 /// Broad categories of register classes
410 /// The exact class is finalized by the render method.
412 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
413 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
415 RegKind_FCC = 4, /// FCC
416 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
417 RegKind_MSACtrl = 16, /// MSA control registers
418 RegKind_COP2 = 32, /// COP2
419 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
421 RegKind_CCR = 128, /// CCR
422 RegKind_HWRegs = 256, /// HWRegs
423 RegKind_COP3 = 512, /// COP3
425 /// Potentially any (e.g. $1)
426 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
427 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
428 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
433 k_Immediate, /// An immediate (possibly involving symbol references)
434 k_Memory, /// Base + Offset Memory Address
435 k_PhysRegister, /// A physical register from the Mips namespace
436 k_RegisterIndex, /// A register index in one or more RegKind.
437 k_Token, /// A simple token
438 k_RegList, /// A physical register list
439 k_RegPair /// A pair of physical register
443 MipsOperand(KindTy K, MipsAsmParser &Parser)
444 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
447 /// For diagnostics, and checking the assembler temporary
448 MipsAsmParser &AsmParser;
456 unsigned Num; /// Register Number
460 unsigned Index; /// Index into the register class
461 RegKind Kind; /// Bitfield of the kinds it could possibly be
462 const MCRegisterInfo *RegInfo;
475 SmallVector<unsigned, 10> *List;
480 struct PhysRegOp PhysReg;
481 struct RegIdxOp RegIdx;
484 struct RegListOp RegList;
487 SMLoc StartLoc, EndLoc;
489 /// Internal constructor for register kinds
490 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
491 const MCRegisterInfo *RegInfo,
493 MipsAsmParser &Parser) {
494 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
495 Op->RegIdx.Index = Index;
496 Op->RegIdx.RegInfo = RegInfo;
497 Op->RegIdx.Kind = RegKind;
504 /// Coerce the register to GPR32 and return the real register for the current
506 unsigned getGPR32Reg() const {
507 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
508 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
509 unsigned ClassID = Mips::GPR32RegClassID;
510 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
513 /// Coerce the register to GPR32 and return the real register for the current
515 unsigned getGPRMM16Reg() const {
516 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
517 unsigned ClassID = Mips::GPR32RegClassID;
518 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
521 /// Coerce the register to GPR64 and return the real register for the current
523 unsigned getGPR64Reg() const {
524 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
525 unsigned ClassID = Mips::GPR64RegClassID;
526 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
530 /// Coerce the register to AFGR64 and return the real register for the current
532 unsigned getAFGR64Reg() const {
533 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
534 if (RegIdx.Index % 2 != 0)
535 AsmParser.Warning(StartLoc, "Float register should be even.");
536 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
537 .getRegister(RegIdx.Index / 2);
540 /// Coerce the register to FGR64 and return the real register for the current
542 unsigned getFGR64Reg() const {
543 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
544 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
545 .getRegister(RegIdx.Index);
548 /// Coerce the register to FGR32 and return the real register for the current
550 unsigned getFGR32Reg() const {
551 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
552 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
553 .getRegister(RegIdx.Index);
556 /// Coerce the register to FGRH32 and return the real register for the current
558 unsigned getFGRH32Reg() const {
559 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
560 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
561 .getRegister(RegIdx.Index);
564 /// Coerce the register to FCC and return the real register for the current
566 unsigned getFCCReg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
568 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
569 .getRegister(RegIdx.Index);
572 /// Coerce the register to MSA128 and return the real register for the current
574 unsigned getMSA128Reg() const {
575 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
576 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
578 unsigned ClassID = Mips::MSA128BRegClassID;
579 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
582 /// Coerce the register to MSACtrl and return the real register for the
584 unsigned getMSACtrlReg() const {
585 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
586 unsigned ClassID = Mips::MSACtrlRegClassID;
587 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
590 /// Coerce the register to COP2 and return the real register for the
592 unsigned getCOP2Reg() const {
593 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
594 unsigned ClassID = Mips::COP2RegClassID;
595 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
598 /// Coerce the register to COP3 and return the real register for the
600 unsigned getCOP3Reg() const {
601 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
602 unsigned ClassID = Mips::COP3RegClassID;
603 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
606 /// Coerce the register to ACC64DSP and return the real register for the
608 unsigned getACC64DSPReg() const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
610 unsigned ClassID = Mips::ACC64DSPRegClassID;
611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
614 /// Coerce the register to HI32DSP and return the real register for the
616 unsigned getHI32DSPReg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
618 unsigned ClassID = Mips::HI32DSPRegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to LO32DSP and return the real register for the
624 unsigned getLO32DSPReg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
626 unsigned ClassID = Mips::LO32DSPRegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to CCR and return the real register for the
632 unsigned getCCRReg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
634 unsigned ClassID = Mips::CCRRegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
638 /// Coerce the register to HWRegs and return the real register for the
640 unsigned getHWRegsReg() const {
641 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
642 unsigned ClassID = Mips::HWRegsRegClassID;
643 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
647 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
648 // Add as immediate when possible. Null MCExpr = 0.
650 Inst.addOperand(MCOperand::CreateImm(0));
651 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
652 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
654 Inst.addOperand(MCOperand::CreateExpr(Expr));
657 void addRegOperands(MCInst &Inst, unsigned N) const {
658 llvm_unreachable("Use a custom parser instead");
661 /// Render the operand to an MCInst as a GPR32
662 /// Asserts if the wrong number of operands are requested, or the operand
663 /// is not a k_RegisterIndex compatible with RegKind_GPR
664 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
665 assert(N == 1 && "Invalid number of operands!");
666 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
669 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
670 assert(N == 1 && "Invalid number of operands!");
671 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
674 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
675 assert(N == 1 && "Invalid number of operands!");
676 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
679 /// Render the operand to an MCInst as a GPR64
680 /// Asserts if the wrong number of operands are requested, or the operand
681 /// is not a k_RegisterIndex compatible with RegKind_GPR
682 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
683 assert(N == 1 && "Invalid number of operands!");
684 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
687 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
688 assert(N == 1 && "Invalid number of operands!");
689 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
692 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
693 assert(N == 1 && "Invalid number of operands!");
694 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
697 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
698 assert(N == 1 && "Invalid number of operands!");
699 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
700 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
701 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
702 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
706 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
707 assert(N == 1 && "Invalid number of operands!");
708 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
711 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
712 assert(N == 1 && "Invalid number of operands!");
713 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
716 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
717 assert(N == 1 && "Invalid number of operands!");
718 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
721 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
722 assert(N == 1 && "Invalid number of operands!");
723 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
726 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 1 && "Invalid number of operands!");
728 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
731 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 1 && "Invalid number of operands!");
733 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
736 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
737 assert(N == 1 && "Invalid number of operands!");
738 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
741 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
742 assert(N == 1 && "Invalid number of operands!");
743 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
746 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
747 assert(N == 1 && "Invalid number of operands!");
748 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
751 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
752 assert(N == 1 && "Invalid number of operands!");
753 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
756 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
757 assert(N == 1 && "Invalid number of operands!");
758 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
761 void addImmOperands(MCInst &Inst, unsigned N) const {
762 assert(N == 1 && "Invalid number of operands!");
763 const MCExpr *Expr = getImm();
767 void addMemOperands(MCInst &Inst, unsigned N) const {
768 assert(N == 2 && "Invalid number of operands!");
770 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
772 const MCExpr *Expr = getMemOff();
776 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
777 assert(N == 2 && "Invalid number of operands!");
779 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
781 const MCExpr *Expr = getMemOff();
785 void addRegListOperands(MCInst &Inst, unsigned N) const {
786 assert(N == 1 && "Invalid number of operands!");
788 for (auto RegNo : getRegList())
789 Inst.addOperand(MCOperand::CreateReg(RegNo));
792 void addRegPairOperands(MCInst &Inst, unsigned N) const {
793 assert(N == 2 && "Invalid number of operands!");
794 unsigned RegNo = getRegPair();
795 Inst.addOperand(MCOperand::CreateReg(RegNo++));
796 Inst.addOperand(MCOperand::CreateReg(RegNo));
799 bool isReg() const override {
800 // As a special case until we sort out the definition of div/divu, pretend
801 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
802 if (isGPRAsmReg() && RegIdx.Index == 0)
805 return Kind == k_PhysRegister;
807 bool isRegIdx() const { return Kind == k_RegisterIndex; }
808 bool isImm() const override { return Kind == k_Immediate; }
809 bool isConstantImm() const {
810 return isImm() && dyn_cast<MCConstantExpr>(getImm());
812 bool isToken() const override {
813 // Note: It's not possible to pretend that other operand kinds are tokens.
814 // The matcher emitter checks tokens first.
815 return Kind == k_Token;
817 bool isMem() const override { return Kind == k_Memory; }
818 bool isConstantMemOff() const {
819 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
821 template <unsigned Bits> bool isMemWithSimmOffset() const {
822 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
824 bool isMemWithGRPMM16Base() const {
825 return isMem() && getMemBase()->isMM16AsmReg();
827 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
828 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
829 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
831 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
832 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
833 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
834 && (getMemBase()->getGPR32Reg() == Mips::SP);
836 bool isRegList16() const {
840 int Size = RegList.List->size();
841 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
842 RegList.List->back() != Mips::RA)
845 int PrevReg = *RegList.List->begin();
846 for (int i = 1; i < Size - 1; i++) {
847 int Reg = (*(RegList.List))[i];
848 if ( Reg != PrevReg + 1)
855 bool isInvNum() const { return Kind == k_Immediate; }
856 bool isLSAImm() const {
857 if (!isConstantImm())
859 int64_t Val = getConstantImm();
860 return 1 <= Val && Val <= 4;
862 bool isRegList() const { return Kind == k_RegList; }
864 StringRef getToken() const {
865 assert(Kind == k_Token && "Invalid access!");
866 return StringRef(Tok.Data, Tok.Length);
868 bool isRegPair() const { return Kind == k_RegPair; }
870 unsigned getReg() const override {
871 // As a special case until we sort out the definition of div/divu, pretend
872 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
873 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
874 RegIdx.Kind & RegKind_GPR)
875 return getGPR32Reg(); // FIXME: GPR64 too
877 assert(Kind == k_PhysRegister && "Invalid access!");
881 const MCExpr *getImm() const {
882 assert((Kind == k_Immediate) && "Invalid access!");
886 int64_t getConstantImm() const {
887 const MCExpr *Val = getImm();
888 return static_cast<const MCConstantExpr *>(Val)->getValue();
891 MipsOperand *getMemBase() const {
892 assert((Kind == k_Memory) && "Invalid access!");
896 const MCExpr *getMemOff() const {
897 assert((Kind == k_Memory) && "Invalid access!");
901 int64_t getConstantMemOff() const {
902 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
905 const SmallVectorImpl<unsigned> &getRegList() const {
906 assert((Kind == k_RegList) && "Invalid access!");
907 return *(RegList.List);
910 unsigned getRegPair() const {
911 assert((Kind == k_RegPair) && "Invalid access!");
915 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
916 MipsAsmParser &Parser) {
917 auto Op = make_unique<MipsOperand>(k_Token, Parser);
918 Op->Tok.Data = Str.data();
919 Op->Tok.Length = Str.size();
925 /// Create a numeric register (e.g. $1). The exact register remains
926 /// unresolved until an instruction successfully matches
927 static std::unique_ptr<MipsOperand>
928 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
929 SMLoc E, MipsAsmParser &Parser) {
930 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
931 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
934 /// Create a register that is definitely a GPR.
935 /// This is typically only used for named registers such as $gp.
936 static std::unique_ptr<MipsOperand>
937 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
938 MipsAsmParser &Parser) {
939 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
942 /// Create a register that is definitely a FGR.
943 /// This is typically only used for named registers such as $f0.
944 static std::unique_ptr<MipsOperand>
945 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
946 MipsAsmParser &Parser) {
947 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
950 /// Create a register that is definitely a HWReg.
951 /// This is typically only used for named registers such as $hwr_cpunum.
952 static std::unique_ptr<MipsOperand>
953 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
954 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
955 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
958 /// Create a register that is definitely an FCC.
959 /// This is typically only used for named registers such as $fcc0.
960 static std::unique_ptr<MipsOperand>
961 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
962 MipsAsmParser &Parser) {
963 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
966 /// Create a register that is definitely an ACC.
967 /// This is typically only used for named registers such as $ac0.
968 static std::unique_ptr<MipsOperand>
969 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
970 MipsAsmParser &Parser) {
971 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
974 /// Create a register that is definitely an MSA128.
975 /// This is typically only used for named registers such as $w0.
976 static std::unique_ptr<MipsOperand>
977 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
978 SMLoc E, MipsAsmParser &Parser) {
979 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
982 /// Create a register that is definitely an MSACtrl.
983 /// This is typically only used for named registers such as $msaaccess.
984 static std::unique_ptr<MipsOperand>
985 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
986 SMLoc E, MipsAsmParser &Parser) {
987 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
990 static std::unique_ptr<MipsOperand>
991 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
992 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
999 static std::unique_ptr<MipsOperand>
1000 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1001 SMLoc E, MipsAsmParser &Parser) {
1002 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1003 Op->Mem.Base = Base.release();
1010 static std::unique_ptr<MipsOperand>
1011 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1012 MipsAsmParser &Parser) {
1013 assert (Regs.size() > 0 && "Empty list not allowed");
1015 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1016 Op->RegList.List = new SmallVector<unsigned, 10>();
1017 for (auto Reg : Regs)
1018 Op->RegList.List->push_back(Reg);
1019 Op->StartLoc = StartLoc;
1020 Op->EndLoc = EndLoc;
1024 static std::unique_ptr<MipsOperand>
1025 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1026 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1027 Op->RegIdx.Index = RegNo;
1033 bool isGPRAsmReg() const {
1034 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1036 bool isMM16AsmReg() const {
1037 if (!(isRegIdx() && RegIdx.Kind))
1039 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1040 || RegIdx.Index == 16 || RegIdx.Index == 17);
1042 bool isMM16AsmRegZero() const {
1043 if (!(isRegIdx() && RegIdx.Kind))
1045 return (RegIdx.Index == 0 ||
1046 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1047 RegIdx.Index == 17);
1049 bool isFGRAsmReg() const {
1050 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1051 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1053 bool isHWRegsAsmReg() const {
1054 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1056 bool isCCRAsmReg() const {
1057 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1059 bool isFCCAsmReg() const {
1060 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1062 if (!AsmParser.hasEightFccRegisters())
1063 return RegIdx.Index == 0;
1064 return RegIdx.Index <= 7;
1066 bool isACCAsmReg() const {
1067 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1069 bool isCOP2AsmReg() const {
1070 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1072 bool isCOP3AsmReg() const {
1073 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1075 bool isMSA128AsmReg() const {
1076 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1078 bool isMSACtrlAsmReg() const {
1079 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1082 /// getStartLoc - Get the location of the first token of this operand.
1083 SMLoc getStartLoc() const override { return StartLoc; }
1084 /// getEndLoc - Get the location of the last token of this operand.
1085 SMLoc getEndLoc() const override { return EndLoc; }
1087 virtual ~MipsOperand() {
1095 delete RegList.List;
1096 case k_PhysRegister:
1097 case k_RegisterIndex:
1104 void print(raw_ostream &OS) const override {
1113 Mem.Base->print(OS);
1118 case k_PhysRegister:
1119 OS << "PhysReg<" << PhysReg.Num << ">";
1121 case k_RegisterIndex:
1122 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1129 for (auto Reg : (*RegList.List))
1134 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1138 }; // class MipsOperand
1142 extern const MCInstrDesc MipsInsts[];
1144 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1145 return MipsInsts[Opcode];
1148 static bool hasShortDelaySlot(unsigned Opcode) {
1151 case Mips::JALRS_MM:
1152 case Mips::JALRS16_MM:
1153 case Mips::BGEZALS_MM:
1154 case Mips::BLTZALS_MM:
1161 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1162 SmallVectorImpl<MCInst> &Instructions) {
1163 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1167 if (MCID.isBranch() || MCID.isCall()) {
1168 const unsigned Opcode = Inst.getOpcode();
1178 assert(hasCnMips() && "instruction only valid for octeon cpus");
1185 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1186 Offset = Inst.getOperand(2);
1187 if (!Offset.isImm())
1188 break; // We'll deal with this situation later on when applying fixups.
1189 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1190 return Error(IDLoc, "branch target out of range");
1191 if (OffsetToAlignment(Offset.getImm(),
1192 1LL << (inMicroMipsMode() ? 1 : 2)))
1193 return Error(IDLoc, "branch to misaligned address");
1207 case Mips::BGEZAL_MM:
1208 case Mips::BLTZAL_MM:
1211 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1212 Offset = Inst.getOperand(1);
1213 if (!Offset.isImm())
1214 break; // We'll deal with this situation later on when applying fixups.
1215 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1216 return Error(IDLoc, "branch target out of range");
1217 if (OffsetToAlignment(Offset.getImm(),
1218 1LL << (inMicroMipsMode() ? 1 : 2)))
1219 return Error(IDLoc, "branch to misaligned address");
1221 case Mips::BEQZ16_MM:
1222 case Mips::BNEZ16_MM:
1223 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1224 Offset = Inst.getOperand(1);
1225 if (!Offset.isImm())
1226 break; // We'll deal with this situation later on when applying fixups.
1227 if (!isIntN(8, Offset.getImm()))
1228 return Error(IDLoc, "branch target out of range");
1229 if (OffsetToAlignment(Offset.getImm(), 2LL))
1230 return Error(IDLoc, "branch to misaligned address");
1235 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1236 // We still accept it but it is a normal nop.
1237 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1238 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1239 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1244 const unsigned Opcode = Inst.getOpcode();
1256 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1257 // The offset is handled above
1258 Opnd = Inst.getOperand(1);
1260 return Error(IDLoc, "expected immediate operand kind");
1261 Imm = Opnd.getImm();
1262 if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1263 Opcode == Mips::BBIT1 ? 63 : 31))
1264 return Error(IDLoc, "immediate operand value out of range");
1266 Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1268 Inst.getOperand(1).setImm(Imm - 32);
1276 assert(MCID.getNumOperands() == 4 && "unexpected number of operands");
1278 Opnd = Inst.getOperand(3);
1280 return Error(IDLoc, "expected immediate operand kind");
1281 Imm = Opnd.getImm();
1282 if (Imm < 0 || Imm > 31)
1283 return Error(IDLoc, "immediate operand value out of range");
1285 Opnd = Inst.getOperand(2);
1287 return Error(IDLoc, "expected immediate operand kind");
1288 Imm = Opnd.getImm();
1289 if (Imm < 0 || Imm > (Opcode == Mips::CINS ||
1290 Opcode == Mips::EXTS ? 63 : 31))
1291 return Error(IDLoc, "immediate operand value out of range");
1293 Inst.setOpcode(Opcode == Mips::CINS ? Mips::CINS32 : Mips::EXTS32);
1294 Inst.getOperand(2).setImm(Imm - 32);
1300 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1301 Opnd = Inst.getOperand(2);
1303 return Error(IDLoc, "expected immediate operand kind");
1304 Imm = Opnd.getImm();
1305 if (!isInt<10>(Imm))
1306 return Error(IDLoc, "immediate operand value out of range");
1311 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1312 // If this instruction has a delay slot and .set reorder is active,
1313 // emit a NOP after it.
1314 Instructions.push_back(Inst);
1316 if (hasShortDelaySlot(Inst.getOpcode())) {
1317 NopInst.setOpcode(Mips::MOVE16_MM);
1318 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1319 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1321 NopInst.setOpcode(Mips::SLL);
1322 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1323 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1324 NopInst.addOperand(MCOperand::CreateImm(0));
1326 Instructions.push_back(NopInst);
1330 if (MCID.mayLoad() || MCID.mayStore()) {
1331 // Check the offset of memory operand, if it is a symbol
1332 // reference or immediate we may have to expand instructions.
1333 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1334 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1335 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1336 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1337 MCOperand &Op = Inst.getOperand(i);
1339 int MemOffset = Op.getImm();
1340 if (MemOffset < -32768 || MemOffset > 32767) {
1341 // Offset can't exceed 16bit value.
1342 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1345 } else if (Op.isExpr()) {
1346 const MCExpr *Expr = Op.getExpr();
1347 if (Expr->getKind() == MCExpr::SymbolRef) {
1348 const MCSymbolRefExpr *SR =
1349 static_cast<const MCSymbolRefExpr *>(Expr);
1350 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1352 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1355 } else if (!isEvaluated(Expr)) {
1356 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1364 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1365 if (inMicroMipsMode()) {
1369 switch (Inst.getOpcode()) {
1372 case Mips::ADDIUS5_MM:
1373 Opnd = Inst.getOperand(2);
1375 return Error(IDLoc, "expected immediate operand kind");
1376 Imm = Opnd.getImm();
1377 if (Imm < -8 || Imm > 7)
1378 return Error(IDLoc, "immediate operand value out of range");
1380 case Mips::ADDIUSP_MM:
1381 Opnd = Inst.getOperand(0);
1383 return Error(IDLoc, "expected immediate operand kind");
1384 Imm = Opnd.getImm();
1385 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1387 return Error(IDLoc, "immediate operand value out of range");
1389 case Mips::SLL16_MM:
1390 case Mips::SRL16_MM:
1391 Opnd = Inst.getOperand(2);
1393 return Error(IDLoc, "expected immediate operand kind");
1394 Imm = Opnd.getImm();
1395 if (Imm < 1 || Imm > 8)
1396 return Error(IDLoc, "immediate operand value out of range");
1399 Opnd = Inst.getOperand(1);
1401 return Error(IDLoc, "expected immediate operand kind");
1402 Imm = Opnd.getImm();
1403 if (Imm < -1 || Imm > 126)
1404 return Error(IDLoc, "immediate operand value out of range");
1406 case Mips::ADDIUR2_MM:
1407 Opnd = Inst.getOperand(2);
1409 return Error(IDLoc, "expected immediate operand kind");
1410 Imm = Opnd.getImm();
1411 if (!(Imm == 1 || Imm == -1 ||
1412 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1413 return Error(IDLoc, "immediate operand value out of range");
1415 case Mips::ADDIUR1SP_MM:
1416 Opnd = Inst.getOperand(1);
1418 return Error(IDLoc, "expected immediate operand kind");
1419 Imm = Opnd.getImm();
1420 if (OffsetToAlignment(Imm, 4LL))
1421 return Error(IDLoc, "misaligned immediate operand value");
1422 if (Imm < 0 || Imm > 255)
1423 return Error(IDLoc, "immediate operand value out of range");
1425 case Mips::ANDI16_MM:
1426 Opnd = Inst.getOperand(2);
1428 return Error(IDLoc, "expected immediate operand kind");
1429 Imm = Opnd.getImm();
1430 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1431 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1432 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1433 return Error(IDLoc, "immediate operand value out of range");
1435 case Mips::LBU16_MM:
1436 Opnd = Inst.getOperand(2);
1438 return Error(IDLoc, "expected immediate operand kind");
1439 Imm = Opnd.getImm();
1440 if (Imm < -1 || Imm > 14)
1441 return Error(IDLoc, "immediate operand value out of range");
1444 Opnd = Inst.getOperand(2);
1446 return Error(IDLoc, "expected immediate operand kind");
1447 Imm = Opnd.getImm();
1448 if (Imm < 0 || Imm > 15)
1449 return Error(IDLoc, "immediate operand value out of range");
1451 case Mips::LHU16_MM:
1453 Opnd = Inst.getOperand(2);
1455 return Error(IDLoc, "expected immediate operand kind");
1456 Imm = Opnd.getImm();
1457 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1458 return Error(IDLoc, "immediate operand value out of range");
1462 Opnd = Inst.getOperand(2);
1464 return Error(IDLoc, "expected immediate operand kind");
1465 Imm = Opnd.getImm();
1466 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1467 return Error(IDLoc, "immediate operand value out of range");
1471 Opnd = Inst.getOperand(2);
1473 return Error(IDLoc, "expected immediate operand kind");
1474 Imm = Opnd.getImm();
1475 if (!isUInt<5>(Imm))
1476 return Error(IDLoc, "immediate operand value out of range");
1478 case Mips::ADDIUPC_MM:
1479 MCOperand Opnd = Inst.getOperand(1);
1481 return Error(IDLoc, "expected immediate operand kind");
1482 int Imm = Opnd.getImm();
1483 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1484 return Error(IDLoc, "immediate operand value out of range");
1489 if (needsExpansion(Inst))
1490 return expandInstruction(Inst, IDLoc, Instructions);
1492 Instructions.push_back(Inst);
1497 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1499 switch (Inst.getOpcode()) {
1500 case Mips::LoadImm32Reg:
1501 case Mips::LoadAddr32Imm:
1502 case Mips::LoadAddr32Reg:
1503 case Mips::LoadImm64Reg:
1504 case Mips::B_MM_Pseudo:
1511 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1512 SmallVectorImpl<MCInst> &Instructions) {
1513 switch (Inst.getOpcode()) {
1514 default: llvm_unreachable("unimplemented expansion");
1515 case Mips::LoadImm32Reg:
1516 return expandLoadImm(Inst, IDLoc, Instructions);
1517 case Mips::LoadImm64Reg:
1519 Error(IDLoc, "instruction requires a 64-bit architecture");
1522 return expandLoadImm(Inst, IDLoc, Instructions);
1523 case Mips::LoadAddr32Imm:
1524 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1525 case Mips::LoadAddr32Reg:
1526 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1527 case Mips::B_MM_Pseudo:
1528 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1533 template <bool PerformShift>
1534 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1535 SmallVectorImpl<MCInst> &Instructions) {
1538 tmpInst.setOpcode(Mips::DSLL);
1539 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1540 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1541 tmpInst.addOperand(MCOperand::CreateImm(16));
1542 tmpInst.setLoc(IDLoc);
1543 Instructions.push_back(tmpInst);
1546 tmpInst.setOpcode(Mips::ORi);
1547 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1548 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1549 tmpInst.addOperand(Operand);
1550 tmpInst.setLoc(IDLoc);
1551 Instructions.push_back(tmpInst);
1554 template <int Shift, bool PerformShift>
1555 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1556 SmallVectorImpl<MCInst> &Instructions) {
1557 createShiftOr<PerformShift>(
1558 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1559 IDLoc, Instructions);
1563 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1564 SmallVectorImpl<MCInst> &Instructions) {
1566 const MCOperand &ImmOp = Inst.getOperand(1);
1567 assert(ImmOp.isImm() && "expected immediate operand kind");
1568 const MCOperand &RegOp = Inst.getOperand(0);
1569 assert(RegOp.isReg() && "expected register operand kind");
1571 int64_t ImmValue = ImmOp.getImm();
1572 tmpInst.setLoc(IDLoc);
1573 // FIXME: gas has a special case for values that are 000...1111, which
1574 // becomes a li -1 and then a dsrl
1575 if (0 <= ImmValue && ImmValue <= 65535) {
1576 // For 0 <= j <= 65535.
1577 // li d,j => ori d,$zero,j
1578 tmpInst.setOpcode(Mips::ORi);
1579 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1580 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1581 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1582 Instructions.push_back(tmpInst);
1583 } else if (ImmValue < 0 && ImmValue >= -32768) {
1584 // For -32768 <= j < 0.
1585 // li d,j => addiu d,$zero,j
1586 tmpInst.setOpcode(Mips::ADDiu);
1587 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1588 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1589 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1590 Instructions.push_back(tmpInst);
1591 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1592 // For any value of j that is representable as a 32-bit integer, create
1594 // li d,j => lui d,hi16(j)
1596 tmpInst.setOpcode(Mips::LUi);
1597 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1598 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1599 Instructions.push_back(tmpInst);
1600 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1601 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1603 Error(IDLoc, "instruction requires a 64-bit architecture");
1607 // <------- lo32 ------>
1608 // <------- hi32 ------>
1609 // <- hi16 -> <- lo16 ->
1610 // _________________________________
1612 // | 16-bytes | 16-bytes | 16-bytes |
1613 // |__________|__________|__________|
1615 // For any value of j that is representable as a 48-bit integer, create
1617 // li d,j => lui d,hi16(j)
1618 // ori d,d,hi16(lo32(j))
1620 // ori d,d,lo16(lo32(j))
1621 tmpInst.setOpcode(Mips::LUi);
1622 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1624 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1625 Instructions.push_back(tmpInst);
1626 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1627 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1630 Error(IDLoc, "instruction requires a 64-bit architecture");
1634 // <------- hi32 ------> <------- lo32 ------>
1635 // <- hi16 -> <- lo16 ->
1636 // ___________________________________________
1638 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1639 // |__________|__________|__________|__________|
1641 // For any value of j that isn't representable as a 48-bit integer.
1642 // li d,j => lui d,hi16(j)
1643 // ori d,d,lo16(hi32(j))
1645 // ori d,d,hi16(lo32(j))
1647 // ori d,d,lo16(lo32(j))
1648 tmpInst.setOpcode(Mips::LUi);
1649 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1651 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1652 Instructions.push_back(tmpInst);
1653 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1654 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1655 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1661 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1662 SmallVectorImpl<MCInst> &Instructions) {
1664 const MCOperand &ImmOp = Inst.getOperand(2);
1665 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1666 "expected immediate operand kind");
1667 if (!ImmOp.isImm()) {
1668 expandLoadAddressSym(Inst, IDLoc, Instructions);
1671 const MCOperand &SrcRegOp = Inst.getOperand(1);
1672 assert(SrcRegOp.isReg() && "expected register operand kind");
1673 const MCOperand &DstRegOp = Inst.getOperand(0);
1674 assert(DstRegOp.isReg() && "expected register operand kind");
1675 int ImmValue = ImmOp.getImm();
1676 if (-32768 <= ImmValue && ImmValue <= 65535) {
1677 // For -32768 <= j <= 65535.
1678 // la d,j(s) => addiu d,s,j
1679 tmpInst.setOpcode(Mips::ADDiu);
1680 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1681 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1682 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1683 Instructions.push_back(tmpInst);
1685 // For any other value of j that is representable as a 32-bit integer.
1686 // la d,j(s) => lui d,hi16(j)
1689 tmpInst.setOpcode(Mips::LUi);
1690 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1691 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1692 Instructions.push_back(tmpInst);
1694 tmpInst.setOpcode(Mips::ORi);
1695 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1696 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1697 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1698 Instructions.push_back(tmpInst);
1700 tmpInst.setOpcode(Mips::ADDu);
1701 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1702 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1703 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1704 Instructions.push_back(tmpInst);
1710 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1711 SmallVectorImpl<MCInst> &Instructions) {
1713 const MCOperand &ImmOp = Inst.getOperand(1);
1714 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1715 "expected immediate operand kind");
1716 if (!ImmOp.isImm()) {
1717 expandLoadAddressSym(Inst, IDLoc, Instructions);
1720 const MCOperand &RegOp = Inst.getOperand(0);
1721 assert(RegOp.isReg() && "expected register operand kind");
1722 int ImmValue = ImmOp.getImm();
1723 if (-32768 <= ImmValue && ImmValue <= 65535) {
1724 // For -32768 <= j <= 65535.
1725 // la d,j => addiu d,$zero,j
1726 tmpInst.setOpcode(Mips::ADDiu);
1727 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1728 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1729 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1730 Instructions.push_back(tmpInst);
1732 // For any other value of j that is representable as a 32-bit integer.
1733 // la d,j => lui d,hi16(j)
1735 tmpInst.setOpcode(Mips::LUi);
1736 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1737 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1738 Instructions.push_back(tmpInst);
1740 tmpInst.setOpcode(Mips::ORi);
1741 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1742 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1743 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1744 Instructions.push_back(tmpInst);
1750 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1751 SmallVectorImpl<MCInst> &Instructions) {
1752 // FIXME: If we do have a valid at register to use, we should generate a
1753 // slightly shorter sequence here.
1755 int ExprOperandNo = 1;
1756 // Sometimes the assembly parser will get the immediate expression as
1757 // a $zero + an immediate.
1758 if (Inst.getNumOperands() == 3) {
1759 assert(Inst.getOperand(1).getReg() ==
1760 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1763 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1764 assert(SymOp.isExpr() && "expected symbol operand kind");
1765 const MCOperand &RegOp = Inst.getOperand(0);
1766 unsigned RegNo = RegOp.getReg();
1767 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1768 const MCSymbolRefExpr *HiExpr =
1769 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1770 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1771 const MCSymbolRefExpr *LoExpr =
1772 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1773 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1775 // If it's a 64-bit architecture, expand to:
1776 // la d,sym => lui d,highest(sym)
1777 // ori d,d,higher(sym)
1779 // ori d,d,hi16(sym)
1781 // ori d,d,lo16(sym)
1782 const MCSymbolRefExpr *HighestExpr =
1783 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1784 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1785 const MCSymbolRefExpr *HigherExpr =
1786 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1787 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1789 tmpInst.setOpcode(Mips::LUi);
1790 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1791 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1792 Instructions.push_back(tmpInst);
1794 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1796 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1798 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1801 // Otherwise, expand to:
1802 // la d,sym => lui d,hi16(sym)
1803 // ori d,d,lo16(sym)
1804 tmpInst.setOpcode(Mips::LUi);
1805 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1806 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1807 Instructions.push_back(tmpInst);
1809 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1814 bool MipsAsmParser::expandUncondBranchMMPseudo(
1815 MCInst &Inst, SMLoc IDLoc, SmallVectorImpl<MCInst> &Instructions) {
1816 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1817 "unexpected number of operands");
1819 MCOperand Offset = Inst.getOperand(0);
1820 if (Offset.isExpr()) {
1822 Inst.setOpcode(Mips::BEQ_MM);
1823 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1824 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1825 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1827 assert(Offset.isImm() && "expected immediate operand kind");
1828 if (isIntN(11, Offset.getImm())) {
1829 // If offset fits into 11 bits then this instruction becomes microMIPS
1830 // 16-bit unconditional branch instruction.
1831 Inst.setOpcode(Mips::B16_MM);
1833 if (!isIntN(17, Offset.getImm()))
1834 Error(IDLoc, "branch target out of range");
1835 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1836 Error(IDLoc, "branch to misaligned address");
1838 Inst.setOpcode(Mips::BEQ_MM);
1839 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1840 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1841 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1844 Instructions.push_back(Inst);
1846 if (AssemblerOptions.back()->isReorder()) {
1847 // If .set reorder is active, emit a NOP after the branch instruction.
1849 NopInst.setOpcode(Mips::MOVE16_MM);
1850 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1851 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1852 Instructions.push_back(NopInst);
1857 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1858 SmallVectorImpl<MCInst> &Instructions,
1859 bool isLoad, bool isImmOpnd) {
1860 const MCSymbolRefExpr *SR;
1862 unsigned ImmOffset, HiOffset, LoOffset;
1863 const MCExpr *ExprOffset;
1865 // 1st operand is either the source or destination register.
1866 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1867 unsigned RegOpNum = Inst.getOperand(0).getReg();
1868 // 2nd operand is the base register.
1869 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1870 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1871 // 3rd operand is either an immediate or expression.
1873 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1874 ImmOffset = Inst.getOperand(2).getImm();
1875 LoOffset = ImmOffset & 0x0000ffff;
1876 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1877 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1878 if (LoOffset & 0x8000)
1881 ExprOffset = Inst.getOperand(2).getExpr();
1882 // All instructions will have the same location.
1883 TempInst.setLoc(IDLoc);
1884 // These are some of the types of expansions we perform here:
1885 // 1) lw $8, sym => lui $8, %hi(sym)
1886 // lw $8, %lo(sym)($8)
1887 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1889 // lw $8, %lo(offset)($9)
1890 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1892 // lw $8, %lo(offset)($at)
1893 // 4) sw $8, sym => lui $at, %hi(sym)
1894 // sw $8, %lo(sym)($at)
1895 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1897 // sw $8, %lo(offset)($at)
1898 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1899 // ldc1 $f0, %lo(sym)($at)
1901 // For load instructions we can use the destination register as a temporary
1902 // if base and dst are different (examples 1 and 2) and if the base register
1903 // is general purpose otherwise we must use $at (example 6) and error if it's
1904 // not available. For stores we must use $at (examples 4 and 5) because we
1905 // must not clobber the source register setting up the offset.
1906 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1907 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1908 unsigned RegClassIDOp0 =
1909 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1910 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1911 (RegClassIDOp0 == Mips::GPR64RegClassID);
1912 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1913 TmpRegNum = RegOpNum;
1915 int AT = getATReg(IDLoc);
1916 // At this point we need AT to perform the expansions and we exit if it is
1921 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1924 TempInst.setOpcode(Mips::LUi);
1925 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1927 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1929 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1930 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1931 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1932 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1934 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1936 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1937 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1940 // Add the instruction to the list.
1941 Instructions.push_back(TempInst);
1942 // Prepare TempInst for next instruction.
1944 // Add temp register to base.
1945 TempInst.setOpcode(Mips::ADDu);
1946 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1947 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1948 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1949 Instructions.push_back(TempInst);
1951 // And finally, create original instruction with low part
1952 // of offset and new base.
1953 TempInst.setOpcode(Inst.getOpcode());
1954 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1955 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1957 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1959 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1960 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1961 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1963 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1965 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1966 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1969 Instructions.push_back(TempInst);
1973 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1974 // As described by the Mips32r2 spec, the registers Rd and Rs for
1975 // jalr.hb must be different.
1976 unsigned Opcode = Inst.getOpcode();
1978 if (Opcode == Mips::JALR_HB &&
1979 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1980 return Match_RequiresDifferentSrcAndDst;
1982 return Match_Success;
1985 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1986 OperandVector &Operands,
1988 uint64_t &ErrorInfo,
1989 bool MatchingInlineAsm) {
1992 SmallVector<MCInst, 8> Instructions;
1993 unsigned MatchResult =
1994 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1996 switch (MatchResult) {
1997 case Match_Success: {
1998 if (processInstruction(Inst, IDLoc, Instructions))
2000 for (unsigned i = 0; i < Instructions.size(); i++)
2001 Out.EmitInstruction(Instructions[i], STI);
2004 case Match_MissingFeature:
2005 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
2007 case Match_InvalidOperand: {
2008 SMLoc ErrorLoc = IDLoc;
2009 if (ErrorInfo != ~0ULL) {
2010 if (ErrorInfo >= Operands.size())
2011 return Error(IDLoc, "too few operands for instruction");
2013 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
2014 if (ErrorLoc == SMLoc())
2018 return Error(ErrorLoc, "invalid operand for instruction");
2020 case Match_MnemonicFail:
2021 return Error(IDLoc, "invalid instruction");
2022 case Match_RequiresDifferentSrcAndDst:
2023 return Error(IDLoc, "source and destination must be different");
2026 llvm_unreachable("Implement any new match types added!");
2029 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
2030 if ((RegIndex != 0) &&
2031 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
2033 Warning(Loc, "used $at without \".set noat\"");
2035 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
2036 Twine(RegIndex) + "\"");
2041 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
2042 SMRange Range, bool ShowColors) {
2043 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
2044 Range, SMFixIt(Range, FixMsg),
2048 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
2051 CC = StringSwitch<unsigned>(Name)
2087 if (!(isABI_N32() || isABI_N64()))
2090 if (12 <= CC && CC <= 15) {
2091 // Name is one of t4-t7
2092 AsmToken RegTok = getLexer().peekTok();
2093 SMRange RegRange = RegTok.getLocRange();
2095 StringRef FixedName = StringSwitch<StringRef>(Name)
2101 assert(FixedName != "" && "Register name is not one of t4-t7.");
2103 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2104 "Did you mean $" + FixedName + "?", RegRange);
2107 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2108 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2109 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2110 if (8 <= CC && CC <= 11)
2114 CC = StringSwitch<unsigned>(Name)
2126 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2129 CC = StringSwitch<unsigned>(Name)
2130 .Case("hwr_cpunum", 0)
2131 .Case("hwr_synci_step", 1)
2133 .Case("hwr_ccres", 3)
2134 .Case("hwr_ulr", 29)
2140 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2142 if (Name[0] == 'f') {
2143 StringRef NumString = Name.substr(1);
2145 if (NumString.getAsInteger(10, IntVal))
2146 return -1; // This is not an integer.
2147 if (IntVal > 31) // Maximum index for fpu register.
2154 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2156 if (Name.startswith("fcc")) {
2157 StringRef NumString = Name.substr(3);
2159 if (NumString.getAsInteger(10, IntVal))
2160 return -1; // This is not an integer.
2161 if (IntVal > 7) // There are only 8 fcc registers.
2168 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2170 if (Name.startswith("ac")) {
2171 StringRef NumString = Name.substr(2);
2173 if (NumString.getAsInteger(10, IntVal))
2174 return -1; // This is not an integer.
2175 if (IntVal > 3) // There are only 3 acc registers.
2182 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2185 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2194 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2197 CC = StringSwitch<unsigned>(Name)
2200 .Case("msaaccess", 2)
2202 .Case("msamodify", 4)
2203 .Case("msarequest", 5)
2205 .Case("msaunmap", 7)
2211 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2219 int MipsAsmParser::getATReg(SMLoc Loc) {
2220 int AT = AssemblerOptions.back()->getATRegNum();
2222 reportParseError(Loc,
2223 "pseudo-instruction requires $at, which is not available");
2227 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2228 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2231 unsigned MipsAsmParser::getGPR(int RegNo) {
2232 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2236 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2238 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2241 return getReg(RegClass, RegNum);
2244 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2245 MCAsmParser &Parser = getParser();
2246 DEBUG(dbgs() << "parseOperand\n");
2248 // Check if the current operand has a custom associated parser, if so, try to
2249 // custom parse the operand, or fallback to the general approach.
2250 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2251 if (ResTy == MatchOperand_Success)
2253 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2254 // there was a match, but an error occurred, in which case, just return that
2255 // the operand parsing failed.
2256 if (ResTy == MatchOperand_ParseFail)
2259 DEBUG(dbgs() << ".. Generic Parser\n");
2261 switch (getLexer().getKind()) {
2263 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2265 case AsmToken::Dollar: {
2266 // Parse the register.
2267 SMLoc S = Parser.getTok().getLoc();
2269 // Almost all registers have been parsed by custom parsers. There is only
2270 // one exception to this. $zero (and it's alias $0) will reach this point
2271 // for div, divu, and similar instructions because it is not an operand
2272 // to the instruction definition but an explicit register. Special case
2273 // this situation for now.
2274 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2277 // Maybe it is a symbol reference.
2278 StringRef Identifier;
2279 if (Parser.parseIdentifier(Identifier))
2282 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2283 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2284 // Otherwise create a symbol reference.
2286 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2288 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2291 // Else drop to expression parsing.
2292 case AsmToken::LParen:
2293 case AsmToken::Minus:
2294 case AsmToken::Plus:
2295 case AsmToken::Integer:
2296 case AsmToken::Tilde:
2297 case AsmToken::String: {
2298 DEBUG(dbgs() << ".. generic integer\n");
2299 OperandMatchResultTy ResTy = parseImm(Operands);
2300 return ResTy != MatchOperand_Success;
2302 case AsmToken::Percent: {
2303 // It is a symbol reference or constant expression.
2304 const MCExpr *IdVal;
2305 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2306 if (parseRelocOperand(IdVal))
2309 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2311 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2313 } // case AsmToken::Percent
2314 } // switch(getLexer().getKind())
2318 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2319 StringRef RelocStr) {
2321 // Check the type of the expression.
2322 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2323 // It's a constant, evaluate reloc value.
2325 switch (getVariantKind(RelocStr)) {
2326 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2327 // Get the 1st 16-bits.
2328 Val = MCE->getValue() & 0xffff;
2330 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2331 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2332 // 16 bits being negative.
2333 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2335 case MCSymbolRefExpr::VK_Mips_HIGHER:
2336 // Get the 3rd 16-bits.
2337 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2339 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2340 // Get the 4th 16-bits.
2341 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2344 report_fatal_error("unsupported reloc value");
2346 return MCConstantExpr::Create(Val, getContext());
2349 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2350 // It's a symbol, create a symbolic expression from the symbol.
2351 StringRef Symbol = MSRE->getSymbol().getName();
2352 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2353 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2357 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2358 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2360 // Try to create target expression.
2361 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2362 return MipsMCExpr::Create(VK, Expr, getContext());
2364 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2365 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2366 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2370 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2371 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2372 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2375 // Just return the original expression.
2379 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2381 switch (Expr->getKind()) {
2382 case MCExpr::Constant:
2384 case MCExpr::SymbolRef:
2385 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2386 case MCExpr::Binary:
2387 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2388 if (!isEvaluated(BE->getLHS()))
2390 return isEvaluated(BE->getRHS());
2393 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2394 case MCExpr::Target:
2400 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2401 MCAsmParser &Parser = getParser();
2402 Parser.Lex(); // Eat the % token.
2403 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2404 if (Tok.isNot(AsmToken::Identifier))
2407 std::string Str = Tok.getIdentifier().str();
2409 Parser.Lex(); // Eat the identifier.
2410 // Now make an expression from the rest of the operand.
2411 const MCExpr *IdVal;
2414 if (getLexer().getKind() == AsmToken::LParen) {
2416 Parser.Lex(); // Eat the '(' token.
2417 if (getLexer().getKind() == AsmToken::Percent) {
2418 Parser.Lex(); // Eat the % token.
2419 const AsmToken &nextTok = Parser.getTok();
2420 if (nextTok.isNot(AsmToken::Identifier))
2423 Str += nextTok.getIdentifier();
2424 Parser.Lex(); // Eat the identifier.
2425 if (getLexer().getKind() != AsmToken::LParen)
2430 if (getParser().parseParenExpression(IdVal, EndLoc))
2433 while (getLexer().getKind() == AsmToken::RParen)
2434 Parser.Lex(); // Eat the ')' token.
2437 return true; // Parenthesis must follow the relocation operand.
2439 Res = evaluateRelocExpr(IdVal, Str);
2443 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2445 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2446 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2447 if (ResTy == MatchOperand_Success) {
2448 assert(Operands.size() == 1);
2449 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2450 StartLoc = Operand.getStartLoc();
2451 EndLoc = Operand.getEndLoc();
2453 // AFAIK, we only support numeric registers and named GPR's in CFI
2455 // Don't worry about eating tokens before failing. Using an unrecognised
2456 // register is a parse error.
2457 if (Operand.isGPRAsmReg()) {
2458 // Resolve to GPR32 or GPR64 appropriately.
2459 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2462 return (RegNo == (unsigned)-1);
2465 assert(Operands.size() == 0);
2466 return (RegNo == (unsigned)-1);
2469 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2470 MCAsmParser &Parser = getParser();
2474 while (getLexer().getKind() == AsmToken::LParen)
2477 switch (getLexer().getKind()) {
2480 case AsmToken::Identifier:
2481 case AsmToken::LParen:
2482 case AsmToken::Integer:
2483 case AsmToken::Minus:
2484 case AsmToken::Plus:
2486 Result = getParser().parseParenExpression(Res, S);
2488 Result = (getParser().parseExpression(Res));
2489 while (getLexer().getKind() == AsmToken::RParen)
2492 case AsmToken::Percent:
2493 Result = parseRelocOperand(Res);
2498 MipsAsmParser::OperandMatchResultTy
2499 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2500 MCAsmParser &Parser = getParser();
2501 DEBUG(dbgs() << "parseMemOperand\n");
2502 const MCExpr *IdVal = nullptr;
2504 bool isParenExpr = false;
2505 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2506 // First operand is the offset.
2507 S = Parser.getTok().getLoc();
2509 if (getLexer().getKind() == AsmToken::LParen) {
2514 if (getLexer().getKind() != AsmToken::Dollar) {
2515 if (parseMemOffset(IdVal, isParenExpr))
2516 return MatchOperand_ParseFail;
2518 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2519 if (Tok.isNot(AsmToken::LParen)) {
2520 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2521 if (Mnemonic.getToken() == "la") {
2523 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2524 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2525 return MatchOperand_Success;
2527 if (Tok.is(AsmToken::EndOfStatement)) {
2529 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2531 // Zero register assumed, add a memory operand with ZERO as its base.
2532 // "Base" will be managed by k_Memory.
2533 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2536 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2537 return MatchOperand_Success;
2539 Error(Parser.getTok().getLoc(), "'(' expected");
2540 return MatchOperand_ParseFail;
2543 Parser.Lex(); // Eat the '(' token.
2546 Res = parseAnyRegister(Operands);
2547 if (Res != MatchOperand_Success)
2550 if (Parser.getTok().isNot(AsmToken::RParen)) {
2551 Error(Parser.getTok().getLoc(), "')' expected");
2552 return MatchOperand_ParseFail;
2555 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2557 Parser.Lex(); // Eat the ')' token.
2560 IdVal = MCConstantExpr::Create(0, getContext());
2562 // Replace the register operand with the memory operand.
2563 std::unique_ptr<MipsOperand> op(
2564 static_cast<MipsOperand *>(Operands.back().release()));
2565 // Remove the register from the operands.
2566 // "op" will be managed by k_Memory.
2567 Operands.pop_back();
2568 // Add the memory operand.
2569 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2571 if (IdVal->EvaluateAsAbsolute(Imm))
2572 IdVal = MCConstantExpr::Create(Imm, getContext());
2573 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2574 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2578 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2579 return MatchOperand_Success;
2582 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2583 MCAsmParser &Parser = getParser();
2584 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2586 SMLoc S = Parser.getTok().getLoc();
2588 if (Sym->isVariable())
2589 Expr = Sym->getVariableValue();
2592 if (Expr->getKind() == MCExpr::SymbolRef) {
2593 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2594 StringRef DefSymbol = Ref->getSymbol().getName();
2595 if (DefSymbol.startswith("$")) {
2596 OperandMatchResultTy ResTy =
2597 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2598 if (ResTy == MatchOperand_Success) {
2601 } else if (ResTy == MatchOperand_ParseFail)
2602 llvm_unreachable("Should never ParseFail");
2605 } else if (Expr->getKind() == MCExpr::Constant) {
2607 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2609 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2616 MipsAsmParser::OperandMatchResultTy
2617 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2618 StringRef Identifier,
2620 int Index = matchCPURegisterName(Identifier);
2622 Operands.push_back(MipsOperand::createGPRReg(
2623 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2624 return MatchOperand_Success;
2627 Index = matchHWRegsRegisterName(Identifier);
2629 Operands.push_back(MipsOperand::createHWRegsReg(
2630 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2631 return MatchOperand_Success;
2634 Index = matchFPURegisterName(Identifier);
2636 Operands.push_back(MipsOperand::createFGRReg(
2637 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2638 return MatchOperand_Success;
2641 Index = matchFCCRegisterName(Identifier);
2643 Operands.push_back(MipsOperand::createFCCReg(
2644 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2645 return MatchOperand_Success;
2648 Index = matchACRegisterName(Identifier);
2650 Operands.push_back(MipsOperand::createACCReg(
2651 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2652 return MatchOperand_Success;
2655 Index = matchMSA128RegisterName(Identifier);
2657 Operands.push_back(MipsOperand::createMSA128Reg(
2658 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2659 return MatchOperand_Success;
2662 Index = matchMSA128CtrlRegisterName(Identifier);
2664 Operands.push_back(MipsOperand::createMSACtrlReg(
2665 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2666 return MatchOperand_Success;
2669 return MatchOperand_NoMatch;
2672 MipsAsmParser::OperandMatchResultTy
2673 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2674 MCAsmParser &Parser = getParser();
2675 auto Token = Parser.getLexer().peekTok(false);
2677 if (Token.is(AsmToken::Identifier)) {
2678 DEBUG(dbgs() << ".. identifier\n");
2679 StringRef Identifier = Token.getIdentifier();
2680 OperandMatchResultTy ResTy =
2681 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2683 } else if (Token.is(AsmToken::Integer)) {
2684 DEBUG(dbgs() << ".. integer\n");
2685 Operands.push_back(MipsOperand::createNumericReg(
2686 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2688 return MatchOperand_Success;
2691 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2693 return MatchOperand_NoMatch;
2696 MipsAsmParser::OperandMatchResultTy
2697 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2698 MCAsmParser &Parser = getParser();
2699 DEBUG(dbgs() << "parseAnyRegister\n");
2701 auto Token = Parser.getTok();
2703 SMLoc S = Token.getLoc();
2705 if (Token.isNot(AsmToken::Dollar)) {
2706 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2707 if (Token.is(AsmToken::Identifier)) {
2708 if (searchSymbolAlias(Operands))
2709 return MatchOperand_Success;
2711 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2712 return MatchOperand_NoMatch;
2714 DEBUG(dbgs() << ".. $\n");
2716 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2717 if (ResTy == MatchOperand_Success) {
2719 Parser.Lex(); // identifier
2724 MipsAsmParser::OperandMatchResultTy
2725 MipsAsmParser::parseImm(OperandVector &Operands) {
2726 MCAsmParser &Parser = getParser();
2727 switch (getLexer().getKind()) {
2729 return MatchOperand_NoMatch;
2730 case AsmToken::LParen:
2731 case AsmToken::Minus:
2732 case AsmToken::Plus:
2733 case AsmToken::Integer:
2734 case AsmToken::Tilde:
2735 case AsmToken::String:
2739 const MCExpr *IdVal;
2740 SMLoc S = Parser.getTok().getLoc();
2741 if (getParser().parseExpression(IdVal))
2742 return MatchOperand_ParseFail;
2744 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2745 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2746 return MatchOperand_Success;
2749 MipsAsmParser::OperandMatchResultTy
2750 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2751 MCAsmParser &Parser = getParser();
2752 DEBUG(dbgs() << "parseJumpTarget\n");
2754 SMLoc S = getLexer().getLoc();
2756 // Integers and expressions are acceptable
2757 OperandMatchResultTy ResTy = parseImm(Operands);
2758 if (ResTy != MatchOperand_NoMatch)
2761 // Registers are a valid target and have priority over symbols.
2762 ResTy = parseAnyRegister(Operands);
2763 if (ResTy != MatchOperand_NoMatch)
2766 const MCExpr *Expr = nullptr;
2767 if (Parser.parseExpression(Expr)) {
2768 // We have no way of knowing if a symbol was consumed so we must ParseFail
2769 return MatchOperand_ParseFail;
2772 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2773 return MatchOperand_Success;
2776 MipsAsmParser::OperandMatchResultTy
2777 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2778 MCAsmParser &Parser = getParser();
2779 const MCExpr *IdVal;
2780 // If the first token is '$' we may have register operand.
2781 if (Parser.getTok().is(AsmToken::Dollar))
2782 return MatchOperand_NoMatch;
2783 SMLoc S = Parser.getTok().getLoc();
2784 if (getParser().parseExpression(IdVal))
2785 return MatchOperand_ParseFail;
2786 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2787 assert(MCE && "Unexpected MCExpr type.");
2788 int64_t Val = MCE->getValue();
2789 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2790 Operands.push_back(MipsOperand::CreateImm(
2791 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2792 return MatchOperand_Success;
2795 MipsAsmParser::OperandMatchResultTy
2796 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2797 MCAsmParser &Parser = getParser();
2798 switch (getLexer().getKind()) {
2800 return MatchOperand_NoMatch;
2801 case AsmToken::LParen:
2802 case AsmToken::Plus:
2803 case AsmToken::Minus:
2804 case AsmToken::Integer:
2809 SMLoc S = Parser.getTok().getLoc();
2811 if (getParser().parseExpression(Expr))
2812 return MatchOperand_ParseFail;
2815 if (!Expr->EvaluateAsAbsolute(Val)) {
2816 Error(S, "expected immediate value");
2817 return MatchOperand_ParseFail;
2820 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2821 // and because the CPU always adds one to the immediate field, the allowed
2822 // range becomes 1..4. We'll only check the range here and will deal
2823 // with the addition/subtraction when actually decoding/encoding
2825 if (Val < 1 || Val > 4) {
2826 Error(S, "immediate not in range (1..4)");
2827 return MatchOperand_ParseFail;
2831 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2832 return MatchOperand_Success;
2835 MipsAsmParser::OperandMatchResultTy
2836 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2837 MCAsmParser &Parser = getParser();
2838 SmallVector<unsigned, 10> Regs;
2840 unsigned PrevReg = Mips::NoRegister;
2841 bool RegRange = false;
2842 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2844 if (Parser.getTok().isNot(AsmToken::Dollar))
2845 return MatchOperand_ParseFail;
2847 SMLoc S = Parser.getTok().getLoc();
2848 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2849 SMLoc E = getLexer().getLoc();
2850 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2851 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2853 // Remove last register operand because registers from register range
2854 // should be inserted first.
2855 if (RegNo == Mips::RA) {
2856 Regs.push_back(RegNo);
2858 unsigned TmpReg = PrevReg + 1;
2859 while (TmpReg <= RegNo) {
2860 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2861 Error(E, "invalid register operand");
2862 return MatchOperand_ParseFail;
2866 Regs.push_back(TmpReg++);
2872 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2873 (RegNo != Mips::RA)) {
2874 Error(E, "$16 or $31 expected");
2875 return MatchOperand_ParseFail;
2876 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2877 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2878 Error(E, "invalid register operand");
2879 return MatchOperand_ParseFail;
2880 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2881 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2882 Error(E, "consecutive register numbers expected");
2883 return MatchOperand_ParseFail;
2886 Regs.push_back(RegNo);
2889 if (Parser.getTok().is(AsmToken::Minus))
2892 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2893 !Parser.getTok().isNot(AsmToken::Comma)) {
2894 Error(E, "',' or '-' expected");
2895 return MatchOperand_ParseFail;
2898 Lex(); // Consume comma or minus
2899 if (Parser.getTok().isNot(AsmToken::Dollar))
2905 SMLoc E = Parser.getTok().getLoc();
2906 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2907 parseMemOperand(Operands);
2908 return MatchOperand_Success;
2911 MipsAsmParser::OperandMatchResultTy
2912 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2913 MCAsmParser &Parser = getParser();
2915 SMLoc S = Parser.getTok().getLoc();
2916 if (parseAnyRegister(Operands) != MatchOperand_Success)
2917 return MatchOperand_ParseFail;
2919 SMLoc E = Parser.getTok().getLoc();
2920 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2921 unsigned Reg = Op.getGPR32Reg();
2922 Operands.pop_back();
2923 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2924 return MatchOperand_Success;
2927 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2929 MCSymbolRefExpr::VariantKind VK =
2930 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2931 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2932 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2933 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2934 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2935 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2936 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2937 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2938 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2939 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2940 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2941 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2942 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2943 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2944 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2945 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2946 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2947 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2948 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2949 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2950 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2951 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2952 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2953 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2954 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2955 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2956 .Default(MCSymbolRefExpr::VK_None);
2958 assert(VK != MCSymbolRefExpr::VK_None);
2963 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2965 /// ::= '(', register, ')'
2966 /// handle it before we iterate so we don't get tripped up by the lack of
2968 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2969 MCAsmParser &Parser = getParser();
2970 if (getLexer().is(AsmToken::LParen)) {
2972 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2974 if (parseOperand(Operands, Name)) {
2975 SMLoc Loc = getLexer().getLoc();
2976 Parser.eatToEndOfStatement();
2977 return Error(Loc, "unexpected token in argument list");
2979 if (Parser.getTok().isNot(AsmToken::RParen)) {
2980 SMLoc Loc = getLexer().getLoc();
2981 Parser.eatToEndOfStatement();
2982 return Error(Loc, "unexpected token, expected ')'");
2985 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2991 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2992 /// either one of these.
2993 /// ::= '[', register, ']'
2994 /// ::= '[', integer, ']'
2995 /// handle it before we iterate so we don't get tripped up by the lack of
2997 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2998 OperandVector &Operands) {
2999 MCAsmParser &Parser = getParser();
3000 if (getLexer().is(AsmToken::LBrac)) {
3002 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
3004 if (parseOperand(Operands, Name)) {
3005 SMLoc Loc = getLexer().getLoc();
3006 Parser.eatToEndOfStatement();
3007 return Error(Loc, "unexpected token in argument list");
3009 if (Parser.getTok().isNot(AsmToken::RBrac)) {
3010 SMLoc Loc = getLexer().getLoc();
3011 Parser.eatToEndOfStatement();
3012 return Error(Loc, "unexpected token, expected ']'");
3015 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
3021 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
3022 SMLoc NameLoc, OperandVector &Operands) {
3023 MCAsmParser &Parser = getParser();
3024 DEBUG(dbgs() << "ParseInstruction\n");
3026 // We have reached first instruction, module directive are now forbidden.
3027 getTargetStreamer().forbidModuleDirective();
3029 // Check if we have valid mnemonic
3030 if (!mnemonicIsValid(Name, 0)) {
3031 Parser.eatToEndOfStatement();
3032 return Error(NameLoc, "unknown instruction");
3034 // First operand in MCInst is instruction mnemonic.
3035 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
3037 // Read the remaining operands.
3038 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3039 // Read the first operand.
3040 if (parseOperand(Operands, Name)) {
3041 SMLoc Loc = getLexer().getLoc();
3042 Parser.eatToEndOfStatement();
3043 return Error(Loc, "unexpected token in argument list");
3045 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
3047 // AFAIK, parenthesis suffixes are never on the first operand
3049 while (getLexer().is(AsmToken::Comma)) {
3050 Parser.Lex(); // Eat the comma.
3051 // Parse and remember the operand.
3052 if (parseOperand(Operands, Name)) {
3053 SMLoc Loc = getLexer().getLoc();
3054 Parser.eatToEndOfStatement();
3055 return Error(Loc, "unexpected token in argument list");
3057 // Parse bracket and parenthesis suffixes before we iterate
3058 if (getLexer().is(AsmToken::LBrac)) {
3059 if (parseBracketSuffix(Name, Operands))
3061 } else if (getLexer().is(AsmToken::LParen) &&
3062 parseParenSuffix(Name, Operands))
3066 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3067 SMLoc Loc = getLexer().getLoc();
3068 Parser.eatToEndOfStatement();
3069 return Error(Loc, "unexpected token in argument list");
3071 Parser.Lex(); // Consume the EndOfStatement.
3075 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3076 MCAsmParser &Parser = getParser();
3077 SMLoc Loc = getLexer().getLoc();
3078 Parser.eatToEndOfStatement();
3079 return Error(Loc, ErrorMsg);
3082 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3083 return Error(Loc, ErrorMsg);
3086 bool MipsAsmParser::parseSetNoAtDirective() {
3087 MCAsmParser &Parser = getParser();
3088 // Line should look like: ".set noat".
3090 AssemblerOptions.back()->setATReg(0);
3093 // If this is not the end of the statement, report an error.
3094 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3095 reportParseError("unexpected token, expected end of statement");
3098 Parser.Lex(); // Consume the EndOfStatement.
3102 bool MipsAsmParser::parseSetAtDirective() {
3103 MCAsmParser &Parser = getParser();
3104 // Line can be .set at - defaults to $1
3108 if (getLexer().is(AsmToken::EndOfStatement)) {
3109 AssemblerOptions.back()->setATReg(1);
3110 Parser.Lex(); // Consume the EndOfStatement.
3112 } else if (getLexer().is(AsmToken::Equal)) {
3113 getParser().Lex(); // Eat the '='.
3114 if (getLexer().isNot(AsmToken::Dollar)) {
3115 reportParseError("unexpected token, expected dollar sign '$'");
3118 Parser.Lex(); // Eat the '$'.
3119 const AsmToken &Reg = Parser.getTok();
3120 if (Reg.is(AsmToken::Identifier)) {
3121 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3122 } else if (Reg.is(AsmToken::Integer)) {
3123 AtRegNo = Reg.getIntVal();
3125 reportParseError("unexpected token, expected identifier or integer");
3129 if (AtRegNo < 0 || AtRegNo > 31) {
3130 reportParseError("unexpected token in statement");
3134 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3135 reportParseError("invalid register");
3138 getParser().Lex(); // Eat the register.
3140 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3141 reportParseError("unexpected token, expected end of statement");
3144 Parser.Lex(); // Consume the EndOfStatement.
3147 reportParseError("unexpected token in statement");
3152 bool MipsAsmParser::parseSetReorderDirective() {
3153 MCAsmParser &Parser = getParser();
3155 // If this is not the end of the statement, report an error.
3156 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3157 reportParseError("unexpected token, expected end of statement");
3160 AssemblerOptions.back()->setReorder();
3161 getTargetStreamer().emitDirectiveSetReorder();
3162 Parser.Lex(); // Consume the EndOfStatement.
3166 bool MipsAsmParser::parseSetNoReorderDirective() {
3167 MCAsmParser &Parser = getParser();
3169 // If this is not the end of the statement, report an error.
3170 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3171 reportParseError("unexpected token, expected end of statement");
3174 AssemblerOptions.back()->setNoReorder();
3175 getTargetStreamer().emitDirectiveSetNoReorder();
3176 Parser.Lex(); // Consume the EndOfStatement.
3180 bool MipsAsmParser::parseSetMacroDirective() {
3181 MCAsmParser &Parser = getParser();
3183 // If this is not the end of the statement, report an error.
3184 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3185 reportParseError("unexpected token, expected end of statement");
3188 AssemblerOptions.back()->setMacro();
3189 Parser.Lex(); // Consume the EndOfStatement.
3193 bool MipsAsmParser::parseSetNoMacroDirective() {
3194 MCAsmParser &Parser = getParser();
3196 // If this is not the end of the statement, report an error.
3197 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3198 reportParseError("unexpected token, expected end of statement");
3201 if (AssemblerOptions.back()->isReorder()) {
3202 reportParseError("`noreorder' must be set before `nomacro'");
3205 AssemblerOptions.back()->setNoMacro();
3206 Parser.Lex(); // Consume the EndOfStatement.
3210 bool MipsAsmParser::parseSetMsaDirective() {
3211 MCAsmParser &Parser = getParser();
3214 // If this is not the end of the statement, report an error.
3215 if (getLexer().isNot(AsmToken::EndOfStatement))
3216 return reportParseError("unexpected token, expected end of statement");
3218 setFeatureBits(Mips::FeatureMSA, "msa");
3219 getTargetStreamer().emitDirectiveSetMsa();
3223 bool MipsAsmParser::parseSetNoMsaDirective() {
3224 MCAsmParser &Parser = getParser();
3227 // If this is not the end of the statement, report an error.
3228 if (getLexer().isNot(AsmToken::EndOfStatement))
3229 return reportParseError("unexpected token, expected end of statement");
3231 clearFeatureBits(Mips::FeatureMSA, "msa");
3232 getTargetStreamer().emitDirectiveSetNoMsa();
3236 bool MipsAsmParser::parseSetNoDspDirective() {
3237 MCAsmParser &Parser = getParser();
3238 Parser.Lex(); // Eat "nodsp".
3240 // If this is not the end of the statement, report an error.
3241 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3242 reportParseError("unexpected token, expected end of statement");
3246 clearFeatureBits(Mips::FeatureDSP, "dsp");
3247 getTargetStreamer().emitDirectiveSetNoDsp();
3251 bool MipsAsmParser::parseSetMips16Directive() {
3252 MCAsmParser &Parser = getParser();
3253 Parser.Lex(); // Eat "mips16".
3255 // If this is not the end of the statement, report an error.
3256 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3257 reportParseError("unexpected token, expected end of statement");
3261 setFeatureBits(Mips::FeatureMips16, "mips16");
3262 getTargetStreamer().emitDirectiveSetMips16();
3263 Parser.Lex(); // Consume the EndOfStatement.
3267 bool MipsAsmParser::parseSetNoMips16Directive() {
3268 MCAsmParser &Parser = getParser();
3269 Parser.Lex(); // Eat "nomips16".
3271 // If this is not the end of the statement, report an error.
3272 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3273 reportParseError("unexpected token, expected end of statement");
3277 clearFeatureBits(Mips::FeatureMips16, "mips16");
3278 getTargetStreamer().emitDirectiveSetNoMips16();
3279 Parser.Lex(); // Consume the EndOfStatement.
3283 bool MipsAsmParser::parseSetFpDirective() {
3284 MCAsmParser &Parser = getParser();
3285 MipsABIFlagsSection::FpABIKind FpAbiVal;
3286 // Line can be: .set fp=32
3289 Parser.Lex(); // Eat fp token
3290 AsmToken Tok = Parser.getTok();
3291 if (Tok.isNot(AsmToken::Equal)) {
3292 reportParseError("unexpected token, expected equals sign '='");
3295 Parser.Lex(); // Eat '=' token.
3296 Tok = Parser.getTok();
3298 if (!parseFpABIValue(FpAbiVal, ".set"))
3301 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3302 reportParseError("unexpected token, expected end of statement");
3305 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3306 Parser.Lex(); // Consume the EndOfStatement.
3310 bool MipsAsmParser::parseSetPopDirective() {
3311 MCAsmParser &Parser = getParser();
3312 SMLoc Loc = getLexer().getLoc();
3315 if (getLexer().isNot(AsmToken::EndOfStatement))
3316 return reportParseError("unexpected token, expected end of statement");
3318 // Always keep an element on the options "stack" to prevent the user
3319 // from changing the initial options. This is how we remember them.
3320 if (AssemblerOptions.size() == 2)
3321 return reportParseError(Loc, ".set pop with no .set push");
3323 AssemblerOptions.pop_back();
3324 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3326 getTargetStreamer().emitDirectiveSetPop();
3330 bool MipsAsmParser::parseSetPushDirective() {
3331 MCAsmParser &Parser = getParser();
3333 if (getLexer().isNot(AsmToken::EndOfStatement))
3334 return reportParseError("unexpected token, expected end of statement");
3336 // Create a copy of the current assembler options environment and push it.
3337 AssemblerOptions.push_back(
3338 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3340 getTargetStreamer().emitDirectiveSetPush();
3344 bool MipsAsmParser::parseSetAssignment() {
3346 const MCExpr *Value;
3347 MCAsmParser &Parser = getParser();
3349 if (Parser.parseIdentifier(Name))
3350 reportParseError("expected identifier after .set");
3352 if (getLexer().isNot(AsmToken::Comma))
3353 return reportParseError("unexpected token, expected comma");
3356 if (Parser.parseExpression(Value))
3357 return reportParseError("expected valid expression after comma");
3359 // Check if the Name already exists as a symbol.
3360 MCSymbol *Sym = getContext().LookupSymbol(Name);
3362 return reportParseError("symbol already defined");
3363 Sym = getContext().GetOrCreateSymbol(Name);
3364 Sym->setVariableValue(Value);
3369 bool MipsAsmParser::parseSetMips0Directive() {
3370 MCAsmParser &Parser = getParser();
3372 if (getLexer().isNot(AsmToken::EndOfStatement))
3373 return reportParseError("unexpected token, expected end of statement");
3375 // Reset assembler options to their initial values.
3376 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3377 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3379 getTargetStreamer().emitDirectiveSetMips0();
3383 bool MipsAsmParser::parseSetArchDirective() {
3384 MCAsmParser &Parser = getParser();
3386 if (getLexer().isNot(AsmToken::Equal))
3387 return reportParseError("unexpected token, expected equals sign");
3391 if (Parser.parseIdentifier(Arch))
3392 return reportParseError("expected arch identifier");
3394 StringRef ArchFeatureName =
3395 StringSwitch<StringRef>(Arch)
3396 .Case("mips1", "mips1")
3397 .Case("mips2", "mips2")
3398 .Case("mips3", "mips3")
3399 .Case("mips4", "mips4")
3400 .Case("mips5", "mips5")
3401 .Case("mips32", "mips32")
3402 .Case("mips32r2", "mips32r2")
3403 .Case("mips32r6", "mips32r6")
3404 .Case("mips64", "mips64")
3405 .Case("mips64r2", "mips64r2")
3406 .Case("mips64r6", "mips64r6")
3407 .Case("cnmips", "cnmips")
3408 .Case("r4000", "mips3") // This is an implementation of Mips3.
3411 if (ArchFeatureName.empty())
3412 return reportParseError("unsupported architecture");
3414 selectArch(ArchFeatureName);
3415 getTargetStreamer().emitDirectiveSetArch(Arch);
3419 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3420 MCAsmParser &Parser = getParser();
3422 if (getLexer().isNot(AsmToken::EndOfStatement))
3423 return reportParseError("unexpected token, expected end of statement");
3427 llvm_unreachable("Unimplemented feature");
3428 case Mips::FeatureDSP:
3429 setFeatureBits(Mips::FeatureDSP, "dsp");
3430 getTargetStreamer().emitDirectiveSetDsp();
3432 case Mips::FeatureMicroMips:
3433 getTargetStreamer().emitDirectiveSetMicroMips();
3435 case Mips::FeatureMips1:
3436 selectArch("mips1");
3437 getTargetStreamer().emitDirectiveSetMips1();
3439 case Mips::FeatureMips2:
3440 selectArch("mips2");
3441 getTargetStreamer().emitDirectiveSetMips2();
3443 case Mips::FeatureMips3:
3444 selectArch("mips3");
3445 getTargetStreamer().emitDirectiveSetMips3();
3447 case Mips::FeatureMips4:
3448 selectArch("mips4");
3449 getTargetStreamer().emitDirectiveSetMips4();
3451 case Mips::FeatureMips5:
3452 selectArch("mips5");
3453 getTargetStreamer().emitDirectiveSetMips5();
3455 case Mips::FeatureMips32:
3456 selectArch("mips32");
3457 getTargetStreamer().emitDirectiveSetMips32();
3459 case Mips::FeatureMips32r2:
3460 selectArch("mips32r2");
3461 getTargetStreamer().emitDirectiveSetMips32R2();
3463 case Mips::FeatureMips32r6:
3464 selectArch("mips32r6");
3465 getTargetStreamer().emitDirectiveSetMips32R6();
3467 case Mips::FeatureMips64:
3468 selectArch("mips64");
3469 getTargetStreamer().emitDirectiveSetMips64();
3471 case Mips::FeatureMips64r2:
3472 selectArch("mips64r2");
3473 getTargetStreamer().emitDirectiveSetMips64R2();
3475 case Mips::FeatureMips64r6:
3476 selectArch("mips64r6");
3477 getTargetStreamer().emitDirectiveSetMips64R6();
3483 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3484 MCAsmParser &Parser = getParser();
3485 if (getLexer().isNot(AsmToken::Comma)) {
3486 SMLoc Loc = getLexer().getLoc();
3487 Parser.eatToEndOfStatement();
3488 return Error(Loc, ErrorStr);
3491 Parser.Lex(); // Eat the comma.
3495 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3496 if (AssemblerOptions.back()->isReorder())
3497 Warning(Loc, ".cpload should be inside a noreorder section");
3499 if (inMips16Mode()) {
3500 reportParseError(".cpload is not supported in Mips16 mode");
3504 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3505 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3506 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3507 reportParseError("expected register containing function address");
3511 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3512 if (!RegOpnd.isGPRAsmReg()) {
3513 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3517 // If this is not the end of the statement, report an error.
3518 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3519 reportParseError("unexpected token, expected end of statement");
3523 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3527 bool MipsAsmParser::parseDirectiveCPSetup() {
3528 MCAsmParser &Parser = getParser();
3531 bool SaveIsReg = true;
3533 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3534 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3535 if (ResTy == MatchOperand_NoMatch) {
3536 reportParseError("expected register containing function address");
3537 Parser.eatToEndOfStatement();
3541 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3542 if (!FuncRegOpnd.isGPRAsmReg()) {
3543 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3544 Parser.eatToEndOfStatement();
3548 FuncReg = FuncRegOpnd.getGPR32Reg();
3551 if (!eatComma("unexpected token, expected comma"))
3554 ResTy = parseAnyRegister(TmpReg);
3555 if (ResTy == MatchOperand_NoMatch) {
3556 const AsmToken &Tok = Parser.getTok();
3557 if (Tok.is(AsmToken::Integer)) {
3558 Save = Tok.getIntVal();
3562 reportParseError("expected save register or stack offset");
3563 Parser.eatToEndOfStatement();
3567 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3568 if (!SaveOpnd.isGPRAsmReg()) {
3569 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3570 Parser.eatToEndOfStatement();
3573 Save = SaveOpnd.getGPR32Reg();
3576 if (!eatComma("unexpected token, expected comma"))
3580 if (Parser.parseIdentifier(Name))
3581 reportParseError("expected identifier");
3582 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3584 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3588 bool MipsAsmParser::parseDirectiveNaN() {
3589 MCAsmParser &Parser = getParser();
3590 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3591 const AsmToken &Tok = Parser.getTok();
3593 if (Tok.getString() == "2008") {
3595 getTargetStreamer().emitDirectiveNaN2008();
3597 } else if (Tok.getString() == "legacy") {
3599 getTargetStreamer().emitDirectiveNaNLegacy();
3603 // If we don't recognize the option passed to the .nan
3604 // directive (e.g. no option or unknown option), emit an error.
3605 reportParseError("invalid option in .nan directive");
3609 bool MipsAsmParser::parseDirectiveSet() {
3610 MCAsmParser &Parser = getParser();
3611 // Get the next token.
3612 const AsmToken &Tok = Parser.getTok();
3614 if (Tok.getString() == "noat") {
3615 return parseSetNoAtDirective();
3616 } else if (Tok.getString() == "at") {
3617 return parseSetAtDirective();
3618 } else if (Tok.getString() == "arch") {
3619 return parseSetArchDirective();
3620 } else if (Tok.getString() == "fp") {
3621 return parseSetFpDirective();
3622 } else if (Tok.getString() == "pop") {
3623 return parseSetPopDirective();
3624 } else if (Tok.getString() == "push") {
3625 return parseSetPushDirective();
3626 } else if (Tok.getString() == "reorder") {
3627 return parseSetReorderDirective();
3628 } else if (Tok.getString() == "noreorder") {
3629 return parseSetNoReorderDirective();
3630 } else if (Tok.getString() == "macro") {
3631 return parseSetMacroDirective();
3632 } else if (Tok.getString() == "nomacro") {
3633 return parseSetNoMacroDirective();
3634 } else if (Tok.getString() == "mips16") {
3635 return parseSetMips16Directive();
3636 } else if (Tok.getString() == "nomips16") {
3637 return parseSetNoMips16Directive();
3638 } else if (Tok.getString() == "nomicromips") {
3639 getTargetStreamer().emitDirectiveSetNoMicroMips();
3640 Parser.eatToEndOfStatement();
3642 } else if (Tok.getString() == "micromips") {
3643 return parseSetFeature(Mips::FeatureMicroMips);
3644 } else if (Tok.getString() == "mips0") {
3645 return parseSetMips0Directive();
3646 } else if (Tok.getString() == "mips1") {
3647 return parseSetFeature(Mips::FeatureMips1);
3648 } else if (Tok.getString() == "mips2") {
3649 return parseSetFeature(Mips::FeatureMips2);
3650 } else if (Tok.getString() == "mips3") {
3651 return parseSetFeature(Mips::FeatureMips3);
3652 } else if (Tok.getString() == "mips4") {
3653 return parseSetFeature(Mips::FeatureMips4);
3654 } else if (Tok.getString() == "mips5") {
3655 return parseSetFeature(Mips::FeatureMips5);
3656 } else if (Tok.getString() == "mips32") {
3657 return parseSetFeature(Mips::FeatureMips32);
3658 } else if (Tok.getString() == "mips32r2") {
3659 return parseSetFeature(Mips::FeatureMips32r2);
3660 } else if (Tok.getString() == "mips32r6") {
3661 return parseSetFeature(Mips::FeatureMips32r6);
3662 } else if (Tok.getString() == "mips64") {
3663 return parseSetFeature(Mips::FeatureMips64);
3664 } else if (Tok.getString() == "mips64r2") {
3665 return parseSetFeature(Mips::FeatureMips64r2);
3666 } else if (Tok.getString() == "mips64r6") {
3667 return parseSetFeature(Mips::FeatureMips64r6);
3668 } else if (Tok.getString() == "dsp") {
3669 return parseSetFeature(Mips::FeatureDSP);
3670 } else if (Tok.getString() == "nodsp") {
3671 return parseSetNoDspDirective();
3672 } else if (Tok.getString() == "msa") {
3673 return parseSetMsaDirective();
3674 } else if (Tok.getString() == "nomsa") {
3675 return parseSetNoMsaDirective();
3677 // It is just an identifier, look for an assignment.
3678 parseSetAssignment();
3685 /// parseDataDirective
3686 /// ::= .word [ expression (, expression)* ]
3687 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3688 MCAsmParser &Parser = getParser();
3689 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3691 const MCExpr *Value;
3692 if (getParser().parseExpression(Value))
3695 getParser().getStreamer().EmitValue(Value, Size);
3697 if (getLexer().is(AsmToken::EndOfStatement))
3700 if (getLexer().isNot(AsmToken::Comma))
3701 return Error(L, "unexpected token, expected comma");
3710 /// parseDirectiveGpWord
3711 /// ::= .gpword local_sym
3712 bool MipsAsmParser::parseDirectiveGpWord() {
3713 MCAsmParser &Parser = getParser();
3714 const MCExpr *Value;
3715 // EmitGPRel32Value requires an expression, so we are using base class
3716 // method to evaluate the expression.
3717 if (getParser().parseExpression(Value))
3719 getParser().getStreamer().EmitGPRel32Value(Value);
3721 if (getLexer().isNot(AsmToken::EndOfStatement))
3722 return Error(getLexer().getLoc(),
3723 "unexpected token, expected end of statement");
3724 Parser.Lex(); // Eat EndOfStatement token.
3728 /// parseDirectiveGpDWord
3729 /// ::= .gpdword local_sym
3730 bool MipsAsmParser::parseDirectiveGpDWord() {
3731 MCAsmParser &Parser = getParser();
3732 const MCExpr *Value;
3733 // EmitGPRel64Value requires an expression, so we are using base class
3734 // method to evaluate the expression.
3735 if (getParser().parseExpression(Value))
3737 getParser().getStreamer().EmitGPRel64Value(Value);
3739 if (getLexer().isNot(AsmToken::EndOfStatement))
3740 return Error(getLexer().getLoc(),
3741 "unexpected token, expected end of statement");
3742 Parser.Lex(); // Eat EndOfStatement token.
3746 bool MipsAsmParser::parseDirectiveOption() {
3747 MCAsmParser &Parser = getParser();
3748 // Get the option token.
3749 AsmToken Tok = Parser.getTok();
3750 // At the moment only identifiers are supported.
3751 if (Tok.isNot(AsmToken::Identifier)) {
3752 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3753 Parser.eatToEndOfStatement();
3757 StringRef Option = Tok.getIdentifier();
3759 if (Option == "pic0") {
3760 getTargetStreamer().emitDirectiveOptionPic0();
3762 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3763 Error(Parser.getTok().getLoc(),
3764 "unexpected token, expected end of statement");
3765 Parser.eatToEndOfStatement();
3770 if (Option == "pic2") {
3771 getTargetStreamer().emitDirectiveOptionPic2();
3773 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3774 Error(Parser.getTok().getLoc(),
3775 "unexpected token, expected end of statement");
3776 Parser.eatToEndOfStatement();
3782 Warning(Parser.getTok().getLoc(),
3783 "unknown option, expected 'pic0' or 'pic2'");
3784 Parser.eatToEndOfStatement();
3788 /// parseDirectiveModule
3789 /// ::= .module oddspreg
3790 /// ::= .module nooddspreg
3791 /// ::= .module fp=value
3792 bool MipsAsmParser::parseDirectiveModule() {
3793 MCAsmParser &Parser = getParser();
3794 MCAsmLexer &Lexer = getLexer();
3795 SMLoc L = Lexer.getLoc();
3797 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3798 // TODO : get a better message.
3799 reportParseError(".module directive must appear before any code");
3804 if (Parser.parseIdentifier(Option)) {
3805 reportParseError("expected .module option identifier");
3809 if (Option == "oddspreg") {
3810 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3811 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3813 // If this is not the end of the statement, report an error.
3814 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3815 reportParseError("unexpected token, expected end of statement");
3819 return false; // parseDirectiveModule has finished successfully.
3820 } else if (Option == "nooddspreg") {
3822 Error(L, "'.module nooddspreg' requires the O32 ABI");
3826 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3827 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3829 // If this is not the end of the statement, report an error.
3830 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3831 reportParseError("unexpected token, expected end of statement");
3835 return false; // parseDirectiveModule has finished successfully.
3836 } else if (Option == "fp") {
3837 return parseDirectiveModuleFP();
3839 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3843 /// parseDirectiveModuleFP
3847 bool MipsAsmParser::parseDirectiveModuleFP() {
3848 MCAsmParser &Parser = getParser();
3849 MCAsmLexer &Lexer = getLexer();
3851 if (Lexer.isNot(AsmToken::Equal)) {
3852 reportParseError("unexpected token, expected equals sign '='");
3855 Parser.Lex(); // Eat '=' token.
3857 MipsABIFlagsSection::FpABIKind FpABI;
3858 if (!parseFpABIValue(FpABI, ".module"))
3861 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3862 reportParseError("unexpected token, expected end of statement");
3866 // Emit appropriate flags.
3867 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3868 Parser.Lex(); // Consume the EndOfStatement.
3872 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3873 StringRef Directive) {
3874 MCAsmParser &Parser = getParser();
3875 MCAsmLexer &Lexer = getLexer();
3877 if (Lexer.is(AsmToken::Identifier)) {
3878 StringRef Value = Parser.getTok().getString();
3881 if (Value != "xx") {
3882 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3887 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3891 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3895 if (Lexer.is(AsmToken::Integer)) {
3896 unsigned Value = Parser.getTok().getIntVal();
3899 if (Value != 32 && Value != 64) {
3900 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3906 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3910 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3912 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3920 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3921 MCAsmParser &Parser = getParser();
3922 StringRef IDVal = DirectiveID.getString();
3924 if (IDVal == ".cpload")
3925 return parseDirectiveCpLoad(DirectiveID.getLoc());
3926 if (IDVal == ".dword") {
3927 parseDataDirective(8, DirectiveID.getLoc());
3930 if (IDVal == ".ent") {
3931 StringRef SymbolName;
3933 if (Parser.parseIdentifier(SymbolName)) {
3934 reportParseError("expected identifier after .ent");
3938 // There's an undocumented extension that allows an integer to
3939 // follow the name of the procedure which AFAICS is ignored by GAS.
3940 // Example: .ent foo,2
3941 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3942 if (getLexer().isNot(AsmToken::Comma)) {
3943 // Even though we accept this undocumented extension for compatibility
3944 // reasons, the additional integer argument does not actually change
3945 // the behaviour of the '.ent' directive, so we would like to discourage
3946 // its use. We do this by not referring to the extended version in
3947 // error messages which are not directly related to its use.
3948 reportParseError("unexpected token, expected end of statement");
3951 Parser.Lex(); // Eat the comma.
3952 const MCExpr *DummyNumber;
3953 int64_t DummyNumberVal;
3954 // If the user was explicitly trying to use the extended version,
3955 // we still give helpful extension-related error messages.
3956 if (Parser.parseExpression(DummyNumber)) {
3957 reportParseError("expected number after comma");
3960 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3961 reportParseError("expected an absolute expression after comma");
3966 // If this is not the end of the statement, report an error.
3967 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3968 reportParseError("unexpected token, expected end of statement");
3972 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3974 getTargetStreamer().emitDirectiveEnt(*Sym);
3979 if (IDVal == ".end") {
3980 StringRef SymbolName;
3982 if (Parser.parseIdentifier(SymbolName)) {
3983 reportParseError("expected identifier after .end");
3987 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3988 reportParseError("unexpected token, expected end of statement");
3992 if (CurrentFn == nullptr) {
3993 reportParseError(".end used without .ent");
3997 if ((SymbolName != CurrentFn->getName())) {
3998 reportParseError(".end symbol does not match .ent symbol");
4002 getTargetStreamer().emitDirectiveEnd(SymbolName);
4003 CurrentFn = nullptr;
4007 if (IDVal == ".frame") {
4008 // .frame $stack_reg, frame_size_in_bytes, $return_reg
4009 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
4010 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
4011 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4012 reportParseError("expected stack register");
4016 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4017 if (!StackRegOpnd.isGPRAsmReg()) {
4018 reportParseError(StackRegOpnd.getStartLoc(),
4019 "expected general purpose register");
4022 unsigned StackReg = StackRegOpnd.getGPR32Reg();
4024 if (Parser.getTok().is(AsmToken::Comma))
4027 reportParseError("unexpected token, expected comma");
4031 // Parse the frame size.
4032 const MCExpr *FrameSize;
4033 int64_t FrameSizeVal;
4035 if (Parser.parseExpression(FrameSize)) {
4036 reportParseError("expected frame size value");
4040 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
4041 reportParseError("frame size not an absolute expression");
4045 if (Parser.getTok().is(AsmToken::Comma))
4048 reportParseError("unexpected token, expected comma");
4052 // Parse the return register.
4054 ResTy = parseAnyRegister(TmpReg);
4055 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
4056 reportParseError("expected return register");
4060 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
4061 if (!ReturnRegOpnd.isGPRAsmReg()) {
4062 reportParseError(ReturnRegOpnd.getStartLoc(),
4063 "expected general purpose register");
4067 // If this is not the end of the statement, report an error.
4068 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4069 reportParseError("unexpected token, expected end of statement");
4073 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
4074 ReturnRegOpnd.getGPR32Reg());
4078 if (IDVal == ".set") {
4079 return parseDirectiveSet();
4082 if (IDVal == ".mask" || IDVal == ".fmask") {
4083 // .mask bitmask, frame_offset
4084 // bitmask: One bit for each register used.
4085 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4086 // first register is expected to be saved.
4088 // .mask 0x80000000, -4
4089 // .fmask 0x80000000, -4
4092 // Parse the bitmask
4093 const MCExpr *BitMask;
4096 if (Parser.parseExpression(BitMask)) {
4097 reportParseError("expected bitmask value");
4101 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4102 reportParseError("bitmask not an absolute expression");
4106 if (Parser.getTok().is(AsmToken::Comma))
4109 reportParseError("unexpected token, expected comma");
4113 // Parse the frame_offset
4114 const MCExpr *FrameOffset;
4115 int64_t FrameOffsetVal;
4117 if (Parser.parseExpression(FrameOffset)) {
4118 reportParseError("expected frame offset value");
4122 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4123 reportParseError("frame offset not an absolute expression");
4127 // If this is not the end of the statement, report an error.
4128 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4129 reportParseError("unexpected token, expected end of statement");
4133 if (IDVal == ".mask")
4134 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4136 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4140 if (IDVal == ".nan")
4141 return parseDirectiveNaN();
4143 if (IDVal == ".gpword") {
4144 parseDirectiveGpWord();
4148 if (IDVal == ".gpdword") {
4149 parseDirectiveGpDWord();
4153 if (IDVal == ".word") {
4154 parseDataDirective(4, DirectiveID.getLoc());
4158 if (IDVal == ".option")
4159 return parseDirectiveOption();
4161 if (IDVal == ".abicalls") {
4162 getTargetStreamer().emitDirectiveAbiCalls();
4163 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4164 Error(Parser.getTok().getLoc(),
4165 "unexpected token, expected end of statement");
4167 Parser.eatToEndOfStatement();
4172 if (IDVal == ".cpsetup")
4173 return parseDirectiveCPSetup();
4175 if (IDVal == ".module")
4176 return parseDirectiveModule();
4181 extern "C" void LLVMInitializeMipsAsmParser() {
4182 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4183 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4184 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4185 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4188 #define GET_REGISTER_MATCHER
4189 #define GET_MATCHER_IMPLEMENTATION
4190 #include "MipsGenAsmMatcher.inc"