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/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/TargetRegistry.h"
35 #define DEBUG_TYPE "mips-asm-parser"
42 class MipsAssemblerOptions {
44 MipsAssemblerOptions(uint64_t Features_) :
45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48 ATReg = Opts->getATRegNum();
49 Reorder = Opts->isReorder();
50 Macro = Opts->isMacro();
51 Features = Opts->getFeatures();
54 unsigned getATRegNum() const { return ATReg; }
55 bool setATReg(unsigned Reg);
57 bool isReorder() const { return Reorder; }
58 void setReorder() { Reorder = true; }
59 void setNoReorder() { Reorder = false; }
61 bool isMacro() const { return Macro; }
62 void setMacro() { Macro = true; }
63 void setNoMacro() { Macro = false; }
65 uint64_t getFeatures() const { return Features; }
66 void setFeatures(uint64_t Features_) { Features = Features_; }
68 // Set of features that are either architecture features or referenced
69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71 // The reason we need this mask is explained in the selectArch function.
72 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
91 class MipsAsmParser : public MCTargetAsmParser {
92 MipsTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
104 // Print a warning along with its fix-it message at the given range.
105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
106 SMRange Range, bool ShowColors = true);
108 #define GET_ASSEMBLER_HEADER
109 #include "MipsGenAsmMatcher.inc"
111 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
114 OperandVector &Operands, MCStreamer &Out,
116 bool MatchingInlineAsm) override;
118 /// Parse a register as used in CFI directives
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
121 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 SMLoc NameLoc, OperandVector &Operands) override;
128 bool ParseDirective(AsmToken DirectiveID) override;
130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
134 StringRef Identifier, SMLoc S);
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy
150 parseRegisterPair (OperandVector &Operands);
152 MipsAsmParser::OperandMatchResultTy
153 parseRegisterList (OperandVector &Operands);
155 bool searchSymbolAlias(OperandVector &Operands);
157 bool parseOperand(OperandVector &, StringRef Mnemonic);
159 bool needsExpansion(MCInst &Inst);
161 // Expands assembly pseudo instructions.
162 // Returns false on success, true otherwise.
163 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
164 SmallVectorImpl<MCInst> &Instructions);
166 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
169 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
174 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
183 bool reportParseError(Twine ErrorMsg);
184 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
186 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
187 bool parseRelocOperand(const MCExpr *&Res);
189 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
191 bool isEvaluated(const MCExpr *Expr);
192 bool parseSetMips0Directive();
193 bool parseSetArchDirective();
194 bool parseSetFeature(uint64_t Feature);
195 bool parseDirectiveCpLoad(SMLoc Loc);
196 bool parseDirectiveCPSetup();
197 bool parseDirectiveNaN();
198 bool parseDirectiveSet();
199 bool parseDirectiveOption();
201 bool parseSetAtDirective();
202 bool parseSetNoAtDirective();
203 bool parseSetMacroDirective();
204 bool parseSetNoMacroDirective();
205 bool parseSetMsaDirective();
206 bool parseSetNoMsaDirective();
207 bool parseSetNoDspDirective();
208 bool parseSetReorderDirective();
209 bool parseSetNoReorderDirective();
210 bool parseSetMips16Directive();
211 bool parseSetNoMips16Directive();
212 bool parseSetFpDirective();
213 bool parseSetPopDirective();
214 bool parseSetPushDirective();
216 bool parseSetAssignment();
218 bool parseDataDirective(unsigned Size, SMLoc L);
219 bool parseDirectiveGpWord();
220 bool parseDirectiveGpDWord();
221 bool parseDirectiveModule();
222 bool parseDirectiveModuleFP();
223 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
224 StringRef Directive);
226 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
228 bool eatComma(StringRef ErrorStr);
230 int matchCPURegisterName(StringRef Symbol);
232 int matchHWRegsRegisterName(StringRef Symbol);
234 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
236 int matchFPURegisterName(StringRef Name);
238 int matchFCCRegisterName(StringRef Name);
240 int matchACRegisterName(StringRef Name);
242 int matchMSA128RegisterName(StringRef Name);
244 int matchMSA128CtrlRegisterName(StringRef Name);
246 unsigned getReg(int RC, int RegNo);
248 unsigned getGPR(int RegNo);
250 int getATReg(SMLoc Loc);
252 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
253 SmallVectorImpl<MCInst> &Instructions);
255 // Helper function that checks if the value of a vector index is within the
256 // boundaries of accepted values for each RegisterKind
257 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
258 bool validateMSAIndex(int Val, int RegKind);
260 // Selects a new architecture by updating the FeatureBits with the necessary
261 // info including implied dependencies.
262 // Internally, it clears all the feature bits related to *any* architecture
263 // and selects the new one using the ToggleFeature functionality of the
264 // MCSubtargetInfo object that handles implied dependencies. The reason we
265 // clear all the arch related bits manually is because ToggleFeature only
266 // clears the features that imply the feature being cleared and not the
267 // features implied by the feature being cleared. This is easier to see
269 // --------------------------------------------------
270 // | Feature | Implies |
271 // | -------------------------------------------------|
272 // | FeatureMips1 | None |
273 // | FeatureMips2 | FeatureMips1 |
274 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
275 // | FeatureMips4 | FeatureMips3 |
277 // --------------------------------------------------
279 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
280 // FeatureMipsGP64 | FeatureMips1)
281 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
282 void selectArch(StringRef ArchFeature) {
283 uint64_t FeatureBits = STI.getFeatureBits();
284 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
285 STI.setFeatureBits(FeatureBits);
286 setAvailableFeatures(
287 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
288 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
291 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
292 if (!(STI.getFeatureBits() & Feature)) {
293 setAvailableFeatures(
294 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
296 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
299 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
300 if (STI.getFeatureBits() & Feature) {
301 setAvailableFeatures(
302 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
304 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
308 enum MipsMatchResultTy {
309 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
310 #define GET_OPERAND_DIAGNOSTIC_TYPES
311 #include "MipsGenAsmMatcher.inc"
312 #undef GET_OPERAND_DIAGNOSTIC_TYPES
316 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
317 const MCInstrInfo &MII, const MCTargetOptions &Options)
318 : MCTargetAsmParser(), STI(sti) {
319 MCAsmParserExtension::Initialize(parser);
321 // Initialize the set of available features.
322 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
324 // Remember the initial assembler options. The user can not modify these.
325 AssemblerOptions.push_back(
326 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
328 // Create an assembler options environment for the user to modify.
329 AssemblerOptions.push_back(
330 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
332 getTargetStreamer().updateABIInfo(*this);
334 // Assert exactly one ABI was chosen.
335 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
336 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
337 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
338 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
340 if (!isABI_O32() && !useOddSPReg() != 0)
341 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
346 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
347 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
349 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
350 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
351 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
352 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
353 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
354 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
356 bool useOddSPReg() const {
357 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
360 bool inMicroMipsMode() const {
361 return STI.getFeatureBits() & Mips::FeatureMicroMips;
363 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
364 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
365 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
366 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
367 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
368 bool hasMips32() const {
369 return (STI.getFeatureBits() & Mips::FeatureMips32);
371 bool hasMips64() const {
372 return (STI.getFeatureBits() & Mips::FeatureMips64);
374 bool hasMips32r2() const {
375 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
377 bool hasMips64r2() const {
378 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
380 bool hasMips32r6() const {
381 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
383 bool hasMips64r6() const {
384 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
386 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
387 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
388 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
390 bool inMips16Mode() const {
391 return STI.getFeatureBits() & Mips::FeatureMips16;
393 // TODO: see how can we get this info.
394 bool abiUsesSoftFloat() const { return false; }
396 /// Warn if RegNo is the current assembler temporary.
397 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
403 /// MipsOperand - Instances of this class represent a parsed Mips machine
405 class MipsOperand : public MCParsedAsmOperand {
407 /// Broad categories of register classes
408 /// The exact class is finalized by the render method.
410 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
411 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
413 RegKind_FCC = 4, /// FCC
414 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
415 RegKind_MSACtrl = 16, /// MSA control registers
416 RegKind_COP2 = 32, /// COP2
417 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
419 RegKind_CCR = 128, /// CCR
420 RegKind_HWRegs = 256, /// HWRegs
421 RegKind_COP3 = 512, /// COP3
423 /// Potentially any (e.g. $1)
424 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
425 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
426 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
431 k_Immediate, /// An immediate (possibly involving symbol references)
432 k_Memory, /// Base + Offset Memory Address
433 k_PhysRegister, /// A physical register from the Mips namespace
434 k_RegisterIndex, /// A register index in one or more RegKind.
435 k_Token, /// A simple token
436 k_RegList, /// A physical register list
437 k_RegPair /// A pair of physical register
441 MipsOperand(KindTy K, MipsAsmParser &Parser)
442 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
445 /// For diagnostics, and checking the assembler temporary
446 MipsAsmParser &AsmParser;
454 unsigned Num; /// Register Number
458 unsigned Index; /// Index into the register class
459 RegKind Kind; /// Bitfield of the kinds it could possibly be
460 const MCRegisterInfo *RegInfo;
473 SmallVector<unsigned, 10> *List;
478 struct PhysRegOp PhysReg;
479 struct RegIdxOp RegIdx;
482 struct RegListOp RegList;
485 SMLoc StartLoc, EndLoc;
487 /// Internal constructor for register kinds
488 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
489 const MCRegisterInfo *RegInfo,
491 MipsAsmParser &Parser) {
492 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
493 Op->RegIdx.Index = Index;
494 Op->RegIdx.RegInfo = RegInfo;
495 Op->RegIdx.Kind = RegKind;
502 /// Coerce the register to GPR32 and return the real register for the current
504 unsigned getGPR32Reg() const {
505 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
506 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
507 unsigned ClassID = Mips::GPR32RegClassID;
508 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
511 /// Coerce the register to GPR32 and return the real register for the current
513 unsigned getGPRMM16Reg() const {
514 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
515 unsigned ClassID = Mips::GPR32RegClassID;
516 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
519 /// Coerce the register to GPR64 and return the real register for the current
521 unsigned getGPR64Reg() const {
522 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
523 unsigned ClassID = Mips::GPR64RegClassID;
524 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
528 /// Coerce the register to AFGR64 and return the real register for the current
530 unsigned getAFGR64Reg() const {
531 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
532 if (RegIdx.Index % 2 != 0)
533 AsmParser.Warning(StartLoc, "Float register should be even.");
534 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
535 .getRegister(RegIdx.Index / 2);
538 /// Coerce the register to FGR64 and return the real register for the current
540 unsigned getFGR64Reg() const {
541 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
542 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
543 .getRegister(RegIdx.Index);
546 /// Coerce the register to FGR32 and return the real register for the current
548 unsigned getFGR32Reg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
550 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
551 .getRegister(RegIdx.Index);
554 /// Coerce the register to FGRH32 and return the real register for the current
556 unsigned getFGRH32Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
558 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
559 .getRegister(RegIdx.Index);
562 /// Coerce the register to FCC and return the real register for the current
564 unsigned getFCCReg() const {
565 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
566 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
567 .getRegister(RegIdx.Index);
570 /// Coerce the register to MSA128 and return the real register for the current
572 unsigned getMSA128Reg() const {
573 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
574 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
576 unsigned ClassID = Mips::MSA128BRegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to MSACtrl and return the real register for the
582 unsigned getMSACtrlReg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
584 unsigned ClassID = Mips::MSACtrlRegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
588 /// Coerce the register to COP2 and return the real register for the
590 unsigned getCOP2Reg() const {
591 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
592 unsigned ClassID = Mips::COP2RegClassID;
593 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
596 /// Coerce the register to COP3 and return the real register for the
598 unsigned getCOP3Reg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
600 unsigned ClassID = Mips::COP3RegClassID;
601 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604 /// Coerce the register to ACC64DSP and return the real register for the
606 unsigned getACC64DSPReg() const {
607 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
608 unsigned ClassID = Mips::ACC64DSPRegClassID;
609 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
612 /// Coerce the register to HI32DSP and return the real register for the
614 unsigned getHI32DSPReg() const {
615 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
616 unsigned ClassID = Mips::HI32DSPRegClassID;
617 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
620 /// Coerce the register to LO32DSP and return the real register for the
622 unsigned getLO32DSPReg() const {
623 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
624 unsigned ClassID = Mips::LO32DSPRegClassID;
625 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
628 /// Coerce the register to CCR and return the real register for the
630 unsigned getCCRReg() const {
631 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
632 unsigned ClassID = Mips::CCRRegClassID;
633 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
636 /// Coerce the register to HWRegs and return the real register for the
638 unsigned getHWRegsReg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
640 unsigned ClassID = Mips::HWRegsRegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
645 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
646 // Add as immediate when possible. Null MCExpr = 0.
648 Inst.addOperand(MCOperand::CreateImm(0));
649 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
650 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
652 Inst.addOperand(MCOperand::CreateExpr(Expr));
655 void addRegOperands(MCInst &Inst, unsigned N) const {
656 llvm_unreachable("Use a custom parser instead");
659 /// Render the operand to an MCInst as a GPR32
660 /// Asserts if the wrong number of operands are requested, or the operand
661 /// is not a k_RegisterIndex compatible with RegKind_GPR
662 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
663 assert(N == 1 && "Invalid number of operands!");
664 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
667 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
668 assert(N == 1 && "Invalid number of operands!");
669 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
672 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
673 assert(N == 1 && "Invalid number of operands!");
674 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
677 /// Render the operand to an MCInst as a GPR64
678 /// Asserts if the wrong number of operands are requested, or the operand
679 /// is not a k_RegisterIndex compatible with RegKind_GPR
680 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
681 assert(N == 1 && "Invalid number of operands!");
682 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
685 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
690 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
695 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
696 assert(N == 1 && "Invalid number of operands!");
697 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
698 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
699 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
700 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
704 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
705 assert(N == 1 && "Invalid number of operands!");
706 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
709 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
710 assert(N == 1 && "Invalid number of operands!");
711 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
714 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
719 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
720 assert(N == 1 && "Invalid number of operands!");
721 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
724 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
725 assert(N == 1 && "Invalid number of operands!");
726 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
729 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
734 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
739 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
744 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
749 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
754 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
759 void addImmOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 const MCExpr *Expr = getImm();
765 void addMemOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 2 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
770 const MCExpr *Expr = getMemOff();
774 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 2 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
779 const MCExpr *Expr = getMemOff();
783 void addRegListOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
786 for (auto RegNo : getRegList())
787 Inst.addOperand(MCOperand::CreateReg(RegNo));
790 void addRegPairOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 2 && "Invalid number of operands!");
792 unsigned RegNo = getRegPair();
793 Inst.addOperand(MCOperand::CreateReg(RegNo++));
794 Inst.addOperand(MCOperand::CreateReg(RegNo));
797 bool isReg() const override {
798 // As a special case until we sort out the definition of div/divu, pretend
799 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
800 if (isGPRAsmReg() && RegIdx.Index == 0)
803 return Kind == k_PhysRegister;
805 bool isRegIdx() const { return Kind == k_RegisterIndex; }
806 bool isImm() const override { return Kind == k_Immediate; }
807 bool isConstantImm() const {
808 return isImm() && dyn_cast<MCConstantExpr>(getImm());
810 bool isToken() const override {
811 // Note: It's not possible to pretend that other operand kinds are tokens.
812 // The matcher emitter checks tokens first.
813 return Kind == k_Token;
815 bool isMem() const override { return Kind == k_Memory; }
816 bool isConstantMemOff() const {
817 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
819 template <unsigned Bits> bool isMemWithSimmOffset() const {
820 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
822 bool isMemWithGRPMM16Base() const {
823 return isMem() && getMemBase()->isMM16AsmReg();
825 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
826 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
827 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
829 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
830 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
831 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
832 && (getMemBase()->getGPR32Reg() == Mips::SP);
834 bool isRegList16() const {
838 int Size = RegList.List->size();
839 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
840 RegList.List->back() != Mips::RA)
843 int PrevReg = *RegList.List->begin();
844 for (int i = 1; i < Size - 1; i++) {
845 int Reg = (*(RegList.List))[i];
846 if ( Reg != PrevReg + 1)
853 bool isInvNum() const { return Kind == k_Immediate; }
854 bool isLSAImm() const {
855 if (!isConstantImm())
857 int64_t Val = getConstantImm();
858 return 1 <= Val && Val <= 4;
860 bool isRegList() const { return Kind == k_RegList; }
862 StringRef getToken() const {
863 assert(Kind == k_Token && "Invalid access!");
864 return StringRef(Tok.Data, Tok.Length);
866 bool isRegPair() const { return Kind == k_RegPair; }
868 unsigned getReg() const override {
869 // As a special case until we sort out the definition of div/divu, pretend
870 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
871 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
872 RegIdx.Kind & RegKind_GPR)
873 return getGPR32Reg(); // FIXME: GPR64 too
875 assert(Kind == k_PhysRegister && "Invalid access!");
879 const MCExpr *getImm() const {
880 assert((Kind == k_Immediate) && "Invalid access!");
884 int64_t getConstantImm() const {
885 const MCExpr *Val = getImm();
886 return static_cast<const MCConstantExpr *>(Val)->getValue();
889 MipsOperand *getMemBase() const {
890 assert((Kind == k_Memory) && "Invalid access!");
894 const MCExpr *getMemOff() const {
895 assert((Kind == k_Memory) && "Invalid access!");
899 int64_t getConstantMemOff() const {
900 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
903 const SmallVectorImpl<unsigned> &getRegList() const {
904 assert((Kind == k_RegList) && "Invalid access!");
905 return *(RegList.List);
908 unsigned getRegPair() const {
909 assert((Kind == k_RegPair) && "Invalid access!");
913 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
914 MipsAsmParser &Parser) {
915 auto Op = make_unique<MipsOperand>(k_Token, Parser);
916 Op->Tok.Data = Str.data();
917 Op->Tok.Length = Str.size();
923 /// Create a numeric register (e.g. $1). The exact register remains
924 /// unresolved until an instruction successfully matches
925 static std::unique_ptr<MipsOperand>
926 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
927 SMLoc E, MipsAsmParser &Parser) {
928 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
929 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
932 /// Create a register that is definitely a GPR.
933 /// This is typically only used for named registers such as $gp.
934 static std::unique_ptr<MipsOperand>
935 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
936 MipsAsmParser &Parser) {
937 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
940 /// Create a register that is definitely a FGR.
941 /// This is typically only used for named registers such as $f0.
942 static std::unique_ptr<MipsOperand>
943 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
944 MipsAsmParser &Parser) {
945 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
948 /// Create a register that is definitely a HWReg.
949 /// This is typically only used for named registers such as $hwr_cpunum.
950 static std::unique_ptr<MipsOperand>
951 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
952 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
953 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
956 /// Create a register that is definitely an FCC.
957 /// This is typically only used for named registers such as $fcc0.
958 static std::unique_ptr<MipsOperand>
959 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
960 MipsAsmParser &Parser) {
961 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
964 /// Create a register that is definitely an ACC.
965 /// This is typically only used for named registers such as $ac0.
966 static std::unique_ptr<MipsOperand>
967 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
968 MipsAsmParser &Parser) {
969 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
972 /// Create a register that is definitely an MSA128.
973 /// This is typically only used for named registers such as $w0.
974 static std::unique_ptr<MipsOperand>
975 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
976 SMLoc E, MipsAsmParser &Parser) {
977 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
980 /// Create a register that is definitely an MSACtrl.
981 /// This is typically only used for named registers such as $msaaccess.
982 static std::unique_ptr<MipsOperand>
983 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
984 SMLoc E, MipsAsmParser &Parser) {
985 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
988 static std::unique_ptr<MipsOperand>
989 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
990 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
997 static std::unique_ptr<MipsOperand>
998 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
999 SMLoc E, MipsAsmParser &Parser) {
1000 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1001 Op->Mem.Base = Base.release();
1008 static std::unique_ptr<MipsOperand>
1009 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1010 MipsAsmParser &Parser) {
1011 assert (Regs.size() > 0 && "Empty list not allowed");
1013 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1014 Op->RegList.List = new SmallVector<unsigned, 10>();
1015 for (auto Reg : Regs)
1016 Op->RegList.List->push_back(Reg);
1017 Op->StartLoc = StartLoc;
1018 Op->EndLoc = EndLoc;
1022 static std::unique_ptr<MipsOperand>
1023 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1024 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1025 Op->RegIdx.Index = RegNo;
1031 bool isGPRAsmReg() const {
1032 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1034 bool isMM16AsmReg() const {
1035 if (!(isRegIdx() && RegIdx.Kind))
1037 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1038 || RegIdx.Index == 16 || RegIdx.Index == 17);
1040 bool isMM16AsmRegZero() const {
1041 if (!(isRegIdx() && RegIdx.Kind))
1043 return (RegIdx.Index == 0 ||
1044 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1045 RegIdx.Index == 17);
1047 bool isFGRAsmReg() const {
1048 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1049 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1051 bool isHWRegsAsmReg() const {
1052 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1054 bool isCCRAsmReg() const {
1055 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1057 bool isFCCAsmReg() const {
1058 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1060 if (!AsmParser.hasEightFccRegisters())
1061 return RegIdx.Index == 0;
1062 return RegIdx.Index <= 7;
1064 bool isACCAsmReg() const {
1065 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1067 bool isCOP2AsmReg() const {
1068 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1070 bool isCOP3AsmReg() const {
1071 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1073 bool isMSA128AsmReg() const {
1074 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1076 bool isMSACtrlAsmReg() const {
1077 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1080 /// getStartLoc - Get the location of the first token of this operand.
1081 SMLoc getStartLoc() const override { return StartLoc; }
1082 /// getEndLoc - Get the location of the last token of this operand.
1083 SMLoc getEndLoc() const override { return EndLoc; }
1085 virtual ~MipsOperand() {
1093 delete RegList.List;
1094 case k_PhysRegister:
1095 case k_RegisterIndex:
1102 void print(raw_ostream &OS) const override {
1111 Mem.Base->print(OS);
1116 case k_PhysRegister:
1117 OS << "PhysReg<" << PhysReg.Num << ">";
1119 case k_RegisterIndex:
1120 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1127 for (auto Reg : (*RegList.List))
1132 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1136 }; // class MipsOperand
1140 extern const MCInstrDesc MipsInsts[];
1142 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1143 return MipsInsts[Opcode];
1146 static bool hasShortDelaySlot(unsigned Opcode) {
1149 case Mips::JALRS_MM:
1150 case Mips::JALRS16_MM:
1151 case Mips::BGEZALS_MM:
1152 case Mips::BLTZALS_MM:
1159 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1160 SmallVectorImpl<MCInst> &Instructions) {
1161 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1165 if (MCID.isBranch() || MCID.isCall()) {
1166 const unsigned Opcode = Inst.getOpcode();
1176 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1177 Offset = Inst.getOperand(2);
1178 if (!Offset.isImm())
1179 break; // We'll deal with this situation later on when applying fixups.
1180 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1181 return Error(IDLoc, "branch target out of range");
1182 if (OffsetToAlignment(Offset.getImm(),
1183 1LL << (inMicroMipsMode() ? 1 : 2)))
1184 return Error(IDLoc, "branch to misaligned address");
1198 case Mips::BGEZAL_MM:
1199 case Mips::BLTZAL_MM:
1202 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1203 Offset = Inst.getOperand(1);
1204 if (!Offset.isImm())
1205 break; // We'll deal with this situation later on when applying fixups.
1206 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1207 return Error(IDLoc, "branch target out of range");
1208 if (OffsetToAlignment(Offset.getImm(),
1209 1LL << (inMicroMipsMode() ? 1 : 2)))
1210 return Error(IDLoc, "branch to misaligned address");
1212 case Mips::BEQZ16_MM:
1213 case Mips::BNEZ16_MM:
1214 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1215 Offset = Inst.getOperand(1);
1216 if (!Offset.isImm())
1217 break; // We'll deal with this situation later on when applying fixups.
1218 if (!isIntN(8, Offset.getImm()))
1219 return Error(IDLoc, "branch target out of range");
1220 if (OffsetToAlignment(Offset.getImm(), 2LL))
1221 return Error(IDLoc, "branch to misaligned address");
1226 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1227 // We still accept it but it is a normal nop.
1228 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1229 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1230 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1234 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1235 // If this instruction has a delay slot and .set reorder is active,
1236 // emit a NOP after it.
1237 Instructions.push_back(Inst);
1239 if (hasShortDelaySlot(Inst.getOpcode())) {
1240 NopInst.setOpcode(Mips::MOVE16_MM);
1241 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1242 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1244 NopInst.setOpcode(Mips::SLL);
1245 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1246 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1247 NopInst.addOperand(MCOperand::CreateImm(0));
1249 Instructions.push_back(NopInst);
1253 if (MCID.mayLoad() || MCID.mayStore()) {
1254 // Check the offset of memory operand, if it is a symbol
1255 // reference or immediate we may have to expand instructions.
1256 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1257 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1258 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1259 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1260 MCOperand &Op = Inst.getOperand(i);
1262 int MemOffset = Op.getImm();
1263 if (MemOffset < -32768 || MemOffset > 32767) {
1264 // Offset can't exceed 16bit value.
1265 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1268 } else if (Op.isExpr()) {
1269 const MCExpr *Expr = Op.getExpr();
1270 if (Expr->getKind() == MCExpr::SymbolRef) {
1271 const MCSymbolRefExpr *SR =
1272 static_cast<const MCSymbolRefExpr *>(Expr);
1273 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1275 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1278 } else if (!isEvaluated(Expr)) {
1279 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1287 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1288 if (inMicroMipsMode()) {
1292 switch (Inst.getOpcode()) {
1295 case Mips::ADDIUS5_MM:
1296 Opnd = Inst.getOperand(2);
1298 return Error(IDLoc, "expected immediate operand kind");
1299 Imm = Opnd.getImm();
1300 if (Imm < -8 || Imm > 7)
1301 return Error(IDLoc, "immediate operand value out of range");
1303 case Mips::ADDIUSP_MM:
1304 Opnd = Inst.getOperand(0);
1306 return Error(IDLoc, "expected immediate operand kind");
1307 Imm = Opnd.getImm();
1308 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1310 return Error(IDLoc, "immediate operand value out of range");
1312 case Mips::SLL16_MM:
1313 case Mips::SRL16_MM:
1314 Opnd = Inst.getOperand(2);
1316 return Error(IDLoc, "expected immediate operand kind");
1317 Imm = Opnd.getImm();
1318 if (Imm < 1 || Imm > 8)
1319 return Error(IDLoc, "immediate operand value out of range");
1322 Opnd = Inst.getOperand(1);
1324 return Error(IDLoc, "expected immediate operand kind");
1325 Imm = Opnd.getImm();
1326 if (Imm < -1 || Imm > 126)
1327 return Error(IDLoc, "immediate operand value out of range");
1329 case Mips::ADDIUR2_MM:
1330 Opnd = Inst.getOperand(2);
1332 return Error(IDLoc, "expected immediate operand kind");
1333 Imm = Opnd.getImm();
1334 if (!(Imm == 1 || Imm == -1 ||
1335 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1336 return Error(IDLoc, "immediate operand value out of range");
1338 case Mips::ADDIUR1SP_MM:
1339 Opnd = Inst.getOperand(1);
1341 return Error(IDLoc, "expected immediate operand kind");
1342 Imm = Opnd.getImm();
1343 if (OffsetToAlignment(Imm, 4LL))
1344 return Error(IDLoc, "misaligned immediate operand value");
1345 if (Imm < 0 || Imm > 255)
1346 return Error(IDLoc, "immediate operand value out of range");
1348 case Mips::ANDI16_MM:
1349 Opnd = Inst.getOperand(2);
1351 return Error(IDLoc, "expected immediate operand kind");
1352 Imm = Opnd.getImm();
1353 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1354 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1355 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1356 return Error(IDLoc, "immediate operand value out of range");
1358 case Mips::LBU16_MM:
1359 Opnd = Inst.getOperand(2);
1361 return Error(IDLoc, "expected immediate operand kind");
1362 Imm = Opnd.getImm();
1363 if (Imm < -1 || Imm > 14)
1364 return Error(IDLoc, "immediate operand value out of range");
1367 Opnd = Inst.getOperand(2);
1369 return Error(IDLoc, "expected immediate operand kind");
1370 Imm = Opnd.getImm();
1371 if (Imm < 0 || Imm > 15)
1372 return Error(IDLoc, "immediate operand value out of range");
1374 case Mips::LHU16_MM:
1376 Opnd = Inst.getOperand(2);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1381 return Error(IDLoc, "immediate operand value out of range");
1385 Opnd = Inst.getOperand(2);
1387 return Error(IDLoc, "expected immediate operand kind");
1388 Imm = Opnd.getImm();
1389 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1390 return Error(IDLoc, "immediate operand value out of range");
1394 Opnd = Inst.getOperand(2);
1396 return Error(IDLoc, "expected immediate operand kind");
1397 Imm = Opnd.getImm();
1398 if (!isUInt<5>(Imm))
1399 return Error(IDLoc, "immediate operand value out of range");
1401 case Mips::ADDIUPC_MM:
1402 MCOperand Opnd = Inst.getOperand(1);
1404 return Error(IDLoc, "expected immediate operand kind");
1405 int Imm = Opnd.getImm();
1406 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1407 return Error(IDLoc, "immediate operand value out of range");
1412 if (needsExpansion(Inst))
1413 return expandInstruction(Inst, IDLoc, Instructions);
1415 Instructions.push_back(Inst);
1420 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1422 switch (Inst.getOpcode()) {
1423 case Mips::LoadImm32Reg:
1424 case Mips::LoadAddr32Imm:
1425 case Mips::LoadAddr32Reg:
1426 case Mips::LoadImm64Reg:
1427 case Mips::B_MM_Pseudo:
1434 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1435 SmallVectorImpl<MCInst> &Instructions) {
1436 switch (Inst.getOpcode()) {
1437 default: llvm_unreachable("unimplemented expansion");
1438 case Mips::LoadImm32Reg:
1439 return expandLoadImm(Inst, IDLoc, Instructions);
1440 case Mips::LoadImm64Reg:
1442 Error(IDLoc, "instruction requires a 64-bit architecture");
1445 return expandLoadImm(Inst, IDLoc, Instructions);
1446 case Mips::LoadAddr32Imm:
1447 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1448 case Mips::LoadAddr32Reg:
1449 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1450 case Mips::B_MM_Pseudo:
1451 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1456 template <bool PerformShift>
1457 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1458 SmallVectorImpl<MCInst> &Instructions) {
1461 tmpInst.setOpcode(Mips::DSLL);
1462 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1463 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1464 tmpInst.addOperand(MCOperand::CreateImm(16));
1465 tmpInst.setLoc(IDLoc);
1466 Instructions.push_back(tmpInst);
1469 tmpInst.setOpcode(Mips::ORi);
1470 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1471 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1472 tmpInst.addOperand(Operand);
1473 tmpInst.setLoc(IDLoc);
1474 Instructions.push_back(tmpInst);
1477 template <int Shift, bool PerformShift>
1478 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1479 SmallVectorImpl<MCInst> &Instructions) {
1480 createShiftOr<PerformShift>(
1481 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1482 IDLoc, Instructions);
1486 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1487 SmallVectorImpl<MCInst> &Instructions) {
1489 const MCOperand &ImmOp = Inst.getOperand(1);
1490 assert(ImmOp.isImm() && "expected immediate operand kind");
1491 const MCOperand &RegOp = Inst.getOperand(0);
1492 assert(RegOp.isReg() && "expected register operand kind");
1494 int64_t ImmValue = ImmOp.getImm();
1495 tmpInst.setLoc(IDLoc);
1496 // FIXME: gas has a special case for values that are 000...1111, which
1497 // becomes a li -1 and then a dsrl
1498 if (0 <= ImmValue && ImmValue <= 65535) {
1499 // For 0 <= j <= 65535.
1500 // li d,j => ori d,$zero,j
1501 tmpInst.setOpcode(Mips::ORi);
1502 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1503 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1504 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1505 Instructions.push_back(tmpInst);
1506 } else if (ImmValue < 0 && ImmValue >= -32768) {
1507 // For -32768 <= j < 0.
1508 // li d,j => addiu d,$zero,j
1509 tmpInst.setOpcode(Mips::ADDiu);
1510 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1511 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1512 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1513 Instructions.push_back(tmpInst);
1514 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1515 // For any value of j that is representable as a 32-bit integer, create
1517 // li d,j => lui d,hi16(j)
1519 tmpInst.setOpcode(Mips::LUi);
1520 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1521 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1522 Instructions.push_back(tmpInst);
1523 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1524 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1526 Error(IDLoc, "instruction requires a 64-bit architecture");
1530 // <------- lo32 ------>
1531 // <------- hi32 ------>
1532 // <- hi16 -> <- lo16 ->
1533 // _________________________________
1535 // | 16-bytes | 16-bytes | 16-bytes |
1536 // |__________|__________|__________|
1538 // For any value of j that is representable as a 48-bit integer, create
1540 // li d,j => lui d,hi16(j)
1541 // ori d,d,hi16(lo32(j))
1543 // ori d,d,lo16(lo32(j))
1544 tmpInst.setOpcode(Mips::LUi);
1545 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1547 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1548 Instructions.push_back(tmpInst);
1549 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1550 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1553 Error(IDLoc, "instruction requires a 64-bit architecture");
1557 // <------- hi32 ------> <------- lo32 ------>
1558 // <- hi16 -> <- lo16 ->
1559 // ___________________________________________
1561 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1562 // |__________|__________|__________|__________|
1564 // For any value of j that isn't representable as a 48-bit integer.
1565 // li d,j => lui d,hi16(j)
1566 // ori d,d,lo16(hi32(j))
1568 // ori d,d,hi16(lo32(j))
1570 // ori d,d,lo16(lo32(j))
1571 tmpInst.setOpcode(Mips::LUi);
1572 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1574 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1575 Instructions.push_back(tmpInst);
1576 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1577 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1578 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1584 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1585 SmallVectorImpl<MCInst> &Instructions) {
1587 const MCOperand &ImmOp = Inst.getOperand(2);
1588 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1589 "expected immediate operand kind");
1590 if (!ImmOp.isImm()) {
1591 expandLoadAddressSym(Inst, IDLoc, Instructions);
1594 const MCOperand &SrcRegOp = Inst.getOperand(1);
1595 assert(SrcRegOp.isReg() && "expected register operand kind");
1596 const MCOperand &DstRegOp = Inst.getOperand(0);
1597 assert(DstRegOp.isReg() && "expected register operand kind");
1598 int ImmValue = ImmOp.getImm();
1599 if (-32768 <= ImmValue && ImmValue <= 65535) {
1600 // For -32768 <= j <= 65535.
1601 // la d,j(s) => addiu d,s,j
1602 tmpInst.setOpcode(Mips::ADDiu);
1603 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1604 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1605 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1606 Instructions.push_back(tmpInst);
1608 // For any other value of j that is representable as a 32-bit integer.
1609 // la d,j(s) => lui d,hi16(j)
1612 tmpInst.setOpcode(Mips::LUi);
1613 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1614 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1615 Instructions.push_back(tmpInst);
1617 tmpInst.setOpcode(Mips::ORi);
1618 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1619 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1620 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1621 Instructions.push_back(tmpInst);
1623 tmpInst.setOpcode(Mips::ADDu);
1624 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1625 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1626 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1627 Instructions.push_back(tmpInst);
1633 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1634 SmallVectorImpl<MCInst> &Instructions) {
1636 const MCOperand &ImmOp = Inst.getOperand(1);
1637 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1638 "expected immediate operand kind");
1639 if (!ImmOp.isImm()) {
1640 expandLoadAddressSym(Inst, IDLoc, Instructions);
1643 const MCOperand &RegOp = Inst.getOperand(0);
1644 assert(RegOp.isReg() && "expected register operand kind");
1645 int ImmValue = ImmOp.getImm();
1646 if (-32768 <= ImmValue && ImmValue <= 65535) {
1647 // For -32768 <= j <= 65535.
1648 // la d,j => addiu d,$zero,j
1649 tmpInst.setOpcode(Mips::ADDiu);
1650 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1651 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1652 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1653 Instructions.push_back(tmpInst);
1655 // For any other value of j that is representable as a 32-bit integer.
1656 // la d,j => lui d,hi16(j)
1658 tmpInst.setOpcode(Mips::LUi);
1659 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1660 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1661 Instructions.push_back(tmpInst);
1663 tmpInst.setOpcode(Mips::ORi);
1664 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1665 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1666 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1667 Instructions.push_back(tmpInst);
1673 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1674 SmallVectorImpl<MCInst> &Instructions) {
1675 // FIXME: If we do have a valid at register to use, we should generate a
1676 // slightly shorter sequence here.
1678 int ExprOperandNo = 1;
1679 // Sometimes the assembly parser will get the immediate expression as
1680 // a $zero + an immediate.
1681 if (Inst.getNumOperands() == 3) {
1682 assert(Inst.getOperand(1).getReg() ==
1683 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1686 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1687 assert(SymOp.isExpr() && "expected symbol operand kind");
1688 const MCOperand &RegOp = Inst.getOperand(0);
1689 unsigned RegNo = RegOp.getReg();
1690 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1691 const MCSymbolRefExpr *HiExpr =
1692 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1693 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1694 const MCSymbolRefExpr *LoExpr =
1695 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1696 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1698 // If it's a 64-bit architecture, expand to:
1699 // la d,sym => lui d,highest(sym)
1700 // ori d,d,higher(sym)
1702 // ori d,d,hi16(sym)
1704 // ori d,d,lo16(sym)
1705 const MCSymbolRefExpr *HighestExpr =
1706 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1707 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1708 const MCSymbolRefExpr *HigherExpr =
1709 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1710 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1712 tmpInst.setOpcode(Mips::LUi);
1713 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1714 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1715 Instructions.push_back(tmpInst);
1717 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1719 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1721 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1724 // Otherwise, expand to:
1725 // la d,sym => lui d,hi16(sym)
1726 // ori d,d,lo16(sym)
1727 tmpInst.setOpcode(Mips::LUi);
1728 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1729 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1730 Instructions.push_back(tmpInst);
1732 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1737 bool MipsAsmParser::
1738 expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
1739 SmallVectorImpl<MCInst> &Instructions) {
1740 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1741 "unexpected number of operands");
1743 MCOperand Offset = Inst.getOperand(0);
1744 if (Offset.isExpr()) {
1746 Inst.setOpcode(Mips::BEQ_MM);
1747 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1748 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1749 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1751 assert(Offset.isImm() && "expected immediate operand kind");
1752 if (isIntN(11, Offset.getImm())) {
1753 // If offset fits into 11 bits then this instruction becomes microMIPS
1754 // 16-bit unconditional branch instruction.
1755 Inst.setOpcode(Mips::B16_MM);
1757 if (!isIntN(17, Offset.getImm()))
1758 Error(IDLoc, "branch target out of range");
1759 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1760 Error(IDLoc, "branch to misaligned address");
1762 Inst.setOpcode(Mips::BEQ_MM);
1763 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1764 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1765 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1768 Instructions.push_back(Inst);
1770 if (AssemblerOptions.back()->isReorder()) {
1771 // If .set reorder is active, emit a NOP after the branch instruction.
1773 NopInst.setOpcode(Mips::MOVE16_MM);
1774 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1775 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1776 Instructions.push_back(NopInst);
1781 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1782 SmallVectorImpl<MCInst> &Instructions,
1783 bool isLoad, bool isImmOpnd) {
1784 const MCSymbolRefExpr *SR;
1786 unsigned ImmOffset, HiOffset, LoOffset;
1787 const MCExpr *ExprOffset;
1789 // 1st operand is either the source or destination register.
1790 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1791 unsigned RegOpNum = Inst.getOperand(0).getReg();
1792 // 2nd operand is the base register.
1793 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1794 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1795 // 3rd operand is either an immediate or expression.
1797 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1798 ImmOffset = Inst.getOperand(2).getImm();
1799 LoOffset = ImmOffset & 0x0000ffff;
1800 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1801 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1802 if (LoOffset & 0x8000)
1805 ExprOffset = Inst.getOperand(2).getExpr();
1806 // All instructions will have the same location.
1807 TempInst.setLoc(IDLoc);
1808 // These are some of the types of expansions we perform here:
1809 // 1) lw $8, sym => lui $8, %hi(sym)
1810 // lw $8, %lo(sym)($8)
1811 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1813 // lw $8, %lo(offset)($9)
1814 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1816 // lw $8, %lo(offset)($at)
1817 // 4) sw $8, sym => lui $at, %hi(sym)
1818 // sw $8, %lo(sym)($at)
1819 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1821 // sw $8, %lo(offset)($at)
1822 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1823 // ldc1 $f0, %lo(sym)($at)
1825 // For load instructions we can use the destination register as a temporary
1826 // if base and dst are different (examples 1 and 2) and if the base register
1827 // is general purpose otherwise we must use $at (example 6) and error if it's
1828 // not available. For stores we must use $at (examples 4 and 5) because we
1829 // must not clobber the source register setting up the offset.
1830 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1831 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1832 unsigned RegClassIDOp0 =
1833 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1834 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1835 (RegClassIDOp0 == Mips::GPR64RegClassID);
1836 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1837 TmpRegNum = RegOpNum;
1839 int AT = getATReg(IDLoc);
1840 // At this point we need AT to perform the expansions and we exit if it is
1845 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1848 TempInst.setOpcode(Mips::LUi);
1849 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1851 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1853 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1854 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1855 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1856 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1858 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1860 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1861 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1864 // Add the instruction to the list.
1865 Instructions.push_back(TempInst);
1866 // Prepare TempInst for next instruction.
1868 // Add temp register to base.
1869 TempInst.setOpcode(Mips::ADDu);
1870 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1871 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1872 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1873 Instructions.push_back(TempInst);
1875 // And finally, create original instruction with low part
1876 // of offset and new base.
1877 TempInst.setOpcode(Inst.getOpcode());
1878 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1879 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1881 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1883 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1884 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1885 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1887 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1889 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1890 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1893 Instructions.push_back(TempInst);
1897 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1898 // As described by the Mips32r2 spec, the registers Rd and Rs for
1899 // jalr.hb must be different.
1900 unsigned Opcode = Inst.getOpcode();
1902 if (Opcode == Mips::JALR_HB &&
1903 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1904 return Match_RequiresDifferentSrcAndDst;
1906 return Match_Success;
1909 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1910 OperandVector &Operands,
1912 uint64_t &ErrorInfo,
1913 bool MatchingInlineAsm) {
1916 SmallVector<MCInst, 8> Instructions;
1917 unsigned MatchResult =
1918 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1920 switch (MatchResult) {
1921 case Match_Success: {
1922 if (processInstruction(Inst, IDLoc, Instructions))
1924 for (unsigned i = 0; i < Instructions.size(); i++)
1925 Out.EmitInstruction(Instructions[i], STI);
1928 case Match_MissingFeature:
1929 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1931 case Match_InvalidOperand: {
1932 SMLoc ErrorLoc = IDLoc;
1933 if (ErrorInfo != ~0ULL) {
1934 if (ErrorInfo >= Operands.size())
1935 return Error(IDLoc, "too few operands for instruction");
1937 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1938 if (ErrorLoc == SMLoc())
1942 return Error(ErrorLoc, "invalid operand for instruction");
1944 case Match_MnemonicFail:
1945 return Error(IDLoc, "invalid instruction");
1946 case Match_RequiresDifferentSrcAndDst:
1947 return Error(IDLoc, "source and destination must be different");
1950 llvm_unreachable("Implement any new match types added!");
1953 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1954 if ((RegIndex != 0) &&
1955 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1957 Warning(Loc, "used $at without \".set noat\"");
1959 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1960 Twine(RegIndex) + "\"");
1965 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1966 SMRange Range, bool ShowColors) {
1967 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1968 Range, SMFixIt(Range, FixMsg),
1972 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1975 CC = StringSwitch<unsigned>(Name)
2011 if (!(isABI_N32() || isABI_N64()))
2014 if (12 <= CC && CC <= 15) {
2015 // Name is one of t4-t7
2016 AsmToken RegTok = getLexer().peekTok();
2017 SMRange RegRange = RegTok.getLocRange();
2019 StringRef FixedName = StringSwitch<StringRef>(Name)
2025 assert(FixedName != "" && "Register name is not one of t4-t7.");
2027 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2028 "Did you mean $" + FixedName + "?", RegRange);
2031 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2032 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2033 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2034 if (8 <= CC && CC <= 11)
2038 CC = StringSwitch<unsigned>(Name)
2050 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2053 CC = StringSwitch<unsigned>(Name)
2054 .Case("hwr_cpunum", 0)
2055 .Case("hwr_synci_step", 1)
2057 .Case("hwr_ccres", 3)
2058 .Case("hwr_ulr", 29)
2064 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2066 if (Name[0] == 'f') {
2067 StringRef NumString = Name.substr(1);
2069 if (NumString.getAsInteger(10, IntVal))
2070 return -1; // This is not an integer.
2071 if (IntVal > 31) // Maximum index for fpu register.
2078 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2080 if (Name.startswith("fcc")) {
2081 StringRef NumString = Name.substr(3);
2083 if (NumString.getAsInteger(10, IntVal))
2084 return -1; // This is not an integer.
2085 if (IntVal > 7) // There are only 8 fcc registers.
2092 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2094 if (Name.startswith("ac")) {
2095 StringRef NumString = Name.substr(2);
2097 if (NumString.getAsInteger(10, IntVal))
2098 return -1; // This is not an integer.
2099 if (IntVal > 3) // There are only 3 acc registers.
2106 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2109 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2118 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2121 CC = StringSwitch<unsigned>(Name)
2124 .Case("msaaccess", 2)
2126 .Case("msamodify", 4)
2127 .Case("msarequest", 5)
2129 .Case("msaunmap", 7)
2135 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2143 int MipsAsmParser::getATReg(SMLoc Loc) {
2144 int AT = AssemblerOptions.back()->getATRegNum();
2146 reportParseError(Loc,
2147 "pseudo-instruction requires $at, which is not available");
2151 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2152 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2155 unsigned MipsAsmParser::getGPR(int RegNo) {
2156 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2160 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2162 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2165 return getReg(RegClass, RegNum);
2168 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2169 MCAsmParser &Parser = getParser();
2170 DEBUG(dbgs() << "parseOperand\n");
2172 // Check if the current operand has a custom associated parser, if so, try to
2173 // custom parse the operand, or fallback to the general approach.
2174 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2175 if (ResTy == MatchOperand_Success)
2177 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2178 // there was a match, but an error occurred, in which case, just return that
2179 // the operand parsing failed.
2180 if (ResTy == MatchOperand_ParseFail)
2183 DEBUG(dbgs() << ".. Generic Parser\n");
2185 switch (getLexer().getKind()) {
2187 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2189 case AsmToken::Dollar: {
2190 // Parse the register.
2191 SMLoc S = Parser.getTok().getLoc();
2193 // Almost all registers have been parsed by custom parsers. There is only
2194 // one exception to this. $zero (and it's alias $0) will reach this point
2195 // for div, divu, and similar instructions because it is not an operand
2196 // to the instruction definition but an explicit register. Special case
2197 // this situation for now.
2198 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2201 // Maybe it is a symbol reference.
2202 StringRef Identifier;
2203 if (Parser.parseIdentifier(Identifier))
2206 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2207 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2208 // Otherwise create a symbol reference.
2210 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2212 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2215 // Else drop to expression parsing.
2216 case AsmToken::LParen:
2217 case AsmToken::Minus:
2218 case AsmToken::Plus:
2219 case AsmToken::Integer:
2220 case AsmToken::Tilde:
2221 case AsmToken::String: {
2222 DEBUG(dbgs() << ".. generic integer\n");
2223 OperandMatchResultTy ResTy = parseImm(Operands);
2224 return ResTy != MatchOperand_Success;
2226 case AsmToken::Percent: {
2227 // It is a symbol reference or constant expression.
2228 const MCExpr *IdVal;
2229 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2230 if (parseRelocOperand(IdVal))
2233 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2235 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2237 } // case AsmToken::Percent
2238 } // switch(getLexer().getKind())
2242 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2243 StringRef RelocStr) {
2245 // Check the type of the expression.
2246 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2247 // It's a constant, evaluate reloc value.
2249 switch (getVariantKind(RelocStr)) {
2250 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2251 // Get the 1st 16-bits.
2252 Val = MCE->getValue() & 0xffff;
2254 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2255 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2256 // 16 bits being negative.
2257 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2259 case MCSymbolRefExpr::VK_Mips_HIGHER:
2260 // Get the 3rd 16-bits.
2261 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2263 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2264 // Get the 4th 16-bits.
2265 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2268 report_fatal_error("unsupported reloc value");
2270 return MCConstantExpr::Create(Val, getContext());
2273 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2274 // It's a symbol, create a symbolic expression from the symbol.
2275 StringRef Symbol = MSRE->getSymbol().getName();
2276 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2277 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2281 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2282 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2284 // Try to create target expression.
2285 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2286 return MipsMCExpr::Create(VK, Expr, getContext());
2288 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2289 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2290 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2294 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2295 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2296 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2299 // Just return the original expression.
2303 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2305 switch (Expr->getKind()) {
2306 case MCExpr::Constant:
2308 case MCExpr::SymbolRef:
2309 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2310 case MCExpr::Binary:
2311 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2312 if (!isEvaluated(BE->getLHS()))
2314 return isEvaluated(BE->getRHS());
2317 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2318 case MCExpr::Target:
2324 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2325 MCAsmParser &Parser = getParser();
2326 Parser.Lex(); // Eat the % token.
2327 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2328 if (Tok.isNot(AsmToken::Identifier))
2331 std::string Str = Tok.getIdentifier().str();
2333 Parser.Lex(); // Eat the identifier.
2334 // Now make an expression from the rest of the operand.
2335 const MCExpr *IdVal;
2338 if (getLexer().getKind() == AsmToken::LParen) {
2340 Parser.Lex(); // Eat the '(' token.
2341 if (getLexer().getKind() == AsmToken::Percent) {
2342 Parser.Lex(); // Eat the % token.
2343 const AsmToken &nextTok = Parser.getTok();
2344 if (nextTok.isNot(AsmToken::Identifier))
2347 Str += nextTok.getIdentifier();
2348 Parser.Lex(); // Eat the identifier.
2349 if (getLexer().getKind() != AsmToken::LParen)
2354 if (getParser().parseParenExpression(IdVal, EndLoc))
2357 while (getLexer().getKind() == AsmToken::RParen)
2358 Parser.Lex(); // Eat the ')' token.
2361 return true; // Parenthesis must follow the relocation operand.
2363 Res = evaluateRelocExpr(IdVal, Str);
2367 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2369 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2370 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2371 if (ResTy == MatchOperand_Success) {
2372 assert(Operands.size() == 1);
2373 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2374 StartLoc = Operand.getStartLoc();
2375 EndLoc = Operand.getEndLoc();
2377 // AFAIK, we only support numeric registers and named GPR's in CFI
2379 // Don't worry about eating tokens before failing. Using an unrecognised
2380 // register is a parse error.
2381 if (Operand.isGPRAsmReg()) {
2382 // Resolve to GPR32 or GPR64 appropriately.
2383 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2386 return (RegNo == (unsigned)-1);
2389 assert(Operands.size() == 0);
2390 return (RegNo == (unsigned)-1);
2393 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2394 MCAsmParser &Parser = getParser();
2398 while (getLexer().getKind() == AsmToken::LParen)
2401 switch (getLexer().getKind()) {
2404 case AsmToken::Identifier:
2405 case AsmToken::LParen:
2406 case AsmToken::Integer:
2407 case AsmToken::Minus:
2408 case AsmToken::Plus:
2410 Result = getParser().parseParenExpression(Res, S);
2412 Result = (getParser().parseExpression(Res));
2413 while (getLexer().getKind() == AsmToken::RParen)
2416 case AsmToken::Percent:
2417 Result = parseRelocOperand(Res);
2422 MipsAsmParser::OperandMatchResultTy
2423 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2424 MCAsmParser &Parser = getParser();
2425 DEBUG(dbgs() << "parseMemOperand\n");
2426 const MCExpr *IdVal = nullptr;
2428 bool isParenExpr = false;
2429 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2430 // First operand is the offset.
2431 S = Parser.getTok().getLoc();
2433 if (getLexer().getKind() == AsmToken::LParen) {
2438 if (getLexer().getKind() != AsmToken::Dollar) {
2439 if (parseMemOffset(IdVal, isParenExpr))
2440 return MatchOperand_ParseFail;
2442 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2443 if (Tok.isNot(AsmToken::LParen)) {
2444 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2445 if (Mnemonic.getToken() == "la") {
2447 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2448 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2449 return MatchOperand_Success;
2451 if (Tok.is(AsmToken::EndOfStatement)) {
2453 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2455 // Zero register assumed, add a memory operand with ZERO as its base.
2456 // "Base" will be managed by k_Memory.
2457 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2460 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2461 return MatchOperand_Success;
2463 Error(Parser.getTok().getLoc(), "'(' expected");
2464 return MatchOperand_ParseFail;
2467 Parser.Lex(); // Eat the '(' token.
2470 Res = parseAnyRegister(Operands);
2471 if (Res != MatchOperand_Success)
2474 if (Parser.getTok().isNot(AsmToken::RParen)) {
2475 Error(Parser.getTok().getLoc(), "')' expected");
2476 return MatchOperand_ParseFail;
2479 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2481 Parser.Lex(); // Eat the ')' token.
2484 IdVal = MCConstantExpr::Create(0, getContext());
2486 // Replace the register operand with the memory operand.
2487 std::unique_ptr<MipsOperand> op(
2488 static_cast<MipsOperand *>(Operands.back().release()));
2489 // Remove the register from the operands.
2490 // "op" will be managed by k_Memory.
2491 Operands.pop_back();
2492 // Add the memory operand.
2493 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2495 if (IdVal->EvaluateAsAbsolute(Imm))
2496 IdVal = MCConstantExpr::Create(Imm, getContext());
2497 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2498 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2502 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2503 return MatchOperand_Success;
2506 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2507 MCAsmParser &Parser = getParser();
2508 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2510 SMLoc S = Parser.getTok().getLoc();
2512 if (Sym->isVariable())
2513 Expr = Sym->getVariableValue();
2516 if (Expr->getKind() == MCExpr::SymbolRef) {
2517 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2518 StringRef DefSymbol = Ref->getSymbol().getName();
2519 if (DefSymbol.startswith("$")) {
2520 OperandMatchResultTy ResTy =
2521 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2522 if (ResTy == MatchOperand_Success) {
2525 } else if (ResTy == MatchOperand_ParseFail)
2526 llvm_unreachable("Should never ParseFail");
2529 } else if (Expr->getKind() == MCExpr::Constant) {
2531 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2533 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2540 MipsAsmParser::OperandMatchResultTy
2541 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2542 StringRef Identifier,
2544 int Index = matchCPURegisterName(Identifier);
2546 Operands.push_back(MipsOperand::createGPRReg(
2547 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2548 return MatchOperand_Success;
2551 Index = matchHWRegsRegisterName(Identifier);
2553 Operands.push_back(MipsOperand::createHWRegsReg(
2554 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2555 return MatchOperand_Success;
2558 Index = matchFPURegisterName(Identifier);
2560 Operands.push_back(MipsOperand::createFGRReg(
2561 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2562 return MatchOperand_Success;
2565 Index = matchFCCRegisterName(Identifier);
2567 Operands.push_back(MipsOperand::createFCCReg(
2568 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2569 return MatchOperand_Success;
2572 Index = matchACRegisterName(Identifier);
2574 Operands.push_back(MipsOperand::createACCReg(
2575 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2576 return MatchOperand_Success;
2579 Index = matchMSA128RegisterName(Identifier);
2581 Operands.push_back(MipsOperand::createMSA128Reg(
2582 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2583 return MatchOperand_Success;
2586 Index = matchMSA128CtrlRegisterName(Identifier);
2588 Operands.push_back(MipsOperand::createMSACtrlReg(
2589 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2590 return MatchOperand_Success;
2593 return MatchOperand_NoMatch;
2596 MipsAsmParser::OperandMatchResultTy
2597 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2598 MCAsmParser &Parser = getParser();
2599 auto Token = Parser.getLexer().peekTok(false);
2601 if (Token.is(AsmToken::Identifier)) {
2602 DEBUG(dbgs() << ".. identifier\n");
2603 StringRef Identifier = Token.getIdentifier();
2604 OperandMatchResultTy ResTy =
2605 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2607 } else if (Token.is(AsmToken::Integer)) {
2608 DEBUG(dbgs() << ".. integer\n");
2609 Operands.push_back(MipsOperand::createNumericReg(
2610 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2612 return MatchOperand_Success;
2615 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2617 return MatchOperand_NoMatch;
2620 MipsAsmParser::OperandMatchResultTy
2621 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2622 MCAsmParser &Parser = getParser();
2623 DEBUG(dbgs() << "parseAnyRegister\n");
2625 auto Token = Parser.getTok();
2627 SMLoc S = Token.getLoc();
2629 if (Token.isNot(AsmToken::Dollar)) {
2630 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2631 if (Token.is(AsmToken::Identifier)) {
2632 if (searchSymbolAlias(Operands))
2633 return MatchOperand_Success;
2635 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2636 return MatchOperand_NoMatch;
2638 DEBUG(dbgs() << ".. $\n");
2640 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2641 if (ResTy == MatchOperand_Success) {
2643 Parser.Lex(); // identifier
2648 MipsAsmParser::OperandMatchResultTy
2649 MipsAsmParser::parseImm(OperandVector &Operands) {
2650 MCAsmParser &Parser = getParser();
2651 switch (getLexer().getKind()) {
2653 return MatchOperand_NoMatch;
2654 case AsmToken::LParen:
2655 case AsmToken::Minus:
2656 case AsmToken::Plus:
2657 case AsmToken::Integer:
2658 case AsmToken::Tilde:
2659 case AsmToken::String:
2663 const MCExpr *IdVal;
2664 SMLoc S = Parser.getTok().getLoc();
2665 if (getParser().parseExpression(IdVal))
2666 return MatchOperand_ParseFail;
2668 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2669 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2670 return MatchOperand_Success;
2673 MipsAsmParser::OperandMatchResultTy
2674 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2675 MCAsmParser &Parser = getParser();
2676 DEBUG(dbgs() << "parseJumpTarget\n");
2678 SMLoc S = getLexer().getLoc();
2680 // Integers and expressions are acceptable
2681 OperandMatchResultTy ResTy = parseImm(Operands);
2682 if (ResTy != MatchOperand_NoMatch)
2685 // Registers are a valid target and have priority over symbols.
2686 ResTy = parseAnyRegister(Operands);
2687 if (ResTy != MatchOperand_NoMatch)
2690 const MCExpr *Expr = nullptr;
2691 if (Parser.parseExpression(Expr)) {
2692 // We have no way of knowing if a symbol was consumed so we must ParseFail
2693 return MatchOperand_ParseFail;
2696 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2697 return MatchOperand_Success;
2700 MipsAsmParser::OperandMatchResultTy
2701 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2702 MCAsmParser &Parser = getParser();
2703 const MCExpr *IdVal;
2704 // If the first token is '$' we may have register operand.
2705 if (Parser.getTok().is(AsmToken::Dollar))
2706 return MatchOperand_NoMatch;
2707 SMLoc S = Parser.getTok().getLoc();
2708 if (getParser().parseExpression(IdVal))
2709 return MatchOperand_ParseFail;
2710 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2711 assert(MCE && "Unexpected MCExpr type.");
2712 int64_t Val = MCE->getValue();
2713 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2714 Operands.push_back(MipsOperand::CreateImm(
2715 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2716 return MatchOperand_Success;
2719 MipsAsmParser::OperandMatchResultTy
2720 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2721 MCAsmParser &Parser = getParser();
2722 switch (getLexer().getKind()) {
2724 return MatchOperand_NoMatch;
2725 case AsmToken::LParen:
2726 case AsmToken::Plus:
2727 case AsmToken::Minus:
2728 case AsmToken::Integer:
2733 SMLoc S = Parser.getTok().getLoc();
2735 if (getParser().parseExpression(Expr))
2736 return MatchOperand_ParseFail;
2739 if (!Expr->EvaluateAsAbsolute(Val)) {
2740 Error(S, "expected immediate value");
2741 return MatchOperand_ParseFail;
2744 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2745 // and because the CPU always adds one to the immediate field, the allowed
2746 // range becomes 1..4. We'll only check the range here and will deal
2747 // with the addition/subtraction when actually decoding/encoding
2749 if (Val < 1 || Val > 4) {
2750 Error(S, "immediate not in range (1..4)");
2751 return MatchOperand_ParseFail;
2755 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2756 return MatchOperand_Success;
2759 MipsAsmParser::OperandMatchResultTy
2760 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2761 MCAsmParser &Parser = getParser();
2762 SmallVector<unsigned, 10> Regs;
2764 unsigned PrevReg = Mips::NoRegister;
2765 bool RegRange = false;
2766 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2768 if (Parser.getTok().isNot(AsmToken::Dollar))
2769 return MatchOperand_ParseFail;
2771 SMLoc S = Parser.getTok().getLoc();
2772 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2773 SMLoc E = getLexer().getLoc();
2774 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2775 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2777 // Remove last register operand because registers from register range
2778 // should be inserted first.
2779 if (RegNo == Mips::RA) {
2780 Regs.push_back(RegNo);
2782 unsigned TmpReg = PrevReg + 1;
2783 while (TmpReg <= RegNo) {
2784 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2785 Error(E, "invalid register operand");
2786 return MatchOperand_ParseFail;
2790 Regs.push_back(TmpReg++);
2796 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2797 (RegNo != Mips::RA)) {
2798 Error(E, "$16 or $31 expected");
2799 return MatchOperand_ParseFail;
2800 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2801 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2802 Error(E, "invalid register operand");
2803 return MatchOperand_ParseFail;
2804 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2805 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2806 Error(E, "consecutive register numbers expected");
2807 return MatchOperand_ParseFail;
2810 Regs.push_back(RegNo);
2813 if (Parser.getTok().is(AsmToken::Minus))
2816 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2817 !Parser.getTok().isNot(AsmToken::Comma)) {
2818 Error(E, "',' or '-' expected");
2819 return MatchOperand_ParseFail;
2822 Lex(); // Consume comma or minus
2823 if (Parser.getTok().isNot(AsmToken::Dollar))
2829 SMLoc E = Parser.getTok().getLoc();
2830 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2831 parseMemOperand(Operands);
2832 return MatchOperand_Success;
2835 MipsAsmParser::OperandMatchResultTy
2836 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2837 MCAsmParser &Parser = getParser();
2839 SMLoc S = Parser.getTok().getLoc();
2840 if (parseAnyRegister(Operands) != MatchOperand_Success)
2841 return MatchOperand_ParseFail;
2843 SMLoc E = Parser.getTok().getLoc();
2844 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2845 unsigned Reg = Op.getGPR32Reg();
2846 Operands.pop_back();
2847 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2848 return MatchOperand_Success;
2851 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2853 MCSymbolRefExpr::VariantKind VK =
2854 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2855 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2856 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2857 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2858 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2859 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2860 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2861 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2862 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2863 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2864 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2865 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2866 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2867 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2868 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2869 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2870 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2871 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2872 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2873 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2874 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2875 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2876 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2877 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2878 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2879 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2880 .Default(MCSymbolRefExpr::VK_None);
2882 assert(VK != MCSymbolRefExpr::VK_None);
2887 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2889 /// ::= '(', register, ')'
2890 /// handle it before we iterate so we don't get tripped up by the lack of
2892 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2893 MCAsmParser &Parser = getParser();
2894 if (getLexer().is(AsmToken::LParen)) {
2896 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2898 if (parseOperand(Operands, Name)) {
2899 SMLoc Loc = getLexer().getLoc();
2900 Parser.eatToEndOfStatement();
2901 return Error(Loc, "unexpected token in argument list");
2903 if (Parser.getTok().isNot(AsmToken::RParen)) {
2904 SMLoc Loc = getLexer().getLoc();
2905 Parser.eatToEndOfStatement();
2906 return Error(Loc, "unexpected token, expected ')'");
2909 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2915 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2916 /// either one of these.
2917 /// ::= '[', register, ']'
2918 /// ::= '[', integer, ']'
2919 /// handle it before we iterate so we don't get tripped up by the lack of
2921 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2922 OperandVector &Operands) {
2923 MCAsmParser &Parser = getParser();
2924 if (getLexer().is(AsmToken::LBrac)) {
2926 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2928 if (parseOperand(Operands, Name)) {
2929 SMLoc Loc = getLexer().getLoc();
2930 Parser.eatToEndOfStatement();
2931 return Error(Loc, "unexpected token in argument list");
2933 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2934 SMLoc Loc = getLexer().getLoc();
2935 Parser.eatToEndOfStatement();
2936 return Error(Loc, "unexpected token, expected ']'");
2939 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2945 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2946 SMLoc NameLoc, OperandVector &Operands) {
2947 MCAsmParser &Parser = getParser();
2948 DEBUG(dbgs() << "ParseInstruction\n");
2950 // We have reached first instruction, module directive are now forbidden.
2951 getTargetStreamer().forbidModuleDirective();
2953 // Check if we have valid mnemonic
2954 if (!mnemonicIsValid(Name, 0)) {
2955 Parser.eatToEndOfStatement();
2956 return Error(NameLoc, "unknown instruction");
2958 // First operand in MCInst is instruction mnemonic.
2959 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2961 // Read the remaining operands.
2962 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2963 // Read the first operand.
2964 if (parseOperand(Operands, Name)) {
2965 SMLoc Loc = getLexer().getLoc();
2966 Parser.eatToEndOfStatement();
2967 return Error(Loc, "unexpected token in argument list");
2969 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2971 // AFAIK, parenthesis suffixes are never on the first operand
2973 while (getLexer().is(AsmToken::Comma)) {
2974 Parser.Lex(); // Eat the comma.
2975 // Parse and remember the operand.
2976 if (parseOperand(Operands, Name)) {
2977 SMLoc Loc = getLexer().getLoc();
2978 Parser.eatToEndOfStatement();
2979 return Error(Loc, "unexpected token in argument list");
2981 // Parse bracket and parenthesis suffixes before we iterate
2982 if (getLexer().is(AsmToken::LBrac)) {
2983 if (parseBracketSuffix(Name, Operands))
2985 } else if (getLexer().is(AsmToken::LParen) &&
2986 parseParenSuffix(Name, Operands))
2990 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2991 SMLoc Loc = getLexer().getLoc();
2992 Parser.eatToEndOfStatement();
2993 return Error(Loc, "unexpected token in argument list");
2995 Parser.Lex(); // Consume the EndOfStatement.
2999 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3000 MCAsmParser &Parser = getParser();
3001 SMLoc Loc = getLexer().getLoc();
3002 Parser.eatToEndOfStatement();
3003 return Error(Loc, ErrorMsg);
3006 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3007 return Error(Loc, ErrorMsg);
3010 bool MipsAsmParser::parseSetNoAtDirective() {
3011 MCAsmParser &Parser = getParser();
3012 // Line should look like: ".set noat".
3014 AssemblerOptions.back()->setATReg(0);
3017 // If this is not the end of the statement, report an error.
3018 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3019 reportParseError("unexpected token, expected end of statement");
3022 Parser.Lex(); // Consume the EndOfStatement.
3026 bool MipsAsmParser::parseSetAtDirective() {
3027 MCAsmParser &Parser = getParser();
3028 // Line can be .set at - defaults to $1
3032 if (getLexer().is(AsmToken::EndOfStatement)) {
3033 AssemblerOptions.back()->setATReg(1);
3034 Parser.Lex(); // Consume the EndOfStatement.
3036 } else if (getLexer().is(AsmToken::Equal)) {
3037 getParser().Lex(); // Eat the '='.
3038 if (getLexer().isNot(AsmToken::Dollar)) {
3039 reportParseError("unexpected token, expected dollar sign '$'");
3042 Parser.Lex(); // Eat the '$'.
3043 const AsmToken &Reg = Parser.getTok();
3044 if (Reg.is(AsmToken::Identifier)) {
3045 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3046 } else if (Reg.is(AsmToken::Integer)) {
3047 AtRegNo = Reg.getIntVal();
3049 reportParseError("unexpected token, expected identifier or integer");
3053 if (AtRegNo < 0 || AtRegNo > 31) {
3054 reportParseError("unexpected token in statement");
3058 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3059 reportParseError("invalid register");
3062 getParser().Lex(); // Eat the register.
3064 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3065 reportParseError("unexpected token, expected end of statement");
3068 Parser.Lex(); // Consume the EndOfStatement.
3071 reportParseError("unexpected token in statement");
3076 bool MipsAsmParser::parseSetReorderDirective() {
3077 MCAsmParser &Parser = getParser();
3079 // If this is not the end of the statement, report an error.
3080 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3081 reportParseError("unexpected token, expected end of statement");
3084 AssemblerOptions.back()->setReorder();
3085 getTargetStreamer().emitDirectiveSetReorder();
3086 Parser.Lex(); // Consume the EndOfStatement.
3090 bool MipsAsmParser::parseSetNoReorderDirective() {
3091 MCAsmParser &Parser = getParser();
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 AssemblerOptions.back()->setNoReorder();
3099 getTargetStreamer().emitDirectiveSetNoReorder();
3100 Parser.Lex(); // Consume the EndOfStatement.
3104 bool MipsAsmParser::parseSetMacroDirective() {
3105 MCAsmParser &Parser = getParser();
3107 // If this is not the end of the statement, report an error.
3108 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3109 reportParseError("unexpected token, expected end of statement");
3112 AssemblerOptions.back()->setMacro();
3113 Parser.Lex(); // Consume the EndOfStatement.
3117 bool MipsAsmParser::parseSetNoMacroDirective() {
3118 MCAsmParser &Parser = getParser();
3120 // If this is not the end of the statement, report an error.
3121 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3122 reportParseError("unexpected token, expected end of statement");
3125 if (AssemblerOptions.back()->isReorder()) {
3126 reportParseError("`noreorder' must be set before `nomacro'");
3129 AssemblerOptions.back()->setNoMacro();
3130 Parser.Lex(); // Consume the EndOfStatement.
3134 bool MipsAsmParser::parseSetMsaDirective() {
3135 MCAsmParser &Parser = getParser();
3138 // If this is not the end of the statement, report an error.
3139 if (getLexer().isNot(AsmToken::EndOfStatement))
3140 return reportParseError("unexpected token, expected end of statement");
3142 setFeatureBits(Mips::FeatureMSA, "msa");
3143 getTargetStreamer().emitDirectiveSetMsa();
3147 bool MipsAsmParser::parseSetNoMsaDirective() {
3148 MCAsmParser &Parser = getParser();
3151 // If this is not the end of the statement, report an error.
3152 if (getLexer().isNot(AsmToken::EndOfStatement))
3153 return reportParseError("unexpected token, expected end of statement");
3155 clearFeatureBits(Mips::FeatureMSA, "msa");
3156 getTargetStreamer().emitDirectiveSetNoMsa();
3160 bool MipsAsmParser::parseSetNoDspDirective() {
3161 MCAsmParser &Parser = getParser();
3162 Parser.Lex(); // Eat "nodsp".
3164 // If this is not the end of the statement, report an error.
3165 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3166 reportParseError("unexpected token, expected end of statement");
3170 clearFeatureBits(Mips::FeatureDSP, "dsp");
3171 getTargetStreamer().emitDirectiveSetNoDsp();
3175 bool MipsAsmParser::parseSetMips16Directive() {
3176 MCAsmParser &Parser = getParser();
3177 Parser.Lex(); // Eat "mips16".
3179 // If this is not the end of the statement, report an error.
3180 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3181 reportParseError("unexpected token, expected end of statement");
3185 setFeatureBits(Mips::FeatureMips16, "mips16");
3186 getTargetStreamer().emitDirectiveSetMips16();
3187 Parser.Lex(); // Consume the EndOfStatement.
3191 bool MipsAsmParser::parseSetNoMips16Directive() {
3192 MCAsmParser &Parser = getParser();
3193 Parser.Lex(); // Eat "nomips16".
3195 // If this is not the end of the statement, report an error.
3196 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3197 reportParseError("unexpected token, expected end of statement");
3201 clearFeatureBits(Mips::FeatureMips16, "mips16");
3202 getTargetStreamer().emitDirectiveSetNoMips16();
3203 Parser.Lex(); // Consume the EndOfStatement.
3207 bool MipsAsmParser::parseSetFpDirective() {
3208 MCAsmParser &Parser = getParser();
3209 MipsABIFlagsSection::FpABIKind FpAbiVal;
3210 // Line can be: .set fp=32
3213 Parser.Lex(); // Eat fp token
3214 AsmToken Tok = Parser.getTok();
3215 if (Tok.isNot(AsmToken::Equal)) {
3216 reportParseError("unexpected token, expected equals sign '='");
3219 Parser.Lex(); // Eat '=' token.
3220 Tok = Parser.getTok();
3222 if (!parseFpABIValue(FpAbiVal, ".set"))
3225 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3226 reportParseError("unexpected token, expected end of statement");
3229 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3230 Parser.Lex(); // Consume the EndOfStatement.
3234 bool MipsAsmParser::parseSetPopDirective() {
3235 MCAsmParser &Parser = getParser();
3236 SMLoc Loc = getLexer().getLoc();
3239 if (getLexer().isNot(AsmToken::EndOfStatement))
3240 return reportParseError("unexpected token, expected end of statement");
3242 // Always keep an element on the options "stack" to prevent the user
3243 // from changing the initial options. This is how we remember them.
3244 if (AssemblerOptions.size() == 2)
3245 return reportParseError(Loc, ".set pop with no .set push");
3247 AssemblerOptions.pop_back();
3248 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3250 getTargetStreamer().emitDirectiveSetPop();
3254 bool MipsAsmParser::parseSetPushDirective() {
3255 MCAsmParser &Parser = getParser();
3257 if (getLexer().isNot(AsmToken::EndOfStatement))
3258 return reportParseError("unexpected token, expected end of statement");
3260 // Create a copy of the current assembler options environment and push it.
3261 AssemblerOptions.push_back(
3262 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3264 getTargetStreamer().emitDirectiveSetPush();
3268 bool MipsAsmParser::parseSetAssignment() {
3270 const MCExpr *Value;
3271 MCAsmParser &Parser = getParser();
3273 if (Parser.parseIdentifier(Name))
3274 reportParseError("expected identifier after .set");
3276 if (getLexer().isNot(AsmToken::Comma))
3277 return reportParseError("unexpected token, expected comma");
3280 if (Parser.parseExpression(Value))
3281 return reportParseError("expected valid expression after comma");
3283 // Check if the Name already exists as a symbol.
3284 MCSymbol *Sym = getContext().LookupSymbol(Name);
3286 return reportParseError("symbol already defined");
3287 Sym = getContext().GetOrCreateSymbol(Name);
3288 Sym->setVariableValue(Value);
3293 bool MipsAsmParser::parseSetMips0Directive() {
3294 MCAsmParser &Parser = getParser();
3296 if (getLexer().isNot(AsmToken::EndOfStatement))
3297 return reportParseError("unexpected token, expected end of statement");
3299 // Reset assembler options to their initial values.
3300 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3301 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3303 getTargetStreamer().emitDirectiveSetMips0();
3307 bool MipsAsmParser::parseSetArchDirective() {
3308 MCAsmParser &Parser = getParser();
3310 if (getLexer().isNot(AsmToken::Equal))
3311 return reportParseError("unexpected token, expected equals sign");
3315 if (Parser.parseIdentifier(Arch))
3316 return reportParseError("expected arch identifier");
3318 StringRef ArchFeatureName =
3319 StringSwitch<StringRef>(Arch)
3320 .Case("mips1", "mips1")
3321 .Case("mips2", "mips2")
3322 .Case("mips3", "mips3")
3323 .Case("mips4", "mips4")
3324 .Case("mips5", "mips5")
3325 .Case("mips32", "mips32")
3326 .Case("mips32r2", "mips32r2")
3327 .Case("mips32r6", "mips32r6")
3328 .Case("mips64", "mips64")
3329 .Case("mips64r2", "mips64r2")
3330 .Case("mips64r6", "mips64r6")
3331 .Case("cnmips", "cnmips")
3332 .Case("r4000", "mips3") // This is an implementation of Mips3.
3335 if (ArchFeatureName.empty())
3336 return reportParseError("unsupported architecture");
3338 selectArch(ArchFeatureName);
3339 getTargetStreamer().emitDirectiveSetArch(Arch);
3343 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3344 MCAsmParser &Parser = getParser();
3346 if (getLexer().isNot(AsmToken::EndOfStatement))
3347 return reportParseError("unexpected token, expected end of statement");
3351 llvm_unreachable("Unimplemented feature");
3352 case Mips::FeatureDSP:
3353 setFeatureBits(Mips::FeatureDSP, "dsp");
3354 getTargetStreamer().emitDirectiveSetDsp();
3356 case Mips::FeatureMicroMips:
3357 getTargetStreamer().emitDirectiveSetMicroMips();
3359 case Mips::FeatureMips1:
3360 selectArch("mips1");
3361 getTargetStreamer().emitDirectiveSetMips1();
3363 case Mips::FeatureMips2:
3364 selectArch("mips2");
3365 getTargetStreamer().emitDirectiveSetMips2();
3367 case Mips::FeatureMips3:
3368 selectArch("mips3");
3369 getTargetStreamer().emitDirectiveSetMips3();
3371 case Mips::FeatureMips4:
3372 selectArch("mips4");
3373 getTargetStreamer().emitDirectiveSetMips4();
3375 case Mips::FeatureMips5:
3376 selectArch("mips5");
3377 getTargetStreamer().emitDirectiveSetMips5();
3379 case Mips::FeatureMips32:
3380 selectArch("mips32");
3381 getTargetStreamer().emitDirectiveSetMips32();
3383 case Mips::FeatureMips32r2:
3384 selectArch("mips32r2");
3385 getTargetStreamer().emitDirectiveSetMips32R2();
3387 case Mips::FeatureMips32r6:
3388 selectArch("mips32r6");
3389 getTargetStreamer().emitDirectiveSetMips32R6();
3391 case Mips::FeatureMips64:
3392 selectArch("mips64");
3393 getTargetStreamer().emitDirectiveSetMips64();
3395 case Mips::FeatureMips64r2:
3396 selectArch("mips64r2");
3397 getTargetStreamer().emitDirectiveSetMips64R2();
3399 case Mips::FeatureMips64r6:
3400 selectArch("mips64r6");
3401 getTargetStreamer().emitDirectiveSetMips64R6();
3407 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3408 MCAsmParser &Parser = getParser();
3409 if (getLexer().isNot(AsmToken::Comma)) {
3410 SMLoc Loc = getLexer().getLoc();
3411 Parser.eatToEndOfStatement();
3412 return Error(Loc, ErrorStr);
3415 Parser.Lex(); // Eat the comma.
3419 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3420 if (AssemblerOptions.back()->isReorder())
3421 Warning(Loc, ".cpload should be inside a noreorder section");
3423 if (inMips16Mode()) {
3424 reportParseError(".cpload is not supported in Mips16 mode");
3428 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3429 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3430 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3431 reportParseError("expected register containing function address");
3435 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3436 if (!RegOpnd.isGPRAsmReg()) {
3437 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3441 // If this is not the end of the statement, report an error.
3442 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3443 reportParseError("unexpected token, expected end of statement");
3447 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3451 bool MipsAsmParser::parseDirectiveCPSetup() {
3452 MCAsmParser &Parser = getParser();
3455 bool SaveIsReg = true;
3457 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3458 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3459 if (ResTy == MatchOperand_NoMatch) {
3460 reportParseError("expected register containing function address");
3461 Parser.eatToEndOfStatement();
3465 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3466 if (!FuncRegOpnd.isGPRAsmReg()) {
3467 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3468 Parser.eatToEndOfStatement();
3472 FuncReg = FuncRegOpnd.getGPR32Reg();
3475 if (!eatComma("unexpected token, expected comma"))
3478 ResTy = parseAnyRegister(TmpReg);
3479 if (ResTy == MatchOperand_NoMatch) {
3480 const AsmToken &Tok = Parser.getTok();
3481 if (Tok.is(AsmToken::Integer)) {
3482 Save = Tok.getIntVal();
3486 reportParseError("expected save register or stack offset");
3487 Parser.eatToEndOfStatement();
3491 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3492 if (!SaveOpnd.isGPRAsmReg()) {
3493 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3494 Parser.eatToEndOfStatement();
3497 Save = SaveOpnd.getGPR32Reg();
3500 if (!eatComma("unexpected token, expected comma"))
3504 if (Parser.parseIdentifier(Name))
3505 reportParseError("expected identifier");
3506 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3508 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3512 bool MipsAsmParser::parseDirectiveNaN() {
3513 MCAsmParser &Parser = getParser();
3514 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3515 const AsmToken &Tok = Parser.getTok();
3517 if (Tok.getString() == "2008") {
3519 getTargetStreamer().emitDirectiveNaN2008();
3521 } else if (Tok.getString() == "legacy") {
3523 getTargetStreamer().emitDirectiveNaNLegacy();
3527 // If we don't recognize the option passed to the .nan
3528 // directive (e.g. no option or unknown option), emit an error.
3529 reportParseError("invalid option in .nan directive");
3533 bool MipsAsmParser::parseDirectiveSet() {
3534 MCAsmParser &Parser = getParser();
3535 // Get the next token.
3536 const AsmToken &Tok = Parser.getTok();
3538 if (Tok.getString() == "noat") {
3539 return parseSetNoAtDirective();
3540 } else if (Tok.getString() == "at") {
3541 return parseSetAtDirective();
3542 } else if (Tok.getString() == "arch") {
3543 return parseSetArchDirective();
3544 } else if (Tok.getString() == "fp") {
3545 return parseSetFpDirective();
3546 } else if (Tok.getString() == "pop") {
3547 return parseSetPopDirective();
3548 } else if (Tok.getString() == "push") {
3549 return parseSetPushDirective();
3550 } else if (Tok.getString() == "reorder") {
3551 return parseSetReorderDirective();
3552 } else if (Tok.getString() == "noreorder") {
3553 return parseSetNoReorderDirective();
3554 } else if (Tok.getString() == "macro") {
3555 return parseSetMacroDirective();
3556 } else if (Tok.getString() == "nomacro") {
3557 return parseSetNoMacroDirective();
3558 } else if (Tok.getString() == "mips16") {
3559 return parseSetMips16Directive();
3560 } else if (Tok.getString() == "nomips16") {
3561 return parseSetNoMips16Directive();
3562 } else if (Tok.getString() == "nomicromips") {
3563 getTargetStreamer().emitDirectiveSetNoMicroMips();
3564 Parser.eatToEndOfStatement();
3566 } else if (Tok.getString() == "micromips") {
3567 return parseSetFeature(Mips::FeatureMicroMips);
3568 } else if (Tok.getString() == "mips0") {
3569 return parseSetMips0Directive();
3570 } else if (Tok.getString() == "mips1") {
3571 return parseSetFeature(Mips::FeatureMips1);
3572 } else if (Tok.getString() == "mips2") {
3573 return parseSetFeature(Mips::FeatureMips2);
3574 } else if (Tok.getString() == "mips3") {
3575 return parseSetFeature(Mips::FeatureMips3);
3576 } else if (Tok.getString() == "mips4") {
3577 return parseSetFeature(Mips::FeatureMips4);
3578 } else if (Tok.getString() == "mips5") {
3579 return parseSetFeature(Mips::FeatureMips5);
3580 } else if (Tok.getString() == "mips32") {
3581 return parseSetFeature(Mips::FeatureMips32);
3582 } else if (Tok.getString() == "mips32r2") {
3583 return parseSetFeature(Mips::FeatureMips32r2);
3584 } else if (Tok.getString() == "mips32r6") {
3585 return parseSetFeature(Mips::FeatureMips32r6);
3586 } else if (Tok.getString() == "mips64") {
3587 return parseSetFeature(Mips::FeatureMips64);
3588 } else if (Tok.getString() == "mips64r2") {
3589 return parseSetFeature(Mips::FeatureMips64r2);
3590 } else if (Tok.getString() == "mips64r6") {
3591 return parseSetFeature(Mips::FeatureMips64r6);
3592 } else if (Tok.getString() == "dsp") {
3593 return parseSetFeature(Mips::FeatureDSP);
3594 } else if (Tok.getString() == "nodsp") {
3595 return parseSetNoDspDirective();
3596 } else if (Tok.getString() == "msa") {
3597 return parseSetMsaDirective();
3598 } else if (Tok.getString() == "nomsa") {
3599 return parseSetNoMsaDirective();
3601 // It is just an identifier, look for an assignment.
3602 parseSetAssignment();
3609 /// parseDataDirective
3610 /// ::= .word [ expression (, expression)* ]
3611 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3612 MCAsmParser &Parser = getParser();
3613 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3615 const MCExpr *Value;
3616 if (getParser().parseExpression(Value))
3619 getParser().getStreamer().EmitValue(Value, Size);
3621 if (getLexer().is(AsmToken::EndOfStatement))
3624 if (getLexer().isNot(AsmToken::Comma))
3625 return Error(L, "unexpected token, expected comma");
3634 /// parseDirectiveGpWord
3635 /// ::= .gpword local_sym
3636 bool MipsAsmParser::parseDirectiveGpWord() {
3637 MCAsmParser &Parser = getParser();
3638 const MCExpr *Value;
3639 // EmitGPRel32Value requires an expression, so we are using base class
3640 // method to evaluate the expression.
3641 if (getParser().parseExpression(Value))
3643 getParser().getStreamer().EmitGPRel32Value(Value);
3645 if (getLexer().isNot(AsmToken::EndOfStatement))
3646 return Error(getLexer().getLoc(),
3647 "unexpected token, expected end of statement");
3648 Parser.Lex(); // Eat EndOfStatement token.
3652 /// parseDirectiveGpDWord
3653 /// ::= .gpdword local_sym
3654 bool MipsAsmParser::parseDirectiveGpDWord() {
3655 MCAsmParser &Parser = getParser();
3656 const MCExpr *Value;
3657 // EmitGPRel64Value requires an expression, so we are using base class
3658 // method to evaluate the expression.
3659 if (getParser().parseExpression(Value))
3661 getParser().getStreamer().EmitGPRel64Value(Value);
3663 if (getLexer().isNot(AsmToken::EndOfStatement))
3664 return Error(getLexer().getLoc(),
3665 "unexpected token, expected end of statement");
3666 Parser.Lex(); // Eat EndOfStatement token.
3670 bool MipsAsmParser::parseDirectiveOption() {
3671 MCAsmParser &Parser = getParser();
3672 // Get the option token.
3673 AsmToken Tok = Parser.getTok();
3674 // At the moment only identifiers are supported.
3675 if (Tok.isNot(AsmToken::Identifier)) {
3676 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3677 Parser.eatToEndOfStatement();
3681 StringRef Option = Tok.getIdentifier();
3683 if (Option == "pic0") {
3684 getTargetStreamer().emitDirectiveOptionPic0();
3686 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3687 Error(Parser.getTok().getLoc(),
3688 "unexpected token, expected end of statement");
3689 Parser.eatToEndOfStatement();
3694 if (Option == "pic2") {
3695 getTargetStreamer().emitDirectiveOptionPic2();
3697 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3698 Error(Parser.getTok().getLoc(),
3699 "unexpected token, expected end of statement");
3700 Parser.eatToEndOfStatement();
3706 Warning(Parser.getTok().getLoc(),
3707 "unknown option, expected 'pic0' or 'pic2'");
3708 Parser.eatToEndOfStatement();
3712 /// parseDirectiveModule
3713 /// ::= .module oddspreg
3714 /// ::= .module nooddspreg
3715 /// ::= .module fp=value
3716 bool MipsAsmParser::parseDirectiveModule() {
3717 MCAsmParser &Parser = getParser();
3718 MCAsmLexer &Lexer = getLexer();
3719 SMLoc L = Lexer.getLoc();
3721 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3722 // TODO : get a better message.
3723 reportParseError(".module directive must appear before any code");
3727 if (Lexer.is(AsmToken::Identifier)) {
3728 StringRef Option = Parser.getTok().getString();
3731 if (Option == "oddspreg") {
3732 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3733 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3735 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3736 reportParseError("unexpected token, expected end of statement");
3741 } else if (Option == "nooddspreg") {
3743 Error(L, "'.module nooddspreg' requires the O32 ABI");
3747 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3748 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3750 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3751 reportParseError("unexpected token, expected end of statement");
3756 } else if (Option == "fp") {
3757 return parseDirectiveModuleFP();
3760 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3766 /// parseDirectiveModuleFP
3770 bool MipsAsmParser::parseDirectiveModuleFP() {
3771 MCAsmParser &Parser = getParser();
3772 MCAsmLexer &Lexer = getLexer();
3774 if (Lexer.isNot(AsmToken::Equal)) {
3775 reportParseError("unexpected token, expected equals sign '='");
3778 Parser.Lex(); // Eat '=' token.
3780 MipsABIFlagsSection::FpABIKind FpABI;
3781 if (!parseFpABIValue(FpABI, ".module"))
3784 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3785 reportParseError("unexpected token, expected end of statement");
3789 // Emit appropriate flags.
3790 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3791 Parser.Lex(); // Consume the EndOfStatement.
3795 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3796 StringRef Directive) {
3797 MCAsmParser &Parser = getParser();
3798 MCAsmLexer &Lexer = getLexer();
3800 if (Lexer.is(AsmToken::Identifier)) {
3801 StringRef Value = Parser.getTok().getString();
3804 if (Value != "xx") {
3805 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3810 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3814 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3818 if (Lexer.is(AsmToken::Integer)) {
3819 unsigned Value = Parser.getTok().getIntVal();
3822 if (Value != 32 && Value != 64) {
3823 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3829 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3833 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3835 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3843 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3844 MCAsmParser &Parser = getParser();
3845 StringRef IDVal = DirectiveID.getString();
3847 if (IDVal == ".cpload")
3848 return parseDirectiveCpLoad(DirectiveID.getLoc());
3849 if (IDVal == ".dword") {
3850 parseDataDirective(8, DirectiveID.getLoc());
3853 if (IDVal == ".ent") {
3854 StringRef SymbolName;
3856 if (Parser.parseIdentifier(SymbolName)) {
3857 reportParseError("expected identifier after .ent");
3861 // There's an undocumented extension that allows an integer to
3862 // follow the name of the procedure which AFAICS is ignored by GAS.
3863 // Example: .ent foo,2
3864 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3865 if (getLexer().isNot(AsmToken::Comma)) {
3866 // Even though we accept this undocumented extension for compatibility
3867 // reasons, the additional integer argument does not actually change
3868 // the behaviour of the '.ent' directive, so we would like to discourage
3869 // its use. We do this by not referring to the extended version in
3870 // error messages which are not directly related to its use.
3871 reportParseError("unexpected token, expected end of statement");
3874 Parser.Lex(); // Eat the comma.
3875 const MCExpr *DummyNumber;
3876 int64_t DummyNumberVal;
3877 // If the user was explicitly trying to use the extended version,
3878 // we still give helpful extension-related error messages.
3879 if (Parser.parseExpression(DummyNumber)) {
3880 reportParseError("expected number after comma");
3883 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3884 reportParseError("expected an absolute expression after comma");
3889 // If this is not the end of the statement, report an error.
3890 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3891 reportParseError("unexpected token, expected end of statement");
3895 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3897 getTargetStreamer().emitDirectiveEnt(*Sym);
3902 if (IDVal == ".end") {
3903 StringRef SymbolName;
3905 if (Parser.parseIdentifier(SymbolName)) {
3906 reportParseError("expected identifier after .end");
3910 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3911 reportParseError("unexpected token, expected end of statement");
3915 if (CurrentFn == nullptr) {
3916 reportParseError(".end used without .ent");
3920 if ((SymbolName != CurrentFn->getName())) {
3921 reportParseError(".end symbol does not match .ent symbol");
3925 getTargetStreamer().emitDirectiveEnd(SymbolName);
3926 CurrentFn = nullptr;
3930 if (IDVal == ".frame") {
3931 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3932 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3933 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3934 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3935 reportParseError("expected stack register");
3939 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3940 if (!StackRegOpnd.isGPRAsmReg()) {
3941 reportParseError(StackRegOpnd.getStartLoc(),
3942 "expected general purpose register");
3945 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3947 if (Parser.getTok().is(AsmToken::Comma))
3950 reportParseError("unexpected token, expected comma");
3954 // Parse the frame size.
3955 const MCExpr *FrameSize;
3956 int64_t FrameSizeVal;
3958 if (Parser.parseExpression(FrameSize)) {
3959 reportParseError("expected frame size value");
3963 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3964 reportParseError("frame size not an absolute expression");
3968 if (Parser.getTok().is(AsmToken::Comma))
3971 reportParseError("unexpected token, expected comma");
3975 // Parse the return register.
3977 ResTy = parseAnyRegister(TmpReg);
3978 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3979 reportParseError("expected return register");
3983 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3984 if (!ReturnRegOpnd.isGPRAsmReg()) {
3985 reportParseError(ReturnRegOpnd.getStartLoc(),
3986 "expected general purpose register");
3990 // If this is not the end of the statement, report an error.
3991 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3992 reportParseError("unexpected token, expected end of statement");
3996 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3997 ReturnRegOpnd.getGPR32Reg());
4001 if (IDVal == ".set") {
4002 return parseDirectiveSet();
4005 if (IDVal == ".mask" || IDVal == ".fmask") {
4006 // .mask bitmask, frame_offset
4007 // bitmask: One bit for each register used.
4008 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4009 // first register is expected to be saved.
4011 // .mask 0x80000000, -4
4012 // .fmask 0x80000000, -4
4015 // Parse the bitmask
4016 const MCExpr *BitMask;
4019 if (Parser.parseExpression(BitMask)) {
4020 reportParseError("expected bitmask value");
4024 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4025 reportParseError("bitmask not an absolute expression");
4029 if (Parser.getTok().is(AsmToken::Comma))
4032 reportParseError("unexpected token, expected comma");
4036 // Parse the frame_offset
4037 const MCExpr *FrameOffset;
4038 int64_t FrameOffsetVal;
4040 if (Parser.parseExpression(FrameOffset)) {
4041 reportParseError("expected frame offset value");
4045 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4046 reportParseError("frame offset not an absolute expression");
4050 // If this is not the end of the statement, report an error.
4051 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4052 reportParseError("unexpected token, expected end of statement");
4056 if (IDVal == ".mask")
4057 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4059 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4063 if (IDVal == ".nan")
4064 return parseDirectiveNaN();
4066 if (IDVal == ".gpword") {
4067 parseDirectiveGpWord();
4071 if (IDVal == ".gpdword") {
4072 parseDirectiveGpDWord();
4076 if (IDVal == ".word") {
4077 parseDataDirective(4, DirectiveID.getLoc());
4081 if (IDVal == ".option")
4082 return parseDirectiveOption();
4084 if (IDVal == ".abicalls") {
4085 getTargetStreamer().emitDirectiveAbiCalls();
4086 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4087 Error(Parser.getTok().getLoc(),
4088 "unexpected token, expected end of statement");
4090 Parser.eatToEndOfStatement();
4095 if (IDVal == ".cpsetup")
4096 return parseDirectiveCPSetup();
4098 if (IDVal == ".module")
4099 return parseDirectiveModule();
4104 extern "C" void LLVMInitializeMipsAsmParser() {
4105 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4106 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4107 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4108 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4111 #define GET_REGISTER_MATCHER
4112 #define GET_MATCHER_IMPLEMENTATION
4113 #include "MipsGenAsmMatcher.inc"