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/StringSwitch.h"
16 #include "llvm/ADT/SmallVector.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/TargetRegistry.h"
30 #include "llvm/Support/SourceMgr.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 = *Parser.getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
99 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
100 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
101 // nullptr, which indicates that no function is currently
102 // selected. This usually happens after an '.end func'
105 // Print a warning along with its fix-it message at the given range.
106 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
107 SMRange Range, bool ShowColors = true);
109 #define GET_ASSEMBLER_HEADER
110 #include "MipsGenAsmMatcher.inc"
112 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
114 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
115 OperandVector &Operands, MCStreamer &Out,
117 bool MatchingInlineAsm) override;
119 /// Parse a register as used in CFI directives
120 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
122 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
124 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
126 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
127 SMLoc NameLoc, OperandVector &Operands) override;
129 bool ParseDirective(AsmToken DirectiveID) override;
131 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
133 MipsAsmParser::OperandMatchResultTy
134 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
135 StringRef Identifier, SMLoc S);
137 MipsAsmParser::OperandMatchResultTy
138 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
140 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
144 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
146 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
148 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
150 bool searchSymbolAlias(OperandVector &Operands);
152 bool parseOperand(OperandVector &, StringRef Mnemonic);
154 bool needsExpansion(MCInst &Inst);
156 // Expands assembly pseudo instructions.
157 // Returns false on success, true otherwise.
158 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
159 SmallVectorImpl<MCInst> &Instructions);
161 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
162 SmallVectorImpl<MCInst> &Instructions);
164 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
165 SmallVectorImpl<MCInst> &Instructions);
167 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
168 SmallVectorImpl<MCInst> &Instructions);
170 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
171 SmallVectorImpl<MCInst> &Instructions);
173 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
174 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
176 bool reportParseError(Twine ErrorMsg);
177 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
179 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
180 bool parseRelocOperand(const MCExpr *&Res);
182 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
184 bool isEvaluated(const MCExpr *Expr);
185 bool parseSetMips0Directive();
186 bool parseSetArchDirective();
187 bool parseSetFeature(uint64_t Feature);
188 bool parseDirectiveCpLoad(SMLoc Loc);
189 bool parseDirectiveCPSetup();
190 bool parseDirectiveNaN();
191 bool parseDirectiveSet();
192 bool parseDirectiveOption();
194 bool parseSetAtDirective();
195 bool parseSetNoAtDirective();
196 bool parseSetMacroDirective();
197 bool parseSetNoMacroDirective();
198 bool parseSetMsaDirective();
199 bool parseSetNoMsaDirective();
200 bool parseSetNoDspDirective();
201 bool parseSetReorderDirective();
202 bool parseSetNoReorderDirective();
203 bool parseSetMips16Directive();
204 bool parseSetNoMips16Directive();
205 bool parseSetFpDirective();
206 bool parseSetPopDirective();
207 bool parseSetPushDirective();
209 bool parseSetAssignment();
211 bool parseDataDirective(unsigned Size, SMLoc L);
212 bool parseDirectiveGpWord();
213 bool parseDirectiveGpDWord();
214 bool parseDirectiveModule();
215 bool parseDirectiveModuleFP();
216 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
217 StringRef Directive);
219 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
221 bool eatComma(StringRef ErrorStr);
223 int matchCPURegisterName(StringRef Symbol);
225 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
227 int matchFPURegisterName(StringRef Name);
229 int matchFCCRegisterName(StringRef Name);
231 int matchACRegisterName(StringRef Name);
233 int matchMSA128RegisterName(StringRef Name);
235 int matchMSA128CtrlRegisterName(StringRef Name);
237 unsigned getReg(int RC, int RegNo);
239 unsigned getGPR(int RegNo);
241 int getATReg(SMLoc Loc);
243 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
244 SmallVectorImpl<MCInst> &Instructions);
246 // Helper function that checks if the value of a vector index is within the
247 // boundaries of accepted values for each RegisterKind
248 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
249 bool validateMSAIndex(int Val, int RegKind);
251 // Selects a new architecture by updating the FeatureBits with the necessary
252 // info including implied dependencies.
253 // Internally, it clears all the feature bits related to *any* architecture
254 // and selects the new one using the ToggleFeature functionality of the
255 // MCSubtargetInfo object that handles implied dependencies. The reason we
256 // clear all the arch related bits manually is because ToggleFeature only
257 // clears the features that imply the feature being cleared and not the
258 // features implied by the feature being cleared. This is easier to see
260 // --------------------------------------------------
261 // | Feature | Implies |
262 // | -------------------------------------------------|
263 // | FeatureMips1 | None |
264 // | FeatureMips2 | FeatureMips1 |
265 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
266 // | FeatureMips4 | FeatureMips3 |
268 // --------------------------------------------------
270 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
271 // FeatureMipsGP64 | FeatureMips1)
272 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
273 void selectArch(StringRef ArchFeature) {
274 uint64_t FeatureBits = STI.getFeatureBits();
275 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
276 STI.setFeatureBits(FeatureBits);
277 setAvailableFeatures(
278 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
279 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
282 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
283 if (!(STI.getFeatureBits() & Feature)) {
284 setAvailableFeatures(
285 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
287 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
290 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
291 if (STI.getFeatureBits() & Feature) {
292 setAvailableFeatures(
293 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
295 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
299 enum MipsMatchResultTy {
300 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
301 #define GET_OPERAND_DIAGNOSTIC_TYPES
302 #include "MipsGenAsmMatcher.inc"
303 #undef GET_OPERAND_DIAGNOSTIC_TYPES
307 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
308 const MCInstrInfo &MII, const MCTargetOptions &Options)
309 : MCTargetAsmParser(), STI(sti), Parser(parser) {
310 // Initialize the set of available features.
311 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
313 // Remember the initial assembler options. The user can not modify these.
314 AssemblerOptions.push_back(
315 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
317 // Create an assembler options environment for the user to modify.
318 AssemblerOptions.push_back(
319 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
321 getTargetStreamer().updateABIInfo(*this);
323 // Assert exactly one ABI was chosen.
324 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
325 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
326 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
327 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
329 if (!isABI_O32() && !useOddSPReg() != 0)
330 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
335 MCAsmParser &getParser() const { return Parser; }
336 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
338 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
339 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
341 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
342 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
343 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
344 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
345 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
346 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
348 bool useOddSPReg() const {
349 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
352 bool inMicroMipsMode() const {
353 return STI.getFeatureBits() & Mips::FeatureMicroMips;
355 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
356 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
357 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
358 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
359 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
360 bool hasMips32() const {
361 return (STI.getFeatureBits() & Mips::FeatureMips32);
363 bool hasMips64() const {
364 return (STI.getFeatureBits() & Mips::FeatureMips64);
366 bool hasMips32r2() const {
367 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
369 bool hasMips64r2() const {
370 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
372 bool hasMips32r6() const {
373 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
375 bool hasMips64r6() const {
376 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
378 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
379 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
380 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
382 bool inMips16Mode() const {
383 return STI.getFeatureBits() & Mips::FeatureMips16;
385 // TODO: see how can we get this info.
386 bool abiUsesSoftFloat() const { return false; }
388 /// Warn if RegNo is the current assembler temporary.
389 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
395 /// MipsOperand - Instances of this class represent a parsed Mips machine
397 class MipsOperand : public MCParsedAsmOperand {
399 /// Broad categories of register classes
400 /// The exact class is finalized by the render method.
402 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
403 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
405 RegKind_FCC = 4, /// FCC
406 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
407 RegKind_MSACtrl = 16, /// MSA control registers
408 RegKind_COP2 = 32, /// COP2
409 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
411 RegKind_CCR = 128, /// CCR
412 RegKind_HWRegs = 256, /// HWRegs
413 RegKind_COP3 = 512, /// COP3
415 /// Potentially any (e.g. $1)
416 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
417 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
418 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
423 k_Immediate, /// An immediate (possibly involving symbol references)
424 k_Memory, /// Base + Offset Memory Address
425 k_PhysRegister, /// A physical register from the Mips namespace
426 k_RegisterIndex, /// A register index in one or more RegKind.
427 k_Token /// A simple token
431 MipsOperand(KindTy K, MipsAsmParser &Parser)
432 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
435 /// For diagnostics, and checking the assembler temporary
436 MipsAsmParser &AsmParser;
444 unsigned Num; /// Register Number
448 unsigned Index; /// Index into the register class
449 RegKind Kind; /// Bitfield of the kinds it could possibly be
450 const MCRegisterInfo *RegInfo;
464 struct PhysRegOp PhysReg;
465 struct RegIdxOp RegIdx;
470 SMLoc StartLoc, EndLoc;
472 /// Internal constructor for register kinds
473 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
474 const MCRegisterInfo *RegInfo,
476 MipsAsmParser &Parser) {
477 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
478 Op->RegIdx.Index = Index;
479 Op->RegIdx.RegInfo = RegInfo;
480 Op->RegIdx.Kind = RegKind;
487 /// Coerce the register to GPR32 and return the real register for the current
489 unsigned getGPR32Reg() const {
490 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
491 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
492 unsigned ClassID = Mips::GPR32RegClassID;
493 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
496 /// Coerce the register to GPR32 and return the real register for the current
498 unsigned getGPRMM16Reg() const {
499 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
500 unsigned ClassID = Mips::GPR32RegClassID;
501 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
504 /// Coerce the register to GPR64 and return the real register for the current
506 unsigned getGPR64Reg() const {
507 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
508 unsigned ClassID = Mips::GPR64RegClassID;
509 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
513 /// Coerce the register to AFGR64 and return the real register for the current
515 unsigned getAFGR64Reg() const {
516 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
517 if (RegIdx.Index % 2 != 0)
518 AsmParser.Warning(StartLoc, "Float register should be even.");
519 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
520 .getRegister(RegIdx.Index / 2);
523 /// Coerce the register to FGR64 and return the real register for the current
525 unsigned getFGR64Reg() const {
526 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
527 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
528 .getRegister(RegIdx.Index);
531 /// Coerce the register to FGR32 and return the real register for the current
533 unsigned getFGR32Reg() const {
534 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
535 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
536 .getRegister(RegIdx.Index);
539 /// Coerce the register to FGRH32 and return the real register for the current
541 unsigned getFGRH32Reg() const {
542 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
543 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
544 .getRegister(RegIdx.Index);
547 /// Coerce the register to FCC and return the real register for the current
549 unsigned getFCCReg() const {
550 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
551 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
552 .getRegister(RegIdx.Index);
555 /// Coerce the register to MSA128 and return the real register for the current
557 unsigned getMSA128Reg() const {
558 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
559 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
561 unsigned ClassID = Mips::MSA128BRegClassID;
562 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
565 /// Coerce the register to MSACtrl and return the real register for the
567 unsigned getMSACtrlReg() const {
568 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
569 unsigned ClassID = Mips::MSACtrlRegClassID;
570 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
573 /// Coerce the register to COP2 and return the real register for the
575 unsigned getCOP2Reg() const {
576 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
577 unsigned ClassID = Mips::COP2RegClassID;
578 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
581 /// Coerce the register to COP3 and return the real register for the
583 unsigned getCOP3Reg() const {
584 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
585 unsigned ClassID = Mips::COP3RegClassID;
586 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
589 /// Coerce the register to ACC64DSP and return the real register for the
591 unsigned getACC64DSPReg() const {
592 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
593 unsigned ClassID = Mips::ACC64DSPRegClassID;
594 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
597 /// Coerce the register to HI32DSP and return the real register for the
599 unsigned getHI32DSPReg() const {
600 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
601 unsigned ClassID = Mips::HI32DSPRegClassID;
602 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
605 /// Coerce the register to LO32DSP and return the real register for the
607 unsigned getLO32DSPReg() const {
608 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
609 unsigned ClassID = Mips::LO32DSPRegClassID;
610 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
613 /// Coerce the register to CCR and return the real register for the
615 unsigned getCCRReg() const {
616 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
617 unsigned ClassID = Mips::CCRRegClassID;
618 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
621 /// Coerce the register to HWRegs and return the real register for the
623 unsigned getHWRegsReg() const {
624 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
625 unsigned ClassID = Mips::HWRegsRegClassID;
626 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
631 // Add as immediate when possible. Null MCExpr = 0.
633 Inst.addOperand(MCOperand::CreateImm(0));
634 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
635 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
637 Inst.addOperand(MCOperand::CreateExpr(Expr));
640 void addRegOperands(MCInst &Inst, unsigned N) const {
641 llvm_unreachable("Use a custom parser instead");
644 /// Render the operand to an MCInst as a GPR32
645 /// Asserts if the wrong number of operands are requested, or the operand
646 /// is not a k_RegisterIndex compatible with RegKind_GPR
647 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
648 assert(N == 1 && "Invalid number of operands!");
649 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
652 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
653 assert(N == 1 && "Invalid number of operands!");
654 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
657 /// Render the operand to an MCInst as a GPR64
658 /// Asserts if the wrong number of operands are requested, or the operand
659 /// is not a k_RegisterIndex compatible with RegKind_GPR
660 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
661 assert(N == 1 && "Invalid number of operands!");
662 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
665 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
666 assert(N == 1 && "Invalid number of operands!");
667 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
670 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
671 assert(N == 1 && "Invalid number of operands!");
672 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
675 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
676 assert(N == 1 && "Invalid number of operands!");
677 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
678 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
679 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
680 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
684 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
685 assert(N == 1 && "Invalid number of operands!");
686 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
689 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
690 assert(N == 1 && "Invalid number of operands!");
691 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
694 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
695 assert(N == 1 && "Invalid number of operands!");
696 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
699 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
700 assert(N == 1 && "Invalid number of operands!");
701 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
704 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
705 assert(N == 1 && "Invalid number of operands!");
706 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
709 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
710 assert(N == 1 && "Invalid number of operands!");
711 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
714 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
715 assert(N == 1 && "Invalid number of operands!");
716 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
719 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
720 assert(N == 1 && "Invalid number of operands!");
721 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
724 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
725 assert(N == 1 && "Invalid number of operands!");
726 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
729 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
730 assert(N == 1 && "Invalid number of operands!");
731 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
734 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
735 assert(N == 1 && "Invalid number of operands!");
736 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
739 void addImmOperands(MCInst &Inst, unsigned N) const {
740 assert(N == 1 && "Invalid number of operands!");
741 const MCExpr *Expr = getImm();
745 void addMemOperands(MCInst &Inst, unsigned N) const {
746 assert(N == 2 && "Invalid number of operands!");
748 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
750 const MCExpr *Expr = getMemOff();
754 bool isReg() const override {
755 // As a special case until we sort out the definition of div/divu, pretend
756 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
757 if (isGPRAsmReg() && RegIdx.Index == 0)
760 return Kind == k_PhysRegister;
762 bool isRegIdx() const { return Kind == k_RegisterIndex; }
763 bool isImm() const override { return Kind == k_Immediate; }
764 bool isConstantImm() const {
765 return isImm() && dyn_cast<MCConstantExpr>(getImm());
767 bool isToken() const override {
768 // Note: It's not possible to pretend that other operand kinds are tokens.
769 // The matcher emitter checks tokens first.
770 return Kind == k_Token;
772 bool isMem() const override { return Kind == k_Memory; }
773 bool isConstantMemOff() const {
774 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
776 template <unsigned Bits> bool isMemWithSimmOffset() const {
777 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
779 bool isInvNum() const { return Kind == k_Immediate; }
780 bool isLSAImm() const {
781 if (!isConstantImm())
783 int64_t Val = getConstantImm();
784 return 1 <= Val && Val <= 4;
787 StringRef getToken() const {
788 assert(Kind == k_Token && "Invalid access!");
789 return StringRef(Tok.Data, Tok.Length);
792 unsigned getReg() const override {
793 // As a special case until we sort out the definition of div/divu, pretend
794 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
795 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
796 RegIdx.Kind & RegKind_GPR)
797 return getGPR32Reg(); // FIXME: GPR64 too
799 assert(Kind == k_PhysRegister && "Invalid access!");
803 const MCExpr *getImm() const {
804 assert((Kind == k_Immediate) && "Invalid access!");
808 int64_t getConstantImm() const {
809 const MCExpr *Val = getImm();
810 return static_cast<const MCConstantExpr *>(Val)->getValue();
813 MipsOperand *getMemBase() const {
814 assert((Kind == k_Memory) && "Invalid access!");
818 const MCExpr *getMemOff() const {
819 assert((Kind == k_Memory) && "Invalid access!");
823 int64_t getConstantMemOff() const {
824 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
827 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
828 MipsAsmParser &Parser) {
829 auto Op = make_unique<MipsOperand>(k_Token, Parser);
830 Op->Tok.Data = Str.data();
831 Op->Tok.Length = Str.size();
837 /// Create a numeric register (e.g. $1). The exact register remains
838 /// unresolved until an instruction successfully matches
839 static std::unique_ptr<MipsOperand>
840 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
841 SMLoc E, MipsAsmParser &Parser) {
842 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
843 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
846 /// Create a register that is definitely a GPR.
847 /// This is typically only used for named registers such as $gp.
848 static std::unique_ptr<MipsOperand>
849 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
850 MipsAsmParser &Parser) {
851 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
854 /// Create a register that is definitely a FGR.
855 /// This is typically only used for named registers such as $f0.
856 static std::unique_ptr<MipsOperand>
857 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
858 MipsAsmParser &Parser) {
859 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
862 /// Create a register that is definitely an FCC.
863 /// This is typically only used for named registers such as $fcc0.
864 static std::unique_ptr<MipsOperand>
865 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
866 MipsAsmParser &Parser) {
867 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
870 /// Create a register that is definitely an ACC.
871 /// This is typically only used for named registers such as $ac0.
872 static std::unique_ptr<MipsOperand>
873 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
874 MipsAsmParser &Parser) {
875 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
878 /// Create a register that is definitely an MSA128.
879 /// This is typically only used for named registers such as $w0.
880 static std::unique_ptr<MipsOperand>
881 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
882 SMLoc E, MipsAsmParser &Parser) {
883 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
886 /// Create a register that is definitely an MSACtrl.
887 /// This is typically only used for named registers such as $msaaccess.
888 static std::unique_ptr<MipsOperand>
889 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
890 SMLoc E, MipsAsmParser &Parser) {
891 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
894 static std::unique_ptr<MipsOperand>
895 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
896 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
903 static std::unique_ptr<MipsOperand>
904 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
905 SMLoc E, MipsAsmParser &Parser) {
906 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
907 Op->Mem.Base = Base.release();
914 bool isGPRAsmReg() const {
915 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
917 bool isMM16AsmReg() const {
918 if (!(isRegIdx() && RegIdx.Kind))
920 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
921 || RegIdx.Index == 16 || RegIdx.Index == 17);
923 bool isFGRAsmReg() const {
924 // AFGR64 is $0-$15 but we handle this in getAFGR64()
925 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
927 bool isHWRegsAsmReg() const {
928 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
930 bool isCCRAsmReg() const {
931 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
933 bool isFCCAsmReg() const {
934 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
936 if (!AsmParser.hasEightFccRegisters())
937 return RegIdx.Index == 0;
938 return RegIdx.Index <= 7;
940 bool isACCAsmReg() const {
941 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
943 bool isCOP2AsmReg() const {
944 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
946 bool isCOP3AsmReg() const {
947 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
949 bool isMSA128AsmReg() const {
950 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
952 bool isMSACtrlAsmReg() const {
953 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
956 /// getStartLoc - Get the location of the first token of this operand.
957 SMLoc getStartLoc() const override { return StartLoc; }
958 /// getEndLoc - Get the location of the last token of this operand.
959 SMLoc getEndLoc() const override { return EndLoc; }
961 virtual ~MipsOperand() {
969 case k_RegisterIndex:
975 void print(raw_ostream &OS) const override {
990 OS << "PhysReg<" << PhysReg.Num << ">";
992 case k_RegisterIndex:
993 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1000 }; // class MipsOperand
1004 extern const MCInstrDesc MipsInsts[];
1006 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1007 return MipsInsts[Opcode];
1010 static bool hasShortDelaySlot(unsigned Opcode) {
1013 case Mips::JALRS_MM:
1014 case Mips::JALRS16_MM:
1015 case Mips::BGEZALS_MM:
1016 case Mips::BLTZALS_MM:
1023 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1024 SmallVectorImpl<MCInst> &Instructions) {
1025 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1029 if (MCID.isBranch() || MCID.isCall()) {
1030 const unsigned Opcode = Inst.getOpcode();
1040 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1041 Offset = Inst.getOperand(2);
1042 if (!Offset.isImm())
1043 break; // We'll deal with this situation later on when applying fixups.
1044 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1045 return Error(IDLoc, "branch target out of range");
1046 if (OffsetToAlignment(Offset.getImm(),
1047 1LL << (inMicroMipsMode() ? 1 : 2)))
1048 return Error(IDLoc, "branch to misaligned address");
1062 case Mips::BGEZAL_MM:
1063 case Mips::BLTZAL_MM:
1066 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1067 Offset = Inst.getOperand(1);
1068 if (!Offset.isImm())
1069 break; // We'll deal with this situation later on when applying fixups.
1070 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1071 return Error(IDLoc, "branch target out of range");
1072 if (OffsetToAlignment(Offset.getImm(),
1073 1LL << (inMicroMipsMode() ? 1 : 2)))
1074 return Error(IDLoc, "branch to misaligned address");
1079 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1080 // We still accept it but it is a normal nop.
1081 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1082 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1083 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1087 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1088 // If this instruction has a delay slot and .set reorder is active,
1089 // emit a NOP after it.
1090 Instructions.push_back(Inst);
1092 if (hasShortDelaySlot(Inst.getOpcode())) {
1093 NopInst.setOpcode(Mips::MOVE16_MM);
1094 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1095 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1097 NopInst.setOpcode(Mips::SLL);
1098 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1099 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1100 NopInst.addOperand(MCOperand::CreateImm(0));
1102 Instructions.push_back(NopInst);
1106 if (MCID.mayLoad() || MCID.mayStore()) {
1107 // Check the offset of memory operand, if it is a symbol
1108 // reference or immediate we may have to expand instructions.
1109 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1110 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1111 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1112 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1113 MCOperand &Op = Inst.getOperand(i);
1115 int MemOffset = Op.getImm();
1116 if (MemOffset < -32768 || MemOffset > 32767) {
1117 // Offset can't exceed 16bit value.
1118 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1121 } else if (Op.isExpr()) {
1122 const MCExpr *Expr = Op.getExpr();
1123 if (Expr->getKind() == MCExpr::SymbolRef) {
1124 const MCSymbolRefExpr *SR =
1125 static_cast<const MCSymbolRefExpr *>(Expr);
1126 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1128 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1131 } else if (!isEvaluated(Expr)) {
1132 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1140 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1141 if (inMicroMipsMode()) {
1145 switch (Inst.getOpcode()) {
1148 case Mips::ADDIUS5_MM:
1149 Opnd = Inst.getOperand(2);
1151 return Error(IDLoc, "expected immediate operand kind");
1152 Imm = Opnd.getImm();
1153 if (Imm < -8 || Imm > 7)
1154 return Error(IDLoc, "immediate operand value out of range");
1156 case Mips::ADDIUSP_MM:
1157 Opnd = Inst.getOperand(0);
1159 return Error(IDLoc, "expected immediate operand kind");
1160 Imm = Opnd.getImm();
1161 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1163 return Error(IDLoc, "immediate operand value out of range");
1165 case Mips::SLL16_MM:
1166 case Mips::SRL16_MM:
1167 Opnd = Inst.getOperand(2);
1169 return Error(IDLoc, "expected immediate operand kind");
1170 Imm = Opnd.getImm();
1171 if (Imm < 1 || Imm > 8)
1172 return Error(IDLoc, "immediate operand value out of range");
1175 Opnd = Inst.getOperand(1);
1177 return Error(IDLoc, "expected immediate operand kind");
1178 Imm = Opnd.getImm();
1179 if (Imm < -1 || Imm > 126)
1180 return Error(IDLoc, "immediate operand value out of range");
1182 case Mips::ADDIUR2_MM:
1183 Opnd = Inst.getOperand(2);
1185 return Error(IDLoc, "expected immediate operand kind");
1186 Imm = Opnd.getImm();
1187 if (!(Imm == 1 || Imm == -1 ||
1188 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1189 return Error(IDLoc, "immediate operand value out of range");
1191 case Mips::ADDIUR1SP_MM:
1192 Opnd = Inst.getOperand(1);
1194 return Error(IDLoc, "expected immediate operand kind");
1195 Imm = Opnd.getImm();
1196 if (OffsetToAlignment(Imm, 4LL))
1197 return Error(IDLoc, "misaligned immediate operand value");
1198 if (Imm < 0 || Imm > 255)
1199 return Error(IDLoc, "immediate operand value out of range");
1201 case Mips::ANDI16_MM:
1202 Opnd = Inst.getOperand(2);
1204 return Error(IDLoc, "expected immediate operand kind");
1205 Imm = Opnd.getImm();
1206 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1207 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1208 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1209 return Error(IDLoc, "immediate operand value out of range");
1214 if (needsExpansion(Inst))
1215 return expandInstruction(Inst, IDLoc, Instructions);
1217 Instructions.push_back(Inst);
1222 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1224 switch (Inst.getOpcode()) {
1225 case Mips::LoadImm32Reg:
1226 case Mips::LoadAddr32Imm:
1227 case Mips::LoadAddr32Reg:
1228 case Mips::LoadImm64Reg:
1235 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1236 SmallVectorImpl<MCInst> &Instructions) {
1237 switch (Inst.getOpcode()) {
1239 assert(0 && "unimplemented expansion");
1241 case Mips::LoadImm32Reg:
1242 return expandLoadImm(Inst, IDLoc, Instructions);
1243 case Mips::LoadImm64Reg:
1245 Error(IDLoc, "instruction requires a 64-bit architecture");
1248 return expandLoadImm(Inst, IDLoc, Instructions);
1249 case Mips::LoadAddr32Imm:
1250 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1251 case Mips::LoadAddr32Reg:
1252 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1257 template <bool PerformShift>
1258 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1259 SmallVectorImpl<MCInst> &Instructions) {
1262 tmpInst.setOpcode(Mips::DSLL);
1263 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1264 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1265 tmpInst.addOperand(MCOperand::CreateImm(16));
1266 tmpInst.setLoc(IDLoc);
1267 Instructions.push_back(tmpInst);
1270 tmpInst.setOpcode(Mips::ORi);
1271 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1272 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1273 tmpInst.addOperand(Operand);
1274 tmpInst.setLoc(IDLoc);
1275 Instructions.push_back(tmpInst);
1278 template <int Shift, bool PerformShift>
1279 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1280 SmallVectorImpl<MCInst> &Instructions) {
1281 createShiftOr<PerformShift>(
1282 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1283 IDLoc, Instructions);
1287 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1288 SmallVectorImpl<MCInst> &Instructions) {
1290 const MCOperand &ImmOp = Inst.getOperand(1);
1291 assert(ImmOp.isImm() && "expected immediate operand kind");
1292 const MCOperand &RegOp = Inst.getOperand(0);
1293 assert(RegOp.isReg() && "expected register operand kind");
1295 int64_t ImmValue = ImmOp.getImm();
1296 tmpInst.setLoc(IDLoc);
1297 // FIXME: gas has a special case for values that are 000...1111, which
1298 // becomes a li -1 and then a dsrl
1299 if (0 <= ImmValue && ImmValue <= 65535) {
1300 // For 0 <= j <= 65535.
1301 // li d,j => ori d,$zero,j
1302 tmpInst.setOpcode(Mips::ORi);
1303 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1304 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1305 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1306 Instructions.push_back(tmpInst);
1307 } else if (ImmValue < 0 && ImmValue >= -32768) {
1308 // For -32768 <= j < 0.
1309 // li d,j => addiu d,$zero,j
1310 tmpInst.setOpcode(Mips::ADDiu);
1311 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1312 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1313 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1314 Instructions.push_back(tmpInst);
1315 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1316 // For any value of j that is representable as a 32-bit integer, create
1318 // li d,j => lui d,hi16(j)
1320 tmpInst.setOpcode(Mips::LUi);
1321 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1322 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1323 Instructions.push_back(tmpInst);
1324 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1325 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1327 Error(IDLoc, "instruction requires a 64-bit architecture");
1331 // <------- lo32 ------>
1332 // <------- hi32 ------>
1333 // <- hi16 -> <- lo16 ->
1334 // _________________________________
1336 // | 16-bytes | 16-bytes | 16-bytes |
1337 // |__________|__________|__________|
1339 // For any value of j that is representable as a 48-bit integer, create
1341 // li d,j => lui d,hi16(j)
1342 // ori d,d,hi16(lo32(j))
1344 // ori d,d,lo16(lo32(j))
1345 tmpInst.setOpcode(Mips::LUi);
1346 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1348 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1349 Instructions.push_back(tmpInst);
1350 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1351 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1354 Error(IDLoc, "instruction requires a 64-bit architecture");
1358 // <------- hi32 ------> <------- lo32 ------>
1359 // <- hi16 -> <- lo16 ->
1360 // ___________________________________________
1362 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1363 // |__________|__________|__________|__________|
1365 // For any value of j that isn't representable as a 48-bit integer.
1366 // li d,j => lui d,hi16(j)
1367 // ori d,d,lo16(hi32(j))
1369 // ori d,d,hi16(lo32(j))
1371 // ori d,d,lo16(lo32(j))
1372 tmpInst.setOpcode(Mips::LUi);
1373 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1375 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1376 Instructions.push_back(tmpInst);
1377 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1378 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1379 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1385 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1386 SmallVectorImpl<MCInst> &Instructions) {
1388 const MCOperand &ImmOp = Inst.getOperand(2);
1389 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1390 "expected immediate operand kind");
1391 if (!ImmOp.isImm()) {
1392 expandLoadAddressSym(Inst, IDLoc, Instructions);
1395 const MCOperand &SrcRegOp = Inst.getOperand(1);
1396 assert(SrcRegOp.isReg() && "expected register operand kind");
1397 const MCOperand &DstRegOp = Inst.getOperand(0);
1398 assert(DstRegOp.isReg() && "expected register operand kind");
1399 int ImmValue = ImmOp.getImm();
1400 if (-32768 <= ImmValue && ImmValue <= 65535) {
1401 // For -32768 <= j <= 65535.
1402 // la d,j(s) => addiu d,s,j
1403 tmpInst.setOpcode(Mips::ADDiu);
1404 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1405 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1406 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1407 Instructions.push_back(tmpInst);
1409 // For any other value of j that is representable as a 32-bit integer.
1410 // la d,j(s) => lui d,hi16(j)
1413 tmpInst.setOpcode(Mips::LUi);
1414 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1415 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1416 Instructions.push_back(tmpInst);
1418 tmpInst.setOpcode(Mips::ORi);
1419 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1420 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1421 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1422 Instructions.push_back(tmpInst);
1424 tmpInst.setOpcode(Mips::ADDu);
1425 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1426 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1427 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1428 Instructions.push_back(tmpInst);
1434 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1435 SmallVectorImpl<MCInst> &Instructions) {
1437 const MCOperand &ImmOp = Inst.getOperand(1);
1438 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1439 "expected immediate operand kind");
1440 if (!ImmOp.isImm()) {
1441 expandLoadAddressSym(Inst, IDLoc, Instructions);
1444 const MCOperand &RegOp = Inst.getOperand(0);
1445 assert(RegOp.isReg() && "expected register operand kind");
1446 int ImmValue = ImmOp.getImm();
1447 if (-32768 <= ImmValue && ImmValue <= 65535) {
1448 // For -32768 <= j <= 65535.
1449 // la d,j => addiu d,$zero,j
1450 tmpInst.setOpcode(Mips::ADDiu);
1451 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1452 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1453 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1454 Instructions.push_back(tmpInst);
1456 // For any other value of j that is representable as a 32-bit integer.
1457 // la d,j => lui d,hi16(j)
1459 tmpInst.setOpcode(Mips::LUi);
1460 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1461 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1462 Instructions.push_back(tmpInst);
1464 tmpInst.setOpcode(Mips::ORi);
1465 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1466 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1467 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1468 Instructions.push_back(tmpInst);
1474 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1475 SmallVectorImpl<MCInst> &Instructions) {
1476 // FIXME: If we do have a valid at register to use, we should generate a
1477 // slightly shorter sequence here.
1479 int ExprOperandNo = 1;
1480 // Sometimes the assembly parser will get the immediate expression as
1481 // a $zero + an immediate.
1482 if (Inst.getNumOperands() == 3) {
1483 assert(Inst.getOperand(1).getReg() ==
1484 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1487 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1488 assert(SymOp.isExpr() && "expected symbol operand kind");
1489 const MCOperand &RegOp = Inst.getOperand(0);
1490 unsigned RegNo = RegOp.getReg();
1491 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1492 const MCSymbolRefExpr *HiExpr =
1493 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1494 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1495 const MCSymbolRefExpr *LoExpr =
1496 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1497 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1499 // If it's a 64-bit architecture, expand to:
1500 // la d,sym => lui d,highest(sym)
1501 // ori d,d,higher(sym)
1503 // ori d,d,hi16(sym)
1505 // ori d,d,lo16(sym)
1506 const MCSymbolRefExpr *HighestExpr =
1507 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1508 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1509 const MCSymbolRefExpr *HigherExpr =
1510 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1511 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1513 tmpInst.setOpcode(Mips::LUi);
1514 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1515 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1516 Instructions.push_back(tmpInst);
1518 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1520 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1522 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1525 // Otherwise, expand to:
1526 // la d,sym => lui d,hi16(sym)
1527 // ori d,d,lo16(sym)
1528 tmpInst.setOpcode(Mips::LUi);
1529 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1530 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1531 Instructions.push_back(tmpInst);
1533 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1538 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1539 SmallVectorImpl<MCInst> &Instructions,
1540 bool isLoad, bool isImmOpnd) {
1541 const MCSymbolRefExpr *SR;
1543 unsigned ImmOffset, HiOffset, LoOffset;
1544 const MCExpr *ExprOffset;
1546 // 1st operand is either the source or destination register.
1547 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1548 unsigned RegOpNum = Inst.getOperand(0).getReg();
1549 // 2nd operand is the base register.
1550 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1551 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1552 // 3rd operand is either an immediate or expression.
1554 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1555 ImmOffset = Inst.getOperand(2).getImm();
1556 LoOffset = ImmOffset & 0x0000ffff;
1557 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1558 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1559 if (LoOffset & 0x8000)
1562 ExprOffset = Inst.getOperand(2).getExpr();
1563 // All instructions will have the same location.
1564 TempInst.setLoc(IDLoc);
1565 // These are some of the types of expansions we perform here:
1566 // 1) lw $8, sym => lui $8, %hi(sym)
1567 // lw $8, %lo(sym)($8)
1568 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1570 // lw $8, %lo(offset)($9)
1571 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1573 // lw $8, %lo(offset)($at)
1574 // 4) sw $8, sym => lui $at, %hi(sym)
1575 // sw $8, %lo(sym)($at)
1576 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1578 // sw $8, %lo(offset)($at)
1579 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1580 // ldc1 $f0, %lo(sym)($at)
1582 // For load instructions we can use the destination register as a temporary
1583 // if base and dst are different (examples 1 and 2) and if the base register
1584 // is general purpose otherwise we must use $at (example 6) and error if it's
1585 // not available. For stores we must use $at (examples 4 and 5) because we
1586 // must not clobber the source register setting up the offset.
1587 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1588 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1589 unsigned RegClassIDOp0 =
1590 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1591 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1592 (RegClassIDOp0 == Mips::GPR64RegClassID);
1593 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1594 TmpRegNum = RegOpNum;
1596 int AT = getATReg(IDLoc);
1597 // At this point we need AT to perform the expansions and we exit if it is
1602 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1605 TempInst.setOpcode(Mips::LUi);
1606 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1608 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1610 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1611 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1612 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1613 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1615 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1617 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1618 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1621 // Add the instruction to the list.
1622 Instructions.push_back(TempInst);
1623 // Prepare TempInst for next instruction.
1625 // Add temp register to base.
1626 TempInst.setOpcode(Mips::ADDu);
1627 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1628 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1629 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1630 Instructions.push_back(TempInst);
1632 // And finally, create original instruction with low part
1633 // of offset and new base.
1634 TempInst.setOpcode(Inst.getOpcode());
1635 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1636 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1638 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1640 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1641 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1642 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1644 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1646 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1647 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1650 Instructions.push_back(TempInst);
1654 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1655 // As described by the Mips32r2 spec, the registers Rd and Rs for
1656 // jalr.hb must be different.
1657 unsigned Opcode = Inst.getOpcode();
1659 if (Opcode == Mips::JALR_HB &&
1660 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1661 return Match_RequiresDifferentSrcAndDst;
1663 return Match_Success;
1666 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1667 OperandVector &Operands,
1669 uint64_t &ErrorInfo,
1670 bool MatchingInlineAsm) {
1673 SmallVector<MCInst, 8> Instructions;
1674 unsigned MatchResult =
1675 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1677 switch (MatchResult) {
1680 case Match_Success: {
1681 if (processInstruction(Inst, IDLoc, Instructions))
1683 for (unsigned i = 0; i < Instructions.size(); i++)
1684 Out.EmitInstruction(Instructions[i], STI);
1687 case Match_MissingFeature:
1688 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1690 case Match_InvalidOperand: {
1691 SMLoc ErrorLoc = IDLoc;
1692 if (ErrorInfo != ~0ULL) {
1693 if (ErrorInfo >= Operands.size())
1694 return Error(IDLoc, "too few operands for instruction");
1696 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1697 if (ErrorLoc == SMLoc())
1701 return Error(ErrorLoc, "invalid operand for instruction");
1703 case Match_MnemonicFail:
1704 return Error(IDLoc, "invalid instruction");
1705 case Match_RequiresDifferentSrcAndDst:
1706 return Error(IDLoc, "source and destination must be different");
1711 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1712 if ((RegIndex != 0) &&
1713 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1715 Warning(Loc, "used $at without \".set noat\"");
1717 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1718 Twine(RegIndex) + "\"");
1723 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1724 SMRange Range, bool ShowColors) {
1725 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1726 Range, SMFixIt(Range, FixMsg),
1730 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1733 CC = StringSwitch<unsigned>(Name)
1769 if (!(isABI_N32() || isABI_N64()))
1772 if (12 <= CC && CC <= 15) {
1773 // Name is one of t4-t7
1774 AsmToken RegTok = getLexer().peekTok();
1775 SMRange RegRange = RegTok.getLocRange();
1777 StringRef FixedName = StringSwitch<StringRef>(Name)
1783 assert(FixedName != "" && "Register name is not one of t4-t7.");
1785 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1786 "Did you mean $" + FixedName + "?", RegRange);
1789 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1790 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1791 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1792 if (8 <= CC && CC <= 11)
1796 CC = StringSwitch<unsigned>(Name)
1808 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1810 if (Name[0] == 'f') {
1811 StringRef NumString = Name.substr(1);
1813 if (NumString.getAsInteger(10, IntVal))
1814 return -1; // This is not an integer.
1815 if (IntVal > 31) // Maximum index for fpu register.
1822 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1824 if (Name.startswith("fcc")) {
1825 StringRef NumString = Name.substr(3);
1827 if (NumString.getAsInteger(10, IntVal))
1828 return -1; // This is not an integer.
1829 if (IntVal > 7) // There are only 8 fcc registers.
1836 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1838 if (Name.startswith("ac")) {
1839 StringRef NumString = Name.substr(2);
1841 if (NumString.getAsInteger(10, IntVal))
1842 return -1; // This is not an integer.
1843 if (IntVal > 3) // There are only 3 acc registers.
1850 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1853 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1862 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1865 CC = StringSwitch<unsigned>(Name)
1868 .Case("msaaccess", 2)
1870 .Case("msamodify", 4)
1871 .Case("msarequest", 5)
1873 .Case("msaunmap", 7)
1879 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1887 int MipsAsmParser::getATReg(SMLoc Loc) {
1888 int AT = AssemblerOptions.back()->getATRegNum();
1890 reportParseError(Loc,
1891 "pseudo-instruction requires $at, which is not available");
1895 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1896 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1899 unsigned MipsAsmParser::getGPR(int RegNo) {
1900 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1904 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1906 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1909 return getReg(RegClass, RegNum);
1912 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1913 DEBUG(dbgs() << "parseOperand\n");
1915 // Check if the current operand has a custom associated parser, if so, try to
1916 // custom parse the operand, or fallback to the general approach.
1917 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1918 if (ResTy == MatchOperand_Success)
1920 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1921 // there was a match, but an error occurred, in which case, just return that
1922 // the operand parsing failed.
1923 if (ResTy == MatchOperand_ParseFail)
1926 DEBUG(dbgs() << ".. Generic Parser\n");
1928 switch (getLexer().getKind()) {
1930 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1932 case AsmToken::Dollar: {
1933 // Parse the register.
1934 SMLoc S = Parser.getTok().getLoc();
1936 // Almost all registers have been parsed by custom parsers. There is only
1937 // one exception to this. $zero (and it's alias $0) will reach this point
1938 // for div, divu, and similar instructions because it is not an operand
1939 // to the instruction definition but an explicit register. Special case
1940 // this situation for now.
1941 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1944 // Maybe it is a symbol reference.
1945 StringRef Identifier;
1946 if (Parser.parseIdentifier(Identifier))
1949 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1950 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1951 // Otherwise create a symbol reference.
1953 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1955 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1958 // Else drop to expression parsing.
1959 case AsmToken::LParen:
1960 case AsmToken::Minus:
1961 case AsmToken::Plus:
1962 case AsmToken::Integer:
1963 case AsmToken::Tilde:
1964 case AsmToken::String: {
1965 DEBUG(dbgs() << ".. generic integer\n");
1966 OperandMatchResultTy ResTy = parseImm(Operands);
1967 return ResTy != MatchOperand_Success;
1969 case AsmToken::Percent: {
1970 // It is a symbol reference or constant expression.
1971 const MCExpr *IdVal;
1972 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1973 if (parseRelocOperand(IdVal))
1976 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1978 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1980 } // case AsmToken::Percent
1981 } // switch(getLexer().getKind())
1985 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1986 StringRef RelocStr) {
1988 // Check the type of the expression.
1989 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1990 // It's a constant, evaluate reloc value.
1992 switch (getVariantKind(RelocStr)) {
1993 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1994 // Get the 1st 16-bits.
1995 Val = MCE->getValue() & 0xffff;
1997 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1998 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1999 // 16 bits being negative.
2000 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2002 case MCSymbolRefExpr::VK_Mips_HIGHER:
2003 // Get the 3rd 16-bits.
2004 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2006 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2007 // Get the 4th 16-bits.
2008 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2011 report_fatal_error("unsupported reloc value");
2013 return MCConstantExpr::Create(Val, getContext());
2016 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2017 // It's a symbol, create a symbolic expression from the symbol.
2018 StringRef Symbol = MSRE->getSymbol().getName();
2019 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2020 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2024 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2025 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2027 // Try to create target expression.
2028 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2029 return MipsMCExpr::Create(VK, Expr, getContext());
2031 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2032 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2033 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2037 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2038 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2039 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2042 // Just return the original expression.
2046 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2048 switch (Expr->getKind()) {
2049 case MCExpr::Constant:
2051 case MCExpr::SymbolRef:
2052 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2053 case MCExpr::Binary:
2054 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2055 if (!isEvaluated(BE->getLHS()))
2057 return isEvaluated(BE->getRHS());
2060 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2061 case MCExpr::Target:
2067 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2068 Parser.Lex(); // Eat the % token.
2069 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2070 if (Tok.isNot(AsmToken::Identifier))
2073 std::string Str = Tok.getIdentifier().str();
2075 Parser.Lex(); // Eat the identifier.
2076 // Now make an expression from the rest of the operand.
2077 const MCExpr *IdVal;
2080 if (getLexer().getKind() == AsmToken::LParen) {
2082 Parser.Lex(); // Eat the '(' token.
2083 if (getLexer().getKind() == AsmToken::Percent) {
2084 Parser.Lex(); // Eat the % token.
2085 const AsmToken &nextTok = Parser.getTok();
2086 if (nextTok.isNot(AsmToken::Identifier))
2089 Str += nextTok.getIdentifier();
2090 Parser.Lex(); // Eat the identifier.
2091 if (getLexer().getKind() != AsmToken::LParen)
2096 if (getParser().parseParenExpression(IdVal, EndLoc))
2099 while (getLexer().getKind() == AsmToken::RParen)
2100 Parser.Lex(); // Eat the ')' token.
2103 return true; // Parenthesis must follow the relocation operand.
2105 Res = evaluateRelocExpr(IdVal, Str);
2109 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2111 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2112 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2113 if (ResTy == MatchOperand_Success) {
2114 assert(Operands.size() == 1);
2115 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2116 StartLoc = Operand.getStartLoc();
2117 EndLoc = Operand.getEndLoc();
2119 // AFAIK, we only support numeric registers and named GPR's in CFI
2121 // Don't worry about eating tokens before failing. Using an unrecognised
2122 // register is a parse error.
2123 if (Operand.isGPRAsmReg()) {
2124 // Resolve to GPR32 or GPR64 appropriately.
2125 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2128 return (RegNo == (unsigned)-1);
2131 assert(Operands.size() == 0);
2132 return (RegNo == (unsigned)-1);
2135 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2139 while (getLexer().getKind() == AsmToken::LParen)
2142 switch (getLexer().getKind()) {
2145 case AsmToken::Identifier:
2146 case AsmToken::LParen:
2147 case AsmToken::Integer:
2148 case AsmToken::Minus:
2149 case AsmToken::Plus:
2151 Result = getParser().parseParenExpression(Res, S);
2153 Result = (getParser().parseExpression(Res));
2154 while (getLexer().getKind() == AsmToken::RParen)
2157 case AsmToken::Percent:
2158 Result = parseRelocOperand(Res);
2163 MipsAsmParser::OperandMatchResultTy
2164 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2165 DEBUG(dbgs() << "parseMemOperand\n");
2166 const MCExpr *IdVal = nullptr;
2168 bool isParenExpr = false;
2169 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2170 // First operand is the offset.
2171 S = Parser.getTok().getLoc();
2173 if (getLexer().getKind() == AsmToken::LParen) {
2178 if (getLexer().getKind() != AsmToken::Dollar) {
2179 if (parseMemOffset(IdVal, isParenExpr))
2180 return MatchOperand_ParseFail;
2182 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2183 if (Tok.isNot(AsmToken::LParen)) {
2184 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2185 if (Mnemonic.getToken() == "la") {
2187 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2188 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2189 return MatchOperand_Success;
2191 if (Tok.is(AsmToken::EndOfStatement)) {
2193 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2195 // Zero register assumed, add a memory operand with ZERO as its base.
2196 // "Base" will be managed by k_Memory.
2197 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2200 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2201 return MatchOperand_Success;
2203 Error(Parser.getTok().getLoc(), "'(' expected");
2204 return MatchOperand_ParseFail;
2207 Parser.Lex(); // Eat the '(' token.
2210 Res = parseAnyRegister(Operands);
2211 if (Res != MatchOperand_Success)
2214 if (Parser.getTok().isNot(AsmToken::RParen)) {
2215 Error(Parser.getTok().getLoc(), "')' expected");
2216 return MatchOperand_ParseFail;
2219 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2221 Parser.Lex(); // Eat the ')' token.
2224 IdVal = MCConstantExpr::Create(0, getContext());
2226 // Replace the register operand with the memory operand.
2227 std::unique_ptr<MipsOperand> op(
2228 static_cast<MipsOperand *>(Operands.back().release()));
2229 // Remove the register from the operands.
2230 // "op" will be managed by k_Memory.
2231 Operands.pop_back();
2232 // Add the memory operand.
2233 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2235 if (IdVal->EvaluateAsAbsolute(Imm))
2236 IdVal = MCConstantExpr::Create(Imm, getContext());
2237 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2238 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2242 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2243 return MatchOperand_Success;
2246 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2248 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2250 SMLoc S = Parser.getTok().getLoc();
2252 if (Sym->isVariable())
2253 Expr = Sym->getVariableValue();
2256 if (Expr->getKind() == MCExpr::SymbolRef) {
2257 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2258 StringRef DefSymbol = Ref->getSymbol().getName();
2259 if (DefSymbol.startswith("$")) {
2260 OperandMatchResultTy ResTy =
2261 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2262 if (ResTy == MatchOperand_Success) {
2265 } else if (ResTy == MatchOperand_ParseFail)
2266 llvm_unreachable("Should never ParseFail");
2269 } else if (Expr->getKind() == MCExpr::Constant) {
2271 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2273 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2280 MipsAsmParser::OperandMatchResultTy
2281 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2282 StringRef Identifier,
2284 int Index = matchCPURegisterName(Identifier);
2286 Operands.push_back(MipsOperand::createGPRReg(
2287 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2288 return MatchOperand_Success;
2291 Index = matchFPURegisterName(Identifier);
2293 Operands.push_back(MipsOperand::createFGRReg(
2294 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2295 return MatchOperand_Success;
2298 Index = matchFCCRegisterName(Identifier);
2300 Operands.push_back(MipsOperand::createFCCReg(
2301 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2302 return MatchOperand_Success;
2305 Index = matchACRegisterName(Identifier);
2307 Operands.push_back(MipsOperand::createACCReg(
2308 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2309 return MatchOperand_Success;
2312 Index = matchMSA128RegisterName(Identifier);
2314 Operands.push_back(MipsOperand::createMSA128Reg(
2315 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2316 return MatchOperand_Success;
2319 Index = matchMSA128CtrlRegisterName(Identifier);
2321 Operands.push_back(MipsOperand::createMSACtrlReg(
2322 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2323 return MatchOperand_Success;
2326 return MatchOperand_NoMatch;
2329 MipsAsmParser::OperandMatchResultTy
2330 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2331 auto Token = Parser.getLexer().peekTok(false);
2333 if (Token.is(AsmToken::Identifier)) {
2334 DEBUG(dbgs() << ".. identifier\n");
2335 StringRef Identifier = Token.getIdentifier();
2336 OperandMatchResultTy ResTy =
2337 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2339 } else if (Token.is(AsmToken::Integer)) {
2340 DEBUG(dbgs() << ".. integer\n");
2341 Operands.push_back(MipsOperand::createNumericReg(
2342 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2344 return MatchOperand_Success;
2347 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2349 return MatchOperand_NoMatch;
2352 MipsAsmParser::OperandMatchResultTy
2353 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2354 DEBUG(dbgs() << "parseAnyRegister\n");
2356 auto Token = Parser.getTok();
2358 SMLoc S = Token.getLoc();
2360 if (Token.isNot(AsmToken::Dollar)) {
2361 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2362 if (Token.is(AsmToken::Identifier)) {
2363 if (searchSymbolAlias(Operands))
2364 return MatchOperand_Success;
2366 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2367 return MatchOperand_NoMatch;
2369 DEBUG(dbgs() << ".. $\n");
2371 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2372 if (ResTy == MatchOperand_Success) {
2374 Parser.Lex(); // identifier
2379 MipsAsmParser::OperandMatchResultTy
2380 MipsAsmParser::parseImm(OperandVector &Operands) {
2381 switch (getLexer().getKind()) {
2383 return MatchOperand_NoMatch;
2384 case AsmToken::LParen:
2385 case AsmToken::Minus:
2386 case AsmToken::Plus:
2387 case AsmToken::Integer:
2388 case AsmToken::Tilde:
2389 case AsmToken::String:
2393 const MCExpr *IdVal;
2394 SMLoc S = Parser.getTok().getLoc();
2395 if (getParser().parseExpression(IdVal))
2396 return MatchOperand_ParseFail;
2398 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2399 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2400 return MatchOperand_Success;
2403 MipsAsmParser::OperandMatchResultTy
2404 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2405 DEBUG(dbgs() << "parseJumpTarget\n");
2407 SMLoc S = getLexer().getLoc();
2409 // Integers and expressions are acceptable
2410 OperandMatchResultTy ResTy = parseImm(Operands);
2411 if (ResTy != MatchOperand_NoMatch)
2414 // Registers are a valid target and have priority over symbols.
2415 ResTy = parseAnyRegister(Operands);
2416 if (ResTy != MatchOperand_NoMatch)
2419 const MCExpr *Expr = nullptr;
2420 if (Parser.parseExpression(Expr)) {
2421 // We have no way of knowing if a symbol was consumed so we must ParseFail
2422 return MatchOperand_ParseFail;
2425 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2426 return MatchOperand_Success;
2429 MipsAsmParser::OperandMatchResultTy
2430 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2431 const MCExpr *IdVal;
2432 // If the first token is '$' we may have register operand.
2433 if (Parser.getTok().is(AsmToken::Dollar))
2434 return MatchOperand_NoMatch;
2435 SMLoc S = Parser.getTok().getLoc();
2436 if (getParser().parseExpression(IdVal))
2437 return MatchOperand_ParseFail;
2438 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2439 assert(MCE && "Unexpected MCExpr type.");
2440 int64_t Val = MCE->getValue();
2441 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2442 Operands.push_back(MipsOperand::CreateImm(
2443 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2444 return MatchOperand_Success;
2447 MipsAsmParser::OperandMatchResultTy
2448 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2449 switch (getLexer().getKind()) {
2451 return MatchOperand_NoMatch;
2452 case AsmToken::LParen:
2453 case AsmToken::Plus:
2454 case AsmToken::Minus:
2455 case AsmToken::Integer:
2460 SMLoc S = Parser.getTok().getLoc();
2462 if (getParser().parseExpression(Expr))
2463 return MatchOperand_ParseFail;
2466 if (!Expr->EvaluateAsAbsolute(Val)) {
2467 Error(S, "expected immediate value");
2468 return MatchOperand_ParseFail;
2471 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2472 // and because the CPU always adds one to the immediate field, the allowed
2473 // range becomes 1..4. We'll only check the range here and will deal
2474 // with the addition/subtraction when actually decoding/encoding
2476 if (Val < 1 || Val > 4) {
2477 Error(S, "immediate not in range (1..4)");
2478 return MatchOperand_ParseFail;
2482 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2483 return MatchOperand_Success;
2486 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2488 MCSymbolRefExpr::VariantKind VK =
2489 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2490 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2491 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2492 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2493 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2494 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2495 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2496 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2497 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2498 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2499 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2500 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2501 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2502 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2503 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2504 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2505 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2506 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2507 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2508 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2509 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2510 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2511 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2512 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2513 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2514 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2515 .Default(MCSymbolRefExpr::VK_None);
2517 assert(VK != MCSymbolRefExpr::VK_None);
2522 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2524 /// ::= '(', register, ')'
2525 /// handle it before we iterate so we don't get tripped up by the lack of
2527 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2528 if (getLexer().is(AsmToken::LParen)) {
2530 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2532 if (parseOperand(Operands, Name)) {
2533 SMLoc Loc = getLexer().getLoc();
2534 Parser.eatToEndOfStatement();
2535 return Error(Loc, "unexpected token in argument list");
2537 if (Parser.getTok().isNot(AsmToken::RParen)) {
2538 SMLoc Loc = getLexer().getLoc();
2539 Parser.eatToEndOfStatement();
2540 return Error(Loc, "unexpected token, expected ')'");
2543 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2549 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2550 /// either one of these.
2551 /// ::= '[', register, ']'
2552 /// ::= '[', integer, ']'
2553 /// handle it before we iterate so we don't get tripped up by the lack of
2555 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2556 OperandVector &Operands) {
2557 if (getLexer().is(AsmToken::LBrac)) {
2559 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2561 if (parseOperand(Operands, Name)) {
2562 SMLoc Loc = getLexer().getLoc();
2563 Parser.eatToEndOfStatement();
2564 return Error(Loc, "unexpected token in argument list");
2566 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2567 SMLoc Loc = getLexer().getLoc();
2568 Parser.eatToEndOfStatement();
2569 return Error(Loc, "unexpected token, expected ']'");
2572 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2578 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2579 SMLoc NameLoc, OperandVector &Operands) {
2580 DEBUG(dbgs() << "ParseInstruction\n");
2582 // We have reached first instruction, module directive are now forbidden.
2583 getTargetStreamer().forbidModuleDirective();
2585 // Check if we have valid mnemonic
2586 if (!mnemonicIsValid(Name, 0)) {
2587 Parser.eatToEndOfStatement();
2588 return Error(NameLoc, "unknown instruction");
2590 // First operand in MCInst is instruction mnemonic.
2591 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2593 // Read the remaining operands.
2594 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2595 // Read the first operand.
2596 if (parseOperand(Operands, Name)) {
2597 SMLoc Loc = getLexer().getLoc();
2598 Parser.eatToEndOfStatement();
2599 return Error(Loc, "unexpected token in argument list");
2601 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2603 // AFAIK, parenthesis suffixes are never on the first operand
2605 while (getLexer().is(AsmToken::Comma)) {
2606 Parser.Lex(); // Eat the comma.
2607 // Parse and remember the operand.
2608 if (parseOperand(Operands, Name)) {
2609 SMLoc Loc = getLexer().getLoc();
2610 Parser.eatToEndOfStatement();
2611 return Error(Loc, "unexpected token in argument list");
2613 // Parse bracket and parenthesis suffixes before we iterate
2614 if (getLexer().is(AsmToken::LBrac)) {
2615 if (parseBracketSuffix(Name, Operands))
2617 } else if (getLexer().is(AsmToken::LParen) &&
2618 parseParenSuffix(Name, Operands))
2622 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2623 SMLoc Loc = getLexer().getLoc();
2624 Parser.eatToEndOfStatement();
2625 return Error(Loc, "unexpected token in argument list");
2627 Parser.Lex(); // Consume the EndOfStatement.
2631 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2632 SMLoc Loc = getLexer().getLoc();
2633 Parser.eatToEndOfStatement();
2634 return Error(Loc, ErrorMsg);
2637 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2638 return Error(Loc, ErrorMsg);
2641 bool MipsAsmParser::parseSetNoAtDirective() {
2642 // Line should look like: ".set noat".
2644 AssemblerOptions.back()->setATReg(0);
2647 // If this is not the end of the statement, report an error.
2648 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2649 reportParseError("unexpected token, expected end of statement");
2652 Parser.Lex(); // Consume the EndOfStatement.
2656 bool MipsAsmParser::parseSetAtDirective() {
2657 // Line can be .set at - defaults to $1
2661 if (getLexer().is(AsmToken::EndOfStatement)) {
2662 AssemblerOptions.back()->setATReg(1);
2663 Parser.Lex(); // Consume the EndOfStatement.
2665 } else if (getLexer().is(AsmToken::Equal)) {
2666 getParser().Lex(); // Eat the '='.
2667 if (getLexer().isNot(AsmToken::Dollar)) {
2668 reportParseError("unexpected token, expected dollar sign '$'");
2671 Parser.Lex(); // Eat the '$'.
2672 const AsmToken &Reg = Parser.getTok();
2673 if (Reg.is(AsmToken::Identifier)) {
2674 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2675 } else if (Reg.is(AsmToken::Integer)) {
2676 AtRegNo = Reg.getIntVal();
2678 reportParseError("unexpected token, expected identifier or integer");
2682 if (AtRegNo < 0 || AtRegNo > 31) {
2683 reportParseError("unexpected token in statement");
2687 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2688 reportParseError("invalid register");
2691 getParser().Lex(); // Eat the register.
2693 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2694 reportParseError("unexpected token, expected end of statement");
2697 Parser.Lex(); // Consume the EndOfStatement.
2700 reportParseError("unexpected token in statement");
2705 bool MipsAsmParser::parseSetReorderDirective() {
2707 // If this is not the end of the statement, report an error.
2708 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2709 reportParseError("unexpected token, expected end of statement");
2712 AssemblerOptions.back()->setReorder();
2713 getTargetStreamer().emitDirectiveSetReorder();
2714 Parser.Lex(); // Consume the EndOfStatement.
2718 bool MipsAsmParser::parseSetNoReorderDirective() {
2720 // If this is not the end of the statement, report an error.
2721 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2722 reportParseError("unexpected token, expected end of statement");
2725 AssemblerOptions.back()->setNoReorder();
2726 getTargetStreamer().emitDirectiveSetNoReorder();
2727 Parser.Lex(); // Consume the EndOfStatement.
2731 bool MipsAsmParser::parseSetMacroDirective() {
2733 // If this is not the end of the statement, report an error.
2734 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2735 reportParseError("unexpected token, expected end of statement");
2738 AssemblerOptions.back()->setMacro();
2739 Parser.Lex(); // Consume the EndOfStatement.
2743 bool MipsAsmParser::parseSetNoMacroDirective() {
2745 // If this is not the end of the statement, report an error.
2746 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2747 reportParseError("unexpected token, expected end of statement");
2750 if (AssemblerOptions.back()->isReorder()) {
2751 reportParseError("`noreorder' must be set before `nomacro'");
2754 AssemblerOptions.back()->setNoMacro();
2755 Parser.Lex(); // Consume the EndOfStatement.
2759 bool MipsAsmParser::parseSetMsaDirective() {
2762 // If this is not the end of the statement, report an error.
2763 if (getLexer().isNot(AsmToken::EndOfStatement))
2764 return reportParseError("unexpected token, expected end of statement");
2766 setFeatureBits(Mips::FeatureMSA, "msa");
2767 getTargetStreamer().emitDirectiveSetMsa();
2771 bool MipsAsmParser::parseSetNoMsaDirective() {
2774 // If this is not the end of the statement, report an error.
2775 if (getLexer().isNot(AsmToken::EndOfStatement))
2776 return reportParseError("unexpected token, expected end of statement");
2778 clearFeatureBits(Mips::FeatureMSA, "msa");
2779 getTargetStreamer().emitDirectiveSetNoMsa();
2783 bool MipsAsmParser::parseSetNoDspDirective() {
2784 Parser.Lex(); // Eat "nodsp".
2786 // If this is not the end of the statement, report an error.
2787 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2788 reportParseError("unexpected token, expected end of statement");
2792 clearFeatureBits(Mips::FeatureDSP, "dsp");
2793 getTargetStreamer().emitDirectiveSetNoDsp();
2797 bool MipsAsmParser::parseSetMips16Directive() {
2798 Parser.Lex(); // Eat "mips16".
2800 // If this is not the end of the statement, report an error.
2801 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2802 reportParseError("unexpected token, expected end of statement");
2806 setFeatureBits(Mips::FeatureMips16, "mips16");
2807 getTargetStreamer().emitDirectiveSetMips16();
2808 Parser.Lex(); // Consume the EndOfStatement.
2812 bool MipsAsmParser::parseSetNoMips16Directive() {
2813 Parser.Lex(); // Eat "nomips16".
2815 // If this is not the end of the statement, report an error.
2816 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2817 reportParseError("unexpected token, expected end of statement");
2821 clearFeatureBits(Mips::FeatureMips16, "mips16");
2822 getTargetStreamer().emitDirectiveSetNoMips16();
2823 Parser.Lex(); // Consume the EndOfStatement.
2827 bool MipsAsmParser::parseSetFpDirective() {
2828 MipsABIFlagsSection::FpABIKind FpAbiVal;
2829 // Line can be: .set fp=32
2832 Parser.Lex(); // Eat fp token
2833 AsmToken Tok = Parser.getTok();
2834 if (Tok.isNot(AsmToken::Equal)) {
2835 reportParseError("unexpected token, expected equals sign '='");
2838 Parser.Lex(); // Eat '=' token.
2839 Tok = Parser.getTok();
2841 if (!parseFpABIValue(FpAbiVal, ".set"))
2844 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2845 reportParseError("unexpected token, expected end of statement");
2848 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2849 Parser.Lex(); // Consume the EndOfStatement.
2853 bool MipsAsmParser::parseSetPopDirective() {
2854 SMLoc Loc = getLexer().getLoc();
2857 if (getLexer().isNot(AsmToken::EndOfStatement))
2858 return reportParseError("unexpected token, expected end of statement");
2860 // Always keep an element on the options "stack" to prevent the user
2861 // from changing the initial options. This is how we remember them.
2862 if (AssemblerOptions.size() == 2)
2863 return reportParseError(Loc, ".set pop with no .set push");
2865 AssemblerOptions.pop_back();
2866 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2868 getTargetStreamer().emitDirectiveSetPop();
2872 bool MipsAsmParser::parseSetPushDirective() {
2874 if (getLexer().isNot(AsmToken::EndOfStatement))
2875 return reportParseError("unexpected token, expected end of statement");
2877 // Create a copy of the current assembler options environment and push it.
2878 AssemblerOptions.push_back(
2879 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2881 getTargetStreamer().emitDirectiveSetPush();
2885 bool MipsAsmParser::parseSetAssignment() {
2887 const MCExpr *Value;
2889 if (Parser.parseIdentifier(Name))
2890 reportParseError("expected identifier after .set");
2892 if (getLexer().isNot(AsmToken::Comma))
2893 return reportParseError("unexpected token, expected comma");
2896 if (Parser.parseExpression(Value))
2897 return reportParseError("expected valid expression after comma");
2899 // Check if the Name already exists as a symbol.
2900 MCSymbol *Sym = getContext().LookupSymbol(Name);
2902 return reportParseError("symbol already defined");
2903 Sym = getContext().GetOrCreateSymbol(Name);
2904 Sym->setVariableValue(Value);
2909 bool MipsAsmParser::parseSetMips0Directive() {
2911 if (getLexer().isNot(AsmToken::EndOfStatement))
2912 return reportParseError("unexpected token, expected end of statement");
2914 // Reset assembler options to their initial values.
2915 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2916 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2918 getTargetStreamer().emitDirectiveSetMips0();
2922 bool MipsAsmParser::parseSetArchDirective() {
2924 if (getLexer().isNot(AsmToken::Equal))
2925 return reportParseError("unexpected token, expected equals sign");
2929 if (Parser.parseIdentifier(Arch))
2930 return reportParseError("expected arch identifier");
2932 StringRef ArchFeatureName =
2933 StringSwitch<StringRef>(Arch)
2934 .Case("mips1", "mips1")
2935 .Case("mips2", "mips2")
2936 .Case("mips3", "mips3")
2937 .Case("mips4", "mips4")
2938 .Case("mips5", "mips5")
2939 .Case("mips32", "mips32")
2940 .Case("mips32r2", "mips32r2")
2941 .Case("mips32r6", "mips32r6")
2942 .Case("mips64", "mips64")
2943 .Case("mips64r2", "mips64r2")
2944 .Case("mips64r6", "mips64r6")
2945 .Case("cnmips", "cnmips")
2946 .Case("r4000", "mips3") // This is an implementation of Mips3.
2949 if (ArchFeatureName.empty())
2950 return reportParseError("unsupported architecture");
2952 selectArch(ArchFeatureName);
2953 getTargetStreamer().emitDirectiveSetArch(Arch);
2957 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2959 if (getLexer().isNot(AsmToken::EndOfStatement))
2960 return reportParseError("unexpected token, expected end of statement");
2964 llvm_unreachable("Unimplemented feature");
2965 case Mips::FeatureDSP:
2966 setFeatureBits(Mips::FeatureDSP, "dsp");
2967 getTargetStreamer().emitDirectiveSetDsp();
2969 case Mips::FeatureMicroMips:
2970 getTargetStreamer().emitDirectiveSetMicroMips();
2972 case Mips::FeatureMips1:
2973 selectArch("mips1");
2974 getTargetStreamer().emitDirectiveSetMips1();
2976 case Mips::FeatureMips2:
2977 selectArch("mips2");
2978 getTargetStreamer().emitDirectiveSetMips2();
2980 case Mips::FeatureMips3:
2981 selectArch("mips3");
2982 getTargetStreamer().emitDirectiveSetMips3();
2984 case Mips::FeatureMips4:
2985 selectArch("mips4");
2986 getTargetStreamer().emitDirectiveSetMips4();
2988 case Mips::FeatureMips5:
2989 selectArch("mips5");
2990 getTargetStreamer().emitDirectiveSetMips5();
2992 case Mips::FeatureMips32:
2993 selectArch("mips32");
2994 getTargetStreamer().emitDirectiveSetMips32();
2996 case Mips::FeatureMips32r2:
2997 selectArch("mips32r2");
2998 getTargetStreamer().emitDirectiveSetMips32R2();
3000 case Mips::FeatureMips32r6:
3001 selectArch("mips32r6");
3002 getTargetStreamer().emitDirectiveSetMips32R6();
3004 case Mips::FeatureMips64:
3005 selectArch("mips64");
3006 getTargetStreamer().emitDirectiveSetMips64();
3008 case Mips::FeatureMips64r2:
3009 selectArch("mips64r2");
3010 getTargetStreamer().emitDirectiveSetMips64R2();
3012 case Mips::FeatureMips64r6:
3013 selectArch("mips64r6");
3014 getTargetStreamer().emitDirectiveSetMips64R6();
3020 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3021 if (getLexer().isNot(AsmToken::Comma)) {
3022 SMLoc Loc = getLexer().getLoc();
3023 Parser.eatToEndOfStatement();
3024 return Error(Loc, ErrorStr);
3027 Parser.Lex(); // Eat the comma.
3031 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3032 if (AssemblerOptions.back()->isReorder())
3033 Warning(Loc, ".cpload in reorder section");
3035 // FIXME: Warn if cpload is used in Mips16 mode.
3037 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3038 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3039 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3040 reportParseError("expected register containing function address");
3044 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3045 if (!RegOpnd.isGPRAsmReg()) {
3046 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3050 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3054 bool MipsAsmParser::parseDirectiveCPSetup() {
3057 bool SaveIsReg = true;
3059 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3060 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3061 if (ResTy == MatchOperand_NoMatch) {
3062 reportParseError("expected register containing function address");
3063 Parser.eatToEndOfStatement();
3067 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3068 if (!FuncRegOpnd.isGPRAsmReg()) {
3069 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3070 Parser.eatToEndOfStatement();
3074 FuncReg = FuncRegOpnd.getGPR32Reg();
3077 if (!eatComma("unexpected token, expected comma"))
3080 ResTy = parseAnyRegister(TmpReg);
3081 if (ResTy == MatchOperand_NoMatch) {
3082 const AsmToken &Tok = Parser.getTok();
3083 if (Tok.is(AsmToken::Integer)) {
3084 Save = Tok.getIntVal();
3088 reportParseError("expected save register or stack offset");
3089 Parser.eatToEndOfStatement();
3093 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3094 if (!SaveOpnd.isGPRAsmReg()) {
3095 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3096 Parser.eatToEndOfStatement();
3099 Save = SaveOpnd.getGPR32Reg();
3102 if (!eatComma("unexpected token, expected comma"))
3106 if (Parser.parseIdentifier(Name))
3107 reportParseError("expected identifier");
3108 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3110 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3114 bool MipsAsmParser::parseDirectiveNaN() {
3115 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3116 const AsmToken &Tok = Parser.getTok();
3118 if (Tok.getString() == "2008") {
3120 getTargetStreamer().emitDirectiveNaN2008();
3122 } else if (Tok.getString() == "legacy") {
3124 getTargetStreamer().emitDirectiveNaNLegacy();
3128 // If we don't recognize the option passed to the .nan
3129 // directive (e.g. no option or unknown option), emit an error.
3130 reportParseError("invalid option in .nan directive");
3134 bool MipsAsmParser::parseDirectiveSet() {
3136 // Get the next token.
3137 const AsmToken &Tok = Parser.getTok();
3139 if (Tok.getString() == "noat") {
3140 return parseSetNoAtDirective();
3141 } else if (Tok.getString() == "at") {
3142 return parseSetAtDirective();
3143 } else if (Tok.getString() == "arch") {
3144 return parseSetArchDirective();
3145 } else if (Tok.getString() == "fp") {
3146 return parseSetFpDirective();
3147 } else if (Tok.getString() == "pop") {
3148 return parseSetPopDirective();
3149 } else if (Tok.getString() == "push") {
3150 return parseSetPushDirective();
3151 } else if (Tok.getString() == "reorder") {
3152 return parseSetReorderDirective();
3153 } else if (Tok.getString() == "noreorder") {
3154 return parseSetNoReorderDirective();
3155 } else if (Tok.getString() == "macro") {
3156 return parseSetMacroDirective();
3157 } else if (Tok.getString() == "nomacro") {
3158 return parseSetNoMacroDirective();
3159 } else if (Tok.getString() == "mips16") {
3160 return parseSetMips16Directive();
3161 } else if (Tok.getString() == "nomips16") {
3162 return parseSetNoMips16Directive();
3163 } else if (Tok.getString() == "nomicromips") {
3164 getTargetStreamer().emitDirectiveSetNoMicroMips();
3165 Parser.eatToEndOfStatement();
3167 } else if (Tok.getString() == "micromips") {
3168 return parseSetFeature(Mips::FeatureMicroMips);
3169 } else if (Tok.getString() == "mips0") {
3170 return parseSetMips0Directive();
3171 } else if (Tok.getString() == "mips1") {
3172 return parseSetFeature(Mips::FeatureMips1);
3173 } else if (Tok.getString() == "mips2") {
3174 return parseSetFeature(Mips::FeatureMips2);
3175 } else if (Tok.getString() == "mips3") {
3176 return parseSetFeature(Mips::FeatureMips3);
3177 } else if (Tok.getString() == "mips4") {
3178 return parseSetFeature(Mips::FeatureMips4);
3179 } else if (Tok.getString() == "mips5") {
3180 return parseSetFeature(Mips::FeatureMips5);
3181 } else if (Tok.getString() == "mips32") {
3182 return parseSetFeature(Mips::FeatureMips32);
3183 } else if (Tok.getString() == "mips32r2") {
3184 return parseSetFeature(Mips::FeatureMips32r2);
3185 } else if (Tok.getString() == "mips32r6") {
3186 return parseSetFeature(Mips::FeatureMips32r6);
3187 } else if (Tok.getString() == "mips64") {
3188 return parseSetFeature(Mips::FeatureMips64);
3189 } else if (Tok.getString() == "mips64r2") {
3190 return parseSetFeature(Mips::FeatureMips64r2);
3191 } else if (Tok.getString() == "mips64r6") {
3192 return parseSetFeature(Mips::FeatureMips64r6);
3193 } else if (Tok.getString() == "dsp") {
3194 return parseSetFeature(Mips::FeatureDSP);
3195 } else if (Tok.getString() == "nodsp") {
3196 return parseSetNoDspDirective();
3197 } else if (Tok.getString() == "msa") {
3198 return parseSetMsaDirective();
3199 } else if (Tok.getString() == "nomsa") {
3200 return parseSetNoMsaDirective();
3202 // It is just an identifier, look for an assignment.
3203 parseSetAssignment();
3210 /// parseDataDirective
3211 /// ::= .word [ expression (, expression)* ]
3212 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3213 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3215 const MCExpr *Value;
3216 if (getParser().parseExpression(Value))
3219 getParser().getStreamer().EmitValue(Value, Size);
3221 if (getLexer().is(AsmToken::EndOfStatement))
3224 if (getLexer().isNot(AsmToken::Comma))
3225 return Error(L, "unexpected token, expected comma");
3234 /// parseDirectiveGpWord
3235 /// ::= .gpword local_sym
3236 bool MipsAsmParser::parseDirectiveGpWord() {
3237 const MCExpr *Value;
3238 // EmitGPRel32Value requires an expression, so we are using base class
3239 // method to evaluate the expression.
3240 if (getParser().parseExpression(Value))
3242 getParser().getStreamer().EmitGPRel32Value(Value);
3244 if (getLexer().isNot(AsmToken::EndOfStatement))
3245 return Error(getLexer().getLoc(),
3246 "unexpected token, expected end of statement");
3247 Parser.Lex(); // Eat EndOfStatement token.
3251 /// parseDirectiveGpDWord
3252 /// ::= .gpdword local_sym
3253 bool MipsAsmParser::parseDirectiveGpDWord() {
3254 const MCExpr *Value;
3255 // EmitGPRel64Value requires an expression, so we are using base class
3256 // method to evaluate the expression.
3257 if (getParser().parseExpression(Value))
3259 getParser().getStreamer().EmitGPRel64Value(Value);
3261 if (getLexer().isNot(AsmToken::EndOfStatement))
3262 return Error(getLexer().getLoc(),
3263 "unexpected token, expected end of statement");
3264 Parser.Lex(); // Eat EndOfStatement token.
3268 bool MipsAsmParser::parseDirectiveOption() {
3269 // Get the option token.
3270 AsmToken Tok = Parser.getTok();
3271 // At the moment only identifiers are supported.
3272 if (Tok.isNot(AsmToken::Identifier)) {
3273 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3274 Parser.eatToEndOfStatement();
3278 StringRef Option = Tok.getIdentifier();
3280 if (Option == "pic0") {
3281 getTargetStreamer().emitDirectiveOptionPic0();
3283 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3284 Error(Parser.getTok().getLoc(),
3285 "unexpected token, expected end of statement");
3286 Parser.eatToEndOfStatement();
3291 if (Option == "pic2") {
3292 getTargetStreamer().emitDirectiveOptionPic2();
3294 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3295 Error(Parser.getTok().getLoc(),
3296 "unexpected token, expected end of statement");
3297 Parser.eatToEndOfStatement();
3303 Warning(Parser.getTok().getLoc(),
3304 "unknown option, expected 'pic0' or 'pic2'");
3305 Parser.eatToEndOfStatement();
3309 /// parseDirectiveModule
3310 /// ::= .module oddspreg
3311 /// ::= .module nooddspreg
3312 /// ::= .module fp=value
3313 bool MipsAsmParser::parseDirectiveModule() {
3314 MCAsmLexer &Lexer = getLexer();
3315 SMLoc L = Lexer.getLoc();
3317 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3318 // TODO : get a better message.
3319 reportParseError(".module directive must appear before any code");
3323 if (Lexer.is(AsmToken::Identifier)) {
3324 StringRef Option = Parser.getTok().getString();
3327 if (Option == "oddspreg") {
3328 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3329 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3331 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3332 reportParseError("unexpected token, expected end of statement");
3337 } else if (Option == "nooddspreg") {
3339 Error(L, "'.module nooddspreg' requires the O32 ABI");
3343 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3344 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3346 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3347 reportParseError("unexpected token, expected end of statement");
3352 } else if (Option == "fp") {
3353 return parseDirectiveModuleFP();
3356 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3362 /// parseDirectiveModuleFP
3366 bool MipsAsmParser::parseDirectiveModuleFP() {
3367 MCAsmLexer &Lexer = getLexer();
3369 if (Lexer.isNot(AsmToken::Equal)) {
3370 reportParseError("unexpected token, expected equals sign '='");
3373 Parser.Lex(); // Eat '=' token.
3375 MipsABIFlagsSection::FpABIKind FpABI;
3376 if (!parseFpABIValue(FpABI, ".module"))
3379 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3380 reportParseError("unexpected token, expected end of statement");
3384 // Emit appropriate flags.
3385 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3386 Parser.Lex(); // Consume the EndOfStatement.
3390 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3391 StringRef Directive) {
3392 MCAsmLexer &Lexer = getLexer();
3394 if (Lexer.is(AsmToken::Identifier)) {
3395 StringRef Value = Parser.getTok().getString();
3398 if (Value != "xx") {
3399 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3404 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3408 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3412 if (Lexer.is(AsmToken::Integer)) {
3413 unsigned Value = Parser.getTok().getIntVal();
3416 if (Value != 32 && Value != 64) {
3417 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3423 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3427 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3429 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3437 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3438 StringRef IDVal = DirectiveID.getString();
3440 if (IDVal == ".cpload")
3441 return parseDirectiveCpLoad(DirectiveID.getLoc());
3442 if (IDVal == ".dword") {
3443 parseDataDirective(8, DirectiveID.getLoc());
3446 if (IDVal == ".ent") {
3447 StringRef SymbolName;
3449 if (Parser.parseIdentifier(SymbolName)) {
3450 reportParseError("expected identifier after .ent");
3454 // There's an undocumented extension that allows an integer to
3455 // follow the name of the procedure which AFAICS is ignored by GAS.
3456 // Example: .ent foo,2
3457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3458 if (getLexer().isNot(AsmToken::Comma)) {
3459 // Even though we accept this undocumented extension for compatibility
3460 // reasons, the additional integer argument does not actually change
3461 // the behaviour of the '.ent' directive, so we would like to discourage
3462 // its use. We do this by not referring to the extended version in
3463 // error messages which are not directly related to its use.
3464 reportParseError("unexpected token, expected end of statement");
3467 Parser.Lex(); // Eat the comma.
3468 const MCExpr *DummyNumber;
3469 int64_t DummyNumberVal;
3470 // If the user was explicitly trying to use the extended version,
3471 // we still give helpful extension-related error messages.
3472 if (Parser.parseExpression(DummyNumber)) {
3473 reportParseError("expected number after comma");
3476 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3477 reportParseError("expected an absolute expression after comma");
3482 // If this is not the end of the statement, report an error.
3483 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3484 reportParseError("unexpected token, expected end of statement");
3488 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3490 getTargetStreamer().emitDirectiveEnt(*Sym);
3495 if (IDVal == ".end") {
3496 StringRef SymbolName;
3498 if (Parser.parseIdentifier(SymbolName)) {
3499 reportParseError("expected identifier after .end");
3503 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3504 reportParseError("unexpected token, expected end of statement");
3508 if (CurrentFn == nullptr) {
3509 reportParseError(".end used without .ent");
3513 if ((SymbolName != CurrentFn->getName())) {
3514 reportParseError(".end symbol does not match .ent symbol");
3518 getTargetStreamer().emitDirectiveEnd(SymbolName);
3519 CurrentFn = nullptr;
3523 if (IDVal == ".frame") {
3524 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3525 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3526 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3527 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3528 reportParseError("expected stack register");
3532 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3533 if (!StackRegOpnd.isGPRAsmReg()) {
3534 reportParseError(StackRegOpnd.getStartLoc(),
3535 "expected general purpose register");
3538 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3540 if (Parser.getTok().is(AsmToken::Comma))
3543 reportParseError("unexpected token, expected comma");
3547 // Parse the frame size.
3548 const MCExpr *FrameSize;
3549 int64_t FrameSizeVal;
3551 if (Parser.parseExpression(FrameSize)) {
3552 reportParseError("expected frame size value");
3556 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3557 reportParseError("frame size not an absolute expression");
3561 if (Parser.getTok().is(AsmToken::Comma))
3564 reportParseError("unexpected token, expected comma");
3568 // Parse the return register.
3570 ResTy = parseAnyRegister(TmpReg);
3571 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3572 reportParseError("expected return register");
3576 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3577 if (!ReturnRegOpnd.isGPRAsmReg()) {
3578 reportParseError(ReturnRegOpnd.getStartLoc(),
3579 "expected general purpose register");
3583 // If this is not the end of the statement, report an error.
3584 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3585 reportParseError("unexpected token, expected end of statement");
3589 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3590 ReturnRegOpnd.getGPR32Reg());
3594 if (IDVal == ".set") {
3595 return parseDirectiveSet();
3598 if (IDVal == ".mask" || IDVal == ".fmask") {
3599 // .mask bitmask, frame_offset
3600 // bitmask: One bit for each register used.
3601 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3602 // first register is expected to be saved.
3604 // .mask 0x80000000, -4
3605 // .fmask 0x80000000, -4
3608 // Parse the bitmask
3609 const MCExpr *BitMask;
3612 if (Parser.parseExpression(BitMask)) {
3613 reportParseError("expected bitmask value");
3617 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3618 reportParseError("bitmask not an absolute expression");
3622 if (Parser.getTok().is(AsmToken::Comma))
3625 reportParseError("unexpected token, expected comma");
3629 // Parse the frame_offset
3630 const MCExpr *FrameOffset;
3631 int64_t FrameOffsetVal;
3633 if (Parser.parseExpression(FrameOffset)) {
3634 reportParseError("expected frame offset value");
3638 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3639 reportParseError("frame offset not an absolute expression");
3643 // If this is not the end of the statement, report an error.
3644 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3645 reportParseError("unexpected token, expected end of statement");
3649 if (IDVal == ".mask")
3650 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3652 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3656 if (IDVal == ".nan")
3657 return parseDirectiveNaN();
3659 if (IDVal == ".gpword") {
3660 parseDirectiveGpWord();
3664 if (IDVal == ".gpdword") {
3665 parseDirectiveGpDWord();
3669 if (IDVal == ".word") {
3670 parseDataDirective(4, DirectiveID.getLoc());
3674 if (IDVal == ".option")
3675 return parseDirectiveOption();
3677 if (IDVal == ".abicalls") {
3678 getTargetStreamer().emitDirectiveAbiCalls();
3679 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3680 Error(Parser.getTok().getLoc(),
3681 "unexpected token, expected end of statement");
3683 Parser.eatToEndOfStatement();
3688 if (IDVal == ".cpsetup")
3689 return parseDirectiveCPSetup();
3691 if (IDVal == ".module")
3692 return parseDirectiveModule();
3697 extern "C" void LLVMInitializeMipsAsmParser() {
3698 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3699 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3700 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3701 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3704 #define GET_REGISTER_MATCHER
3705 #define GET_MATCHER_IMPLEMENTATION
3706 #include "MipsGenAsmMatcher.inc"