1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/SmallVector.h"
16 #include "llvm/ADT/StringSwitch.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/SourceMgr.h"
30 #include "llvm/Support/TargetRegistry.h"
35 #define DEBUG_TYPE "mips-asm-parser"
42 class MipsAssemblerOptions {
44 MipsAssemblerOptions(uint64_t Features_) :
45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48 ATReg = Opts->getATRegNum();
49 Reorder = Opts->isReorder();
50 Macro = Opts->isMacro();
51 Features = Opts->getFeatures();
54 unsigned getATRegNum() const { return ATReg; }
55 bool setATReg(unsigned Reg);
57 bool isReorder() const { return Reorder; }
58 void setReorder() { Reorder = true; }
59 void setNoReorder() { Reorder = false; }
61 bool isMacro() const { return Macro; }
62 void setMacro() { Macro = true; }
63 void setNoMacro() { Macro = false; }
65 uint64_t getFeatures() const { return Features; }
66 void setFeatures(uint64_t Features_) { Features = Features_; }
68 // Set of features that are either architecture features or referenced
69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71 // The reason we need this mask is explained in the selectArch function.
72 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
91 class MipsAsmParser : public MCTargetAsmParser {
92 MipsTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
104 // Print a warning along with its fix-it message at the given range.
105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
106 SMRange Range, bool ShowColors = true);
108 #define GET_ASSEMBLER_HEADER
109 #include "MipsGenAsmMatcher.inc"
111 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
114 OperandVector &Operands, MCStreamer &Out,
116 bool MatchingInlineAsm) override;
118 /// Parse a register as used in CFI directives
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
121 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 SMLoc NameLoc, OperandVector &Operands) override;
128 bool ParseDirective(AsmToken DirectiveID) override;
130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
134 StringRef Identifier, SMLoc S);
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy
150 parseRegisterPair (OperandVector &Operands);
152 MipsAsmParser::OperandMatchResultTy
153 parseRegisterList (OperandVector &Operands);
155 bool searchSymbolAlias(OperandVector &Operands);
157 bool parseOperand(OperandVector &, StringRef Mnemonic);
159 bool needsExpansion(MCInst &Inst);
161 // Expands assembly pseudo instructions.
162 // Returns false on success, true otherwise.
163 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
164 SmallVectorImpl<MCInst> &Instructions);
166 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
169 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
174 bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
175 SmallVectorImpl<MCInst> &Instructions);
177 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
178 SmallVectorImpl<MCInst> &Instructions);
180 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
181 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
183 bool reportParseError(Twine ErrorMsg);
184 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
186 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
187 bool parseRelocOperand(const MCExpr *&Res);
189 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
191 bool isEvaluated(const MCExpr *Expr);
192 bool parseSetMips0Directive();
193 bool parseSetArchDirective();
194 bool parseSetFeature(uint64_t Feature);
195 bool parseDirectiveCpLoad(SMLoc Loc);
196 bool parseDirectiveCPSetup();
197 bool parseDirectiveNaN();
198 bool parseDirectiveSet();
199 bool parseDirectiveOption();
201 bool parseSetAtDirective();
202 bool parseSetNoAtDirective();
203 bool parseSetMacroDirective();
204 bool parseSetNoMacroDirective();
205 bool parseSetMsaDirective();
206 bool parseSetNoMsaDirective();
207 bool parseSetNoDspDirective();
208 bool parseSetReorderDirective();
209 bool parseSetNoReorderDirective();
210 bool parseSetMips16Directive();
211 bool parseSetNoMips16Directive();
212 bool parseSetFpDirective();
213 bool parseSetPopDirective();
214 bool parseSetPushDirective();
216 bool parseSetAssignment();
218 bool parseDataDirective(unsigned Size, SMLoc L);
219 bool parseDirectiveGpWord();
220 bool parseDirectiveGpDWord();
221 bool parseDirectiveModule();
222 bool parseDirectiveModuleFP();
223 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
224 StringRef Directive);
226 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
228 bool eatComma(StringRef ErrorStr);
230 int matchCPURegisterName(StringRef Symbol);
232 int matchHWRegsRegisterName(StringRef Symbol);
234 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
236 int matchFPURegisterName(StringRef Name);
238 int matchFCCRegisterName(StringRef Name);
240 int matchACRegisterName(StringRef Name);
242 int matchMSA128RegisterName(StringRef Name);
244 int matchMSA128CtrlRegisterName(StringRef Name);
246 unsigned getReg(int RC, int RegNo);
248 unsigned getGPR(int RegNo);
250 int getATReg(SMLoc Loc);
252 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
253 SmallVectorImpl<MCInst> &Instructions);
255 // Helper function that checks if the value of a vector index is within the
256 // boundaries of accepted values for each RegisterKind
257 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
258 bool validateMSAIndex(int Val, int RegKind);
260 // Selects a new architecture by updating the FeatureBits with the necessary
261 // info including implied dependencies.
262 // Internally, it clears all the feature bits related to *any* architecture
263 // and selects the new one using the ToggleFeature functionality of the
264 // MCSubtargetInfo object that handles implied dependencies. The reason we
265 // clear all the arch related bits manually is because ToggleFeature only
266 // clears the features that imply the feature being cleared and not the
267 // features implied by the feature being cleared. This is easier to see
269 // --------------------------------------------------
270 // | Feature | Implies |
271 // | -------------------------------------------------|
272 // | FeatureMips1 | None |
273 // | FeatureMips2 | FeatureMips1 |
274 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
275 // | FeatureMips4 | FeatureMips3 |
277 // --------------------------------------------------
279 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
280 // FeatureMipsGP64 | FeatureMips1)
281 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
282 void selectArch(StringRef ArchFeature) {
283 uint64_t FeatureBits = STI.getFeatureBits();
284 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
285 STI.setFeatureBits(FeatureBits);
286 setAvailableFeatures(
287 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
288 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
291 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
292 if (!(STI.getFeatureBits() & Feature)) {
293 setAvailableFeatures(
294 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
296 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
299 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
300 if (STI.getFeatureBits() & Feature) {
301 setAvailableFeatures(
302 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
304 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
308 enum MipsMatchResultTy {
309 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
310 #define GET_OPERAND_DIAGNOSTIC_TYPES
311 #include "MipsGenAsmMatcher.inc"
312 #undef GET_OPERAND_DIAGNOSTIC_TYPES
316 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
317 const MCInstrInfo &MII, const MCTargetOptions &Options)
318 : MCTargetAsmParser(), STI(sti) {
319 MCAsmParserExtension::Initialize(parser);
321 // Initialize the set of available features.
322 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
324 // Remember the initial assembler options. The user can not modify these.
325 AssemblerOptions.push_back(
326 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
328 // Create an assembler options environment for the user to modify.
329 AssemblerOptions.push_back(
330 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
332 getTargetStreamer().updateABIInfo(*this);
334 // Assert exactly one ABI was chosen.
335 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
336 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
337 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
338 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
340 if (!isABI_O32() && !useOddSPReg() != 0)
341 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
346 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
347 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
349 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
350 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
351 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
352 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
353 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
354 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
356 bool useOddSPReg() const {
357 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
360 bool inMicroMipsMode() const {
361 return STI.getFeatureBits() & Mips::FeatureMicroMips;
363 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
364 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
365 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
366 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
367 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
368 bool hasMips32() const {
369 return (STI.getFeatureBits() & Mips::FeatureMips32);
371 bool hasMips64() const {
372 return (STI.getFeatureBits() & Mips::FeatureMips64);
374 bool hasMips32r2() const {
375 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
377 bool hasMips64r2() const {
378 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
380 bool hasMips32r6() const {
381 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
383 bool hasMips64r6() const {
384 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
386 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
387 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
388 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
390 bool inMips16Mode() const {
391 return STI.getFeatureBits() & Mips::FeatureMips16;
393 // TODO: see how can we get this info.
394 bool abiUsesSoftFloat() const { return false; }
396 /// Warn if RegNo is the current assembler temporary.
397 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
403 /// MipsOperand - Instances of this class represent a parsed Mips machine
405 class MipsOperand : public MCParsedAsmOperand {
407 /// Broad categories of register classes
408 /// The exact class is finalized by the render method.
410 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
411 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
413 RegKind_FCC = 4, /// FCC
414 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
415 RegKind_MSACtrl = 16, /// MSA control registers
416 RegKind_COP2 = 32, /// COP2
417 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
419 RegKind_CCR = 128, /// CCR
420 RegKind_HWRegs = 256, /// HWRegs
421 RegKind_COP3 = 512, /// COP3
423 /// Potentially any (e.g. $1)
424 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
425 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
426 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
431 k_Immediate, /// An immediate (possibly involving symbol references)
432 k_Memory, /// Base + Offset Memory Address
433 k_PhysRegister, /// A physical register from the Mips namespace
434 k_RegisterIndex, /// A register index in one or more RegKind.
435 k_Token, /// A simple token
436 k_RegList, /// A physical register list
437 k_RegPair /// A pair of physical register
441 MipsOperand(KindTy K, MipsAsmParser &Parser)
442 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
445 /// For diagnostics, and checking the assembler temporary
446 MipsAsmParser &AsmParser;
454 unsigned Num; /// Register Number
458 unsigned Index; /// Index into the register class
459 RegKind Kind; /// Bitfield of the kinds it could possibly be
460 const MCRegisterInfo *RegInfo;
473 SmallVector<unsigned, 10> *List;
478 struct PhysRegOp PhysReg;
479 struct RegIdxOp RegIdx;
482 struct RegListOp RegList;
485 SMLoc StartLoc, EndLoc;
487 /// Internal constructor for register kinds
488 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
489 const MCRegisterInfo *RegInfo,
491 MipsAsmParser &Parser) {
492 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
493 Op->RegIdx.Index = Index;
494 Op->RegIdx.RegInfo = RegInfo;
495 Op->RegIdx.Kind = RegKind;
502 /// Coerce the register to GPR32 and return the real register for the current
504 unsigned getGPR32Reg() const {
505 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
506 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
507 unsigned ClassID = Mips::GPR32RegClassID;
508 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
511 /// Coerce the register to GPR32 and return the real register for the current
513 unsigned getGPRMM16Reg() const {
514 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
515 unsigned ClassID = Mips::GPR32RegClassID;
516 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
519 /// Coerce the register to GPR64 and return the real register for the current
521 unsigned getGPR64Reg() const {
522 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
523 unsigned ClassID = Mips::GPR64RegClassID;
524 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
528 /// Coerce the register to AFGR64 and return the real register for the current
530 unsigned getAFGR64Reg() const {
531 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
532 if (RegIdx.Index % 2 != 0)
533 AsmParser.Warning(StartLoc, "Float register should be even.");
534 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
535 .getRegister(RegIdx.Index / 2);
538 /// Coerce the register to FGR64 and return the real register for the current
540 unsigned getFGR64Reg() const {
541 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
542 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
543 .getRegister(RegIdx.Index);
546 /// Coerce the register to FGR32 and return the real register for the current
548 unsigned getFGR32Reg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
550 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
551 .getRegister(RegIdx.Index);
554 /// Coerce the register to FGRH32 and return the real register for the current
556 unsigned getFGRH32Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
558 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
559 .getRegister(RegIdx.Index);
562 /// Coerce the register to FCC and return the real register for the current
564 unsigned getFCCReg() const {
565 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
566 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
567 .getRegister(RegIdx.Index);
570 /// Coerce the register to MSA128 and return the real register for the current
572 unsigned getMSA128Reg() const {
573 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
574 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
576 unsigned ClassID = Mips::MSA128BRegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to MSACtrl and return the real register for the
582 unsigned getMSACtrlReg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
584 unsigned ClassID = Mips::MSACtrlRegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
588 /// Coerce the register to COP2 and return the real register for the
590 unsigned getCOP2Reg() const {
591 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
592 unsigned ClassID = Mips::COP2RegClassID;
593 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
596 /// Coerce the register to COP3 and return the real register for the
598 unsigned getCOP3Reg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
600 unsigned ClassID = Mips::COP3RegClassID;
601 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604 /// Coerce the register to ACC64DSP and return the real register for the
606 unsigned getACC64DSPReg() const {
607 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
608 unsigned ClassID = Mips::ACC64DSPRegClassID;
609 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
612 /// Coerce the register to HI32DSP and return the real register for the
614 unsigned getHI32DSPReg() const {
615 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
616 unsigned ClassID = Mips::HI32DSPRegClassID;
617 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
620 /// Coerce the register to LO32DSP and return the real register for the
622 unsigned getLO32DSPReg() const {
623 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
624 unsigned ClassID = Mips::LO32DSPRegClassID;
625 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
628 /// Coerce the register to CCR and return the real register for the
630 unsigned getCCRReg() const {
631 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
632 unsigned ClassID = Mips::CCRRegClassID;
633 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
636 /// Coerce the register to HWRegs and return the real register for the
638 unsigned getHWRegsReg() const {
639 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
640 unsigned ClassID = Mips::HWRegsRegClassID;
641 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
645 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
646 // Add as immediate when possible. Null MCExpr = 0.
648 Inst.addOperand(MCOperand::CreateImm(0));
649 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
650 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
652 Inst.addOperand(MCOperand::CreateExpr(Expr));
655 void addRegOperands(MCInst &Inst, unsigned N) const {
656 llvm_unreachable("Use a custom parser instead");
659 /// Render the operand to an MCInst as a GPR32
660 /// Asserts if the wrong number of operands are requested, or the operand
661 /// is not a k_RegisterIndex compatible with RegKind_GPR
662 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
663 assert(N == 1 && "Invalid number of operands!");
664 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
667 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
668 assert(N == 1 && "Invalid number of operands!");
669 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
672 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
673 assert(N == 1 && "Invalid number of operands!");
674 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
677 /// Render the operand to an MCInst as a GPR64
678 /// Asserts if the wrong number of operands are requested, or the operand
679 /// is not a k_RegisterIndex compatible with RegKind_GPR
680 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
681 assert(N == 1 && "Invalid number of operands!");
682 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
685 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
690 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
695 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
696 assert(N == 1 && "Invalid number of operands!");
697 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
698 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
699 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
700 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
704 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
705 assert(N == 1 && "Invalid number of operands!");
706 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
709 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
710 assert(N == 1 && "Invalid number of operands!");
711 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
714 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
719 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
720 assert(N == 1 && "Invalid number of operands!");
721 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
724 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
725 assert(N == 1 && "Invalid number of operands!");
726 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
729 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
734 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
739 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
744 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 1 && "Invalid number of operands!");
746 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
749 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
750 assert(N == 1 && "Invalid number of operands!");
751 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
754 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
755 assert(N == 1 && "Invalid number of operands!");
756 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
759 void addImmOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 1 && "Invalid number of operands!");
761 const MCExpr *Expr = getImm();
765 void addMemOperands(MCInst &Inst, unsigned N) const {
766 assert(N == 2 && "Invalid number of operands!");
768 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
770 const MCExpr *Expr = getMemOff();
774 void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
775 assert(N == 2 && "Invalid number of operands!");
777 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPRMM16Reg()));
779 const MCExpr *Expr = getMemOff();
783 void addRegListOperands(MCInst &Inst, unsigned N) const {
784 assert(N == 1 && "Invalid number of operands!");
786 for (auto RegNo : getRegList())
787 Inst.addOperand(MCOperand::CreateReg(RegNo));
790 void addRegPairOperands(MCInst &Inst, unsigned N) const {
791 assert(N == 2 && "Invalid number of operands!");
792 unsigned RegNo = getRegPair();
793 Inst.addOperand(MCOperand::CreateReg(RegNo++));
794 Inst.addOperand(MCOperand::CreateReg(RegNo));
797 bool isReg() const override {
798 // As a special case until we sort out the definition of div/divu, pretend
799 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
800 if (isGPRAsmReg() && RegIdx.Index == 0)
803 return Kind == k_PhysRegister;
805 bool isRegIdx() const { return Kind == k_RegisterIndex; }
806 bool isImm() const override { return Kind == k_Immediate; }
807 bool isConstantImm() const {
808 return isImm() && dyn_cast<MCConstantExpr>(getImm());
810 bool isToken() const override {
811 // Note: It's not possible to pretend that other operand kinds are tokens.
812 // The matcher emitter checks tokens first.
813 return Kind == k_Token;
815 bool isMem() const override { return Kind == k_Memory; }
816 bool isConstantMemOff() const {
817 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
819 template <unsigned Bits> bool isMemWithSimmOffset() const {
820 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
822 bool isMemWithGRPMM16Base() const {
823 return isMem() && getMemBase()->isMM16AsmReg();
825 template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
826 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
827 && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
829 template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
830 return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
831 && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
832 && (getMemBase()->getGPR32Reg() == Mips::SP);
834 bool isRegList16() const {
838 int Size = RegList.List->size();
839 if (Size < 2 || Size > 5 || *RegList.List->begin() != Mips::S0 ||
840 RegList.List->back() != Mips::RA)
843 int PrevReg = *RegList.List->begin();
844 for (int i = 1; i < Size - 1; i++) {
845 int Reg = (*(RegList.List))[i];
846 if ( Reg != PrevReg + 1)
853 bool isInvNum() const { return Kind == k_Immediate; }
854 bool isLSAImm() const {
855 if (!isConstantImm())
857 int64_t Val = getConstantImm();
858 return 1 <= Val && Val <= 4;
860 bool isRegList() const { return Kind == k_RegList; }
862 StringRef getToken() const {
863 assert(Kind == k_Token && "Invalid access!");
864 return StringRef(Tok.Data, Tok.Length);
866 bool isRegPair() const { return Kind == k_RegPair; }
868 unsigned getReg() const override {
869 // As a special case until we sort out the definition of div/divu, pretend
870 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
871 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
872 RegIdx.Kind & RegKind_GPR)
873 return getGPR32Reg(); // FIXME: GPR64 too
875 assert(Kind == k_PhysRegister && "Invalid access!");
879 const MCExpr *getImm() const {
880 assert((Kind == k_Immediate) && "Invalid access!");
884 int64_t getConstantImm() const {
885 const MCExpr *Val = getImm();
886 return static_cast<const MCConstantExpr *>(Val)->getValue();
889 MipsOperand *getMemBase() const {
890 assert((Kind == k_Memory) && "Invalid access!");
894 const MCExpr *getMemOff() const {
895 assert((Kind == k_Memory) && "Invalid access!");
899 int64_t getConstantMemOff() const {
900 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
903 const SmallVectorImpl<unsigned> &getRegList() const {
904 assert((Kind == k_RegList) && "Invalid access!");
905 return *(RegList.List);
908 unsigned getRegPair() const {
909 assert((Kind == k_RegPair) && "Invalid access!");
913 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
914 MipsAsmParser &Parser) {
915 auto Op = make_unique<MipsOperand>(k_Token, Parser);
916 Op->Tok.Data = Str.data();
917 Op->Tok.Length = Str.size();
923 /// Create a numeric register (e.g. $1). The exact register remains
924 /// unresolved until an instruction successfully matches
925 static std::unique_ptr<MipsOperand>
926 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
927 SMLoc E, MipsAsmParser &Parser) {
928 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
929 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
932 /// Create a register that is definitely a GPR.
933 /// This is typically only used for named registers such as $gp.
934 static std::unique_ptr<MipsOperand>
935 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
936 MipsAsmParser &Parser) {
937 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
940 /// Create a register that is definitely a FGR.
941 /// This is typically only used for named registers such as $f0.
942 static std::unique_ptr<MipsOperand>
943 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
944 MipsAsmParser &Parser) {
945 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
948 /// Create a register that is definitely a HWReg.
949 /// This is typically only used for named registers such as $hwr_cpunum.
950 static std::unique_ptr<MipsOperand>
951 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
952 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
953 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
956 /// Create a register that is definitely an FCC.
957 /// This is typically only used for named registers such as $fcc0.
958 static std::unique_ptr<MipsOperand>
959 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
960 MipsAsmParser &Parser) {
961 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
964 /// Create a register that is definitely an ACC.
965 /// This is typically only used for named registers such as $ac0.
966 static std::unique_ptr<MipsOperand>
967 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
968 MipsAsmParser &Parser) {
969 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
972 /// Create a register that is definitely an MSA128.
973 /// This is typically only used for named registers such as $w0.
974 static std::unique_ptr<MipsOperand>
975 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
976 SMLoc E, MipsAsmParser &Parser) {
977 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
980 /// Create a register that is definitely an MSACtrl.
981 /// This is typically only used for named registers such as $msaaccess.
982 static std::unique_ptr<MipsOperand>
983 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
984 SMLoc E, MipsAsmParser &Parser) {
985 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
988 static std::unique_ptr<MipsOperand>
989 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
990 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
997 static std::unique_ptr<MipsOperand>
998 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
999 SMLoc E, MipsAsmParser &Parser) {
1000 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1001 Op->Mem.Base = Base.release();
1008 static std::unique_ptr<MipsOperand>
1009 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
1010 MipsAsmParser &Parser) {
1011 assert (Regs.size() > 0 && "Empty list not allowed");
1013 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1014 Op->RegList.List = new SmallVector<unsigned, 10>();
1015 for (auto Reg : Regs)
1016 Op->RegList.List->push_back(Reg);
1017 Op->StartLoc = StartLoc;
1018 Op->EndLoc = EndLoc;
1022 static std::unique_ptr<MipsOperand>
1023 CreateRegPair(unsigned RegNo, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1024 auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1025 Op->RegIdx.Index = RegNo;
1031 bool isGPRAsmReg() const {
1032 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
1034 bool isMM16AsmReg() const {
1035 if (!(isRegIdx() && RegIdx.Kind))
1037 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
1038 || RegIdx.Index == 16 || RegIdx.Index == 17);
1040 bool isMM16AsmRegZero() const {
1041 if (!(isRegIdx() && RegIdx.Kind))
1043 return (RegIdx.Index == 0 ||
1044 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1045 RegIdx.Index == 17);
1047 bool isFGRAsmReg() const {
1048 // AFGR64 is $0-$15 but we handle this in getAFGR64()
1049 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1051 bool isHWRegsAsmReg() const {
1052 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
1054 bool isCCRAsmReg() const {
1055 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
1057 bool isFCCAsmReg() const {
1058 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1060 if (!AsmParser.hasEightFccRegisters())
1061 return RegIdx.Index == 0;
1062 return RegIdx.Index <= 7;
1064 bool isACCAsmReg() const {
1065 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
1067 bool isCOP2AsmReg() const {
1068 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1070 bool isCOP3AsmReg() const {
1071 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1073 bool isMSA128AsmReg() const {
1074 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1076 bool isMSACtrlAsmReg() const {
1077 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1080 /// getStartLoc - Get the location of the first token of this operand.
1081 SMLoc getStartLoc() const override { return StartLoc; }
1082 /// getEndLoc - Get the location of the last token of this operand.
1083 SMLoc getEndLoc() const override { return EndLoc; }
1085 virtual ~MipsOperand() {
1093 delete RegList.List;
1094 case k_PhysRegister:
1095 case k_RegisterIndex:
1102 void print(raw_ostream &OS) const override {
1111 Mem.Base->print(OS);
1116 case k_PhysRegister:
1117 OS << "PhysReg<" << PhysReg.Num << ">";
1119 case k_RegisterIndex:
1120 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1127 for (auto Reg : (*RegList.List))
1132 OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1136 }; // class MipsOperand
1140 extern const MCInstrDesc MipsInsts[];
1142 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1143 return MipsInsts[Opcode];
1146 static bool hasShortDelaySlot(unsigned Opcode) {
1149 case Mips::JALRS_MM:
1150 case Mips::JALRS16_MM:
1151 case Mips::BGEZALS_MM:
1152 case Mips::BLTZALS_MM:
1159 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1160 SmallVectorImpl<MCInst> &Instructions) {
1161 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1165 if (MCID.isBranch() || MCID.isCall()) {
1166 const unsigned Opcode = Inst.getOpcode();
1176 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1177 Offset = Inst.getOperand(2);
1178 if (!Offset.isImm())
1179 break; // We'll deal with this situation later on when applying fixups.
1180 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1181 return Error(IDLoc, "branch target out of range");
1182 if (OffsetToAlignment(Offset.getImm(),
1183 1LL << (inMicroMipsMode() ? 1 : 2)))
1184 return Error(IDLoc, "branch to misaligned address");
1198 case Mips::BGEZAL_MM:
1199 case Mips::BLTZAL_MM:
1202 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1203 Offset = Inst.getOperand(1);
1204 if (!Offset.isImm())
1205 break; // We'll deal with this situation later on when applying fixups.
1206 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1207 return Error(IDLoc, "branch target out of range");
1208 if (OffsetToAlignment(Offset.getImm(),
1209 1LL << (inMicroMipsMode() ? 1 : 2)))
1210 return Error(IDLoc, "branch to misaligned address");
1212 case Mips::BEQZ16_MM:
1213 case Mips::BNEZ16_MM:
1214 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1215 Offset = Inst.getOperand(1);
1216 if (!Offset.isImm())
1217 break; // We'll deal with this situation later on when applying fixups.
1218 if (!isIntN(8, Offset.getImm()))
1219 return Error(IDLoc, "branch target out of range");
1220 if (OffsetToAlignment(Offset.getImm(), 2LL))
1221 return Error(IDLoc, "branch to misaligned address");
1226 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1227 // We still accept it but it is a normal nop.
1228 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1229 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1230 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1234 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1235 // If this instruction has a delay slot and .set reorder is active,
1236 // emit a NOP after it.
1237 Instructions.push_back(Inst);
1239 if (hasShortDelaySlot(Inst.getOpcode())) {
1240 NopInst.setOpcode(Mips::MOVE16_MM);
1241 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1242 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1244 NopInst.setOpcode(Mips::SLL);
1245 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1246 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1247 NopInst.addOperand(MCOperand::CreateImm(0));
1249 Instructions.push_back(NopInst);
1253 if (MCID.mayLoad() || MCID.mayStore()) {
1254 // Check the offset of memory operand, if it is a symbol
1255 // reference or immediate we may have to expand instructions.
1256 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1257 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1258 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1259 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1260 MCOperand &Op = Inst.getOperand(i);
1262 int MemOffset = Op.getImm();
1263 if (MemOffset < -32768 || MemOffset > 32767) {
1264 // Offset can't exceed 16bit value.
1265 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1268 } else if (Op.isExpr()) {
1269 const MCExpr *Expr = Op.getExpr();
1270 if (Expr->getKind() == MCExpr::SymbolRef) {
1271 const MCSymbolRefExpr *SR =
1272 static_cast<const MCSymbolRefExpr *>(Expr);
1273 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1275 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1278 } else if (!isEvaluated(Expr)) {
1279 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1287 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1288 if (inMicroMipsMode()) {
1292 switch (Inst.getOpcode()) {
1295 case Mips::ADDIUS5_MM:
1296 Opnd = Inst.getOperand(2);
1298 return Error(IDLoc, "expected immediate operand kind");
1299 Imm = Opnd.getImm();
1300 if (Imm < -8 || Imm > 7)
1301 return Error(IDLoc, "immediate operand value out of range");
1303 case Mips::ADDIUSP_MM:
1304 Opnd = Inst.getOperand(0);
1306 return Error(IDLoc, "expected immediate operand kind");
1307 Imm = Opnd.getImm();
1308 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1310 return Error(IDLoc, "immediate operand value out of range");
1312 case Mips::SLL16_MM:
1313 case Mips::SRL16_MM:
1314 Opnd = Inst.getOperand(2);
1316 return Error(IDLoc, "expected immediate operand kind");
1317 Imm = Opnd.getImm();
1318 if (Imm < 1 || Imm > 8)
1319 return Error(IDLoc, "immediate operand value out of range");
1322 Opnd = Inst.getOperand(1);
1324 return Error(IDLoc, "expected immediate operand kind");
1325 Imm = Opnd.getImm();
1326 if (Imm < -1 || Imm > 126)
1327 return Error(IDLoc, "immediate operand value out of range");
1329 case Mips::ADDIUR2_MM:
1330 Opnd = Inst.getOperand(2);
1332 return Error(IDLoc, "expected immediate operand kind");
1333 Imm = Opnd.getImm();
1334 if (!(Imm == 1 || Imm == -1 ||
1335 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1336 return Error(IDLoc, "immediate operand value out of range");
1338 case Mips::ADDIUR1SP_MM:
1339 Opnd = Inst.getOperand(1);
1341 return Error(IDLoc, "expected immediate operand kind");
1342 Imm = Opnd.getImm();
1343 if (OffsetToAlignment(Imm, 4LL))
1344 return Error(IDLoc, "misaligned immediate operand value");
1345 if (Imm < 0 || Imm > 255)
1346 return Error(IDLoc, "immediate operand value out of range");
1348 case Mips::ANDI16_MM:
1349 Opnd = Inst.getOperand(2);
1351 return Error(IDLoc, "expected immediate operand kind");
1352 Imm = Opnd.getImm();
1353 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1354 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1355 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1356 return Error(IDLoc, "immediate operand value out of range");
1358 case Mips::LBU16_MM:
1359 Opnd = Inst.getOperand(2);
1361 return Error(IDLoc, "expected immediate operand kind");
1362 Imm = Opnd.getImm();
1363 if (Imm < -1 || Imm > 14)
1364 return Error(IDLoc, "immediate operand value out of range");
1367 Opnd = Inst.getOperand(2);
1369 return Error(IDLoc, "expected immediate operand kind");
1370 Imm = Opnd.getImm();
1371 if (Imm < 0 || Imm > 15)
1372 return Error(IDLoc, "immediate operand value out of range");
1374 case Mips::LHU16_MM:
1376 Opnd = Inst.getOperand(2);
1378 return Error(IDLoc, "expected immediate operand kind");
1379 Imm = Opnd.getImm();
1380 if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1381 return Error(IDLoc, "immediate operand value out of range");
1385 Opnd = Inst.getOperand(2);
1387 return Error(IDLoc, "expected immediate operand kind");
1388 Imm = Opnd.getImm();
1389 if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1390 return Error(IDLoc, "immediate operand value out of range");
1394 Opnd = Inst.getOperand(2);
1396 return Error(IDLoc, "expected immediate operand kind");
1397 Imm = Opnd.getImm();
1398 if (!isUInt<5>(Imm))
1399 return Error(IDLoc, "immediate operand value out of range");
1401 case Mips::ADDIUPC_MM:
1402 MCOperand Opnd = Inst.getOperand(1);
1404 return Error(IDLoc, "expected immediate operand kind");
1405 int Imm = Opnd.getImm();
1406 if ((Imm % 4 != 0) || !isIntN(25, Imm))
1407 return Error(IDLoc, "immediate operand value out of range");
1412 if (needsExpansion(Inst))
1413 return expandInstruction(Inst, IDLoc, Instructions);
1415 Instructions.push_back(Inst);
1420 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1422 switch (Inst.getOpcode()) {
1423 case Mips::LoadImm32Reg:
1424 case Mips::LoadAddr32Imm:
1425 case Mips::LoadAddr32Reg:
1426 case Mips::LoadImm64Reg:
1427 case Mips::B_MM_Pseudo:
1434 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1435 SmallVectorImpl<MCInst> &Instructions) {
1436 switch (Inst.getOpcode()) {
1437 default: llvm_unreachable("unimplemented expansion");
1438 case Mips::LoadImm32Reg:
1439 return expandLoadImm(Inst, IDLoc, Instructions);
1440 case Mips::LoadImm64Reg:
1442 Error(IDLoc, "instruction requires a 64-bit architecture");
1445 return expandLoadImm(Inst, IDLoc, Instructions);
1446 case Mips::LoadAddr32Imm:
1447 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1448 case Mips::LoadAddr32Reg:
1449 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1450 case Mips::B_MM_Pseudo:
1451 return expandUncondBranchMMPseudo(Inst, IDLoc, Instructions);
1456 template <bool PerformShift>
1457 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1458 SmallVectorImpl<MCInst> &Instructions) {
1461 tmpInst.setOpcode(Mips::DSLL);
1462 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1463 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1464 tmpInst.addOperand(MCOperand::CreateImm(16));
1465 tmpInst.setLoc(IDLoc);
1466 Instructions.push_back(tmpInst);
1469 tmpInst.setOpcode(Mips::ORi);
1470 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1471 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1472 tmpInst.addOperand(Operand);
1473 tmpInst.setLoc(IDLoc);
1474 Instructions.push_back(tmpInst);
1477 template <int Shift, bool PerformShift>
1478 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1479 SmallVectorImpl<MCInst> &Instructions) {
1480 createShiftOr<PerformShift>(
1481 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1482 IDLoc, Instructions);
1486 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1487 SmallVectorImpl<MCInst> &Instructions) {
1489 const MCOperand &ImmOp = Inst.getOperand(1);
1490 assert(ImmOp.isImm() && "expected immediate operand kind");
1491 const MCOperand &RegOp = Inst.getOperand(0);
1492 assert(RegOp.isReg() && "expected register operand kind");
1494 int64_t ImmValue = ImmOp.getImm();
1495 tmpInst.setLoc(IDLoc);
1496 // FIXME: gas has a special case for values that are 000...1111, which
1497 // becomes a li -1 and then a dsrl
1498 if (0 <= ImmValue && ImmValue <= 65535) {
1499 // For 0 <= j <= 65535.
1500 // li d,j => ori d,$zero,j
1501 tmpInst.setOpcode(Mips::ORi);
1502 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1503 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1504 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1505 Instructions.push_back(tmpInst);
1506 } else if (ImmValue < 0 && ImmValue >= -32768) {
1507 // For -32768 <= j < 0.
1508 // li d,j => addiu d,$zero,j
1509 tmpInst.setOpcode(Mips::ADDiu);
1510 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1511 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1512 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1513 Instructions.push_back(tmpInst);
1514 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1515 // For any value of j that is representable as a 32-bit integer, create
1517 // li d,j => lui d,hi16(j)
1519 tmpInst.setOpcode(Mips::LUi);
1520 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1521 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1522 Instructions.push_back(tmpInst);
1523 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1524 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1526 Error(IDLoc, "instruction requires a 64-bit architecture");
1530 // <------- lo32 ------>
1531 // <------- hi32 ------>
1532 // <- hi16 -> <- lo16 ->
1533 // _________________________________
1535 // | 16-bytes | 16-bytes | 16-bytes |
1536 // |__________|__________|__________|
1538 // For any value of j that is representable as a 48-bit integer, create
1540 // li d,j => lui d,hi16(j)
1541 // ori d,d,hi16(lo32(j))
1543 // ori d,d,lo16(lo32(j))
1544 tmpInst.setOpcode(Mips::LUi);
1545 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1547 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1548 Instructions.push_back(tmpInst);
1549 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1550 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1553 Error(IDLoc, "instruction requires a 64-bit architecture");
1557 // <------- hi32 ------> <------- lo32 ------>
1558 // <- hi16 -> <- lo16 ->
1559 // ___________________________________________
1561 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1562 // |__________|__________|__________|__________|
1564 // For any value of j that isn't representable as a 48-bit integer.
1565 // li d,j => lui d,hi16(j)
1566 // ori d,d,lo16(hi32(j))
1568 // ori d,d,hi16(lo32(j))
1570 // ori d,d,lo16(lo32(j))
1571 tmpInst.setOpcode(Mips::LUi);
1572 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1574 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1575 Instructions.push_back(tmpInst);
1576 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1577 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1578 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1584 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1585 SmallVectorImpl<MCInst> &Instructions) {
1587 const MCOperand &ImmOp = Inst.getOperand(2);
1588 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1589 "expected immediate operand kind");
1590 if (!ImmOp.isImm()) {
1591 expandLoadAddressSym(Inst, IDLoc, Instructions);
1594 const MCOperand &SrcRegOp = Inst.getOperand(1);
1595 assert(SrcRegOp.isReg() && "expected register operand kind");
1596 const MCOperand &DstRegOp = Inst.getOperand(0);
1597 assert(DstRegOp.isReg() && "expected register operand kind");
1598 int ImmValue = ImmOp.getImm();
1599 if (-32768 <= ImmValue && ImmValue <= 65535) {
1600 // For -32768 <= j <= 65535.
1601 // la d,j(s) => addiu d,s,j
1602 tmpInst.setOpcode(Mips::ADDiu);
1603 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1604 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1605 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1606 Instructions.push_back(tmpInst);
1608 // For any other value of j that is representable as a 32-bit integer.
1609 // la d,j(s) => lui d,hi16(j)
1612 tmpInst.setOpcode(Mips::LUi);
1613 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1614 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1615 Instructions.push_back(tmpInst);
1617 tmpInst.setOpcode(Mips::ORi);
1618 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1619 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1620 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1621 Instructions.push_back(tmpInst);
1623 tmpInst.setOpcode(Mips::ADDu);
1624 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1625 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1626 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1627 Instructions.push_back(tmpInst);
1633 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1634 SmallVectorImpl<MCInst> &Instructions) {
1636 const MCOperand &ImmOp = Inst.getOperand(1);
1637 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1638 "expected immediate operand kind");
1639 if (!ImmOp.isImm()) {
1640 expandLoadAddressSym(Inst, IDLoc, Instructions);
1643 const MCOperand &RegOp = Inst.getOperand(0);
1644 assert(RegOp.isReg() && "expected register operand kind");
1645 int ImmValue = ImmOp.getImm();
1646 if (-32768 <= ImmValue && ImmValue <= 65535) {
1647 // For -32768 <= j <= 65535.
1648 // la d,j => addiu d,$zero,j
1649 tmpInst.setOpcode(Mips::ADDiu);
1650 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1651 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1652 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1653 Instructions.push_back(tmpInst);
1655 // For any other value of j that is representable as a 32-bit integer.
1656 // la d,j => lui d,hi16(j)
1658 tmpInst.setOpcode(Mips::LUi);
1659 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1660 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1661 Instructions.push_back(tmpInst);
1663 tmpInst.setOpcode(Mips::ORi);
1664 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1665 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1666 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1667 Instructions.push_back(tmpInst);
1673 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1674 SmallVectorImpl<MCInst> &Instructions) {
1675 // FIXME: If we do have a valid at register to use, we should generate a
1676 // slightly shorter sequence here.
1678 int ExprOperandNo = 1;
1679 // Sometimes the assembly parser will get the immediate expression as
1680 // a $zero + an immediate.
1681 if (Inst.getNumOperands() == 3) {
1682 assert(Inst.getOperand(1).getReg() ==
1683 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1686 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1687 assert(SymOp.isExpr() && "expected symbol operand kind");
1688 const MCOperand &RegOp = Inst.getOperand(0);
1689 unsigned RegNo = RegOp.getReg();
1690 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1691 const MCSymbolRefExpr *HiExpr =
1692 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1693 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1694 const MCSymbolRefExpr *LoExpr =
1695 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1696 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1698 // If it's a 64-bit architecture, expand to:
1699 // la d,sym => lui d,highest(sym)
1700 // ori d,d,higher(sym)
1702 // ori d,d,hi16(sym)
1704 // ori d,d,lo16(sym)
1705 const MCSymbolRefExpr *HighestExpr =
1706 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1707 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1708 const MCSymbolRefExpr *HigherExpr =
1709 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1710 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1712 tmpInst.setOpcode(Mips::LUi);
1713 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1714 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1715 Instructions.push_back(tmpInst);
1717 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1719 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1721 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1724 // Otherwise, expand to:
1725 // la d,sym => lui d,hi16(sym)
1726 // ori d,d,lo16(sym)
1727 tmpInst.setOpcode(Mips::LUi);
1728 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1729 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1730 Instructions.push_back(tmpInst);
1732 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1737 bool MipsAsmParser::
1738 expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
1739 SmallVectorImpl<MCInst> &Instructions) {
1740 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1742 assert(MCID.getNumOperands() == 1 && "unexpected number of operands");
1744 MCOperand Offset = Inst.getOperand(0);
1745 if (Offset.isExpr()) {
1747 Inst.setOpcode(Mips::BEQ_MM);
1748 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1749 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1750 Inst.addOperand(MCOperand::CreateExpr(Offset.getExpr()));
1752 assert(Offset.isImm() && "expected immediate operand kind");
1753 if (isIntN(11, Offset.getImm())) {
1754 // If offset fits into 11 bits then this instruction becomes microMIPS
1755 // 16-bit unconditional branch instruction.
1756 Inst.setOpcode(Mips::B16_MM);
1758 if (!isIntN(17, Offset.getImm()))
1759 Error(IDLoc, "branch target out of range");
1760 if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
1761 Error(IDLoc, "branch to misaligned address");
1763 Inst.setOpcode(Mips::BEQ_MM);
1764 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1765 Inst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1766 Inst.addOperand(MCOperand::CreateImm(Offset.getImm()));
1769 Instructions.push_back(Inst);
1771 if (AssemblerOptions.back()->isReorder()) {
1772 // If .set reorder is active, emit a NOP after the branch instruction.
1774 NopInst.setOpcode(Mips::MOVE16_MM);
1775 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1776 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1777 Instructions.push_back(NopInst);
1782 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1783 SmallVectorImpl<MCInst> &Instructions,
1784 bool isLoad, bool isImmOpnd) {
1785 const MCSymbolRefExpr *SR;
1787 unsigned ImmOffset, HiOffset, LoOffset;
1788 const MCExpr *ExprOffset;
1790 // 1st operand is either the source or destination register.
1791 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1792 unsigned RegOpNum = Inst.getOperand(0).getReg();
1793 // 2nd operand is the base register.
1794 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1795 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1796 // 3rd operand is either an immediate or expression.
1798 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1799 ImmOffset = Inst.getOperand(2).getImm();
1800 LoOffset = ImmOffset & 0x0000ffff;
1801 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1802 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1803 if (LoOffset & 0x8000)
1806 ExprOffset = Inst.getOperand(2).getExpr();
1807 // All instructions will have the same location.
1808 TempInst.setLoc(IDLoc);
1809 // These are some of the types of expansions we perform here:
1810 // 1) lw $8, sym => lui $8, %hi(sym)
1811 // lw $8, %lo(sym)($8)
1812 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1814 // lw $8, %lo(offset)($9)
1815 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1817 // lw $8, %lo(offset)($at)
1818 // 4) sw $8, sym => lui $at, %hi(sym)
1819 // sw $8, %lo(sym)($at)
1820 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1822 // sw $8, %lo(offset)($at)
1823 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1824 // ldc1 $f0, %lo(sym)($at)
1826 // For load instructions we can use the destination register as a temporary
1827 // if base and dst are different (examples 1 and 2) and if the base register
1828 // is general purpose otherwise we must use $at (example 6) and error if it's
1829 // not available. For stores we must use $at (examples 4 and 5) because we
1830 // must not clobber the source register setting up the offset.
1831 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1832 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1833 unsigned RegClassIDOp0 =
1834 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1835 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1836 (RegClassIDOp0 == Mips::GPR64RegClassID);
1837 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1838 TmpRegNum = RegOpNum;
1840 int AT = getATReg(IDLoc);
1841 // At this point we need AT to perform the expansions and we exit if it is
1846 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1849 TempInst.setOpcode(Mips::LUi);
1850 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1852 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1854 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1855 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1856 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1857 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1859 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1861 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1862 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1865 // Add the instruction to the list.
1866 Instructions.push_back(TempInst);
1867 // Prepare TempInst for next instruction.
1869 // Add temp register to base.
1870 TempInst.setOpcode(Mips::ADDu);
1871 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1872 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1873 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1874 Instructions.push_back(TempInst);
1876 // And finally, create original instruction with low part
1877 // of offset and new base.
1878 TempInst.setOpcode(Inst.getOpcode());
1879 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1880 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1882 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1884 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1885 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1886 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1888 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1890 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1891 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1894 Instructions.push_back(TempInst);
1898 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1899 // As described by the Mips32r2 spec, the registers Rd and Rs for
1900 // jalr.hb must be different.
1901 unsigned Opcode = Inst.getOpcode();
1903 if (Opcode == Mips::JALR_HB &&
1904 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1905 return Match_RequiresDifferentSrcAndDst;
1907 return Match_Success;
1910 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1911 OperandVector &Operands,
1913 uint64_t &ErrorInfo,
1914 bool MatchingInlineAsm) {
1917 SmallVector<MCInst, 8> Instructions;
1918 unsigned MatchResult =
1919 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1921 switch (MatchResult) {
1922 case Match_Success: {
1923 if (processInstruction(Inst, IDLoc, Instructions))
1925 for (unsigned i = 0; i < Instructions.size(); i++)
1926 Out.EmitInstruction(Instructions[i], STI);
1929 case Match_MissingFeature:
1930 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1932 case Match_InvalidOperand: {
1933 SMLoc ErrorLoc = IDLoc;
1934 if (ErrorInfo != ~0ULL) {
1935 if (ErrorInfo >= Operands.size())
1936 return Error(IDLoc, "too few operands for instruction");
1938 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1939 if (ErrorLoc == SMLoc())
1943 return Error(ErrorLoc, "invalid operand for instruction");
1945 case Match_MnemonicFail:
1946 return Error(IDLoc, "invalid instruction");
1947 case Match_RequiresDifferentSrcAndDst:
1948 return Error(IDLoc, "source and destination must be different");
1951 llvm_unreachable("Implement any new match types added!");
1954 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1955 if ((RegIndex != 0) &&
1956 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1958 Warning(Loc, "used $at without \".set noat\"");
1960 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1961 Twine(RegIndex) + "\"");
1966 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1967 SMRange Range, bool ShowColors) {
1968 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1969 Range, SMFixIt(Range, FixMsg),
1973 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1976 CC = StringSwitch<unsigned>(Name)
2012 if (!(isABI_N32() || isABI_N64()))
2015 if (12 <= CC && CC <= 15) {
2016 // Name is one of t4-t7
2017 AsmToken RegTok = getLexer().peekTok();
2018 SMRange RegRange = RegTok.getLocRange();
2020 StringRef FixedName = StringSwitch<StringRef>(Name)
2026 assert(FixedName != "" && "Register name is not one of t4-t7.");
2028 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
2029 "Did you mean $" + FixedName + "?", RegRange);
2032 // Although SGI documentation just cuts out t0-t3 for n32/n64,
2033 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
2034 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
2035 if (8 <= CC && CC <= 11)
2039 CC = StringSwitch<unsigned>(Name)
2051 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
2054 CC = StringSwitch<unsigned>(Name)
2055 .Case("hwr_cpunum", 0)
2056 .Case("hwr_synci_step", 1)
2058 .Case("hwr_ccres", 3)
2059 .Case("hwr_ulr", 29)
2065 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
2067 if (Name[0] == 'f') {
2068 StringRef NumString = Name.substr(1);
2070 if (NumString.getAsInteger(10, IntVal))
2071 return -1; // This is not an integer.
2072 if (IntVal > 31) // Maximum index for fpu register.
2079 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
2081 if (Name.startswith("fcc")) {
2082 StringRef NumString = Name.substr(3);
2084 if (NumString.getAsInteger(10, IntVal))
2085 return -1; // This is not an integer.
2086 if (IntVal > 7) // There are only 8 fcc registers.
2093 int MipsAsmParser::matchACRegisterName(StringRef Name) {
2095 if (Name.startswith("ac")) {
2096 StringRef NumString = Name.substr(2);
2098 if (NumString.getAsInteger(10, IntVal))
2099 return -1; // This is not an integer.
2100 if (IntVal > 3) // There are only 3 acc registers.
2107 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
2110 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
2119 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
2122 CC = StringSwitch<unsigned>(Name)
2125 .Case("msaaccess", 2)
2127 .Case("msamodify", 4)
2128 .Case("msarequest", 5)
2130 .Case("msaunmap", 7)
2136 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
2144 int MipsAsmParser::getATReg(SMLoc Loc) {
2145 int AT = AssemblerOptions.back()->getATRegNum();
2147 reportParseError(Loc,
2148 "pseudo-instruction requires $at, which is not available");
2152 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
2153 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
2156 unsigned MipsAsmParser::getGPR(int RegNo) {
2157 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
2161 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
2163 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
2166 return getReg(RegClass, RegNum);
2169 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
2170 MCAsmParser &Parser = getParser();
2171 DEBUG(dbgs() << "parseOperand\n");
2173 // Check if the current operand has a custom associated parser, if so, try to
2174 // custom parse the operand, or fallback to the general approach.
2175 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
2176 if (ResTy == MatchOperand_Success)
2178 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2179 // there was a match, but an error occurred, in which case, just return that
2180 // the operand parsing failed.
2181 if (ResTy == MatchOperand_ParseFail)
2184 DEBUG(dbgs() << ".. Generic Parser\n");
2186 switch (getLexer().getKind()) {
2188 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2190 case AsmToken::Dollar: {
2191 // Parse the register.
2192 SMLoc S = Parser.getTok().getLoc();
2194 // Almost all registers have been parsed by custom parsers. There is only
2195 // one exception to this. $zero (and it's alias $0) will reach this point
2196 // for div, divu, and similar instructions because it is not an operand
2197 // to the instruction definition but an explicit register. Special case
2198 // this situation for now.
2199 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2202 // Maybe it is a symbol reference.
2203 StringRef Identifier;
2204 if (Parser.parseIdentifier(Identifier))
2207 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2208 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2209 // Otherwise create a symbol reference.
2211 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2213 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2216 // Else drop to expression parsing.
2217 case AsmToken::LParen:
2218 case AsmToken::Minus:
2219 case AsmToken::Plus:
2220 case AsmToken::Integer:
2221 case AsmToken::Tilde:
2222 case AsmToken::String: {
2223 DEBUG(dbgs() << ".. generic integer\n");
2224 OperandMatchResultTy ResTy = parseImm(Operands);
2225 return ResTy != MatchOperand_Success;
2227 case AsmToken::Percent: {
2228 // It is a symbol reference or constant expression.
2229 const MCExpr *IdVal;
2230 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2231 if (parseRelocOperand(IdVal))
2234 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2236 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2238 } // case AsmToken::Percent
2239 } // switch(getLexer().getKind())
2243 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2244 StringRef RelocStr) {
2246 // Check the type of the expression.
2247 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2248 // It's a constant, evaluate reloc value.
2250 switch (getVariantKind(RelocStr)) {
2251 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2252 // Get the 1st 16-bits.
2253 Val = MCE->getValue() & 0xffff;
2255 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2256 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2257 // 16 bits being negative.
2258 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2260 case MCSymbolRefExpr::VK_Mips_HIGHER:
2261 // Get the 3rd 16-bits.
2262 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2264 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2265 // Get the 4th 16-bits.
2266 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2269 report_fatal_error("unsupported reloc value");
2271 return MCConstantExpr::Create(Val, getContext());
2274 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2275 // It's a symbol, create a symbolic expression from the symbol.
2276 StringRef Symbol = MSRE->getSymbol().getName();
2277 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2278 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2282 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2283 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2285 // Try to create target expression.
2286 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2287 return MipsMCExpr::Create(VK, Expr, getContext());
2289 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2290 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2291 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2295 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2296 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2297 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2300 // Just return the original expression.
2304 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2306 switch (Expr->getKind()) {
2307 case MCExpr::Constant:
2309 case MCExpr::SymbolRef:
2310 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2311 case MCExpr::Binary:
2312 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2313 if (!isEvaluated(BE->getLHS()))
2315 return isEvaluated(BE->getRHS());
2318 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2319 case MCExpr::Target:
2325 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2326 MCAsmParser &Parser = getParser();
2327 Parser.Lex(); // Eat the % token.
2328 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2329 if (Tok.isNot(AsmToken::Identifier))
2332 std::string Str = Tok.getIdentifier().str();
2334 Parser.Lex(); // Eat the identifier.
2335 // Now make an expression from the rest of the operand.
2336 const MCExpr *IdVal;
2339 if (getLexer().getKind() == AsmToken::LParen) {
2341 Parser.Lex(); // Eat the '(' token.
2342 if (getLexer().getKind() == AsmToken::Percent) {
2343 Parser.Lex(); // Eat the % token.
2344 const AsmToken &nextTok = Parser.getTok();
2345 if (nextTok.isNot(AsmToken::Identifier))
2348 Str += nextTok.getIdentifier();
2349 Parser.Lex(); // Eat the identifier.
2350 if (getLexer().getKind() != AsmToken::LParen)
2355 if (getParser().parseParenExpression(IdVal, EndLoc))
2358 while (getLexer().getKind() == AsmToken::RParen)
2359 Parser.Lex(); // Eat the ')' token.
2362 return true; // Parenthesis must follow the relocation operand.
2364 Res = evaluateRelocExpr(IdVal, Str);
2368 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2370 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2371 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2372 if (ResTy == MatchOperand_Success) {
2373 assert(Operands.size() == 1);
2374 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2375 StartLoc = Operand.getStartLoc();
2376 EndLoc = Operand.getEndLoc();
2378 // AFAIK, we only support numeric registers and named GPR's in CFI
2380 // Don't worry about eating tokens before failing. Using an unrecognised
2381 // register is a parse error.
2382 if (Operand.isGPRAsmReg()) {
2383 // Resolve to GPR32 or GPR64 appropriately.
2384 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2387 return (RegNo == (unsigned)-1);
2390 assert(Operands.size() == 0);
2391 return (RegNo == (unsigned)-1);
2394 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2395 MCAsmParser &Parser = getParser();
2399 while (getLexer().getKind() == AsmToken::LParen)
2402 switch (getLexer().getKind()) {
2405 case AsmToken::Identifier:
2406 case AsmToken::LParen:
2407 case AsmToken::Integer:
2408 case AsmToken::Minus:
2409 case AsmToken::Plus:
2411 Result = getParser().parseParenExpression(Res, S);
2413 Result = (getParser().parseExpression(Res));
2414 while (getLexer().getKind() == AsmToken::RParen)
2417 case AsmToken::Percent:
2418 Result = parseRelocOperand(Res);
2423 MipsAsmParser::OperandMatchResultTy
2424 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2425 MCAsmParser &Parser = getParser();
2426 DEBUG(dbgs() << "parseMemOperand\n");
2427 const MCExpr *IdVal = nullptr;
2429 bool isParenExpr = false;
2430 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2431 // First operand is the offset.
2432 S = Parser.getTok().getLoc();
2434 if (getLexer().getKind() == AsmToken::LParen) {
2439 if (getLexer().getKind() != AsmToken::Dollar) {
2440 if (parseMemOffset(IdVal, isParenExpr))
2441 return MatchOperand_ParseFail;
2443 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2444 if (Tok.isNot(AsmToken::LParen)) {
2445 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2446 if (Mnemonic.getToken() == "la") {
2448 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2449 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2450 return MatchOperand_Success;
2452 if (Tok.is(AsmToken::EndOfStatement)) {
2454 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2456 // Zero register assumed, add a memory operand with ZERO as its base.
2457 // "Base" will be managed by k_Memory.
2458 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2461 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2462 return MatchOperand_Success;
2464 Error(Parser.getTok().getLoc(), "'(' expected");
2465 return MatchOperand_ParseFail;
2468 Parser.Lex(); // Eat the '(' token.
2471 Res = parseAnyRegister(Operands);
2472 if (Res != MatchOperand_Success)
2475 if (Parser.getTok().isNot(AsmToken::RParen)) {
2476 Error(Parser.getTok().getLoc(), "')' expected");
2477 return MatchOperand_ParseFail;
2480 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2482 Parser.Lex(); // Eat the ')' token.
2485 IdVal = MCConstantExpr::Create(0, getContext());
2487 // Replace the register operand with the memory operand.
2488 std::unique_ptr<MipsOperand> op(
2489 static_cast<MipsOperand *>(Operands.back().release()));
2490 // Remove the register from the operands.
2491 // "op" will be managed by k_Memory.
2492 Operands.pop_back();
2493 // Add the memory operand.
2494 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2496 if (IdVal->EvaluateAsAbsolute(Imm))
2497 IdVal = MCConstantExpr::Create(Imm, getContext());
2498 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2499 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2503 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2504 return MatchOperand_Success;
2507 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2508 MCAsmParser &Parser = getParser();
2509 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2511 SMLoc S = Parser.getTok().getLoc();
2513 if (Sym->isVariable())
2514 Expr = Sym->getVariableValue();
2517 if (Expr->getKind() == MCExpr::SymbolRef) {
2518 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2519 StringRef DefSymbol = Ref->getSymbol().getName();
2520 if (DefSymbol.startswith("$")) {
2521 OperandMatchResultTy ResTy =
2522 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2523 if (ResTy == MatchOperand_Success) {
2526 } else if (ResTy == MatchOperand_ParseFail)
2527 llvm_unreachable("Should never ParseFail");
2530 } else if (Expr->getKind() == MCExpr::Constant) {
2532 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2534 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2541 MipsAsmParser::OperandMatchResultTy
2542 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2543 StringRef Identifier,
2545 int Index = matchCPURegisterName(Identifier);
2547 Operands.push_back(MipsOperand::createGPRReg(
2548 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2549 return MatchOperand_Success;
2552 Index = matchHWRegsRegisterName(Identifier);
2554 Operands.push_back(MipsOperand::createHWRegsReg(
2555 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2556 return MatchOperand_Success;
2559 Index = matchFPURegisterName(Identifier);
2561 Operands.push_back(MipsOperand::createFGRReg(
2562 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2563 return MatchOperand_Success;
2566 Index = matchFCCRegisterName(Identifier);
2568 Operands.push_back(MipsOperand::createFCCReg(
2569 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2570 return MatchOperand_Success;
2573 Index = matchACRegisterName(Identifier);
2575 Operands.push_back(MipsOperand::createACCReg(
2576 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2577 return MatchOperand_Success;
2580 Index = matchMSA128RegisterName(Identifier);
2582 Operands.push_back(MipsOperand::createMSA128Reg(
2583 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2584 return MatchOperand_Success;
2587 Index = matchMSA128CtrlRegisterName(Identifier);
2589 Operands.push_back(MipsOperand::createMSACtrlReg(
2590 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2591 return MatchOperand_Success;
2594 return MatchOperand_NoMatch;
2597 MipsAsmParser::OperandMatchResultTy
2598 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2599 MCAsmParser &Parser = getParser();
2600 auto Token = Parser.getLexer().peekTok(false);
2602 if (Token.is(AsmToken::Identifier)) {
2603 DEBUG(dbgs() << ".. identifier\n");
2604 StringRef Identifier = Token.getIdentifier();
2605 OperandMatchResultTy ResTy =
2606 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2608 } else if (Token.is(AsmToken::Integer)) {
2609 DEBUG(dbgs() << ".. integer\n");
2610 Operands.push_back(MipsOperand::createNumericReg(
2611 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2613 return MatchOperand_Success;
2616 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2618 return MatchOperand_NoMatch;
2621 MipsAsmParser::OperandMatchResultTy
2622 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2623 MCAsmParser &Parser = getParser();
2624 DEBUG(dbgs() << "parseAnyRegister\n");
2626 auto Token = Parser.getTok();
2628 SMLoc S = Token.getLoc();
2630 if (Token.isNot(AsmToken::Dollar)) {
2631 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2632 if (Token.is(AsmToken::Identifier)) {
2633 if (searchSymbolAlias(Operands))
2634 return MatchOperand_Success;
2636 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2637 return MatchOperand_NoMatch;
2639 DEBUG(dbgs() << ".. $\n");
2641 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2642 if (ResTy == MatchOperand_Success) {
2644 Parser.Lex(); // identifier
2649 MipsAsmParser::OperandMatchResultTy
2650 MipsAsmParser::parseImm(OperandVector &Operands) {
2651 MCAsmParser &Parser = getParser();
2652 switch (getLexer().getKind()) {
2654 return MatchOperand_NoMatch;
2655 case AsmToken::LParen:
2656 case AsmToken::Minus:
2657 case AsmToken::Plus:
2658 case AsmToken::Integer:
2659 case AsmToken::Tilde:
2660 case AsmToken::String:
2664 const MCExpr *IdVal;
2665 SMLoc S = Parser.getTok().getLoc();
2666 if (getParser().parseExpression(IdVal))
2667 return MatchOperand_ParseFail;
2669 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2670 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2671 return MatchOperand_Success;
2674 MipsAsmParser::OperandMatchResultTy
2675 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2676 MCAsmParser &Parser = getParser();
2677 DEBUG(dbgs() << "parseJumpTarget\n");
2679 SMLoc S = getLexer().getLoc();
2681 // Integers and expressions are acceptable
2682 OperandMatchResultTy ResTy = parseImm(Operands);
2683 if (ResTy != MatchOperand_NoMatch)
2686 // Registers are a valid target and have priority over symbols.
2687 ResTy = parseAnyRegister(Operands);
2688 if (ResTy != MatchOperand_NoMatch)
2691 const MCExpr *Expr = nullptr;
2692 if (Parser.parseExpression(Expr)) {
2693 // We have no way of knowing if a symbol was consumed so we must ParseFail
2694 return MatchOperand_ParseFail;
2697 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2698 return MatchOperand_Success;
2701 MipsAsmParser::OperandMatchResultTy
2702 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2703 MCAsmParser &Parser = getParser();
2704 const MCExpr *IdVal;
2705 // If the first token is '$' we may have register operand.
2706 if (Parser.getTok().is(AsmToken::Dollar))
2707 return MatchOperand_NoMatch;
2708 SMLoc S = Parser.getTok().getLoc();
2709 if (getParser().parseExpression(IdVal))
2710 return MatchOperand_ParseFail;
2711 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2712 assert(MCE && "Unexpected MCExpr type.");
2713 int64_t Val = MCE->getValue();
2714 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2715 Operands.push_back(MipsOperand::CreateImm(
2716 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2717 return MatchOperand_Success;
2720 MipsAsmParser::OperandMatchResultTy
2721 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2722 MCAsmParser &Parser = getParser();
2723 switch (getLexer().getKind()) {
2725 return MatchOperand_NoMatch;
2726 case AsmToken::LParen:
2727 case AsmToken::Plus:
2728 case AsmToken::Minus:
2729 case AsmToken::Integer:
2734 SMLoc S = Parser.getTok().getLoc();
2736 if (getParser().parseExpression(Expr))
2737 return MatchOperand_ParseFail;
2740 if (!Expr->EvaluateAsAbsolute(Val)) {
2741 Error(S, "expected immediate value");
2742 return MatchOperand_ParseFail;
2745 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2746 // and because the CPU always adds one to the immediate field, the allowed
2747 // range becomes 1..4. We'll only check the range here and will deal
2748 // with the addition/subtraction when actually decoding/encoding
2750 if (Val < 1 || Val > 4) {
2751 Error(S, "immediate not in range (1..4)");
2752 return MatchOperand_ParseFail;
2756 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2757 return MatchOperand_Success;
2760 MipsAsmParser::OperandMatchResultTy
2761 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2762 MCAsmParser &Parser = getParser();
2763 SmallVector<unsigned, 10> Regs;
2765 unsigned PrevReg = Mips::NoRegister;
2766 bool RegRange = false;
2767 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2769 if (Parser.getTok().isNot(AsmToken::Dollar))
2770 return MatchOperand_ParseFail;
2772 SMLoc S = Parser.getTok().getLoc();
2773 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2774 SMLoc E = getLexer().getLoc();
2775 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2776 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2778 // Remove last register operand because registers from register range
2779 // should be inserted first.
2780 if (RegNo == Mips::RA) {
2781 Regs.push_back(RegNo);
2783 unsigned TmpReg = PrevReg + 1;
2784 while (TmpReg <= RegNo) {
2785 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2786 Error(E, "invalid register operand");
2787 return MatchOperand_ParseFail;
2791 Regs.push_back(TmpReg++);
2797 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2798 (RegNo != Mips::RA)) {
2799 Error(E, "$16 or $31 expected");
2800 return MatchOperand_ParseFail;
2801 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2802 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2803 Error(E, "invalid register operand");
2804 return MatchOperand_ParseFail;
2805 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2806 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2807 Error(E, "consecutive register numbers expected");
2808 return MatchOperand_ParseFail;
2811 Regs.push_back(RegNo);
2814 if (Parser.getTok().is(AsmToken::Minus))
2817 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2818 !Parser.getTok().isNot(AsmToken::Comma)) {
2819 Error(E, "',' or '-' expected");
2820 return MatchOperand_ParseFail;
2823 Lex(); // Consume comma or minus
2824 if (Parser.getTok().isNot(AsmToken::Dollar))
2830 SMLoc E = Parser.getTok().getLoc();
2831 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2832 parseMemOperand(Operands);
2833 return MatchOperand_Success;
2836 MipsAsmParser::OperandMatchResultTy
2837 MipsAsmParser::parseRegisterPair(OperandVector &Operands) {
2838 MCAsmParser &Parser = getParser();
2840 SMLoc S = Parser.getTok().getLoc();
2841 if (parseAnyRegister(Operands) != MatchOperand_Success)
2842 return MatchOperand_ParseFail;
2844 SMLoc E = Parser.getTok().getLoc();
2845 MipsOperand &Op = static_cast<MipsOperand &>(*Operands.back());
2846 unsigned Reg = Op.getGPR32Reg();
2847 Operands.pop_back();
2848 Operands.push_back(MipsOperand::CreateRegPair(Reg, S, E, *this));
2849 return MatchOperand_Success;
2852 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2854 MCSymbolRefExpr::VariantKind VK =
2855 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2856 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2857 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2858 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2859 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2860 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2861 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2862 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2863 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2864 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2865 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2866 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2867 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2868 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2869 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2870 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2871 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2872 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2873 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2874 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2875 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2876 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2877 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2878 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2879 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2880 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2881 .Default(MCSymbolRefExpr::VK_None);
2883 assert(VK != MCSymbolRefExpr::VK_None);
2888 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2890 /// ::= '(', register, ')'
2891 /// handle it before we iterate so we don't get tripped up by the lack of
2893 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2894 MCAsmParser &Parser = getParser();
2895 if (getLexer().is(AsmToken::LParen)) {
2897 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2899 if (parseOperand(Operands, Name)) {
2900 SMLoc Loc = getLexer().getLoc();
2901 Parser.eatToEndOfStatement();
2902 return Error(Loc, "unexpected token in argument list");
2904 if (Parser.getTok().isNot(AsmToken::RParen)) {
2905 SMLoc Loc = getLexer().getLoc();
2906 Parser.eatToEndOfStatement();
2907 return Error(Loc, "unexpected token, expected ')'");
2910 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2916 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2917 /// either one of these.
2918 /// ::= '[', register, ']'
2919 /// ::= '[', integer, ']'
2920 /// handle it before we iterate so we don't get tripped up by the lack of
2922 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2923 OperandVector &Operands) {
2924 MCAsmParser &Parser = getParser();
2925 if (getLexer().is(AsmToken::LBrac)) {
2927 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2929 if (parseOperand(Operands, Name)) {
2930 SMLoc Loc = getLexer().getLoc();
2931 Parser.eatToEndOfStatement();
2932 return Error(Loc, "unexpected token in argument list");
2934 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2935 SMLoc Loc = getLexer().getLoc();
2936 Parser.eatToEndOfStatement();
2937 return Error(Loc, "unexpected token, expected ']'");
2940 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2946 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2947 SMLoc NameLoc, OperandVector &Operands) {
2948 MCAsmParser &Parser = getParser();
2949 DEBUG(dbgs() << "ParseInstruction\n");
2951 // We have reached first instruction, module directive are now forbidden.
2952 getTargetStreamer().forbidModuleDirective();
2954 // Check if we have valid mnemonic
2955 if (!mnemonicIsValid(Name, 0)) {
2956 Parser.eatToEndOfStatement();
2957 return Error(NameLoc, "unknown instruction");
2959 // First operand in MCInst is instruction mnemonic.
2960 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2962 // Read the remaining operands.
2963 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2964 // Read the first operand.
2965 if (parseOperand(Operands, Name)) {
2966 SMLoc Loc = getLexer().getLoc();
2967 Parser.eatToEndOfStatement();
2968 return Error(Loc, "unexpected token in argument list");
2970 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2972 // AFAIK, parenthesis suffixes are never on the first operand
2974 while (getLexer().is(AsmToken::Comma)) {
2975 Parser.Lex(); // Eat the comma.
2976 // Parse and remember the operand.
2977 if (parseOperand(Operands, Name)) {
2978 SMLoc Loc = getLexer().getLoc();
2979 Parser.eatToEndOfStatement();
2980 return Error(Loc, "unexpected token in argument list");
2982 // Parse bracket and parenthesis suffixes before we iterate
2983 if (getLexer().is(AsmToken::LBrac)) {
2984 if (parseBracketSuffix(Name, Operands))
2986 } else if (getLexer().is(AsmToken::LParen) &&
2987 parseParenSuffix(Name, Operands))
2991 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2992 SMLoc Loc = getLexer().getLoc();
2993 Parser.eatToEndOfStatement();
2994 return Error(Loc, "unexpected token in argument list");
2996 Parser.Lex(); // Consume the EndOfStatement.
3000 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
3001 MCAsmParser &Parser = getParser();
3002 SMLoc Loc = getLexer().getLoc();
3003 Parser.eatToEndOfStatement();
3004 return Error(Loc, ErrorMsg);
3007 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
3008 return Error(Loc, ErrorMsg);
3011 bool MipsAsmParser::parseSetNoAtDirective() {
3012 MCAsmParser &Parser = getParser();
3013 // Line should look like: ".set noat".
3015 AssemblerOptions.back()->setATReg(0);
3018 // If this is not the end of the statement, report an error.
3019 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3020 reportParseError("unexpected token, expected end of statement");
3023 Parser.Lex(); // Consume the EndOfStatement.
3027 bool MipsAsmParser::parseSetAtDirective() {
3028 MCAsmParser &Parser = getParser();
3029 // Line can be .set at - defaults to $1
3033 if (getLexer().is(AsmToken::EndOfStatement)) {
3034 AssemblerOptions.back()->setATReg(1);
3035 Parser.Lex(); // Consume the EndOfStatement.
3037 } else if (getLexer().is(AsmToken::Equal)) {
3038 getParser().Lex(); // Eat the '='.
3039 if (getLexer().isNot(AsmToken::Dollar)) {
3040 reportParseError("unexpected token, expected dollar sign '$'");
3043 Parser.Lex(); // Eat the '$'.
3044 const AsmToken &Reg = Parser.getTok();
3045 if (Reg.is(AsmToken::Identifier)) {
3046 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
3047 } else if (Reg.is(AsmToken::Integer)) {
3048 AtRegNo = Reg.getIntVal();
3050 reportParseError("unexpected token, expected identifier or integer");
3054 if (AtRegNo < 0 || AtRegNo > 31) {
3055 reportParseError("unexpected token in statement");
3059 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
3060 reportParseError("invalid register");
3063 getParser().Lex(); // Eat the register.
3065 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3066 reportParseError("unexpected token, expected end of statement");
3069 Parser.Lex(); // Consume the EndOfStatement.
3072 reportParseError("unexpected token in statement");
3077 bool MipsAsmParser::parseSetReorderDirective() {
3078 MCAsmParser &Parser = getParser();
3080 // If this is not the end of the statement, report an error.
3081 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3082 reportParseError("unexpected token, expected end of statement");
3085 AssemblerOptions.back()->setReorder();
3086 getTargetStreamer().emitDirectiveSetReorder();
3087 Parser.Lex(); // Consume the EndOfStatement.
3091 bool MipsAsmParser::parseSetNoReorderDirective() {
3092 MCAsmParser &Parser = getParser();
3094 // If this is not the end of the statement, report an error.
3095 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3096 reportParseError("unexpected token, expected end of statement");
3099 AssemblerOptions.back()->setNoReorder();
3100 getTargetStreamer().emitDirectiveSetNoReorder();
3101 Parser.Lex(); // Consume the EndOfStatement.
3105 bool MipsAsmParser::parseSetMacroDirective() {
3106 MCAsmParser &Parser = getParser();
3108 // If this is not the end of the statement, report an error.
3109 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3110 reportParseError("unexpected token, expected end of statement");
3113 AssemblerOptions.back()->setMacro();
3114 Parser.Lex(); // Consume the EndOfStatement.
3118 bool MipsAsmParser::parseSetNoMacroDirective() {
3119 MCAsmParser &Parser = getParser();
3121 // If this is not the end of the statement, report an error.
3122 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3123 reportParseError("unexpected token, expected end of statement");
3126 if (AssemblerOptions.back()->isReorder()) {
3127 reportParseError("`noreorder' must be set before `nomacro'");
3130 AssemblerOptions.back()->setNoMacro();
3131 Parser.Lex(); // Consume the EndOfStatement.
3135 bool MipsAsmParser::parseSetMsaDirective() {
3136 MCAsmParser &Parser = getParser();
3139 // If this is not the end of the statement, report an error.
3140 if (getLexer().isNot(AsmToken::EndOfStatement))
3141 return reportParseError("unexpected token, expected end of statement");
3143 setFeatureBits(Mips::FeatureMSA, "msa");
3144 getTargetStreamer().emitDirectiveSetMsa();
3148 bool MipsAsmParser::parseSetNoMsaDirective() {
3149 MCAsmParser &Parser = getParser();
3152 // If this is not the end of the statement, report an error.
3153 if (getLexer().isNot(AsmToken::EndOfStatement))
3154 return reportParseError("unexpected token, expected end of statement");
3156 clearFeatureBits(Mips::FeatureMSA, "msa");
3157 getTargetStreamer().emitDirectiveSetNoMsa();
3161 bool MipsAsmParser::parseSetNoDspDirective() {
3162 MCAsmParser &Parser = getParser();
3163 Parser.Lex(); // Eat "nodsp".
3165 // If this is not the end of the statement, report an error.
3166 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3167 reportParseError("unexpected token, expected end of statement");
3171 clearFeatureBits(Mips::FeatureDSP, "dsp");
3172 getTargetStreamer().emitDirectiveSetNoDsp();
3176 bool MipsAsmParser::parseSetMips16Directive() {
3177 MCAsmParser &Parser = getParser();
3178 Parser.Lex(); // Eat "mips16".
3180 // If this is not the end of the statement, report an error.
3181 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3182 reportParseError("unexpected token, expected end of statement");
3186 setFeatureBits(Mips::FeatureMips16, "mips16");
3187 getTargetStreamer().emitDirectiveSetMips16();
3188 Parser.Lex(); // Consume the EndOfStatement.
3192 bool MipsAsmParser::parseSetNoMips16Directive() {
3193 MCAsmParser &Parser = getParser();
3194 Parser.Lex(); // Eat "nomips16".
3196 // If this is not the end of the statement, report an error.
3197 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3198 reportParseError("unexpected token, expected end of statement");
3202 clearFeatureBits(Mips::FeatureMips16, "mips16");
3203 getTargetStreamer().emitDirectiveSetNoMips16();
3204 Parser.Lex(); // Consume the EndOfStatement.
3208 bool MipsAsmParser::parseSetFpDirective() {
3209 MCAsmParser &Parser = getParser();
3210 MipsABIFlagsSection::FpABIKind FpAbiVal;
3211 // Line can be: .set fp=32
3214 Parser.Lex(); // Eat fp token
3215 AsmToken Tok = Parser.getTok();
3216 if (Tok.isNot(AsmToken::Equal)) {
3217 reportParseError("unexpected token, expected equals sign '='");
3220 Parser.Lex(); // Eat '=' token.
3221 Tok = Parser.getTok();
3223 if (!parseFpABIValue(FpAbiVal, ".set"))
3226 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3227 reportParseError("unexpected token, expected end of statement");
3230 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3231 Parser.Lex(); // Consume the EndOfStatement.
3235 bool MipsAsmParser::parseSetPopDirective() {
3236 MCAsmParser &Parser = getParser();
3237 SMLoc Loc = getLexer().getLoc();
3240 if (getLexer().isNot(AsmToken::EndOfStatement))
3241 return reportParseError("unexpected token, expected end of statement");
3243 // Always keep an element on the options "stack" to prevent the user
3244 // from changing the initial options. This is how we remember them.
3245 if (AssemblerOptions.size() == 2)
3246 return reportParseError(Loc, ".set pop with no .set push");
3248 AssemblerOptions.pop_back();
3249 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3251 getTargetStreamer().emitDirectiveSetPop();
3255 bool MipsAsmParser::parseSetPushDirective() {
3256 MCAsmParser &Parser = getParser();
3258 if (getLexer().isNot(AsmToken::EndOfStatement))
3259 return reportParseError("unexpected token, expected end of statement");
3261 // Create a copy of the current assembler options environment and push it.
3262 AssemblerOptions.push_back(
3263 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3265 getTargetStreamer().emitDirectiveSetPush();
3269 bool MipsAsmParser::parseSetAssignment() {
3271 const MCExpr *Value;
3272 MCAsmParser &Parser = getParser();
3274 if (Parser.parseIdentifier(Name))
3275 reportParseError("expected identifier after .set");
3277 if (getLexer().isNot(AsmToken::Comma))
3278 return reportParseError("unexpected token, expected comma");
3281 if (Parser.parseExpression(Value))
3282 return reportParseError("expected valid expression after comma");
3284 // Check if the Name already exists as a symbol.
3285 MCSymbol *Sym = getContext().LookupSymbol(Name);
3287 return reportParseError("symbol already defined");
3288 Sym = getContext().GetOrCreateSymbol(Name);
3289 Sym->setVariableValue(Value);
3294 bool MipsAsmParser::parseSetMips0Directive() {
3295 MCAsmParser &Parser = getParser();
3297 if (getLexer().isNot(AsmToken::EndOfStatement))
3298 return reportParseError("unexpected token, expected end of statement");
3300 // Reset assembler options to their initial values.
3301 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3302 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3304 getTargetStreamer().emitDirectiveSetMips0();
3308 bool MipsAsmParser::parseSetArchDirective() {
3309 MCAsmParser &Parser = getParser();
3311 if (getLexer().isNot(AsmToken::Equal))
3312 return reportParseError("unexpected token, expected equals sign");
3316 if (Parser.parseIdentifier(Arch))
3317 return reportParseError("expected arch identifier");
3319 StringRef ArchFeatureName =
3320 StringSwitch<StringRef>(Arch)
3321 .Case("mips1", "mips1")
3322 .Case("mips2", "mips2")
3323 .Case("mips3", "mips3")
3324 .Case("mips4", "mips4")
3325 .Case("mips5", "mips5")
3326 .Case("mips32", "mips32")
3327 .Case("mips32r2", "mips32r2")
3328 .Case("mips32r6", "mips32r6")
3329 .Case("mips64", "mips64")
3330 .Case("mips64r2", "mips64r2")
3331 .Case("mips64r6", "mips64r6")
3332 .Case("cnmips", "cnmips")
3333 .Case("r4000", "mips3") // This is an implementation of Mips3.
3336 if (ArchFeatureName.empty())
3337 return reportParseError("unsupported architecture");
3339 selectArch(ArchFeatureName);
3340 getTargetStreamer().emitDirectiveSetArch(Arch);
3344 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3345 MCAsmParser &Parser = getParser();
3347 if (getLexer().isNot(AsmToken::EndOfStatement))
3348 return reportParseError("unexpected token, expected end of statement");
3352 llvm_unreachable("Unimplemented feature");
3353 case Mips::FeatureDSP:
3354 setFeatureBits(Mips::FeatureDSP, "dsp");
3355 getTargetStreamer().emitDirectiveSetDsp();
3357 case Mips::FeatureMicroMips:
3358 getTargetStreamer().emitDirectiveSetMicroMips();
3360 case Mips::FeatureMips1:
3361 selectArch("mips1");
3362 getTargetStreamer().emitDirectiveSetMips1();
3364 case Mips::FeatureMips2:
3365 selectArch("mips2");
3366 getTargetStreamer().emitDirectiveSetMips2();
3368 case Mips::FeatureMips3:
3369 selectArch("mips3");
3370 getTargetStreamer().emitDirectiveSetMips3();
3372 case Mips::FeatureMips4:
3373 selectArch("mips4");
3374 getTargetStreamer().emitDirectiveSetMips4();
3376 case Mips::FeatureMips5:
3377 selectArch("mips5");
3378 getTargetStreamer().emitDirectiveSetMips5();
3380 case Mips::FeatureMips32:
3381 selectArch("mips32");
3382 getTargetStreamer().emitDirectiveSetMips32();
3384 case Mips::FeatureMips32r2:
3385 selectArch("mips32r2");
3386 getTargetStreamer().emitDirectiveSetMips32R2();
3388 case Mips::FeatureMips32r6:
3389 selectArch("mips32r6");
3390 getTargetStreamer().emitDirectiveSetMips32R6();
3392 case Mips::FeatureMips64:
3393 selectArch("mips64");
3394 getTargetStreamer().emitDirectiveSetMips64();
3396 case Mips::FeatureMips64r2:
3397 selectArch("mips64r2");
3398 getTargetStreamer().emitDirectiveSetMips64R2();
3400 case Mips::FeatureMips64r6:
3401 selectArch("mips64r6");
3402 getTargetStreamer().emitDirectiveSetMips64R6();
3408 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3409 MCAsmParser &Parser = getParser();
3410 if (getLexer().isNot(AsmToken::Comma)) {
3411 SMLoc Loc = getLexer().getLoc();
3412 Parser.eatToEndOfStatement();
3413 return Error(Loc, ErrorStr);
3416 Parser.Lex(); // Eat the comma.
3420 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3421 if (AssemblerOptions.back()->isReorder())
3422 Warning(Loc, ".cpload should be inside a noreorder section");
3424 if (inMips16Mode()) {
3425 reportParseError(".cpload is not supported in Mips16 mode");
3429 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3430 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3431 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3432 reportParseError("expected register containing function address");
3436 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3437 if (!RegOpnd.isGPRAsmReg()) {
3438 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3442 // If this is not the end of the statement, report an error.
3443 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3444 reportParseError("unexpected token, expected end of statement");
3448 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3452 bool MipsAsmParser::parseDirectiveCPSetup() {
3453 MCAsmParser &Parser = getParser();
3456 bool SaveIsReg = true;
3458 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3459 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3460 if (ResTy == MatchOperand_NoMatch) {
3461 reportParseError("expected register containing function address");
3462 Parser.eatToEndOfStatement();
3466 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3467 if (!FuncRegOpnd.isGPRAsmReg()) {
3468 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3469 Parser.eatToEndOfStatement();
3473 FuncReg = FuncRegOpnd.getGPR32Reg();
3476 if (!eatComma("unexpected token, expected comma"))
3479 ResTy = parseAnyRegister(TmpReg);
3480 if (ResTy == MatchOperand_NoMatch) {
3481 const AsmToken &Tok = Parser.getTok();
3482 if (Tok.is(AsmToken::Integer)) {
3483 Save = Tok.getIntVal();
3487 reportParseError("expected save register or stack offset");
3488 Parser.eatToEndOfStatement();
3492 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3493 if (!SaveOpnd.isGPRAsmReg()) {
3494 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3495 Parser.eatToEndOfStatement();
3498 Save = SaveOpnd.getGPR32Reg();
3501 if (!eatComma("unexpected token, expected comma"))
3505 if (Parser.parseIdentifier(Name))
3506 reportParseError("expected identifier");
3507 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3509 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3513 bool MipsAsmParser::parseDirectiveNaN() {
3514 MCAsmParser &Parser = getParser();
3515 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3516 const AsmToken &Tok = Parser.getTok();
3518 if (Tok.getString() == "2008") {
3520 getTargetStreamer().emitDirectiveNaN2008();
3522 } else if (Tok.getString() == "legacy") {
3524 getTargetStreamer().emitDirectiveNaNLegacy();
3528 // If we don't recognize the option passed to the .nan
3529 // directive (e.g. no option or unknown option), emit an error.
3530 reportParseError("invalid option in .nan directive");
3534 bool MipsAsmParser::parseDirectiveSet() {
3535 MCAsmParser &Parser = getParser();
3536 // Get the next token.
3537 const AsmToken &Tok = Parser.getTok();
3539 if (Tok.getString() == "noat") {
3540 return parseSetNoAtDirective();
3541 } else if (Tok.getString() == "at") {
3542 return parseSetAtDirective();
3543 } else if (Tok.getString() == "arch") {
3544 return parseSetArchDirective();
3545 } else if (Tok.getString() == "fp") {
3546 return parseSetFpDirective();
3547 } else if (Tok.getString() == "pop") {
3548 return parseSetPopDirective();
3549 } else if (Tok.getString() == "push") {
3550 return parseSetPushDirective();
3551 } else if (Tok.getString() == "reorder") {
3552 return parseSetReorderDirective();
3553 } else if (Tok.getString() == "noreorder") {
3554 return parseSetNoReorderDirective();
3555 } else if (Tok.getString() == "macro") {
3556 return parseSetMacroDirective();
3557 } else if (Tok.getString() == "nomacro") {
3558 return parseSetNoMacroDirective();
3559 } else if (Tok.getString() == "mips16") {
3560 return parseSetMips16Directive();
3561 } else if (Tok.getString() == "nomips16") {
3562 return parseSetNoMips16Directive();
3563 } else if (Tok.getString() == "nomicromips") {
3564 getTargetStreamer().emitDirectiveSetNoMicroMips();
3565 Parser.eatToEndOfStatement();
3567 } else if (Tok.getString() == "micromips") {
3568 return parseSetFeature(Mips::FeatureMicroMips);
3569 } else if (Tok.getString() == "mips0") {
3570 return parseSetMips0Directive();
3571 } else if (Tok.getString() == "mips1") {
3572 return parseSetFeature(Mips::FeatureMips1);
3573 } else if (Tok.getString() == "mips2") {
3574 return parseSetFeature(Mips::FeatureMips2);
3575 } else if (Tok.getString() == "mips3") {
3576 return parseSetFeature(Mips::FeatureMips3);
3577 } else if (Tok.getString() == "mips4") {
3578 return parseSetFeature(Mips::FeatureMips4);
3579 } else if (Tok.getString() == "mips5") {
3580 return parseSetFeature(Mips::FeatureMips5);
3581 } else if (Tok.getString() == "mips32") {
3582 return parseSetFeature(Mips::FeatureMips32);
3583 } else if (Tok.getString() == "mips32r2") {
3584 return parseSetFeature(Mips::FeatureMips32r2);
3585 } else if (Tok.getString() == "mips32r6") {
3586 return parseSetFeature(Mips::FeatureMips32r6);
3587 } else if (Tok.getString() == "mips64") {
3588 return parseSetFeature(Mips::FeatureMips64);
3589 } else if (Tok.getString() == "mips64r2") {
3590 return parseSetFeature(Mips::FeatureMips64r2);
3591 } else if (Tok.getString() == "mips64r6") {
3592 return parseSetFeature(Mips::FeatureMips64r6);
3593 } else if (Tok.getString() == "dsp") {
3594 return parseSetFeature(Mips::FeatureDSP);
3595 } else if (Tok.getString() == "nodsp") {
3596 return parseSetNoDspDirective();
3597 } else if (Tok.getString() == "msa") {
3598 return parseSetMsaDirective();
3599 } else if (Tok.getString() == "nomsa") {
3600 return parseSetNoMsaDirective();
3602 // It is just an identifier, look for an assignment.
3603 parseSetAssignment();
3610 /// parseDataDirective
3611 /// ::= .word [ expression (, expression)* ]
3612 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3613 MCAsmParser &Parser = getParser();
3614 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3616 const MCExpr *Value;
3617 if (getParser().parseExpression(Value))
3620 getParser().getStreamer().EmitValue(Value, Size);
3622 if (getLexer().is(AsmToken::EndOfStatement))
3625 if (getLexer().isNot(AsmToken::Comma))
3626 return Error(L, "unexpected token, expected comma");
3635 /// parseDirectiveGpWord
3636 /// ::= .gpword local_sym
3637 bool MipsAsmParser::parseDirectiveGpWord() {
3638 MCAsmParser &Parser = getParser();
3639 const MCExpr *Value;
3640 // EmitGPRel32Value requires an expression, so we are using base class
3641 // method to evaluate the expression.
3642 if (getParser().parseExpression(Value))
3644 getParser().getStreamer().EmitGPRel32Value(Value);
3646 if (getLexer().isNot(AsmToken::EndOfStatement))
3647 return Error(getLexer().getLoc(),
3648 "unexpected token, expected end of statement");
3649 Parser.Lex(); // Eat EndOfStatement token.
3653 /// parseDirectiveGpDWord
3654 /// ::= .gpdword local_sym
3655 bool MipsAsmParser::parseDirectiveGpDWord() {
3656 MCAsmParser &Parser = getParser();
3657 const MCExpr *Value;
3658 // EmitGPRel64Value requires an expression, so we are using base class
3659 // method to evaluate the expression.
3660 if (getParser().parseExpression(Value))
3662 getParser().getStreamer().EmitGPRel64Value(Value);
3664 if (getLexer().isNot(AsmToken::EndOfStatement))
3665 return Error(getLexer().getLoc(),
3666 "unexpected token, expected end of statement");
3667 Parser.Lex(); // Eat EndOfStatement token.
3671 bool MipsAsmParser::parseDirectiveOption() {
3672 MCAsmParser &Parser = getParser();
3673 // Get the option token.
3674 AsmToken Tok = Parser.getTok();
3675 // At the moment only identifiers are supported.
3676 if (Tok.isNot(AsmToken::Identifier)) {
3677 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3678 Parser.eatToEndOfStatement();
3682 StringRef Option = Tok.getIdentifier();
3684 if (Option == "pic0") {
3685 getTargetStreamer().emitDirectiveOptionPic0();
3687 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3688 Error(Parser.getTok().getLoc(),
3689 "unexpected token, expected end of statement");
3690 Parser.eatToEndOfStatement();
3695 if (Option == "pic2") {
3696 getTargetStreamer().emitDirectiveOptionPic2();
3698 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3699 Error(Parser.getTok().getLoc(),
3700 "unexpected token, expected end of statement");
3701 Parser.eatToEndOfStatement();
3707 Warning(Parser.getTok().getLoc(),
3708 "unknown option, expected 'pic0' or 'pic2'");
3709 Parser.eatToEndOfStatement();
3713 /// parseDirectiveModule
3714 /// ::= .module oddspreg
3715 /// ::= .module nooddspreg
3716 /// ::= .module fp=value
3717 bool MipsAsmParser::parseDirectiveModule() {
3718 MCAsmParser &Parser = getParser();
3719 MCAsmLexer &Lexer = getLexer();
3720 SMLoc L = Lexer.getLoc();
3722 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3723 // TODO : get a better message.
3724 reportParseError(".module directive must appear before any code");
3728 if (Lexer.is(AsmToken::Identifier)) {
3729 StringRef Option = Parser.getTok().getString();
3732 if (Option == "oddspreg") {
3733 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3734 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3736 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3737 reportParseError("unexpected token, expected end of statement");
3742 } else if (Option == "nooddspreg") {
3744 Error(L, "'.module nooddspreg' requires the O32 ABI");
3748 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3749 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3751 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3752 reportParseError("unexpected token, expected end of statement");
3757 } else if (Option == "fp") {
3758 return parseDirectiveModuleFP();
3761 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3767 /// parseDirectiveModuleFP
3771 bool MipsAsmParser::parseDirectiveModuleFP() {
3772 MCAsmParser &Parser = getParser();
3773 MCAsmLexer &Lexer = getLexer();
3775 if (Lexer.isNot(AsmToken::Equal)) {
3776 reportParseError("unexpected token, expected equals sign '='");
3779 Parser.Lex(); // Eat '=' token.
3781 MipsABIFlagsSection::FpABIKind FpABI;
3782 if (!parseFpABIValue(FpABI, ".module"))
3785 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3786 reportParseError("unexpected token, expected end of statement");
3790 // Emit appropriate flags.
3791 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3792 Parser.Lex(); // Consume the EndOfStatement.
3796 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3797 StringRef Directive) {
3798 MCAsmParser &Parser = getParser();
3799 MCAsmLexer &Lexer = getLexer();
3801 if (Lexer.is(AsmToken::Identifier)) {
3802 StringRef Value = Parser.getTok().getString();
3805 if (Value != "xx") {
3806 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3811 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3815 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3819 if (Lexer.is(AsmToken::Integer)) {
3820 unsigned Value = Parser.getTok().getIntVal();
3823 if (Value != 32 && Value != 64) {
3824 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3830 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3834 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3836 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3844 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3845 MCAsmParser &Parser = getParser();
3846 StringRef IDVal = DirectiveID.getString();
3848 if (IDVal == ".cpload")
3849 return parseDirectiveCpLoad(DirectiveID.getLoc());
3850 if (IDVal == ".dword") {
3851 parseDataDirective(8, DirectiveID.getLoc());
3854 if (IDVal == ".ent") {
3855 StringRef SymbolName;
3857 if (Parser.parseIdentifier(SymbolName)) {
3858 reportParseError("expected identifier after .ent");
3862 // There's an undocumented extension that allows an integer to
3863 // follow the name of the procedure which AFAICS is ignored by GAS.
3864 // Example: .ent foo,2
3865 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3866 if (getLexer().isNot(AsmToken::Comma)) {
3867 // Even though we accept this undocumented extension for compatibility
3868 // reasons, the additional integer argument does not actually change
3869 // the behaviour of the '.ent' directive, so we would like to discourage
3870 // its use. We do this by not referring to the extended version in
3871 // error messages which are not directly related to its use.
3872 reportParseError("unexpected token, expected end of statement");
3875 Parser.Lex(); // Eat the comma.
3876 const MCExpr *DummyNumber;
3877 int64_t DummyNumberVal;
3878 // If the user was explicitly trying to use the extended version,
3879 // we still give helpful extension-related error messages.
3880 if (Parser.parseExpression(DummyNumber)) {
3881 reportParseError("expected number after comma");
3884 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3885 reportParseError("expected an absolute expression after comma");
3890 // If this is not the end of the statement, report an error.
3891 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3892 reportParseError("unexpected token, expected end of statement");
3896 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3898 getTargetStreamer().emitDirectiveEnt(*Sym);
3903 if (IDVal == ".end") {
3904 StringRef SymbolName;
3906 if (Parser.parseIdentifier(SymbolName)) {
3907 reportParseError("expected identifier after .end");
3911 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3912 reportParseError("unexpected token, expected end of statement");
3916 if (CurrentFn == nullptr) {
3917 reportParseError(".end used without .ent");
3921 if ((SymbolName != CurrentFn->getName())) {
3922 reportParseError(".end symbol does not match .ent symbol");
3926 getTargetStreamer().emitDirectiveEnd(SymbolName);
3927 CurrentFn = nullptr;
3931 if (IDVal == ".frame") {
3932 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3933 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3934 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3935 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3936 reportParseError("expected stack register");
3940 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3941 if (!StackRegOpnd.isGPRAsmReg()) {
3942 reportParseError(StackRegOpnd.getStartLoc(),
3943 "expected general purpose register");
3946 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3948 if (Parser.getTok().is(AsmToken::Comma))
3951 reportParseError("unexpected token, expected comma");
3955 // Parse the frame size.
3956 const MCExpr *FrameSize;
3957 int64_t FrameSizeVal;
3959 if (Parser.parseExpression(FrameSize)) {
3960 reportParseError("expected frame size value");
3964 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3965 reportParseError("frame size not an absolute expression");
3969 if (Parser.getTok().is(AsmToken::Comma))
3972 reportParseError("unexpected token, expected comma");
3976 // Parse the return register.
3978 ResTy = parseAnyRegister(TmpReg);
3979 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3980 reportParseError("expected return register");
3984 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3985 if (!ReturnRegOpnd.isGPRAsmReg()) {
3986 reportParseError(ReturnRegOpnd.getStartLoc(),
3987 "expected general purpose register");
3991 // If this is not the end of the statement, report an error.
3992 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3993 reportParseError("unexpected token, expected end of statement");
3997 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3998 ReturnRegOpnd.getGPR32Reg());
4002 if (IDVal == ".set") {
4003 return parseDirectiveSet();
4006 if (IDVal == ".mask" || IDVal == ".fmask") {
4007 // .mask bitmask, frame_offset
4008 // bitmask: One bit for each register used.
4009 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
4010 // first register is expected to be saved.
4012 // .mask 0x80000000, -4
4013 // .fmask 0x80000000, -4
4016 // Parse the bitmask
4017 const MCExpr *BitMask;
4020 if (Parser.parseExpression(BitMask)) {
4021 reportParseError("expected bitmask value");
4025 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
4026 reportParseError("bitmask not an absolute expression");
4030 if (Parser.getTok().is(AsmToken::Comma))
4033 reportParseError("unexpected token, expected comma");
4037 // Parse the frame_offset
4038 const MCExpr *FrameOffset;
4039 int64_t FrameOffsetVal;
4041 if (Parser.parseExpression(FrameOffset)) {
4042 reportParseError("expected frame offset value");
4046 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
4047 reportParseError("frame offset not an absolute expression");
4051 // If this is not the end of the statement, report an error.
4052 if (getLexer().isNot(AsmToken::EndOfStatement)) {
4053 reportParseError("unexpected token, expected end of statement");
4057 if (IDVal == ".mask")
4058 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
4060 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
4064 if (IDVal == ".nan")
4065 return parseDirectiveNaN();
4067 if (IDVal == ".gpword") {
4068 parseDirectiveGpWord();
4072 if (IDVal == ".gpdword") {
4073 parseDirectiveGpDWord();
4077 if (IDVal == ".word") {
4078 parseDataDirective(4, DirectiveID.getLoc());
4082 if (IDVal == ".option")
4083 return parseDirectiveOption();
4085 if (IDVal == ".abicalls") {
4086 getTargetStreamer().emitDirectiveAbiCalls();
4087 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
4088 Error(Parser.getTok().getLoc(),
4089 "unexpected token, expected end of statement");
4091 Parser.eatToEndOfStatement();
4096 if (IDVal == ".cpsetup")
4097 return parseDirectiveCPSetup();
4099 if (IDVal == ".module")
4100 return parseDirectiveModule();
4105 extern "C" void LLVMInitializeMipsAsmParser() {
4106 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
4107 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
4108 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
4109 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
4112 #define GET_REGISTER_MATCHER
4113 #define GET_MATCHER_IMPLEMENTATION
4114 #include "MipsGenAsmMatcher.inc"