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");
1404 if (needsExpansion(Inst))
1405 return expandInstruction(Inst, IDLoc, Instructions);
1407 Instructions.push_back(Inst);
1412 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1414 switch (Inst.getOpcode()) {
1415 case Mips::LoadImm32Reg:
1416 case Mips::LoadAddr32Imm:
1417 case Mips::LoadAddr32Reg:
1418 case Mips::LoadImm64Reg:
1419 case Mips::B_MM_Pseudo:
1426 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1427 SmallVectorImpl<MCInst> &Instructions) {
1428 switch (Inst.getOpcode()) {
1429 default: llvm_unreachable("unimplemented expansion");
1430 case Mips::LoadImm32Reg:
1431 return expandLoadImm(Inst, IDLoc, Instructions);
1432 case Mips::LoadImm64Reg:
1434 Error(IDLoc, "instruction requires a 64-bit architecture");
1437 return expandLoadImm(Inst, IDLoc, Instructions);
1438 case Mips::LoadAddr32Imm:
1439 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1440 case Mips::LoadAddr32Reg:
1441 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1442 case Mips::B_MM_Pseudo:
1443 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1448 template <bool PerformShift>
1449 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1450 SmallVectorImpl<MCInst> &Instructions) {
1453 tmpInst.setOpcode(Mips::DSLL);
1454 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1455 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1456 tmpInst.addOperand(MCOperand::CreateImm(16));
1457 tmpInst.setLoc(IDLoc);
1458 Instructions.push_back(tmpInst);
1461 tmpInst.setOpcode(Mips::ORi);
1462 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1463 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1464 tmpInst.addOperand(Operand);
1465 tmpInst.setLoc(IDLoc);
1466 Instructions.push_back(tmpInst);
1469 template <int Shift, bool PerformShift>
1470 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1471 SmallVectorImpl<MCInst> &Instructions) {
1472 createShiftOr<PerformShift>(
1473 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1474 IDLoc, Instructions);
1478 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1479 SmallVectorImpl<MCInst> &Instructions) {
1481 const MCOperand &ImmOp = Inst.getOperand(1);
1482 assert(ImmOp.isImm() && "expected immediate operand kind");
1483 const MCOperand &RegOp = Inst.getOperand(0);
1484 assert(RegOp.isReg() && "expected register operand kind");
1486 int64_t ImmValue = ImmOp.getImm();
1487 tmpInst.setLoc(IDLoc);
1488 // FIXME: gas has a special case for values that are 000...1111, which
1489 // becomes a li -1 and then a dsrl
1490 if (0 <= ImmValue && ImmValue <= 65535) {
1491 // For 0 <= j <= 65535.
1492 // li d,j => ori d,$zero,j
1493 tmpInst.setOpcode(Mips::ORi);
1494 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1495 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1496 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1497 Instructions.push_back(tmpInst);
1498 } else if (ImmValue < 0 && ImmValue >= -32768) {
1499 // For -32768 <= j < 0.
1500 // li d,j => addiu d,$zero,j
1501 tmpInst.setOpcode(Mips::ADDiu);
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 & 0xffffffff) == ImmValue) {
1507 // For any value of j that is representable as a 32-bit integer, create
1509 // li d,j => lui d,hi16(j)
1511 tmpInst.setOpcode(Mips::LUi);
1512 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1513 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1514 Instructions.push_back(tmpInst);
1515 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1516 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1518 Error(IDLoc, "instruction requires a 64-bit architecture");
1522 // <------- lo32 ------>
1523 // <------- hi32 ------>
1524 // <- hi16 -> <- lo16 ->
1525 // _________________________________
1527 // | 16-bytes | 16-bytes | 16-bytes |
1528 // |__________|__________|__________|
1530 // For any value of j that is representable as a 48-bit integer, create
1532 // li d,j => lui d,hi16(j)
1533 // ori d,d,hi16(lo32(j))
1535 // ori d,d,lo16(lo32(j))
1536 tmpInst.setOpcode(Mips::LUi);
1537 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1539 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1540 Instructions.push_back(tmpInst);
1541 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1542 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1545 Error(IDLoc, "instruction requires a 64-bit architecture");
1549 // <------- hi32 ------> <------- lo32 ------>
1550 // <- hi16 -> <- lo16 ->
1551 // ___________________________________________
1553 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1554 // |__________|__________|__________|__________|
1556 // For any value of j that isn't representable as a 48-bit integer.
1557 // li d,j => lui d,hi16(j)
1558 // ori d,d,lo16(hi32(j))
1560 // ori d,d,hi16(lo32(j))
1562 // ori d,d,lo16(lo32(j))
1563 tmpInst.setOpcode(Mips::LUi);
1564 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1566 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1567 Instructions.push_back(tmpInst);
1568 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1569 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1570 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1576 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1577 SmallVectorImpl<MCInst> &Instructions) {
1579 const MCOperand &ImmOp = Inst.getOperand(2);
1580 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1581 "expected immediate operand kind");
1582 if (!ImmOp.isImm()) {
1583 expandLoadAddressSym(Inst, IDLoc, Instructions);
1586 const MCOperand &SrcRegOp = Inst.getOperand(1);
1587 assert(SrcRegOp.isReg() && "expected register operand kind");
1588 const MCOperand &DstRegOp = Inst.getOperand(0);
1589 assert(DstRegOp.isReg() && "expected register operand kind");
1590 int ImmValue = ImmOp.getImm();
1591 if (-32768 <= ImmValue && ImmValue <= 65535) {
1592 // For -32768 <= j <= 65535.
1593 // la d,j(s) => addiu d,s,j
1594 tmpInst.setOpcode(Mips::ADDiu);
1595 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1596 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1597 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1598 Instructions.push_back(tmpInst);
1600 // For any other value of j that is representable as a 32-bit integer.
1601 // la d,j(s) => lui d,hi16(j)
1604 tmpInst.setOpcode(Mips::LUi);
1605 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1606 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1607 Instructions.push_back(tmpInst);
1609 tmpInst.setOpcode(Mips::ORi);
1610 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1611 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1612 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1613 Instructions.push_back(tmpInst);
1615 tmpInst.setOpcode(Mips::ADDu);
1616 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1617 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1618 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1619 Instructions.push_back(tmpInst);
1625 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1626 SmallVectorImpl<MCInst> &Instructions) {
1628 const MCOperand &ImmOp = Inst.getOperand(1);
1629 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1630 "expected immediate operand kind");
1631 if (!ImmOp.isImm()) {
1632 expandLoadAddressSym(Inst, IDLoc, Instructions);
1635 const MCOperand &RegOp = Inst.getOperand(0);
1636 assert(RegOp.isReg() && "expected register operand kind");
1637 int ImmValue = ImmOp.getImm();
1638 if (-32768 <= ImmValue && ImmValue <= 65535) {
1639 // For -32768 <= j <= 65535.
1640 // la d,j => addiu d,$zero,j
1641 tmpInst.setOpcode(Mips::ADDiu);
1642 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1643 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1644 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1645 Instructions.push_back(tmpInst);
1647 // For any other value of j that is representable as a 32-bit integer.
1648 // la d,j => lui d,hi16(j)
1650 tmpInst.setOpcode(Mips::LUi);
1651 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1652 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1653 Instructions.push_back(tmpInst);
1655 tmpInst.setOpcode(Mips::ORi);
1656 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1657 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1658 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1659 Instructions.push_back(tmpInst);
1665 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1666 SmallVectorImpl<MCInst> &Instructions) {
1667 // FIXME: If we do have a valid at register to use, we should generate a
1668 // slightly shorter sequence here.
1670 int ExprOperandNo = 1;
1671 // Sometimes the assembly parser will get the immediate expression as
1672 // a $zero + an immediate.
1673 if (Inst.getNumOperands() == 3) {
1674 assert(Inst.getOperand(1).getReg() ==
1675 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1678 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1679 assert(SymOp.isExpr() && "expected symbol operand kind");
1680 const MCOperand &RegOp = Inst.getOperand(0);
1681 unsigned RegNo = RegOp.getReg();
1682 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1683 const MCSymbolRefExpr *HiExpr =
1684 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1685 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1686 const MCSymbolRefExpr *LoExpr =
1687 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1688 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1690 // If it's a 64-bit architecture, expand to:
1691 // la d,sym => lui d,highest(sym)
1692 // ori d,d,higher(sym)
1694 // ori d,d,hi16(sym)
1696 // ori d,d,lo16(sym)
1697 const MCSymbolRefExpr *HighestExpr =
1698 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1699 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1700 const MCSymbolRefExpr *HigherExpr =
1701 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1702 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1704 tmpInst.setOpcode(Mips::LUi);
1705 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1706 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1707 Instructions.push_back(tmpInst);
1709 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1711 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1713 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1716 // Otherwise, expand to:
1717 // la d,sym => lui d,hi16(sym)
1718 // ori d,d,lo16(sym)
1719 tmpInst.setOpcode(Mips::LUi);
1720 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1721 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1722 Instructions.push_back(tmpInst);
1724 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1729 bool MipsAsmParser::
1730 expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
1731 SmallVectorImpl<MCInst> &Instructions) {
1732 assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
1733 "unexpected number of operands");
1735 MCOperand Offset = Inst.getOperand(0);
1736 if (Offset.isExpr()) {
1738 Inst.setOpcode(Mips::BEQ_MM);
1739 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1740 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1741 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1743 assert(Offset.isImm() && "expected immediate operand kind");
1744 if (isIntN(11, Offset.getImm())) {
1745 // If offset fits into 11 bits then this instruction becomes microMIPS
1746 // 16-bit unconditional branch instruction.
1747 Inst.setOpcode(Mips::B16_MM);
1749 if (!isIntN(17, Offset.getImm()))
1750 Error(IDLoc, "branch target out of range");
1751 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1752 Error(IDLoc, "branch to misaligned address");
1754 Inst.setOpcode(Mips::BEQ_MM);
1755 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1756 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1757 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1760 Instructions.push_back(Inst);
1762 if (AssemblerOptions.back()->isReorder()) {
1763 // If .set reorder is active, emit a NOP after the branch instruction.
1765 NopInst.setOpcode(Mips::MOVE16_MM);
1766 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1767 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1768 Instructions.push_back(NopInst);
1773 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1774 SmallVectorImpl<MCInst> &Instructions,
1775 bool isLoad, bool isImmOpnd) {
1776 const MCSymbolRefExpr *SR;
1778 unsigned ImmOffset, HiOffset, LoOffset;
1779 const MCExpr *ExprOffset;
1781 // 1st operand is either the source or destination register.
1782 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1783 unsigned RegOpNum = Inst.getOperand(0).getReg();
1784 // 2nd operand is the base register.
1785 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1786 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1787 // 3rd operand is either an immediate or expression.
1789 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1790 ImmOffset = Inst.getOperand(2).getImm();
1791 LoOffset = ImmOffset & 0x0000ffff;
1792 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1793 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1794 if (LoOffset & 0x8000)
1797 ExprOffset = Inst.getOperand(2).getExpr();
1798 // All instructions will have the same location.
1799 TempInst.setLoc(IDLoc);
1800 // These are some of the types of expansions we perform here:
1801 // 1) lw $8, sym => lui $8, %hi(sym)
1802 // lw $8, %lo(sym)($8)
1803 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1805 // lw $8, %lo(offset)($9)
1806 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1808 // lw $8, %lo(offset)($at)
1809 // 4) sw $8, sym => lui $at, %hi(sym)
1810 // sw $8, %lo(sym)($at)
1811 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1813 // sw $8, %lo(offset)($at)
1814 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1815 // ldc1 $f0, %lo(sym)($at)
1817 // For load instructions we can use the destination register as a temporary
1818 // if base and dst are different (examples 1 and 2) and if the base register
1819 // is general purpose otherwise we must use $at (example 6) and error if it's
1820 // not available. For stores we must use $at (examples 4 and 5) because we
1821 // must not clobber the source register setting up the offset.
1822 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1823 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1824 unsigned RegClassIDOp0 =
1825 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1826 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1827 (RegClassIDOp0 == Mips::GPR64RegClassID);
1828 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1829 TmpRegNum = RegOpNum;
1831 int AT = getATReg(IDLoc);
1832 // At this point we need AT to perform the expansions and we exit if it is
1837 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1840 TempInst.setOpcode(Mips::LUi);
1841 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1843 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1845 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1846 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1847 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1848 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1850 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1852 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1853 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1856 // Add the instruction to the list.
1857 Instructions.push_back(TempInst);
1858 // Prepare TempInst for next instruction.
1860 // Add temp register to base.
1861 TempInst.setOpcode(Mips::ADDu);
1862 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1863 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1864 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1865 Instructions.push_back(TempInst);
1867 // And finally, create original instruction with low part
1868 // of offset and new base.
1869 TempInst.setOpcode(Inst.getOpcode());
1870 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1871 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1873 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1875 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1876 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1877 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1879 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1881 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1882 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1885 Instructions.push_back(TempInst);
1889 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1890 // As described by the Mips32r2 spec, the registers Rd and Rs for
1891 // jalr.hb must be different.
1892 unsigned Opcode = Inst.getOpcode();
1894 if (Opcode == Mips::JALR_HB &&
1895 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1896 return Match_RequiresDifferentSrcAndDst;
1898 return Match_Success;
1901 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1902 OperandVector &Operands,
1904 uint64_t &ErrorInfo,
1905 bool MatchingInlineAsm) {
1908 SmallVector<MCInst, 8> Instructions;
1909 unsigned MatchResult =
1910 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1912 switch (MatchResult) {
1913 case Match_Success: {
1914 if (processInstruction(Inst, IDLoc, Instructions))
1916 for (unsigned i = 0; i < Instructions.size(); i++)
1917 Out.EmitInstruction(Instructions[i], STI);
1920 case Match_MissingFeature:
1921 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1923 case Match_InvalidOperand: {
1924 SMLoc ErrorLoc = IDLoc;
1925 if (ErrorInfo != ~0ULL) {
1926 if (ErrorInfo >= Operands.size())
1927 return Error(IDLoc, "too few operands for instruction");
1929 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1930 if (ErrorLoc == SMLoc())
1934 return Error(ErrorLoc, "invalid operand for instruction");
1936 case Match_MnemonicFail:
1937 return Error(IDLoc, "invalid instruction");
1938 case Match_RequiresDifferentSrcAndDst:
1939 return Error(IDLoc, "source and destination must be different");
1942 llvm_unreachable("Implement any new match types added!");
1945 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1946 if ((RegIndex != 0) &&
1947 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1949 Warning(Loc, "used $at without \".set noat\"");
1951 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1952 Twine(RegIndex) + "\"");
1957 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1958 SMRange Range, bool ShowColors) {
1959 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1960 Range, SMFixIt(Range, FixMsg),
1964 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1967 CC = StringSwitch<unsigned>(Name)
2003 if (!(isABI_N32() || isABI_N64()))
2006 if (12 <= CC && CC <= 15) {
2007 // Name is one of t4-t7
2008 AsmToken RegTok = getLexer().peekTok();
2009 SMRange RegRange = RegTok.getLocRange();
2011 StringRef FixedName = StringSwitch<StringRef>(Name)
2017 assert(FixedName != "" && "Register name is not one of t4-t7.");
2019 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2020 "Did you mean $" + FixedName + "?", RegRange);
2023 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2024 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2025 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2026 if (8 <= CC && CC <= 11)
2030 CC = StringSwitch<unsigned>(Name)
2042 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2045 CC = StringSwitch<unsigned>(Name)
2046 .Case("hwr_cpunum", 0)
2047 .Case("hwr_synci_step", 1)
2049 .Case("hwr_ccres", 3)
2050 .Case("hwr_ulr", 29)
2056 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2058 if (Name[0] == 'f') {
2059 StringRef NumString = Name.substr(1);
2061 if (NumString.getAsInteger(10, IntVal))
2062 return -1; // This is not an integer.
2063 if (IntVal > 31) // Maximum index for fpu register.
2070 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2072 if (Name.startswith("fcc")) {
2073 StringRef NumString = Name.substr(3);
2075 if (NumString.getAsInteger(10, IntVal))
2076 return -1; // This is not an integer.
2077 if (IntVal > 7) // There are only 8 fcc registers.
2084 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2086 if (Name.startswith("ac")) {
2087 StringRef NumString = Name.substr(2);
2089 if (NumString.getAsInteger(10, IntVal))
2090 return -1; // This is not an integer.
2091 if (IntVal > 3) // There are only 3 acc registers.
2098 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2101 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2110 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2113 CC = StringSwitch<unsigned>(Name)
2116 .Case("msaaccess", 2)
2118 .Case("msamodify", 4)
2119 .Case("msarequest", 5)
2121 .Case("msaunmap", 7)
2127 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2135 int MipsAsmParser::getATReg(SMLoc Loc) {
2136 int AT = AssemblerOptions.back()->getATRegNum();
2138 reportParseError(Loc,
2139 "pseudo-instruction requires $at, which is not available");
2143 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2144 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2147 unsigned MipsAsmParser::getGPR(int RegNo) {
2148 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2152 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2154 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2157 return getReg(RegClass, RegNum);
2160 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2161 MCAsmParser &Parser = getParser();
2162 DEBUG(dbgs() << "parseOperand\n");
2164 // Check if the current operand has a custom associated parser, if so, try to
2165 // custom parse the operand, or fallback to the general approach.
2166 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2167 if (ResTy == MatchOperand_Success)
2169 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2170 // there was a match, but an error occurred, in which case, just return that
2171 // the operand parsing failed.
2172 if (ResTy == MatchOperand_ParseFail)
2175 DEBUG(dbgs() << ".. Generic Parser\n");
2177 switch (getLexer().getKind()) {
2179 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2181 case AsmToken::Dollar: {
2182 // Parse the register.
2183 SMLoc S = Parser.getTok().getLoc();
2185 // Almost all registers have been parsed by custom parsers. There is only
2186 // one exception to this. $zero (and it's alias $0) will reach this point
2187 // for div, divu, and similar instructions because it is not an operand
2188 // to the instruction definition but an explicit register. Special case
2189 // this situation for now.
2190 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2193 // Maybe it is a symbol reference.
2194 StringRef Identifier;
2195 if (Parser.parseIdentifier(Identifier))
2198 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2199 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2200 // Otherwise create a symbol reference.
2202 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2204 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2207 // Else drop to expression parsing.
2208 case AsmToken::LParen:
2209 case AsmToken::Minus:
2210 case AsmToken::Plus:
2211 case AsmToken::Integer:
2212 case AsmToken::Tilde:
2213 case AsmToken::String: {
2214 DEBUG(dbgs() << ".. generic integer\n");
2215 OperandMatchResultTy ResTy = parseImm(Operands);
2216 return ResTy != MatchOperand_Success;
2218 case AsmToken::Percent: {
2219 // It is a symbol reference or constant expression.
2220 const MCExpr *IdVal;
2221 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2222 if (parseRelocOperand(IdVal))
2225 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2227 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2229 } // case AsmToken::Percent
2230 } // switch(getLexer().getKind())
2234 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2235 StringRef RelocStr) {
2237 // Check the type of the expression.
2238 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2239 // It's a constant, evaluate reloc value.
2241 switch (getVariantKind(RelocStr)) {
2242 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2243 // Get the 1st 16-bits.
2244 Val = MCE->getValue() & 0xffff;
2246 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2247 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2248 // 16 bits being negative.
2249 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2251 case MCSymbolRefExpr::VK_Mips_HIGHER:
2252 // Get the 3rd 16-bits.
2253 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2255 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2256 // Get the 4th 16-bits.
2257 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2260 report_fatal_error("unsupported reloc value");
2262 return MCConstantExpr::Create(Val, getContext());
2265 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2266 // It's a symbol, create a symbolic expression from the symbol.
2267 StringRef Symbol = MSRE->getSymbol().getName();
2268 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2269 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2273 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2274 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2276 // Try to create target expression.
2277 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2278 return MipsMCExpr::Create(VK, Expr, getContext());
2280 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2281 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2282 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2286 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2287 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2288 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2291 // Just return the original expression.
2295 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2297 switch (Expr->getKind()) {
2298 case MCExpr::Constant:
2300 case MCExpr::SymbolRef:
2301 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2302 case MCExpr::Binary:
2303 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2304 if (!isEvaluated(BE->getLHS()))
2306 return isEvaluated(BE->getRHS());
2309 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2310 case MCExpr::Target:
2316 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2317 MCAsmParser &Parser = getParser();
2318 Parser.Lex(); // Eat the % token.
2319 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2320 if (Tok.isNot(AsmToken::Identifier))
2323 std::string Str = Tok.getIdentifier().str();
2325 Parser.Lex(); // Eat the identifier.
2326 // Now make an expression from the rest of the operand.
2327 const MCExpr *IdVal;
2330 if (getLexer().getKind() == AsmToken::LParen) {
2332 Parser.Lex(); // Eat the '(' token.
2333 if (getLexer().getKind() == AsmToken::Percent) {
2334 Parser.Lex(); // Eat the % token.
2335 const AsmToken &nextTok = Parser.getTok();
2336 if (nextTok.isNot(AsmToken::Identifier))
2339 Str += nextTok.getIdentifier();
2340 Parser.Lex(); // Eat the identifier.
2341 if (getLexer().getKind() != AsmToken::LParen)
2346 if (getParser().parseParenExpression(IdVal, EndLoc))
2349 while (getLexer().getKind() == AsmToken::RParen)
2350 Parser.Lex(); // Eat the ')' token.
2353 return true; // Parenthesis must follow the relocation operand.
2355 Res = evaluateRelocExpr(IdVal, Str);
2359 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2361 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2362 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2363 if (ResTy == MatchOperand_Success) {
2364 assert(Operands.size() == 1);
2365 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2366 StartLoc = Operand.getStartLoc();
2367 EndLoc = Operand.getEndLoc();
2369 // AFAIK, we only support numeric registers and named GPR's in CFI
2371 // Don't worry about eating tokens before failing. Using an unrecognised
2372 // register is a parse error.
2373 if (Operand.isGPRAsmReg()) {
2374 // Resolve to GPR32 or GPR64 appropriately.
2375 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2378 return (RegNo == (unsigned)-1);
2381 assert(Operands.size() == 0);
2382 return (RegNo == (unsigned)-1);
2385 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2386 MCAsmParser &Parser = getParser();
2390 while (getLexer().getKind() == AsmToken::LParen)
2393 switch (getLexer().getKind()) {
2396 case AsmToken::Identifier:
2397 case AsmToken::LParen:
2398 case AsmToken::Integer:
2399 case AsmToken::Minus:
2400 case AsmToken::Plus:
2402 Result = getParser().parseParenExpression(Res, S);
2404 Result = (getParser().parseExpression(Res));
2405 while (getLexer().getKind() == AsmToken::RParen)
2408 case AsmToken::Percent:
2409 Result = parseRelocOperand(Res);
2414 MipsAsmParser::OperandMatchResultTy
2415 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2416 MCAsmParser &Parser = getParser();
2417 DEBUG(dbgs() << "parseMemOperand\n");
2418 const MCExpr *IdVal = nullptr;
2420 bool isParenExpr = false;
2421 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2422 // First operand is the offset.
2423 S = Parser.getTok().getLoc();
2425 if (getLexer().getKind() == AsmToken::LParen) {
2430 if (getLexer().getKind() != AsmToken::Dollar) {
2431 if (parseMemOffset(IdVal, isParenExpr))
2432 return MatchOperand_ParseFail;
2434 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2435 if (Tok.isNot(AsmToken::LParen)) {
2436 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2437 if (Mnemonic.getToken() == "la") {
2439 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2440 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2441 return MatchOperand_Success;
2443 if (Tok.is(AsmToken::EndOfStatement)) {
2445 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2447 // Zero register assumed, add a memory operand with ZERO as its base.
2448 // "Base" will be managed by k_Memory.
2449 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2452 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2453 return MatchOperand_Success;
2455 Error(Parser.getTok().getLoc(), "'(' expected");
2456 return MatchOperand_ParseFail;
2459 Parser.Lex(); // Eat the '(' token.
2462 Res = parseAnyRegister(Operands);
2463 if (Res != MatchOperand_Success)
2466 if (Parser.getTok().isNot(AsmToken::RParen)) {
2467 Error(Parser.getTok().getLoc(), "')' expected");
2468 return MatchOperand_ParseFail;
2471 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2473 Parser.Lex(); // Eat the ')' token.
2476 IdVal = MCConstantExpr::Create(0, getContext());
2478 // Replace the register operand with the memory operand.
2479 std::unique_ptr<MipsOperand> op(
2480 static_cast<MipsOperand *>(Operands.back().release()));
2481 // Remove the register from the operands.
2482 // "op" will be managed by k_Memory.
2483 Operands.pop_back();
2484 // Add the memory operand.
2485 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2487 if (IdVal->EvaluateAsAbsolute(Imm))
2488 IdVal = MCConstantExpr::Create(Imm, getContext());
2489 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2490 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2494 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2495 return MatchOperand_Success;
2498 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2499 MCAsmParser &Parser = getParser();
2500 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2502 SMLoc S = Parser.getTok().getLoc();
2504 if (Sym->isVariable())
2505 Expr = Sym->getVariableValue();
2508 if (Expr->getKind() == MCExpr::SymbolRef) {
2509 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2510 StringRef DefSymbol = Ref->getSymbol().getName();
2511 if (DefSymbol.startswith("$")) {
2512 OperandMatchResultTy ResTy =
2513 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2514 if (ResTy == MatchOperand_Success) {
2517 } else if (ResTy == MatchOperand_ParseFail)
2518 llvm_unreachable("Should never ParseFail");
2521 } else if (Expr->getKind() == MCExpr::Constant) {
2523 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2525 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2532 MipsAsmParser::OperandMatchResultTy
2533 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2534 StringRef Identifier,
2536 int Index = matchCPURegisterName(Identifier);
2538 Operands.push_back(MipsOperand::createGPRReg(
2539 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2540 return MatchOperand_Success;
2543 Index = matchHWRegsRegisterName(Identifier);
2545 Operands.push_back(MipsOperand::createHWRegsReg(
2546 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2547 return MatchOperand_Success;
2550 Index = matchFPURegisterName(Identifier);
2552 Operands.push_back(MipsOperand::createFGRReg(
2553 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2554 return MatchOperand_Success;
2557 Index = matchFCCRegisterName(Identifier);
2559 Operands.push_back(MipsOperand::createFCCReg(
2560 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2561 return MatchOperand_Success;
2564 Index = matchACRegisterName(Identifier);
2566 Operands.push_back(MipsOperand::createACCReg(
2567 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2568 return MatchOperand_Success;
2571 Index = matchMSA128RegisterName(Identifier);
2573 Operands.push_back(MipsOperand::createMSA128Reg(
2574 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2575 return MatchOperand_Success;
2578 Index = matchMSA128CtrlRegisterName(Identifier);
2580 Operands.push_back(MipsOperand::createMSACtrlReg(
2581 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2582 return MatchOperand_Success;
2585 return MatchOperand_NoMatch;
2588 MipsAsmParser::OperandMatchResultTy
2589 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2590 MCAsmParser &Parser = getParser();
2591 auto Token = Parser.getLexer().peekTok(false);
2593 if (Token.is(AsmToken::Identifier)) {
2594 DEBUG(dbgs() << ".. identifier\n");
2595 StringRef Identifier = Token.getIdentifier();
2596 OperandMatchResultTy ResTy =
2597 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2599 } else if (Token.is(AsmToken::Integer)) {
2600 DEBUG(dbgs() << ".. integer\n");
2601 Operands.push_back(MipsOperand::createNumericReg(
2602 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2604 return MatchOperand_Success;
2607 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2609 return MatchOperand_NoMatch;
2612 MipsAsmParser::OperandMatchResultTy
2613 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2614 MCAsmParser &Parser = getParser();
2615 DEBUG(dbgs() << "parseAnyRegister\n");
2617 auto Token = Parser.getTok();
2619 SMLoc S = Token.getLoc();
2621 if (Token.isNot(AsmToken::Dollar)) {
2622 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2623 if (Token.is(AsmToken::Identifier)) {
2624 if (searchSymbolAlias(Operands))
2625 return MatchOperand_Success;
2627 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2628 return MatchOperand_NoMatch;
2630 DEBUG(dbgs() << ".. $\n");
2632 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2633 if (ResTy == MatchOperand_Success) {
2635 Parser.Lex(); // identifier
2640 MipsAsmParser::OperandMatchResultTy
2641 MipsAsmParser::parseImm(OperandVector &Operands) {
2642 MCAsmParser &Parser = getParser();
2643 switch (getLexer().getKind()) {
2645 return MatchOperand_NoMatch;
2646 case AsmToken::LParen:
2647 case AsmToken::Minus:
2648 case AsmToken::Plus:
2649 case AsmToken::Integer:
2650 case AsmToken::Tilde:
2651 case AsmToken::String:
2655 const MCExpr *IdVal;
2656 SMLoc S = Parser.getTok().getLoc();
2657 if (getParser().parseExpression(IdVal))
2658 return MatchOperand_ParseFail;
2660 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2661 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2662 return MatchOperand_Success;
2665 MipsAsmParser::OperandMatchResultTy
2666 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2667 MCAsmParser &Parser = getParser();
2668 DEBUG(dbgs() << "parseJumpTarget\n");
2670 SMLoc S = getLexer().getLoc();
2672 // Integers and expressions are acceptable
2673 OperandMatchResultTy ResTy = parseImm(Operands);
2674 if (ResTy != MatchOperand_NoMatch)
2677 // Registers are a valid target and have priority over symbols.
2678 ResTy = parseAnyRegister(Operands);
2679 if (ResTy != MatchOperand_NoMatch)
2682 const MCExpr *Expr = nullptr;
2683 if (Parser.parseExpression(Expr)) {
2684 // We have no way of knowing if a symbol was consumed so we must ParseFail
2685 return MatchOperand_ParseFail;
2688 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2689 return MatchOperand_Success;
2692 MipsAsmParser::OperandMatchResultTy
2693 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2694 MCAsmParser &Parser = getParser();
2695 const MCExpr *IdVal;
2696 // If the first token is '$' we may have register operand.
2697 if (Parser.getTok().is(AsmToken::Dollar))
2698 return MatchOperand_NoMatch;
2699 SMLoc S = Parser.getTok().getLoc();
2700 if (getParser().parseExpression(IdVal))
2701 return MatchOperand_ParseFail;
2702 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2703 assert(MCE && "Unexpected MCExpr type.");
2704 int64_t Val = MCE->getValue();
2705 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2706 Operands.push_back(MipsOperand::CreateImm(
2707 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2708 return MatchOperand_Success;
2711 MipsAsmParser::OperandMatchResultTy
2712 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2713 MCAsmParser &Parser = getParser();
2714 switch (getLexer().getKind()) {
2716 return MatchOperand_NoMatch;
2717 case AsmToken::LParen:
2718 case AsmToken::Plus:
2719 case AsmToken::Minus:
2720 case AsmToken::Integer:
2725 SMLoc S = Parser.getTok().getLoc();
2727 if (getParser().parseExpression(Expr))
2728 return MatchOperand_ParseFail;
2731 if (!Expr->EvaluateAsAbsolute(Val)) {
2732 Error(S, "expected immediate value");
2733 return MatchOperand_ParseFail;
2736 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2737 // and because the CPU always adds one to the immediate field, the allowed
2738 // range becomes 1..4. We'll only check the range here and will deal
2739 // with the addition/subtraction when actually decoding/encoding
2741 if (Val < 1 || Val > 4) {
2742 Error(S, "immediate not in range (1..4)");
2743 return MatchOperand_ParseFail;
2747 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2748 return MatchOperand_Success;
2751 MipsAsmParser::OperandMatchResultTy
2752 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2753 MCAsmParser &Parser = getParser();
2754 SmallVector<unsigned, 10> Regs;
2756 unsigned PrevReg = Mips::NoRegister;
2757 bool RegRange = false;
2758 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2760 if (Parser.getTok().isNot(AsmToken::Dollar))
2761 return MatchOperand_ParseFail;
2763 SMLoc S = Parser.getTok().getLoc();
2764 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2765 SMLoc E = getLexer().getLoc();
2766 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2767 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2769 // Remove last register operand because registers from register range
2770 // should be inserted first.
2771 if (RegNo == Mips::RA) {
2772 Regs.push_back(RegNo);
2774 unsigned TmpReg = PrevReg + 1;
2775 while (TmpReg <= RegNo) {
2776 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2777 Error(E, "invalid register operand");
2778 return MatchOperand_ParseFail;
2782 Regs.push_back(TmpReg++);
2788 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2789 (RegNo != Mips::RA)) {
2790 Error(E, "$16 or $31 expected");
2791 return MatchOperand_ParseFail;
2792 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2793 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2794 Error(E, "invalid register operand");
2795 return MatchOperand_ParseFail;
2796 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2797 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2798 Error(E, "consecutive register numbers expected");
2799 return MatchOperand_ParseFail;
2802 Regs.push_back(RegNo);
2805 if (Parser.getTok().is(AsmToken::Minus))
2808 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2809 !Parser.getTok().isNot(AsmToken::Comma)) {
2810 Error(E, "',' or '-' expected");
2811 return MatchOperand_ParseFail;
2814 Lex(); // Consume comma or minus
2815 if (Parser.getTok().isNot(AsmToken::Dollar))
2821 SMLoc E = Parser.getTok().getLoc();
2822 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2823 parseMemOperand(Operands);
2824 return MatchOperand_Success;
2827 MipsAsmParser::OperandMatchResultTy
2828 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2829 MCAsmParser &Parser = getParser();
2831 SMLoc S = Parser.getTok().getLoc();
2832 if (parseAnyRegister(Operands) != MatchOperand_Success)
2833 return MatchOperand_ParseFail;
2835 SMLoc E = Parser.getTok().getLoc();
2836 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2837 unsigned Reg = Op.getGPR32Reg();
2838 Operands.pop_back();
2839 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2840 return MatchOperand_Success;
2843 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2845 MCSymbolRefExpr::VariantKind VK =
2846 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2847 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2848 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2849 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2850 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2851 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2852 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2853 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2854 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2855 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2856 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2857 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2858 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2859 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2860 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2861 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2862 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2863 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2864 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2865 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2866 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2867 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2868 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2869 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2870 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2871 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2872 .Default(MCSymbolRefExpr::VK_None);
2874 assert(VK != MCSymbolRefExpr::VK_None);
2879 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2881 /// ::= '(', register, ')'
2882 /// handle it before we iterate so we don't get tripped up by the lack of
2884 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2885 MCAsmParser &Parser = getParser();
2886 if (getLexer().is(AsmToken::LParen)) {
2888 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2890 if (parseOperand(Operands, Name)) {
2891 SMLoc Loc = getLexer().getLoc();
2892 Parser.eatToEndOfStatement();
2893 return Error(Loc, "unexpected token in argument list");
2895 if (Parser.getTok().isNot(AsmToken::RParen)) {
2896 SMLoc Loc = getLexer().getLoc();
2897 Parser.eatToEndOfStatement();
2898 return Error(Loc, "unexpected token, expected ')'");
2901 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2907 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2908 /// either one of these.
2909 /// ::= '[', register, ']'
2910 /// ::= '[', integer, ']'
2911 /// handle it before we iterate so we don't get tripped up by the lack of
2913 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2914 OperandVector &Operands) {
2915 MCAsmParser &Parser = getParser();
2916 if (getLexer().is(AsmToken::LBrac)) {
2918 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2920 if (parseOperand(Operands, Name)) {
2921 SMLoc Loc = getLexer().getLoc();
2922 Parser.eatToEndOfStatement();
2923 return Error(Loc, "unexpected token in argument list");
2925 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2926 SMLoc Loc = getLexer().getLoc();
2927 Parser.eatToEndOfStatement();
2928 return Error(Loc, "unexpected token, expected ']'");
2931 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2937 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2938 SMLoc NameLoc, OperandVector &Operands) {
2939 MCAsmParser &Parser = getParser();
2940 DEBUG(dbgs() << "ParseInstruction\n");
2942 // We have reached first instruction, module directive are now forbidden.
2943 getTargetStreamer().forbidModuleDirective();
2945 // Check if we have valid mnemonic
2946 if (!mnemonicIsValid(Name, 0)) {
2947 Parser.eatToEndOfStatement();
2948 return Error(NameLoc, "unknown instruction");
2950 // First operand in MCInst is instruction mnemonic.
2951 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2953 // Read the remaining operands.
2954 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2955 // Read the first operand.
2956 if (parseOperand(Operands, Name)) {
2957 SMLoc Loc = getLexer().getLoc();
2958 Parser.eatToEndOfStatement();
2959 return Error(Loc, "unexpected token in argument list");
2961 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2963 // AFAIK, parenthesis suffixes are never on the first operand
2965 while (getLexer().is(AsmToken::Comma)) {
2966 Parser.Lex(); // Eat the comma.
2967 // Parse and remember the operand.
2968 if (parseOperand(Operands, Name)) {
2969 SMLoc Loc = getLexer().getLoc();
2970 Parser.eatToEndOfStatement();
2971 return Error(Loc, "unexpected token in argument list");
2973 // Parse bracket and parenthesis suffixes before we iterate
2974 if (getLexer().is(AsmToken::LBrac)) {
2975 if (parseBracketSuffix(Name, Operands))
2977 } else if (getLexer().is(AsmToken::LParen) &&
2978 parseParenSuffix(Name, Operands))
2982 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2983 SMLoc Loc = getLexer().getLoc();
2984 Parser.eatToEndOfStatement();
2985 return Error(Loc, "unexpected token in argument list");
2987 Parser.Lex(); // Consume the EndOfStatement.
2991 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2992 MCAsmParser &Parser = getParser();
2993 SMLoc Loc = getLexer().getLoc();
2994 Parser.eatToEndOfStatement();
2995 return Error(Loc, ErrorMsg);
2998 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2999 return Error(Loc, ErrorMsg);
3002 bool MipsAsmParser::parseSetNoAtDirective() {
3003 MCAsmParser &Parser = getParser();
3004 // Line should look like: ".set noat".
3006 AssemblerOptions.back()->setATReg(0);
3009 // If this is not the end of the statement, report an error.
3010 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3011 reportParseError("unexpected token, expected end of statement");
3014 Parser.Lex(); // Consume the EndOfStatement.
3018 bool MipsAsmParser::parseSetAtDirective() {
3019 MCAsmParser &Parser = getParser();
3020 // Line can be .set at - defaults to $1
3024 if (getLexer().is(AsmToken::EndOfStatement)) {
3025 AssemblerOptions.back()->setATReg(1);
3026 Parser.Lex(); // Consume the EndOfStatement.
3028 } else if (getLexer().is(AsmToken::Equal)) {
3029 getParser().Lex(); // Eat the '='.
3030 if (getLexer().isNot(AsmToken::Dollar)) {
3031 reportParseError("unexpected token, expected dollar sign '$'");
3034 Parser.Lex(); // Eat the '$'.
3035 const AsmToken &Reg = Parser.getTok();
3036 if (Reg.is(AsmToken::Identifier)) {
3037 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3038 } else if (Reg.is(AsmToken::Integer)) {
3039 AtRegNo = Reg.getIntVal();
3041 reportParseError("unexpected token, expected identifier or integer");
3045 if (AtRegNo < 0 || AtRegNo > 31) {
3046 reportParseError("unexpected token in statement");
3050 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3051 reportParseError("invalid register");
3054 getParser().Lex(); // Eat the register.
3056 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3057 reportParseError("unexpected token, expected end of statement");
3060 Parser.Lex(); // Consume the EndOfStatement.
3063 reportParseError("unexpected token in statement");
3068 bool MipsAsmParser::parseSetReorderDirective() {
3069 MCAsmParser &Parser = getParser();
3071 // If this is not the end of the statement, report an error.
3072 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3073 reportParseError("unexpected token, expected end of statement");
3076 AssemblerOptions.back()->setReorder();
3077 getTargetStreamer().emitDirectiveSetReorder();
3078 Parser.Lex(); // Consume the EndOfStatement.
3082 bool MipsAsmParser::parseSetNoReorderDirective() {
3083 MCAsmParser &Parser = getParser();
3085 // If this is not the end of the statement, report an error.
3086 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3087 reportParseError("unexpected token, expected end of statement");
3090 AssemblerOptions.back()->setNoReorder();
3091 getTargetStreamer().emitDirectiveSetNoReorder();
3092 Parser.Lex(); // Consume the EndOfStatement.
3096 bool MipsAsmParser::parseSetMacroDirective() {
3097 MCAsmParser &Parser = getParser();
3099 // If this is not the end of the statement, report an error.
3100 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3101 reportParseError("unexpected token, expected end of statement");
3104 AssemblerOptions.back()->setMacro();
3105 Parser.Lex(); // Consume the EndOfStatement.
3109 bool MipsAsmParser::parseSetNoMacroDirective() {
3110 MCAsmParser &Parser = getParser();
3112 // If this is not the end of the statement, report an error.
3113 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3114 reportParseError("unexpected token, expected end of statement");
3117 if (AssemblerOptions.back()->isReorder()) {
3118 reportParseError("`noreorder' must be set before `nomacro'");
3121 AssemblerOptions.back()->setNoMacro();
3122 Parser.Lex(); // Consume the EndOfStatement.
3126 bool MipsAsmParser::parseSetMsaDirective() {
3127 MCAsmParser &Parser = getParser();
3130 // If this is not the end of the statement, report an error.
3131 if (getLexer().isNot(AsmToken::EndOfStatement))
3132 return reportParseError("unexpected token, expected end of statement");
3134 setFeatureBits(Mips::FeatureMSA, "msa");
3135 getTargetStreamer().emitDirectiveSetMsa();
3139 bool MipsAsmParser::parseSetNoMsaDirective() {
3140 MCAsmParser &Parser = getParser();
3143 // If this is not the end of the statement, report an error.
3144 if (getLexer().isNot(AsmToken::EndOfStatement))
3145 return reportParseError("unexpected token, expected end of statement");
3147 clearFeatureBits(Mips::FeatureMSA, "msa");
3148 getTargetStreamer().emitDirectiveSetNoMsa();
3152 bool MipsAsmParser::parseSetNoDspDirective() {
3153 MCAsmParser &Parser = getParser();
3154 Parser.Lex(); // Eat "nodsp".
3156 // If this is not the end of the statement, report an error.
3157 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3158 reportParseError("unexpected token, expected end of statement");
3162 clearFeatureBits(Mips::FeatureDSP, "dsp");
3163 getTargetStreamer().emitDirectiveSetNoDsp();
3167 bool MipsAsmParser::parseSetMips16Directive() {
3168 MCAsmParser &Parser = getParser();
3169 Parser.Lex(); // Eat "mips16".
3171 // If this is not the end of the statement, report an error.
3172 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3173 reportParseError("unexpected token, expected end of statement");
3177 setFeatureBits(Mips::FeatureMips16, "mips16");
3178 getTargetStreamer().emitDirectiveSetMips16();
3179 Parser.Lex(); // Consume the EndOfStatement.
3183 bool MipsAsmParser::parseSetNoMips16Directive() {
3184 MCAsmParser &Parser = getParser();
3185 Parser.Lex(); // Eat "nomips16".
3187 // If this is not the end of the statement, report an error.
3188 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3189 reportParseError("unexpected token, expected end of statement");
3193 clearFeatureBits(Mips::FeatureMips16, "mips16");
3194 getTargetStreamer().emitDirectiveSetNoMips16();
3195 Parser.Lex(); // Consume the EndOfStatement.
3199 bool MipsAsmParser::parseSetFpDirective() {
3200 MCAsmParser &Parser = getParser();
3201 MipsABIFlagsSection::FpABIKind FpAbiVal;
3202 // Line can be: .set fp=32
3205 Parser.Lex(); // Eat fp token
3206 AsmToken Tok = Parser.getTok();
3207 if (Tok.isNot(AsmToken::Equal)) {
3208 reportParseError("unexpected token, expected equals sign '='");
3211 Parser.Lex(); // Eat '=' token.
3212 Tok = Parser.getTok();
3214 if (!parseFpABIValue(FpAbiVal, ".set"))
3217 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3218 reportParseError("unexpected token, expected end of statement");
3221 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3222 Parser.Lex(); // Consume the EndOfStatement.
3226 bool MipsAsmParser::parseSetPopDirective() {
3227 MCAsmParser &Parser = getParser();
3228 SMLoc Loc = getLexer().getLoc();
3231 if (getLexer().isNot(AsmToken::EndOfStatement))
3232 return reportParseError("unexpected token, expected end of statement");
3234 // Always keep an element on the options "stack" to prevent the user
3235 // from changing the initial options. This is how we remember them.
3236 if (AssemblerOptions.size() == 2)
3237 return reportParseError(Loc, ".set pop with no .set push");
3239 AssemblerOptions.pop_back();
3240 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3242 getTargetStreamer().emitDirectiveSetPop();
3246 bool MipsAsmParser::parseSetPushDirective() {
3247 MCAsmParser &Parser = getParser();
3249 if (getLexer().isNot(AsmToken::EndOfStatement))
3250 return reportParseError("unexpected token, expected end of statement");
3252 // Create a copy of the current assembler options environment and push it.
3253 AssemblerOptions.push_back(
3254 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3256 getTargetStreamer().emitDirectiveSetPush();
3260 bool MipsAsmParser::parseSetAssignment() {
3262 const MCExpr *Value;
3263 MCAsmParser &Parser = getParser();
3265 if (Parser.parseIdentifier(Name))
3266 reportParseError("expected identifier after .set");
3268 if (getLexer().isNot(AsmToken::Comma))
3269 return reportParseError("unexpected token, expected comma");
3272 if (Parser.parseExpression(Value))
3273 return reportParseError("expected valid expression after comma");
3275 // Check if the Name already exists as a symbol.
3276 MCSymbol *Sym = getContext().LookupSymbol(Name);
3278 return reportParseError("symbol already defined");
3279 Sym = getContext().GetOrCreateSymbol(Name);
3280 Sym->setVariableValue(Value);
3285 bool MipsAsmParser::parseSetMips0Directive() {
3286 MCAsmParser &Parser = getParser();
3288 if (getLexer().isNot(AsmToken::EndOfStatement))
3289 return reportParseError("unexpected token, expected end of statement");
3291 // Reset assembler options to their initial values.
3292 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3293 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3295 getTargetStreamer().emitDirectiveSetMips0();
3299 bool MipsAsmParser::parseSetArchDirective() {
3300 MCAsmParser &Parser = getParser();
3302 if (getLexer().isNot(AsmToken::Equal))
3303 return reportParseError("unexpected token, expected equals sign");
3307 if (Parser.parseIdentifier(Arch))
3308 return reportParseError("expected arch identifier");
3310 StringRef ArchFeatureName =
3311 StringSwitch<StringRef>(Arch)
3312 .Case("mips1", "mips1")
3313 .Case("mips2", "mips2")
3314 .Case("mips3", "mips3")
3315 .Case("mips4", "mips4")
3316 .Case("mips5", "mips5")
3317 .Case("mips32", "mips32")
3318 .Case("mips32r2", "mips32r2")
3319 .Case("mips32r6", "mips32r6")
3320 .Case("mips64", "mips64")
3321 .Case("mips64r2", "mips64r2")
3322 .Case("mips64r6", "mips64r6")
3323 .Case("cnmips", "cnmips")
3324 .Case("r4000", "mips3") // This is an implementation of Mips3.
3327 if (ArchFeatureName.empty())
3328 return reportParseError("unsupported architecture");
3330 selectArch(ArchFeatureName);
3331 getTargetStreamer().emitDirectiveSetArch(Arch);
3335 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3336 MCAsmParser &Parser = getParser();
3338 if (getLexer().isNot(AsmToken::EndOfStatement))
3339 return reportParseError("unexpected token, expected end of statement");
3343 llvm_unreachable("Unimplemented feature");
3344 case Mips::FeatureDSP:
3345 setFeatureBits(Mips::FeatureDSP, "dsp");
3346 getTargetStreamer().emitDirectiveSetDsp();
3348 case Mips::FeatureMicroMips:
3349 getTargetStreamer().emitDirectiveSetMicroMips();
3351 case Mips::FeatureMips1:
3352 selectArch("mips1");
3353 getTargetStreamer().emitDirectiveSetMips1();
3355 case Mips::FeatureMips2:
3356 selectArch("mips2");
3357 getTargetStreamer().emitDirectiveSetMips2();
3359 case Mips::FeatureMips3:
3360 selectArch("mips3");
3361 getTargetStreamer().emitDirectiveSetMips3();
3363 case Mips::FeatureMips4:
3364 selectArch("mips4");
3365 getTargetStreamer().emitDirectiveSetMips4();
3367 case Mips::FeatureMips5:
3368 selectArch("mips5");
3369 getTargetStreamer().emitDirectiveSetMips5();
3371 case Mips::FeatureMips32:
3372 selectArch("mips32");
3373 getTargetStreamer().emitDirectiveSetMips32();
3375 case Mips::FeatureMips32r2:
3376 selectArch("mips32r2");
3377 getTargetStreamer().emitDirectiveSetMips32R2();
3379 case Mips::FeatureMips32r6:
3380 selectArch("mips32r6");
3381 getTargetStreamer().emitDirectiveSetMips32R6();
3383 case Mips::FeatureMips64:
3384 selectArch("mips64");
3385 getTargetStreamer().emitDirectiveSetMips64();
3387 case Mips::FeatureMips64r2:
3388 selectArch("mips64r2");
3389 getTargetStreamer().emitDirectiveSetMips64R2();
3391 case Mips::FeatureMips64r6:
3392 selectArch("mips64r6");
3393 getTargetStreamer().emitDirectiveSetMips64R6();
3399 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3400 MCAsmParser &Parser = getParser();
3401 if (getLexer().isNot(AsmToken::Comma)) {
3402 SMLoc Loc = getLexer().getLoc();
3403 Parser.eatToEndOfStatement();
3404 return Error(Loc, ErrorStr);
3407 Parser.Lex(); // Eat the comma.
3411 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3412 if (AssemblerOptions.back()->isReorder())
3413 Warning(Loc, ".cpload should be inside a noreorder section");
3415 if (inMips16Mode()) {
3416 reportParseError(".cpload is not supported in Mips16 mode");
3420 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3421 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3422 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3423 reportParseError("expected register containing function address");
3427 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3428 if (!RegOpnd.isGPRAsmReg()) {
3429 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3433 // If this is not the end of the statement, report an error.
3434 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3435 reportParseError("unexpected token, expected end of statement");
3439 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3443 bool MipsAsmParser::parseDirectiveCPSetup() {
3444 MCAsmParser &Parser = getParser();
3447 bool SaveIsReg = true;
3449 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3450 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3451 if (ResTy == MatchOperand_NoMatch) {
3452 reportParseError("expected register containing function address");
3453 Parser.eatToEndOfStatement();
3457 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3458 if (!FuncRegOpnd.isGPRAsmReg()) {
3459 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3460 Parser.eatToEndOfStatement();
3464 FuncReg = FuncRegOpnd.getGPR32Reg();
3467 if (!eatComma("unexpected token, expected comma"))
3470 ResTy = parseAnyRegister(TmpReg);
3471 if (ResTy == MatchOperand_NoMatch) {
3472 const AsmToken &Tok = Parser.getTok();
3473 if (Tok.is(AsmToken::Integer)) {
3474 Save = Tok.getIntVal();
3478 reportParseError("expected save register or stack offset");
3479 Parser.eatToEndOfStatement();
3483 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3484 if (!SaveOpnd.isGPRAsmReg()) {
3485 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3486 Parser.eatToEndOfStatement();
3489 Save = SaveOpnd.getGPR32Reg();
3492 if (!eatComma("unexpected token, expected comma"))
3496 if (Parser.parseIdentifier(Name))
3497 reportParseError("expected identifier");
3498 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3500 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3504 bool MipsAsmParser::parseDirectiveNaN() {
3505 MCAsmParser &Parser = getParser();
3506 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3507 const AsmToken &Tok = Parser.getTok();
3509 if (Tok.getString() == "2008") {
3511 getTargetStreamer().emitDirectiveNaN2008();
3513 } else if (Tok.getString() == "legacy") {
3515 getTargetStreamer().emitDirectiveNaNLegacy();
3519 // If we don't recognize the option passed to the .nan
3520 // directive (e.g. no option or unknown option), emit an error.
3521 reportParseError("invalid option in .nan directive");
3525 bool MipsAsmParser::parseDirectiveSet() {
3526 MCAsmParser &Parser = getParser();
3527 // Get the next token.
3528 const AsmToken &Tok = Parser.getTok();
3530 if (Tok.getString() == "noat") {
3531 return parseSetNoAtDirective();
3532 } else if (Tok.getString() == "at") {
3533 return parseSetAtDirective();
3534 } else if (Tok.getString() == "arch") {
3535 return parseSetArchDirective();
3536 } else if (Tok.getString() == "fp") {
3537 return parseSetFpDirective();
3538 } else if (Tok.getString() == "pop") {
3539 return parseSetPopDirective();
3540 } else if (Tok.getString() == "push") {
3541 return parseSetPushDirective();
3542 } else if (Tok.getString() == "reorder") {
3543 return parseSetReorderDirective();
3544 } else if (Tok.getString() == "noreorder") {
3545 return parseSetNoReorderDirective();
3546 } else if (Tok.getString() == "macro") {
3547 return parseSetMacroDirective();
3548 } else if (Tok.getString() == "nomacro") {
3549 return parseSetNoMacroDirective();
3550 } else if (Tok.getString() == "mips16") {
3551 return parseSetMips16Directive();
3552 } else if (Tok.getString() == "nomips16") {
3553 return parseSetNoMips16Directive();
3554 } else if (Tok.getString() == "nomicromips") {
3555 getTargetStreamer().emitDirectiveSetNoMicroMips();
3556 Parser.eatToEndOfStatement();
3558 } else if (Tok.getString() == "micromips") {
3559 return parseSetFeature(Mips::FeatureMicroMips);
3560 } else if (Tok.getString() == "mips0") {
3561 return parseSetMips0Directive();
3562 } else if (Tok.getString() == "mips1") {
3563 return parseSetFeature(Mips::FeatureMips1);
3564 } else if (Tok.getString() == "mips2") {
3565 return parseSetFeature(Mips::FeatureMips2);
3566 } else if (Tok.getString() == "mips3") {
3567 return parseSetFeature(Mips::FeatureMips3);
3568 } else if (Tok.getString() == "mips4") {
3569 return parseSetFeature(Mips::FeatureMips4);
3570 } else if (Tok.getString() == "mips5") {
3571 return parseSetFeature(Mips::FeatureMips5);
3572 } else if (Tok.getString() == "mips32") {
3573 return parseSetFeature(Mips::FeatureMips32);
3574 } else if (Tok.getString() == "mips32r2") {
3575 return parseSetFeature(Mips::FeatureMips32r2);
3576 } else if (Tok.getString() == "mips32r6") {
3577 return parseSetFeature(Mips::FeatureMips32r6);
3578 } else if (Tok.getString() == "mips64") {
3579 return parseSetFeature(Mips::FeatureMips64);
3580 } else if (Tok.getString() == "mips64r2") {
3581 return parseSetFeature(Mips::FeatureMips64r2);
3582 } else if (Tok.getString() == "mips64r6") {
3583 return parseSetFeature(Mips::FeatureMips64r6);
3584 } else if (Tok.getString() == "dsp") {
3585 return parseSetFeature(Mips::FeatureDSP);
3586 } else if (Tok.getString() == "nodsp") {
3587 return parseSetNoDspDirective();
3588 } else if (Tok.getString() == "msa") {
3589 return parseSetMsaDirective();
3590 } else if (Tok.getString() == "nomsa") {
3591 return parseSetNoMsaDirective();
3593 // It is just an identifier, look for an assignment.
3594 parseSetAssignment();
3601 /// parseDataDirective
3602 /// ::= .word [ expression (, expression)* ]
3603 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3604 MCAsmParser &Parser = getParser();
3605 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3607 const MCExpr *Value;
3608 if (getParser().parseExpression(Value))
3611 getParser().getStreamer().EmitValue(Value, Size);
3613 if (getLexer().is(AsmToken::EndOfStatement))
3616 if (getLexer().isNot(AsmToken::Comma))
3617 return Error(L, "unexpected token, expected comma");
3626 /// parseDirectiveGpWord
3627 /// ::= .gpword local_sym
3628 bool MipsAsmParser::parseDirectiveGpWord() {
3629 MCAsmParser &Parser = getParser();
3630 const MCExpr *Value;
3631 // EmitGPRel32Value requires an expression, so we are using base class
3632 // method to evaluate the expression.
3633 if (getParser().parseExpression(Value))
3635 getParser().getStreamer().EmitGPRel32Value(Value);
3637 if (getLexer().isNot(AsmToken::EndOfStatement))
3638 return Error(getLexer().getLoc(),
3639 "unexpected token, expected end of statement");
3640 Parser.Lex(); // Eat EndOfStatement token.
3644 /// parseDirectiveGpDWord
3645 /// ::= .gpdword local_sym
3646 bool MipsAsmParser::parseDirectiveGpDWord() {
3647 MCAsmParser &Parser = getParser();
3648 const MCExpr *Value;
3649 // EmitGPRel64Value requires an expression, so we are using base class
3650 // method to evaluate the expression.
3651 if (getParser().parseExpression(Value))
3653 getParser().getStreamer().EmitGPRel64Value(Value);
3655 if (getLexer().isNot(AsmToken::EndOfStatement))
3656 return Error(getLexer().getLoc(),
3657 "unexpected token, expected end of statement");
3658 Parser.Lex(); // Eat EndOfStatement token.
3662 bool MipsAsmParser::parseDirectiveOption() {
3663 MCAsmParser &Parser = getParser();
3664 // Get the option token.
3665 AsmToken Tok = Parser.getTok();
3666 // At the moment only identifiers are supported.
3667 if (Tok.isNot(AsmToken::Identifier)) {
3668 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3669 Parser.eatToEndOfStatement();
3673 StringRef Option = Tok.getIdentifier();
3675 if (Option == "pic0") {
3676 getTargetStreamer().emitDirectiveOptionPic0();
3678 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3679 Error(Parser.getTok().getLoc(),
3680 "unexpected token, expected end of statement");
3681 Parser.eatToEndOfStatement();
3686 if (Option == "pic2") {
3687 getTargetStreamer().emitDirectiveOptionPic2();
3689 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3690 Error(Parser.getTok().getLoc(),
3691 "unexpected token, expected end of statement");
3692 Parser.eatToEndOfStatement();
3698 Warning(Parser.getTok().getLoc(),
3699 "unknown option, expected 'pic0' or 'pic2'");
3700 Parser.eatToEndOfStatement();
3704 /// parseDirectiveModule
3705 /// ::= .module oddspreg
3706 /// ::= .module nooddspreg
3707 /// ::= .module fp=value
3708 bool MipsAsmParser::parseDirectiveModule() {
3709 MCAsmParser &Parser = getParser();
3710 MCAsmLexer &Lexer = getLexer();
3711 SMLoc L = Lexer.getLoc();
3713 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3714 // TODO : get a better message.
3715 reportParseError(".module directive must appear before any code");
3719 if (Lexer.is(AsmToken::Identifier)) {
3720 StringRef Option = Parser.getTok().getString();
3723 if (Option == "oddspreg") {
3724 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3725 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3727 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3728 reportParseError("unexpected token, expected end of statement");
3733 } else if (Option == "nooddspreg") {
3735 Error(L, "'.module nooddspreg' requires the O32 ABI");
3739 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3740 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3742 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3743 reportParseError("unexpected token, expected end of statement");
3748 } else if (Option == "fp") {
3749 return parseDirectiveModuleFP();
3752 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3758 /// parseDirectiveModuleFP
3762 bool MipsAsmParser::parseDirectiveModuleFP() {
3763 MCAsmParser &Parser = getParser();
3764 MCAsmLexer &Lexer = getLexer();
3766 if (Lexer.isNot(AsmToken::Equal)) {
3767 reportParseError("unexpected token, expected equals sign '='");
3770 Parser.Lex(); // Eat '=' token.
3772 MipsABIFlagsSection::FpABIKind FpABI;
3773 if (!parseFpABIValue(FpABI, ".module"))
3776 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3777 reportParseError("unexpected token, expected end of statement");
3781 // Emit appropriate flags.
3782 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3783 Parser.Lex(); // Consume the EndOfStatement.
3787 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3788 StringRef Directive) {
3789 MCAsmParser &Parser = getParser();
3790 MCAsmLexer &Lexer = getLexer();
3792 if (Lexer.is(AsmToken::Identifier)) {
3793 StringRef Value = Parser.getTok().getString();
3796 if (Value != "xx") {
3797 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3802 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3806 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3810 if (Lexer.is(AsmToken::Integer)) {
3811 unsigned Value = Parser.getTok().getIntVal();
3814 if (Value != 32 && Value != 64) {
3815 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3821 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3825 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3827 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3835 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3836 MCAsmParser &Parser = getParser();
3837 StringRef IDVal = DirectiveID.getString();
3839 if (IDVal == ".cpload")
3840 return parseDirectiveCpLoad(DirectiveID.getLoc());
3841 if (IDVal == ".dword") {
3842 parseDataDirective(8, DirectiveID.getLoc());
3845 if (IDVal == ".ent") {
3846 StringRef SymbolName;
3848 if (Parser.parseIdentifier(SymbolName)) {
3849 reportParseError("expected identifier after .ent");
3853 // There's an undocumented extension that allows an integer to
3854 // follow the name of the procedure which AFAICS is ignored by GAS.
3855 // Example: .ent foo,2
3856 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3857 if (getLexer().isNot(AsmToken::Comma)) {
3858 // Even though we accept this undocumented extension for compatibility
3859 // reasons, the additional integer argument does not actually change
3860 // the behaviour of the '.ent' directive, so we would like to discourage
3861 // its use. We do this by not referring to the extended version in
3862 // error messages which are not directly related to its use.
3863 reportParseError("unexpected token, expected end of statement");
3866 Parser.Lex(); // Eat the comma.
3867 const MCExpr *DummyNumber;
3868 int64_t DummyNumberVal;
3869 // If the user was explicitly trying to use the extended version,
3870 // we still give helpful extension-related error messages.
3871 if (Parser.parseExpression(DummyNumber)) {
3872 reportParseError("expected number after comma");
3875 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3876 reportParseError("expected an absolute expression after comma");
3881 // If this is not the end of the statement, report an error.
3882 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3883 reportParseError("unexpected token, expected end of statement");
3887 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3889 getTargetStreamer().emitDirectiveEnt(*Sym);
3894 if (IDVal == ".end") {
3895 StringRef SymbolName;
3897 if (Parser.parseIdentifier(SymbolName)) {
3898 reportParseError("expected identifier after .end");
3902 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3903 reportParseError("unexpected token, expected end of statement");
3907 if (CurrentFn == nullptr) {
3908 reportParseError(".end used without .ent");
3912 if ((SymbolName != CurrentFn->getName())) {
3913 reportParseError(".end symbol does not match .ent symbol");
3917 getTargetStreamer().emitDirectiveEnd(SymbolName);
3918 CurrentFn = nullptr;
3922 if (IDVal == ".frame") {
3923 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3924 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3925 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3926 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3927 reportParseError("expected stack register");
3931 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3932 if (!StackRegOpnd.isGPRAsmReg()) {
3933 reportParseError(StackRegOpnd.getStartLoc(),
3934 "expected general purpose register");
3937 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3939 if (Parser.getTok().is(AsmToken::Comma))
3942 reportParseError("unexpected token, expected comma");
3946 // Parse the frame size.
3947 const MCExpr *FrameSize;
3948 int64_t FrameSizeVal;
3950 if (Parser.parseExpression(FrameSize)) {
3951 reportParseError("expected frame size value");
3955 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3956 reportParseError("frame size not an absolute expression");
3960 if (Parser.getTok().is(AsmToken::Comma))
3963 reportParseError("unexpected token, expected comma");
3967 // Parse the return register.
3969 ResTy = parseAnyRegister(TmpReg);
3970 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3971 reportParseError("expected return register");
3975 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3976 if (!ReturnRegOpnd.isGPRAsmReg()) {
3977 reportParseError(ReturnRegOpnd.getStartLoc(),
3978 "expected general purpose register");
3982 // If this is not the end of the statement, report an error.
3983 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3984 reportParseError("unexpected token, expected end of statement");
3988 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3989 ReturnRegOpnd.getGPR32Reg());
3993 if (IDVal == ".set") {
3994 return parseDirectiveSet();
3997 if (IDVal == ".mask" || IDVal == ".fmask") {
3998 // .mask bitmask, frame_offset
3999 // bitmask: One bit for each register used.
4000 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4001 // first register is expected to be saved.
4003 // .mask 0x80000000, -4
4004 // .fmask 0x80000000, -4
4007 // Parse the bitmask
4008 const MCExpr *BitMask;
4011 if (Parser.parseExpression(BitMask)) {
4012 reportParseError("expected bitmask value");
4016 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4017 reportParseError("bitmask not an absolute expression");
4021 if (Parser.getTok().is(AsmToken::Comma))
4024 reportParseError("unexpected token, expected comma");
4028 // Parse the frame_offset
4029 const MCExpr *FrameOffset;
4030 int64_t FrameOffsetVal;
4032 if (Parser.parseExpression(FrameOffset)) {
4033 reportParseError("expected frame offset value");
4037 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4038 reportParseError("frame offset not an absolute expression");
4042 // If this is not the end of the statement, report an error.
4043 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4044 reportParseError("unexpected token, expected end of statement");
4048 if (IDVal == ".mask")
4049 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4051 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4055 if (IDVal == ".nan")
4056 return parseDirectiveNaN();
4058 if (IDVal == ".gpword") {
4059 parseDirectiveGpWord();
4063 if (IDVal == ".gpdword") {
4064 parseDirectiveGpDWord();
4068 if (IDVal == ".word") {
4069 parseDataDirective(4, DirectiveID.getLoc());
4073 if (IDVal == ".option")
4074 return parseDirectiveOption();
4076 if (IDVal == ".abicalls") {
4077 getTargetStreamer().emitDirectiveAbiCalls();
4078 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4079 Error(Parser.getTok().getLoc(),
4080 "unexpected token, expected end of statement");
4082 Parser.eatToEndOfStatement();
4087 if (IDVal == ".cpsetup")
4088 return parseDirectiveCPSetup();
4090 if (IDVal == ".module")
4091 return parseDirectiveModule();
4096 extern "C" void LLVMInitializeMipsAsmParser() {
4097 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4098 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4099 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4100 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4103 #define GET_REGISTER_MATCHER
4104 #define GET_MATCHER_IMPLEMENTATION
4105 #include "MipsGenAsmMatcher.inc"