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 parseSetNoMips16Directive();
204 bool parseSetFpDirective();
205 bool parseSetPopDirective();
206 bool parseSetPushDirective();
208 bool parseSetAssignment();
210 bool parseDataDirective(unsigned Size, SMLoc L);
211 bool parseDirectiveGpWord();
212 bool parseDirectiveGpDWord();
213 bool parseDirectiveModule();
214 bool parseDirectiveModuleFP();
215 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
216 StringRef Directive);
218 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
220 bool eatComma(StringRef ErrorStr);
222 int matchCPURegisterName(StringRef Symbol);
224 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
226 int matchFPURegisterName(StringRef Name);
228 int matchFCCRegisterName(StringRef Name);
230 int matchACRegisterName(StringRef Name);
232 int matchMSA128RegisterName(StringRef Name);
234 int matchMSA128CtrlRegisterName(StringRef Name);
236 unsigned getReg(int RC, int RegNo);
238 unsigned getGPR(int RegNo);
240 int getATReg(SMLoc Loc);
242 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
243 SmallVectorImpl<MCInst> &Instructions);
245 // Helper function that checks if the value of a vector index is within the
246 // boundaries of accepted values for each RegisterKind
247 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
248 bool validateMSAIndex(int Val, int RegKind);
250 // Selects a new architecture by updating the FeatureBits with the necessary
251 // info including implied dependencies.
252 // Internally, it clears all the feature bits related to *any* architecture
253 // and selects the new one using the ToggleFeature functionality of the
254 // MCSubtargetInfo object that handles implied dependencies. The reason we
255 // clear all the arch related bits manually is because ToggleFeature only
256 // clears the features that imply the feature being cleared and not the
257 // features implied by the feature being cleared. This is easier to see
259 // --------------------------------------------------
260 // | Feature | Implies |
261 // | -------------------------------------------------|
262 // | FeatureMips1 | None |
263 // | FeatureMips2 | FeatureMips1 |
264 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
265 // | FeatureMips4 | FeatureMips3 |
267 // --------------------------------------------------
269 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
270 // FeatureMipsGP64 | FeatureMips1)
271 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
272 void selectArch(StringRef ArchFeature) {
273 uint64_t FeatureBits = STI.getFeatureBits();
274 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
275 STI.setFeatureBits(FeatureBits);
276 setAvailableFeatures(
277 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
278 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
281 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
282 if (!(STI.getFeatureBits() & Feature)) {
283 setAvailableFeatures(
284 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
286 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
289 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
290 if (STI.getFeatureBits() & Feature) {
291 setAvailableFeatures(
292 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
294 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
298 enum MipsMatchResultTy {
299 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
300 #define GET_OPERAND_DIAGNOSTIC_TYPES
301 #include "MipsGenAsmMatcher.inc"
302 #undef GET_OPERAND_DIAGNOSTIC_TYPES
306 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
307 const MCInstrInfo &MII, const MCTargetOptions &Options)
308 : MCTargetAsmParser(), STI(sti), Parser(parser) {
309 // Initialize the set of available features.
310 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
312 // Remember the initial assembler options. The user can not modify these.
313 AssemblerOptions.push_back(
314 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
316 // Create an assembler options environment for the user to modify.
317 AssemblerOptions.push_back(
318 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
320 getTargetStreamer().updateABIInfo(*this);
322 // Assert exactly one ABI was chosen.
323 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
324 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
325 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
326 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
328 if (!isABI_O32() && !useOddSPReg() != 0)
329 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
334 MCAsmParser &getParser() const { return Parser; }
335 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
337 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
338 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
340 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
341 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
342 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
343 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
344 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
345 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
347 bool useOddSPReg() const {
348 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
351 bool inMicroMipsMode() const {
352 return STI.getFeatureBits() & Mips::FeatureMicroMips;
354 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
355 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
356 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
357 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
358 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
359 bool hasMips32() const {
360 return (STI.getFeatureBits() & Mips::FeatureMips32);
362 bool hasMips64() const {
363 return (STI.getFeatureBits() & Mips::FeatureMips64);
365 bool hasMips32r2() const {
366 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
368 bool hasMips64r2() const {
369 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
371 bool hasMips32r6() const {
372 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
374 bool hasMips64r6() const {
375 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
377 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
378 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
379 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
381 bool inMips16Mode() const {
382 return STI.getFeatureBits() & Mips::FeatureMips16;
384 // TODO: see how can we get this info.
385 bool abiUsesSoftFloat() const { return false; }
387 /// Warn if RegNo is the current assembler temporary.
388 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
394 /// MipsOperand - Instances of this class represent a parsed Mips machine
396 class MipsOperand : public MCParsedAsmOperand {
398 /// Broad categories of register classes
399 /// The exact class is finalized by the render method.
401 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
402 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
404 RegKind_FCC = 4, /// FCC
405 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
406 RegKind_MSACtrl = 16, /// MSA control registers
407 RegKind_COP2 = 32, /// COP2
408 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
410 RegKind_CCR = 128, /// CCR
411 RegKind_HWRegs = 256, /// HWRegs
412 RegKind_COP3 = 512, /// COP3
414 /// Potentially any (e.g. $1)
415 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
416 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
417 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
422 k_Immediate, /// An immediate (possibly involving symbol references)
423 k_Memory, /// Base + Offset Memory Address
424 k_PhysRegister, /// A physical register from the Mips namespace
425 k_RegisterIndex, /// A register index in one or more RegKind.
426 k_Token /// A simple token
430 MipsOperand(KindTy K, MipsAsmParser &Parser)
431 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
434 /// For diagnostics, and checking the assembler temporary
435 MipsAsmParser &AsmParser;
443 unsigned Num; /// Register Number
447 unsigned Index; /// Index into the register class
448 RegKind Kind; /// Bitfield of the kinds it could possibly be
449 const MCRegisterInfo *RegInfo;
463 struct PhysRegOp PhysReg;
464 struct RegIdxOp RegIdx;
469 SMLoc StartLoc, EndLoc;
471 /// Internal constructor for register kinds
472 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
473 const MCRegisterInfo *RegInfo,
475 MipsAsmParser &Parser) {
476 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
477 Op->RegIdx.Index = Index;
478 Op->RegIdx.RegInfo = RegInfo;
479 Op->RegIdx.Kind = RegKind;
486 /// Coerce the register to GPR32 and return the real register for the current
488 unsigned getGPR32Reg() const {
489 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
490 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
491 unsigned ClassID = Mips::GPR32RegClassID;
492 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
495 /// Coerce the register to GPR32 and return the real register for the current
497 unsigned getGPRMM16Reg() const {
498 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
499 unsigned ClassID = Mips::GPR32RegClassID;
500 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
503 /// Coerce the register to GPR64 and return the real register for the current
505 unsigned getGPR64Reg() const {
506 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
507 unsigned ClassID = Mips::GPR64RegClassID;
508 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
512 /// Coerce the register to AFGR64 and return the real register for the current
514 unsigned getAFGR64Reg() const {
515 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
516 if (RegIdx.Index % 2 != 0)
517 AsmParser.Warning(StartLoc, "Float register should be even.");
518 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
519 .getRegister(RegIdx.Index / 2);
522 /// Coerce the register to FGR64 and return the real register for the current
524 unsigned getFGR64Reg() const {
525 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
526 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
527 .getRegister(RegIdx.Index);
530 /// Coerce the register to FGR32 and return the real register for the current
532 unsigned getFGR32Reg() const {
533 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
534 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
535 .getRegister(RegIdx.Index);
538 /// Coerce the register to FGRH32 and return the real register for the current
540 unsigned getFGRH32Reg() const {
541 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
542 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
543 .getRegister(RegIdx.Index);
546 /// Coerce the register to FCC and return the real register for the current
548 unsigned getFCCReg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
550 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
551 .getRegister(RegIdx.Index);
554 /// Coerce the register to MSA128 and return the real register for the current
556 unsigned getMSA128Reg() const {
557 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
558 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
560 unsigned ClassID = Mips::MSA128BRegClassID;
561 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
564 /// Coerce the register to MSACtrl and return the real register for the
566 unsigned getMSACtrlReg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
568 unsigned ClassID = Mips::MSACtrlRegClassID;
569 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
572 /// Coerce the register to COP2 and return the real register for the
574 unsigned getCOP2Reg() const {
575 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
576 unsigned ClassID = Mips::COP2RegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to COP3 and return the real register for the
582 unsigned getCOP3Reg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
584 unsigned ClassID = Mips::COP3RegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
588 /// Coerce the register to ACC64DSP and return the real register for the
590 unsigned getACC64DSPReg() const {
591 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
592 unsigned ClassID = Mips::ACC64DSPRegClassID;
593 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
596 /// Coerce the register to HI32DSP and return the real register for the
598 unsigned getHI32DSPReg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
600 unsigned ClassID = Mips::HI32DSPRegClassID;
601 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604 /// Coerce the register to LO32DSP and return the real register for the
606 unsigned getLO32DSPReg() const {
607 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
608 unsigned ClassID = Mips::LO32DSPRegClassID;
609 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
612 /// Coerce the register to CCR and return the real register for the
614 unsigned getCCRReg() const {
615 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
616 unsigned ClassID = Mips::CCRRegClassID;
617 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
620 /// Coerce the register to HWRegs and return the real register for the
622 unsigned getHWRegsReg() const {
623 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
624 unsigned ClassID = Mips::HWRegsRegClassID;
625 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
629 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
630 // Add as immediate when possible. Null MCExpr = 0.
632 Inst.addOperand(MCOperand::CreateImm(0));
633 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
634 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
636 Inst.addOperand(MCOperand::CreateExpr(Expr));
639 void addRegOperands(MCInst &Inst, unsigned N) const {
640 llvm_unreachable("Use a custom parser instead");
643 /// Render the operand to an MCInst as a GPR32
644 /// Asserts if the wrong number of operands are requested, or the operand
645 /// is not a k_RegisterIndex compatible with RegKind_GPR
646 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
647 assert(N == 1 && "Invalid number of operands!");
648 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
651 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
656 /// Render the operand to an MCInst as a GPR64
657 /// Asserts if the wrong number of operands are requested, or the operand
658 /// is not a k_RegisterIndex compatible with RegKind_GPR
659 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
660 assert(N == 1 && "Invalid number of operands!");
661 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
664 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
665 assert(N == 1 && "Invalid number of operands!");
666 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
669 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
670 assert(N == 1 && "Invalid number of operands!");
671 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
674 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
675 assert(N == 1 && "Invalid number of operands!");
676 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
677 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
678 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
679 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
683 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
684 assert(N == 1 && "Invalid number of operands!");
685 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
688 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
689 assert(N == 1 && "Invalid number of operands!");
690 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
693 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
694 assert(N == 1 && "Invalid number of operands!");
695 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
698 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
699 assert(N == 1 && "Invalid number of operands!");
700 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
703 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
708 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
709 assert(N == 1 && "Invalid number of operands!");
710 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
713 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
714 assert(N == 1 && "Invalid number of operands!");
715 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
718 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
719 assert(N == 1 && "Invalid number of operands!");
720 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
723 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
724 assert(N == 1 && "Invalid number of operands!");
725 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
728 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
733 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
738 void addImmOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 const MCExpr *Expr = getImm();
744 void addMemOperands(MCInst &Inst, unsigned N) const {
745 assert(N == 2 && "Invalid number of operands!");
747 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
749 const MCExpr *Expr = getMemOff();
753 bool isReg() const override {
754 // As a special case until we sort out the definition of div/divu, pretend
755 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
756 if (isGPRAsmReg() && RegIdx.Index == 0)
759 return Kind == k_PhysRegister;
761 bool isRegIdx() const { return Kind == k_RegisterIndex; }
762 bool isImm() const override { return Kind == k_Immediate; }
763 bool isConstantImm() const {
764 return isImm() && dyn_cast<MCConstantExpr>(getImm());
766 bool isToken() const override {
767 // Note: It's not possible to pretend that other operand kinds are tokens.
768 // The matcher emitter checks tokens first.
769 return Kind == k_Token;
771 bool isMem() const override { return Kind == k_Memory; }
772 bool isConstantMemOff() const {
773 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
775 template <unsigned Bits> bool isMemWithSimmOffset() const {
776 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
778 bool isInvNum() const { return Kind == k_Immediate; }
779 bool isLSAImm() const {
780 if (!isConstantImm())
782 int64_t Val = getConstantImm();
783 return 1 <= Val && Val <= 4;
786 StringRef getToken() const {
787 assert(Kind == k_Token && "Invalid access!");
788 return StringRef(Tok.Data, Tok.Length);
791 unsigned getReg() const override {
792 // As a special case until we sort out the definition of div/divu, pretend
793 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
794 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
795 RegIdx.Kind & RegKind_GPR)
796 return getGPR32Reg(); // FIXME: GPR64 too
798 assert(Kind == k_PhysRegister && "Invalid access!");
802 const MCExpr *getImm() const {
803 assert((Kind == k_Immediate) && "Invalid access!");
807 int64_t getConstantImm() const {
808 const MCExpr *Val = getImm();
809 return static_cast<const MCConstantExpr *>(Val)->getValue();
812 MipsOperand *getMemBase() const {
813 assert((Kind == k_Memory) && "Invalid access!");
817 const MCExpr *getMemOff() const {
818 assert((Kind == k_Memory) && "Invalid access!");
822 int64_t getConstantMemOff() const {
823 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
826 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
827 MipsAsmParser &Parser) {
828 auto Op = make_unique<MipsOperand>(k_Token, Parser);
829 Op->Tok.Data = Str.data();
830 Op->Tok.Length = Str.size();
836 /// Create a numeric register (e.g. $1). The exact register remains
837 /// unresolved until an instruction successfully matches
838 static std::unique_ptr<MipsOperand>
839 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
840 SMLoc E, MipsAsmParser &Parser) {
841 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
842 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
845 /// Create a register that is definitely a GPR.
846 /// This is typically only used for named registers such as $gp.
847 static std::unique_ptr<MipsOperand>
848 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
849 MipsAsmParser &Parser) {
850 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
853 /// Create a register that is definitely a FGR.
854 /// This is typically only used for named registers such as $f0.
855 static std::unique_ptr<MipsOperand>
856 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
857 MipsAsmParser &Parser) {
858 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
861 /// Create a register that is definitely an FCC.
862 /// This is typically only used for named registers such as $fcc0.
863 static std::unique_ptr<MipsOperand>
864 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
865 MipsAsmParser &Parser) {
866 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
869 /// Create a register that is definitely an ACC.
870 /// This is typically only used for named registers such as $ac0.
871 static std::unique_ptr<MipsOperand>
872 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
873 MipsAsmParser &Parser) {
874 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
877 /// Create a register that is definitely an MSA128.
878 /// This is typically only used for named registers such as $w0.
879 static std::unique_ptr<MipsOperand>
880 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
881 SMLoc E, MipsAsmParser &Parser) {
882 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
885 /// Create a register that is definitely an MSACtrl.
886 /// This is typically only used for named registers such as $msaaccess.
887 static std::unique_ptr<MipsOperand>
888 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
889 SMLoc E, MipsAsmParser &Parser) {
890 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
893 static std::unique_ptr<MipsOperand>
894 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
895 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
902 static std::unique_ptr<MipsOperand>
903 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
904 SMLoc E, MipsAsmParser &Parser) {
905 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
906 Op->Mem.Base = Base.release();
913 bool isGPRAsmReg() const {
914 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
916 bool isMM16AsmReg() const {
917 if (!(isRegIdx() && RegIdx.Kind))
919 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
920 || RegIdx.Index == 16 || RegIdx.Index == 17);
922 bool isFGRAsmReg() const {
923 // AFGR64 is $0-$15 but we handle this in getAFGR64()
924 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
926 bool isHWRegsAsmReg() const {
927 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
929 bool isCCRAsmReg() const {
930 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
932 bool isFCCAsmReg() const {
933 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
935 if (!AsmParser.hasEightFccRegisters())
936 return RegIdx.Index == 0;
937 return RegIdx.Index <= 7;
939 bool isACCAsmReg() const {
940 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
942 bool isCOP2AsmReg() const {
943 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
945 bool isCOP3AsmReg() const {
946 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
948 bool isMSA128AsmReg() const {
949 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
951 bool isMSACtrlAsmReg() const {
952 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
955 /// getStartLoc - Get the location of the first token of this operand.
956 SMLoc getStartLoc() const override { return StartLoc; }
957 /// getEndLoc - Get the location of the last token of this operand.
958 SMLoc getEndLoc() const override { return EndLoc; }
960 virtual ~MipsOperand() {
968 case k_RegisterIndex:
974 void print(raw_ostream &OS) const override {
989 OS << "PhysReg<" << PhysReg.Num << ">";
991 case k_RegisterIndex:
992 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
999 }; // class MipsOperand
1003 extern const MCInstrDesc MipsInsts[];
1005 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1006 return MipsInsts[Opcode];
1009 static bool hasShortDelaySlot(unsigned Opcode) {
1012 case Mips::JALRS_MM:
1013 case Mips::JALRS16_MM:
1014 case Mips::BGEZALS_MM:
1015 case Mips::BLTZALS_MM:
1022 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1023 SmallVectorImpl<MCInst> &Instructions) {
1024 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1028 if (MCID.isBranch() || MCID.isCall()) {
1029 const unsigned Opcode = Inst.getOpcode();
1039 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1040 Offset = Inst.getOperand(2);
1041 if (!Offset.isImm())
1042 break; // We'll deal with this situation later on when applying fixups.
1043 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1044 return Error(IDLoc, "branch target out of range");
1045 if (OffsetToAlignment(Offset.getImm(),
1046 1LL << (inMicroMipsMode() ? 1 : 2)))
1047 return Error(IDLoc, "branch to misaligned address");
1061 case Mips::BGEZAL_MM:
1062 case Mips::BLTZAL_MM:
1065 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1066 Offset = Inst.getOperand(1);
1067 if (!Offset.isImm())
1068 break; // We'll deal with this situation later on when applying fixups.
1069 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1070 return Error(IDLoc, "branch target out of range");
1071 if (OffsetToAlignment(Offset.getImm(),
1072 1LL << (inMicroMipsMode() ? 1 : 2)))
1073 return Error(IDLoc, "branch to misaligned address");
1078 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1079 // We still accept it but it is a normal nop.
1080 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1081 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1082 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1086 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1087 // If this instruction has a delay slot and .set reorder is active,
1088 // emit a NOP after it.
1089 Instructions.push_back(Inst);
1091 if (hasShortDelaySlot(Inst.getOpcode())) {
1092 NopInst.setOpcode(Mips::MOVE16_MM);
1093 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1094 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1096 NopInst.setOpcode(Mips::SLL);
1097 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1098 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1099 NopInst.addOperand(MCOperand::CreateImm(0));
1101 Instructions.push_back(NopInst);
1105 if (MCID.mayLoad() || MCID.mayStore()) {
1106 // Check the offset of memory operand, if it is a symbol
1107 // reference or immediate we may have to expand instructions.
1108 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1109 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1110 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1111 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1112 MCOperand &Op = Inst.getOperand(i);
1114 int MemOffset = Op.getImm();
1115 if (MemOffset < -32768 || MemOffset > 32767) {
1116 // Offset can't exceed 16bit value.
1117 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1120 } else if (Op.isExpr()) {
1121 const MCExpr *Expr = Op.getExpr();
1122 if (Expr->getKind() == MCExpr::SymbolRef) {
1123 const MCSymbolRefExpr *SR =
1124 static_cast<const MCSymbolRefExpr *>(Expr);
1125 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1127 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1130 } else if (!isEvaluated(Expr)) {
1131 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1139 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1140 if (inMicroMipsMode()) {
1144 switch (Inst.getOpcode()) {
1147 case Mips::ADDIUS5_MM:
1148 Opnd = Inst.getOperand(2);
1150 return Error(IDLoc, "expected immediate operand kind");
1151 Imm = Opnd.getImm();
1152 if (Imm < -8 || Imm > 7)
1153 return Error(IDLoc, "immediate operand value out of range");
1155 case Mips::ADDIUSP_MM:
1156 Opnd = Inst.getOperand(0);
1158 return Error(IDLoc, "expected immediate operand kind");
1159 Imm = Opnd.getImm();
1160 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1162 return Error(IDLoc, "immediate operand value out of range");
1164 case Mips::SLL16_MM:
1165 case Mips::SRL16_MM:
1166 Opnd = Inst.getOperand(2);
1168 return Error(IDLoc, "expected immediate operand kind");
1169 Imm = Opnd.getImm();
1170 if (Imm < 1 || Imm > 8)
1171 return Error(IDLoc, "immediate operand value out of range");
1176 if (needsExpansion(Inst))
1177 return expandInstruction(Inst, IDLoc, Instructions);
1179 Instructions.push_back(Inst);
1184 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1186 switch (Inst.getOpcode()) {
1187 case Mips::LoadImm32Reg:
1188 case Mips::LoadAddr32Imm:
1189 case Mips::LoadAddr32Reg:
1190 case Mips::LoadImm64Reg:
1197 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1198 SmallVectorImpl<MCInst> &Instructions) {
1199 switch (Inst.getOpcode()) {
1201 assert(0 && "unimplemented expansion");
1203 case Mips::LoadImm32Reg:
1204 return expandLoadImm(Inst, IDLoc, Instructions);
1205 case Mips::LoadImm64Reg:
1207 Error(IDLoc, "instruction requires a 64-bit architecture");
1210 return expandLoadImm(Inst, IDLoc, Instructions);
1211 case Mips::LoadAddr32Imm:
1212 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1213 case Mips::LoadAddr32Reg:
1214 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1219 template <bool PerformShift>
1220 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1221 SmallVectorImpl<MCInst> &Instructions) {
1224 tmpInst.setOpcode(Mips::DSLL);
1225 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1226 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1227 tmpInst.addOperand(MCOperand::CreateImm(16));
1228 tmpInst.setLoc(IDLoc);
1229 Instructions.push_back(tmpInst);
1232 tmpInst.setOpcode(Mips::ORi);
1233 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1234 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1235 tmpInst.addOperand(Operand);
1236 tmpInst.setLoc(IDLoc);
1237 Instructions.push_back(tmpInst);
1240 template <int Shift, bool PerformShift>
1241 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1242 SmallVectorImpl<MCInst> &Instructions) {
1243 createShiftOr<PerformShift>(
1244 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1245 IDLoc, Instructions);
1249 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1250 SmallVectorImpl<MCInst> &Instructions) {
1252 const MCOperand &ImmOp = Inst.getOperand(1);
1253 assert(ImmOp.isImm() && "expected immediate operand kind");
1254 const MCOperand &RegOp = Inst.getOperand(0);
1255 assert(RegOp.isReg() && "expected register operand kind");
1257 int64_t ImmValue = ImmOp.getImm();
1258 tmpInst.setLoc(IDLoc);
1259 // FIXME: gas has a special case for values that are 000...1111, which
1260 // becomes a li -1 and then a dsrl
1261 if (0 <= ImmValue && ImmValue <= 65535) {
1262 // For 0 <= j <= 65535.
1263 // li d,j => ori d,$zero,j
1264 tmpInst.setOpcode(Mips::ORi);
1265 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1266 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1267 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1268 Instructions.push_back(tmpInst);
1269 } else if (ImmValue < 0 && ImmValue >= -32768) {
1270 // For -32768 <= j < 0.
1271 // li d,j => addiu d,$zero,j
1272 tmpInst.setOpcode(Mips::ADDiu);
1273 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1274 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1275 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1276 Instructions.push_back(tmpInst);
1277 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1278 // For any value of j that is representable as a 32-bit integer, create
1280 // li d,j => lui d,hi16(j)
1282 tmpInst.setOpcode(Mips::LUi);
1283 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1284 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1285 Instructions.push_back(tmpInst);
1286 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1287 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1289 Error(IDLoc, "instruction requires a 64-bit architecture");
1293 // <------- lo32 ------>
1294 // <------- hi32 ------>
1295 // <- hi16 -> <- lo16 ->
1296 // _________________________________
1298 // | 16-bytes | 16-bytes | 16-bytes |
1299 // |__________|__________|__________|
1301 // For any value of j that is representable as a 48-bit integer, create
1303 // li d,j => lui d,hi16(j)
1304 // ori d,d,hi16(lo32(j))
1306 // ori d,d,lo16(lo32(j))
1307 tmpInst.setOpcode(Mips::LUi);
1308 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1310 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1311 Instructions.push_back(tmpInst);
1312 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1313 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1316 Error(IDLoc, "instruction requires a 64-bit architecture");
1320 // <------- hi32 ------> <------- lo32 ------>
1321 // <- hi16 -> <- lo16 ->
1322 // ___________________________________________
1324 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1325 // |__________|__________|__________|__________|
1327 // For any value of j that isn't representable as a 48-bit integer.
1328 // li d,j => lui d,hi16(j)
1329 // ori d,d,lo16(hi32(j))
1331 // ori d,d,hi16(lo32(j))
1333 // ori d,d,lo16(lo32(j))
1334 tmpInst.setOpcode(Mips::LUi);
1335 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1337 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1338 Instructions.push_back(tmpInst);
1339 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1340 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1341 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1347 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1348 SmallVectorImpl<MCInst> &Instructions) {
1350 const MCOperand &ImmOp = Inst.getOperand(2);
1351 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1352 "expected immediate operand kind");
1353 if (!ImmOp.isImm()) {
1354 expandLoadAddressSym(Inst, IDLoc, Instructions);
1357 const MCOperand &SrcRegOp = Inst.getOperand(1);
1358 assert(SrcRegOp.isReg() && "expected register operand kind");
1359 const MCOperand &DstRegOp = Inst.getOperand(0);
1360 assert(DstRegOp.isReg() && "expected register operand kind");
1361 int ImmValue = ImmOp.getImm();
1362 if (-32768 <= ImmValue && ImmValue <= 65535) {
1363 // For -32768 <= j <= 65535.
1364 // la d,j(s) => addiu d,s,j
1365 tmpInst.setOpcode(Mips::ADDiu);
1366 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1367 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1368 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1369 Instructions.push_back(tmpInst);
1371 // For any other value of j that is representable as a 32-bit integer.
1372 // la d,j(s) => lui d,hi16(j)
1375 tmpInst.setOpcode(Mips::LUi);
1376 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1377 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1378 Instructions.push_back(tmpInst);
1380 tmpInst.setOpcode(Mips::ORi);
1381 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1382 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1383 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1384 Instructions.push_back(tmpInst);
1386 tmpInst.setOpcode(Mips::ADDu);
1387 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1388 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1389 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1390 Instructions.push_back(tmpInst);
1396 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1397 SmallVectorImpl<MCInst> &Instructions) {
1399 const MCOperand &ImmOp = Inst.getOperand(1);
1400 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1401 "expected immediate operand kind");
1402 if (!ImmOp.isImm()) {
1403 expandLoadAddressSym(Inst, IDLoc, Instructions);
1406 const MCOperand &RegOp = Inst.getOperand(0);
1407 assert(RegOp.isReg() && "expected register operand kind");
1408 int ImmValue = ImmOp.getImm();
1409 if (-32768 <= ImmValue && ImmValue <= 65535) {
1410 // For -32768 <= j <= 65535.
1411 // la d,j => addiu d,$zero,j
1412 tmpInst.setOpcode(Mips::ADDiu);
1413 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1414 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1415 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1416 Instructions.push_back(tmpInst);
1418 // For any other value of j that is representable as a 32-bit integer.
1419 // la d,j => lui d,hi16(j)
1421 tmpInst.setOpcode(Mips::LUi);
1422 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1423 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1424 Instructions.push_back(tmpInst);
1426 tmpInst.setOpcode(Mips::ORi);
1427 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1428 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1429 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1430 Instructions.push_back(tmpInst);
1436 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1437 SmallVectorImpl<MCInst> &Instructions) {
1438 // FIXME: If we do have a valid at register to use, we should generate a
1439 // slightly shorter sequence here.
1441 int ExprOperandNo = 1;
1442 // Sometimes the assembly parser will get the immediate expression as
1443 // a $zero + an immediate.
1444 if (Inst.getNumOperands() == 3) {
1445 assert(Inst.getOperand(1).getReg() ==
1446 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1449 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1450 assert(SymOp.isExpr() && "expected symbol operand kind");
1451 const MCOperand &RegOp = Inst.getOperand(0);
1452 unsigned RegNo = RegOp.getReg();
1453 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1454 const MCSymbolRefExpr *HiExpr =
1455 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1456 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1457 const MCSymbolRefExpr *LoExpr =
1458 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1459 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1461 // If it's a 64-bit architecture, expand to:
1462 // la d,sym => lui d,highest(sym)
1463 // ori d,d,higher(sym)
1465 // ori d,d,hi16(sym)
1467 // ori d,d,lo16(sym)
1468 const MCSymbolRefExpr *HighestExpr =
1469 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1470 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1471 const MCSymbolRefExpr *HigherExpr =
1472 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1473 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1475 tmpInst.setOpcode(Mips::LUi);
1476 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1477 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1478 Instructions.push_back(tmpInst);
1480 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1482 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1484 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1487 // Otherwise, expand to:
1488 // la d,sym => lui d,hi16(sym)
1489 // ori d,d,lo16(sym)
1490 tmpInst.setOpcode(Mips::LUi);
1491 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1492 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1493 Instructions.push_back(tmpInst);
1495 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1500 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1501 SmallVectorImpl<MCInst> &Instructions,
1502 bool isLoad, bool isImmOpnd) {
1503 const MCSymbolRefExpr *SR;
1505 unsigned ImmOffset, HiOffset, LoOffset;
1506 const MCExpr *ExprOffset;
1508 // 1st operand is either the source or destination register.
1509 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1510 unsigned RegOpNum = Inst.getOperand(0).getReg();
1511 // 2nd operand is the base register.
1512 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1513 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1514 // 3rd operand is either an immediate or expression.
1516 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1517 ImmOffset = Inst.getOperand(2).getImm();
1518 LoOffset = ImmOffset & 0x0000ffff;
1519 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1520 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1521 if (LoOffset & 0x8000)
1524 ExprOffset = Inst.getOperand(2).getExpr();
1525 // All instructions will have the same location.
1526 TempInst.setLoc(IDLoc);
1527 // These are some of the types of expansions we perform here:
1528 // 1) lw $8, sym => lui $8, %hi(sym)
1529 // lw $8, %lo(sym)($8)
1530 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1532 // lw $8, %lo(offset)($9)
1533 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1535 // lw $8, %lo(offset)($at)
1536 // 4) sw $8, sym => lui $at, %hi(sym)
1537 // sw $8, %lo(sym)($at)
1538 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1540 // sw $8, %lo(offset)($at)
1541 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1542 // ldc1 $f0, %lo(sym)($at)
1544 // For load instructions we can use the destination register as a temporary
1545 // if base and dst are different (examples 1 and 2) and if the base register
1546 // is general purpose otherwise we must use $at (example 6) and error if it's
1547 // not available. For stores we must use $at (examples 4 and 5) because we
1548 // must not clobber the source register setting up the offset.
1549 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1550 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1551 unsigned RegClassIDOp0 =
1552 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1553 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1554 (RegClassIDOp0 == Mips::GPR64RegClassID);
1555 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1556 TmpRegNum = RegOpNum;
1558 int AT = getATReg(IDLoc);
1559 // At this point we need AT to perform the expansions and we exit if it is
1564 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1567 TempInst.setOpcode(Mips::LUi);
1568 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1570 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1572 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1573 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1574 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1575 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1577 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1579 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1580 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1583 // Add the instruction to the list.
1584 Instructions.push_back(TempInst);
1585 // Prepare TempInst for next instruction.
1587 // Add temp register to base.
1588 TempInst.setOpcode(Mips::ADDu);
1589 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1590 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1591 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1592 Instructions.push_back(TempInst);
1594 // And finally, create original instruction with low part
1595 // of offset and new base.
1596 TempInst.setOpcode(Inst.getOpcode());
1597 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1598 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1600 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1602 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1603 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1604 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1606 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1608 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1609 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1612 Instructions.push_back(TempInst);
1616 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1617 // As described by the Mips32r2 spec, the registers Rd and Rs for
1618 // jalr.hb must be different.
1619 unsigned Opcode = Inst.getOpcode();
1621 if (Opcode == Mips::JALR_HB &&
1622 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1623 return Match_RequiresDifferentSrcAndDst;
1625 return Match_Success;
1628 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1629 OperandVector &Operands,
1631 uint64_t &ErrorInfo,
1632 bool MatchingInlineAsm) {
1635 SmallVector<MCInst, 8> Instructions;
1636 unsigned MatchResult =
1637 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1639 switch (MatchResult) {
1642 case Match_Success: {
1643 if (processInstruction(Inst, IDLoc, Instructions))
1645 for (unsigned i = 0; i < Instructions.size(); i++)
1646 Out.EmitInstruction(Instructions[i], STI);
1649 case Match_MissingFeature:
1650 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1652 case Match_InvalidOperand: {
1653 SMLoc ErrorLoc = IDLoc;
1654 if (ErrorInfo != ~0ULL) {
1655 if (ErrorInfo >= Operands.size())
1656 return Error(IDLoc, "too few operands for instruction");
1658 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1659 if (ErrorLoc == SMLoc())
1663 return Error(ErrorLoc, "invalid operand for instruction");
1665 case Match_MnemonicFail:
1666 return Error(IDLoc, "invalid instruction");
1667 case Match_RequiresDifferentSrcAndDst:
1668 return Error(IDLoc, "source and destination must be different");
1673 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1674 if ((RegIndex != 0) &&
1675 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1677 Warning(Loc, "used $at without \".set noat\"");
1679 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1680 Twine(RegIndex) + "\"");
1685 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1686 SMRange Range, bool ShowColors) {
1687 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1688 Range, SMFixIt(Range, FixMsg),
1692 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1695 CC = StringSwitch<unsigned>(Name)
1731 if (!(isABI_N32() || isABI_N64()))
1734 if (12 <= CC && CC <= 15) {
1735 // Name is one of t4-t7
1736 AsmToken RegTok = getLexer().peekTok();
1737 SMRange RegRange = RegTok.getLocRange();
1739 StringRef FixedName = StringSwitch<StringRef>(Name)
1745 assert(FixedName != "" && "Register name is not one of t4-t7.");
1747 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1748 "Did you mean $" + FixedName + "?", RegRange);
1751 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1752 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1753 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1754 if (8 <= CC && CC <= 11)
1758 CC = StringSwitch<unsigned>(Name)
1770 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1772 if (Name[0] == 'f') {
1773 StringRef NumString = Name.substr(1);
1775 if (NumString.getAsInteger(10, IntVal))
1776 return -1; // This is not an integer.
1777 if (IntVal > 31) // Maximum index for fpu register.
1784 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1786 if (Name.startswith("fcc")) {
1787 StringRef NumString = Name.substr(3);
1789 if (NumString.getAsInteger(10, IntVal))
1790 return -1; // This is not an integer.
1791 if (IntVal > 7) // There are only 8 fcc registers.
1798 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1800 if (Name.startswith("ac")) {
1801 StringRef NumString = Name.substr(2);
1803 if (NumString.getAsInteger(10, IntVal))
1804 return -1; // This is not an integer.
1805 if (IntVal > 3) // There are only 3 acc registers.
1812 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1815 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1824 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1827 CC = StringSwitch<unsigned>(Name)
1830 .Case("msaaccess", 2)
1832 .Case("msamodify", 4)
1833 .Case("msarequest", 5)
1835 .Case("msaunmap", 7)
1841 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1849 int MipsAsmParser::getATReg(SMLoc Loc) {
1850 int AT = AssemblerOptions.back()->getATRegNum();
1852 reportParseError(Loc,
1853 "pseudo-instruction requires $at, which is not available");
1857 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1858 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1861 unsigned MipsAsmParser::getGPR(int RegNo) {
1862 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1866 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1868 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1871 return getReg(RegClass, RegNum);
1874 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1875 DEBUG(dbgs() << "parseOperand\n");
1877 // Check if the current operand has a custom associated parser, if so, try to
1878 // custom parse the operand, or fallback to the general approach.
1879 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1880 if (ResTy == MatchOperand_Success)
1882 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1883 // there was a match, but an error occurred, in which case, just return that
1884 // the operand parsing failed.
1885 if (ResTy == MatchOperand_ParseFail)
1888 DEBUG(dbgs() << ".. Generic Parser\n");
1890 switch (getLexer().getKind()) {
1892 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1894 case AsmToken::Dollar: {
1895 // Parse the register.
1896 SMLoc S = Parser.getTok().getLoc();
1898 // Almost all registers have been parsed by custom parsers. There is only
1899 // one exception to this. $zero (and it's alias $0) will reach this point
1900 // for div, divu, and similar instructions because it is not an operand
1901 // to the instruction definition but an explicit register. Special case
1902 // this situation for now.
1903 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1906 // Maybe it is a symbol reference.
1907 StringRef Identifier;
1908 if (Parser.parseIdentifier(Identifier))
1911 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1912 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1913 // Otherwise create a symbol reference.
1915 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1917 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1920 // Else drop to expression parsing.
1921 case AsmToken::LParen:
1922 case AsmToken::Minus:
1923 case AsmToken::Plus:
1924 case AsmToken::Integer:
1925 case AsmToken::Tilde:
1926 case AsmToken::String: {
1927 DEBUG(dbgs() << ".. generic integer\n");
1928 OperandMatchResultTy ResTy = parseImm(Operands);
1929 return ResTy != MatchOperand_Success;
1931 case AsmToken::Percent: {
1932 // It is a symbol reference or constant expression.
1933 const MCExpr *IdVal;
1934 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1935 if (parseRelocOperand(IdVal))
1938 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1940 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1942 } // case AsmToken::Percent
1943 } // switch(getLexer().getKind())
1947 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1948 StringRef RelocStr) {
1950 // Check the type of the expression.
1951 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1952 // It's a constant, evaluate reloc value.
1954 switch (getVariantKind(RelocStr)) {
1955 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1956 // Get the 1st 16-bits.
1957 Val = MCE->getValue() & 0xffff;
1959 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1960 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1961 // 16 bits being negative.
1962 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1964 case MCSymbolRefExpr::VK_Mips_HIGHER:
1965 // Get the 3rd 16-bits.
1966 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1968 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1969 // Get the 4th 16-bits.
1970 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1973 report_fatal_error("unsupported reloc value");
1975 return MCConstantExpr::Create(Val, getContext());
1978 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1979 // It's a symbol, create a symbolic expression from the symbol.
1980 StringRef Symbol = MSRE->getSymbol().getName();
1981 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1982 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1986 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1987 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1989 // Try to create target expression.
1990 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1991 return MipsMCExpr::Create(VK, Expr, getContext());
1993 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1994 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1995 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1999 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2000 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2001 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2004 // Just return the original expression.
2008 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2010 switch (Expr->getKind()) {
2011 case MCExpr::Constant:
2013 case MCExpr::SymbolRef:
2014 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2015 case MCExpr::Binary:
2016 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2017 if (!isEvaluated(BE->getLHS()))
2019 return isEvaluated(BE->getRHS());
2022 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2023 case MCExpr::Target:
2029 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2030 Parser.Lex(); // Eat the % token.
2031 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2032 if (Tok.isNot(AsmToken::Identifier))
2035 std::string Str = Tok.getIdentifier().str();
2037 Parser.Lex(); // Eat the identifier.
2038 // Now make an expression from the rest of the operand.
2039 const MCExpr *IdVal;
2042 if (getLexer().getKind() == AsmToken::LParen) {
2044 Parser.Lex(); // Eat the '(' token.
2045 if (getLexer().getKind() == AsmToken::Percent) {
2046 Parser.Lex(); // Eat the % token.
2047 const AsmToken &nextTok = Parser.getTok();
2048 if (nextTok.isNot(AsmToken::Identifier))
2051 Str += nextTok.getIdentifier();
2052 Parser.Lex(); // Eat the identifier.
2053 if (getLexer().getKind() != AsmToken::LParen)
2058 if (getParser().parseParenExpression(IdVal, EndLoc))
2061 while (getLexer().getKind() == AsmToken::RParen)
2062 Parser.Lex(); // Eat the ')' token.
2065 return true; // Parenthesis must follow the relocation operand.
2067 Res = evaluateRelocExpr(IdVal, Str);
2071 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2073 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2074 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2075 if (ResTy == MatchOperand_Success) {
2076 assert(Operands.size() == 1);
2077 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2078 StartLoc = Operand.getStartLoc();
2079 EndLoc = Operand.getEndLoc();
2081 // AFAIK, we only support numeric registers and named GPR's in CFI
2083 // Don't worry about eating tokens before failing. Using an unrecognised
2084 // register is a parse error.
2085 if (Operand.isGPRAsmReg()) {
2086 // Resolve to GPR32 or GPR64 appropriately.
2087 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2090 return (RegNo == (unsigned)-1);
2093 assert(Operands.size() == 0);
2094 return (RegNo == (unsigned)-1);
2097 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2101 while (getLexer().getKind() == AsmToken::LParen)
2104 switch (getLexer().getKind()) {
2107 case AsmToken::Identifier:
2108 case AsmToken::LParen:
2109 case AsmToken::Integer:
2110 case AsmToken::Minus:
2111 case AsmToken::Plus:
2113 Result = getParser().parseParenExpression(Res, S);
2115 Result = (getParser().parseExpression(Res));
2116 while (getLexer().getKind() == AsmToken::RParen)
2119 case AsmToken::Percent:
2120 Result = parseRelocOperand(Res);
2125 MipsAsmParser::OperandMatchResultTy
2126 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2127 DEBUG(dbgs() << "parseMemOperand\n");
2128 const MCExpr *IdVal = nullptr;
2130 bool isParenExpr = false;
2131 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2132 // First operand is the offset.
2133 S = Parser.getTok().getLoc();
2135 if (getLexer().getKind() == AsmToken::LParen) {
2140 if (getLexer().getKind() != AsmToken::Dollar) {
2141 if (parseMemOffset(IdVal, isParenExpr))
2142 return MatchOperand_ParseFail;
2144 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2145 if (Tok.isNot(AsmToken::LParen)) {
2146 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2147 if (Mnemonic.getToken() == "la") {
2149 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2150 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2151 return MatchOperand_Success;
2153 if (Tok.is(AsmToken::EndOfStatement)) {
2155 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2157 // Zero register assumed, add a memory operand with ZERO as its base.
2158 // "Base" will be managed by k_Memory.
2159 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2162 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2163 return MatchOperand_Success;
2165 Error(Parser.getTok().getLoc(), "'(' expected");
2166 return MatchOperand_ParseFail;
2169 Parser.Lex(); // Eat the '(' token.
2172 Res = parseAnyRegister(Operands);
2173 if (Res != MatchOperand_Success)
2176 if (Parser.getTok().isNot(AsmToken::RParen)) {
2177 Error(Parser.getTok().getLoc(), "')' expected");
2178 return MatchOperand_ParseFail;
2181 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2183 Parser.Lex(); // Eat the ')' token.
2186 IdVal = MCConstantExpr::Create(0, getContext());
2188 // Replace the register operand with the memory operand.
2189 std::unique_ptr<MipsOperand> op(
2190 static_cast<MipsOperand *>(Operands.back().release()));
2191 // Remove the register from the operands.
2192 // "op" will be managed by k_Memory.
2193 Operands.pop_back();
2194 // Add the memory operand.
2195 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2197 if (IdVal->EvaluateAsAbsolute(Imm))
2198 IdVal = MCConstantExpr::Create(Imm, getContext());
2199 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2200 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2204 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2205 return MatchOperand_Success;
2208 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2210 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2212 SMLoc S = Parser.getTok().getLoc();
2214 if (Sym->isVariable())
2215 Expr = Sym->getVariableValue();
2218 if (Expr->getKind() == MCExpr::SymbolRef) {
2219 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2220 StringRef DefSymbol = Ref->getSymbol().getName();
2221 if (DefSymbol.startswith("$")) {
2222 OperandMatchResultTy ResTy =
2223 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2224 if (ResTy == MatchOperand_Success) {
2227 } else if (ResTy == MatchOperand_ParseFail)
2228 llvm_unreachable("Should never ParseFail");
2231 } else if (Expr->getKind() == MCExpr::Constant) {
2233 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2235 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2242 MipsAsmParser::OperandMatchResultTy
2243 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2244 StringRef Identifier,
2246 int Index = matchCPURegisterName(Identifier);
2248 Operands.push_back(MipsOperand::createGPRReg(
2249 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2250 return MatchOperand_Success;
2253 Index = matchFPURegisterName(Identifier);
2255 Operands.push_back(MipsOperand::createFGRReg(
2256 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2257 return MatchOperand_Success;
2260 Index = matchFCCRegisterName(Identifier);
2262 Operands.push_back(MipsOperand::createFCCReg(
2263 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2264 return MatchOperand_Success;
2267 Index = matchACRegisterName(Identifier);
2269 Operands.push_back(MipsOperand::createACCReg(
2270 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2271 return MatchOperand_Success;
2274 Index = matchMSA128RegisterName(Identifier);
2276 Operands.push_back(MipsOperand::createMSA128Reg(
2277 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2278 return MatchOperand_Success;
2281 Index = matchMSA128CtrlRegisterName(Identifier);
2283 Operands.push_back(MipsOperand::createMSACtrlReg(
2284 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2285 return MatchOperand_Success;
2288 return MatchOperand_NoMatch;
2291 MipsAsmParser::OperandMatchResultTy
2292 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2293 auto Token = Parser.getLexer().peekTok(false);
2295 if (Token.is(AsmToken::Identifier)) {
2296 DEBUG(dbgs() << ".. identifier\n");
2297 StringRef Identifier = Token.getIdentifier();
2298 OperandMatchResultTy ResTy =
2299 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2301 } else if (Token.is(AsmToken::Integer)) {
2302 DEBUG(dbgs() << ".. integer\n");
2303 Operands.push_back(MipsOperand::createNumericReg(
2304 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2306 return MatchOperand_Success;
2309 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2311 return MatchOperand_NoMatch;
2314 MipsAsmParser::OperandMatchResultTy
2315 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2316 DEBUG(dbgs() << "parseAnyRegister\n");
2318 auto Token = Parser.getTok();
2320 SMLoc S = Token.getLoc();
2322 if (Token.isNot(AsmToken::Dollar)) {
2323 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2324 if (Token.is(AsmToken::Identifier)) {
2325 if (searchSymbolAlias(Operands))
2326 return MatchOperand_Success;
2328 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2329 return MatchOperand_NoMatch;
2331 DEBUG(dbgs() << ".. $\n");
2333 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2334 if (ResTy == MatchOperand_Success) {
2336 Parser.Lex(); // identifier
2341 MipsAsmParser::OperandMatchResultTy
2342 MipsAsmParser::parseImm(OperandVector &Operands) {
2343 switch (getLexer().getKind()) {
2345 return MatchOperand_NoMatch;
2346 case AsmToken::LParen:
2347 case AsmToken::Minus:
2348 case AsmToken::Plus:
2349 case AsmToken::Integer:
2350 case AsmToken::Tilde:
2351 case AsmToken::String:
2355 const MCExpr *IdVal;
2356 SMLoc S = Parser.getTok().getLoc();
2357 if (getParser().parseExpression(IdVal))
2358 return MatchOperand_ParseFail;
2360 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2361 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2362 return MatchOperand_Success;
2365 MipsAsmParser::OperandMatchResultTy
2366 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2367 DEBUG(dbgs() << "parseJumpTarget\n");
2369 SMLoc S = getLexer().getLoc();
2371 // Integers and expressions are acceptable
2372 OperandMatchResultTy ResTy = parseImm(Operands);
2373 if (ResTy != MatchOperand_NoMatch)
2376 // Registers are a valid target and have priority over symbols.
2377 ResTy = parseAnyRegister(Operands);
2378 if (ResTy != MatchOperand_NoMatch)
2381 const MCExpr *Expr = nullptr;
2382 if (Parser.parseExpression(Expr)) {
2383 // We have no way of knowing if a symbol was consumed so we must ParseFail
2384 return MatchOperand_ParseFail;
2387 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2388 return MatchOperand_Success;
2391 MipsAsmParser::OperandMatchResultTy
2392 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2393 const MCExpr *IdVal;
2394 // If the first token is '$' we may have register operand.
2395 if (Parser.getTok().is(AsmToken::Dollar))
2396 return MatchOperand_NoMatch;
2397 SMLoc S = Parser.getTok().getLoc();
2398 if (getParser().parseExpression(IdVal))
2399 return MatchOperand_ParseFail;
2400 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2401 assert(MCE && "Unexpected MCExpr type.");
2402 int64_t Val = MCE->getValue();
2403 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2404 Operands.push_back(MipsOperand::CreateImm(
2405 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2406 return MatchOperand_Success;
2409 MipsAsmParser::OperandMatchResultTy
2410 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2411 switch (getLexer().getKind()) {
2413 return MatchOperand_NoMatch;
2414 case AsmToken::LParen:
2415 case AsmToken::Plus:
2416 case AsmToken::Minus:
2417 case AsmToken::Integer:
2422 SMLoc S = Parser.getTok().getLoc();
2424 if (getParser().parseExpression(Expr))
2425 return MatchOperand_ParseFail;
2428 if (!Expr->EvaluateAsAbsolute(Val)) {
2429 Error(S, "expected immediate value");
2430 return MatchOperand_ParseFail;
2433 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2434 // and because the CPU always adds one to the immediate field, the allowed
2435 // range becomes 1..4. We'll only check the range here and will deal
2436 // with the addition/subtraction when actually decoding/encoding
2438 if (Val < 1 || Val > 4) {
2439 Error(S, "immediate not in range (1..4)");
2440 return MatchOperand_ParseFail;
2444 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2445 return MatchOperand_Success;
2448 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2450 MCSymbolRefExpr::VariantKind VK =
2451 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2452 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2453 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2454 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2455 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2456 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2457 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2458 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2459 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2460 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2461 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2462 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2463 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2464 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2465 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2466 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2467 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2468 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2469 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2470 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2471 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2472 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2473 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2474 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2475 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2476 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2477 .Default(MCSymbolRefExpr::VK_None);
2479 assert(VK != MCSymbolRefExpr::VK_None);
2484 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2486 /// ::= '(', register, ')'
2487 /// handle it before we iterate so we don't get tripped up by the lack of
2489 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2490 if (getLexer().is(AsmToken::LParen)) {
2492 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2494 if (parseOperand(Operands, Name)) {
2495 SMLoc Loc = getLexer().getLoc();
2496 Parser.eatToEndOfStatement();
2497 return Error(Loc, "unexpected token in argument list");
2499 if (Parser.getTok().isNot(AsmToken::RParen)) {
2500 SMLoc Loc = getLexer().getLoc();
2501 Parser.eatToEndOfStatement();
2502 return Error(Loc, "unexpected token, expected ')'");
2505 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2511 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2512 /// either one of these.
2513 /// ::= '[', register, ']'
2514 /// ::= '[', integer, ']'
2515 /// handle it before we iterate so we don't get tripped up by the lack of
2517 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2518 OperandVector &Operands) {
2519 if (getLexer().is(AsmToken::LBrac)) {
2521 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2523 if (parseOperand(Operands, Name)) {
2524 SMLoc Loc = getLexer().getLoc();
2525 Parser.eatToEndOfStatement();
2526 return Error(Loc, "unexpected token in argument list");
2528 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2529 SMLoc Loc = getLexer().getLoc();
2530 Parser.eatToEndOfStatement();
2531 return Error(Loc, "unexpected token, expected ']'");
2534 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2540 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2541 SMLoc NameLoc, OperandVector &Operands) {
2542 DEBUG(dbgs() << "ParseInstruction\n");
2544 // We have reached first instruction, module directive are now forbidden.
2545 getTargetStreamer().forbidModuleDirective();
2547 // Check if we have valid mnemonic
2548 if (!mnemonicIsValid(Name, 0)) {
2549 Parser.eatToEndOfStatement();
2550 return Error(NameLoc, "unknown instruction");
2552 // First operand in MCInst is instruction mnemonic.
2553 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2555 // Read the remaining operands.
2556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2557 // Read the first operand.
2558 if (parseOperand(Operands, Name)) {
2559 SMLoc Loc = getLexer().getLoc();
2560 Parser.eatToEndOfStatement();
2561 return Error(Loc, "unexpected token in argument list");
2563 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2565 // AFAIK, parenthesis suffixes are never on the first operand
2567 while (getLexer().is(AsmToken::Comma)) {
2568 Parser.Lex(); // Eat the comma.
2569 // Parse and remember the operand.
2570 if (parseOperand(Operands, Name)) {
2571 SMLoc Loc = getLexer().getLoc();
2572 Parser.eatToEndOfStatement();
2573 return Error(Loc, "unexpected token in argument list");
2575 // Parse bracket and parenthesis suffixes before we iterate
2576 if (getLexer().is(AsmToken::LBrac)) {
2577 if (parseBracketSuffix(Name, Operands))
2579 } else if (getLexer().is(AsmToken::LParen) &&
2580 parseParenSuffix(Name, Operands))
2584 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2585 SMLoc Loc = getLexer().getLoc();
2586 Parser.eatToEndOfStatement();
2587 return Error(Loc, "unexpected token in argument list");
2589 Parser.Lex(); // Consume the EndOfStatement.
2593 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2594 SMLoc Loc = getLexer().getLoc();
2595 Parser.eatToEndOfStatement();
2596 return Error(Loc, ErrorMsg);
2599 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2600 return Error(Loc, ErrorMsg);
2603 bool MipsAsmParser::parseSetNoAtDirective() {
2604 // Line should look like: ".set noat".
2606 AssemblerOptions.back()->setATReg(0);
2609 // If this is not the end of the statement, report an error.
2610 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2611 reportParseError("unexpected token, expected end of statement");
2614 Parser.Lex(); // Consume the EndOfStatement.
2618 bool MipsAsmParser::parseSetAtDirective() {
2619 // Line can be .set at - defaults to $1
2623 if (getLexer().is(AsmToken::EndOfStatement)) {
2624 AssemblerOptions.back()->setATReg(1);
2625 Parser.Lex(); // Consume the EndOfStatement.
2627 } else if (getLexer().is(AsmToken::Equal)) {
2628 getParser().Lex(); // Eat the '='.
2629 if (getLexer().isNot(AsmToken::Dollar)) {
2630 reportParseError("unexpected token, expected dollar sign '$'");
2633 Parser.Lex(); // Eat the '$'.
2634 const AsmToken &Reg = Parser.getTok();
2635 if (Reg.is(AsmToken::Identifier)) {
2636 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2637 } else if (Reg.is(AsmToken::Integer)) {
2638 AtRegNo = Reg.getIntVal();
2640 reportParseError("unexpected token, expected identifier or integer");
2644 if (AtRegNo < 0 || AtRegNo > 31) {
2645 reportParseError("unexpected token in statement");
2649 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2650 reportParseError("invalid register");
2653 getParser().Lex(); // Eat the register.
2655 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2656 reportParseError("unexpected token, expected end of statement");
2659 Parser.Lex(); // Consume the EndOfStatement.
2662 reportParseError("unexpected token in statement");
2667 bool MipsAsmParser::parseSetReorderDirective() {
2669 // If this is not the end of the statement, report an error.
2670 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2671 reportParseError("unexpected token, expected end of statement");
2674 AssemblerOptions.back()->setReorder();
2675 getTargetStreamer().emitDirectiveSetReorder();
2676 Parser.Lex(); // Consume the EndOfStatement.
2680 bool MipsAsmParser::parseSetNoReorderDirective() {
2682 // If this is not the end of the statement, report an error.
2683 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2684 reportParseError("unexpected token, expected end of statement");
2687 AssemblerOptions.back()->setNoReorder();
2688 getTargetStreamer().emitDirectiveSetNoReorder();
2689 Parser.Lex(); // Consume the EndOfStatement.
2693 bool MipsAsmParser::parseSetMacroDirective() {
2695 // If this is not the end of the statement, report an error.
2696 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2697 reportParseError("unexpected token, expected end of statement");
2700 AssemblerOptions.back()->setMacro();
2701 Parser.Lex(); // Consume the EndOfStatement.
2705 bool MipsAsmParser::parseSetNoMacroDirective() {
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 if (AssemblerOptions.back()->isReorder()) {
2713 reportParseError("`noreorder' must be set before `nomacro'");
2716 AssemblerOptions.back()->setNoMacro();
2717 Parser.Lex(); // Consume the EndOfStatement.
2721 bool MipsAsmParser::parseSetMsaDirective() {
2724 // If this is not the end of the statement, report an error.
2725 if (getLexer().isNot(AsmToken::EndOfStatement))
2726 return reportParseError("unexpected token, expected end of statement");
2728 setFeatureBits(Mips::FeatureMSA, "msa");
2729 getTargetStreamer().emitDirectiveSetMsa();
2733 bool MipsAsmParser::parseSetNoMsaDirective() {
2736 // If this is not the end of the statement, report an error.
2737 if (getLexer().isNot(AsmToken::EndOfStatement))
2738 return reportParseError("unexpected token, expected end of statement");
2740 clearFeatureBits(Mips::FeatureMSA, "msa");
2741 getTargetStreamer().emitDirectiveSetNoMsa();
2745 bool MipsAsmParser::parseSetNoDspDirective() {
2746 Parser.Lex(); // Eat "nodsp".
2748 // If this is not the end of the statement, report an error.
2749 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2750 reportParseError("unexpected token, expected end of statement");
2754 clearFeatureBits(Mips::FeatureDSP, "dsp");
2755 getTargetStreamer().emitDirectiveSetNoDsp();
2759 bool MipsAsmParser::parseSetNoMips16Directive() {
2761 // If this is not the end of the statement, report an error.
2762 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2763 reportParseError("unexpected token, expected end of statement");
2766 // For now do nothing.
2767 Parser.Lex(); // Consume the EndOfStatement.
2771 bool MipsAsmParser::parseSetFpDirective() {
2772 MipsABIFlagsSection::FpABIKind FpAbiVal;
2773 // Line can be: .set fp=32
2776 Parser.Lex(); // Eat fp token
2777 AsmToken Tok = Parser.getTok();
2778 if (Tok.isNot(AsmToken::Equal)) {
2779 reportParseError("unexpected token, expected equals sign '='");
2782 Parser.Lex(); // Eat '=' token.
2783 Tok = Parser.getTok();
2785 if (!parseFpABIValue(FpAbiVal, ".set"))
2788 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2789 reportParseError("unexpected token, expected end of statement");
2792 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2793 Parser.Lex(); // Consume the EndOfStatement.
2797 bool MipsAsmParser::parseSetPopDirective() {
2798 SMLoc Loc = getLexer().getLoc();
2801 if (getLexer().isNot(AsmToken::EndOfStatement))
2802 return reportParseError("unexpected token, expected end of statement");
2804 // Always keep an element on the options "stack" to prevent the user
2805 // from changing the initial options. This is how we remember them.
2806 if (AssemblerOptions.size() == 2)
2807 return reportParseError(Loc, ".set pop with no .set push");
2809 AssemblerOptions.pop_back();
2810 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2812 getTargetStreamer().emitDirectiveSetPop();
2816 bool MipsAsmParser::parseSetPushDirective() {
2818 if (getLexer().isNot(AsmToken::EndOfStatement))
2819 return reportParseError("unexpected token, expected end of statement");
2821 // Create a copy of the current assembler options environment and push it.
2822 AssemblerOptions.push_back(
2823 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2825 getTargetStreamer().emitDirectiveSetPush();
2829 bool MipsAsmParser::parseSetAssignment() {
2831 const MCExpr *Value;
2833 if (Parser.parseIdentifier(Name))
2834 reportParseError("expected identifier after .set");
2836 if (getLexer().isNot(AsmToken::Comma))
2837 return reportParseError("unexpected token, expected comma");
2840 if (Parser.parseExpression(Value))
2841 return reportParseError("expected valid expression after comma");
2843 // Check if the Name already exists as a symbol.
2844 MCSymbol *Sym = getContext().LookupSymbol(Name);
2846 return reportParseError("symbol already defined");
2847 Sym = getContext().GetOrCreateSymbol(Name);
2848 Sym->setVariableValue(Value);
2853 bool MipsAsmParser::parseSetMips0Directive() {
2855 if (getLexer().isNot(AsmToken::EndOfStatement))
2856 return reportParseError("unexpected token, expected end of statement");
2858 // Reset assembler options to their initial values.
2859 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2860 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2862 getTargetStreamer().emitDirectiveSetMips0();
2866 bool MipsAsmParser::parseSetArchDirective() {
2868 if (getLexer().isNot(AsmToken::Equal))
2869 return reportParseError("unexpected token, expected equals sign");
2873 if (Parser.parseIdentifier(Arch))
2874 return reportParseError("expected arch identifier");
2876 StringRef ArchFeatureName =
2877 StringSwitch<StringRef>(Arch)
2878 .Case("mips1", "mips1")
2879 .Case("mips2", "mips2")
2880 .Case("mips3", "mips3")
2881 .Case("mips4", "mips4")
2882 .Case("mips5", "mips5")
2883 .Case("mips32", "mips32")
2884 .Case("mips32r2", "mips32r2")
2885 .Case("mips32r6", "mips32r6")
2886 .Case("mips64", "mips64")
2887 .Case("mips64r2", "mips64r2")
2888 .Case("mips64r6", "mips64r6")
2889 .Case("cnmips", "cnmips")
2890 .Case("r4000", "mips3") // This is an implementation of Mips3.
2893 if (ArchFeatureName.empty())
2894 return reportParseError("unsupported architecture");
2896 selectArch(ArchFeatureName);
2897 getTargetStreamer().emitDirectiveSetArch(Arch);
2901 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2903 if (getLexer().isNot(AsmToken::EndOfStatement))
2904 return reportParseError("unexpected token, expected end of statement");
2908 llvm_unreachable("Unimplemented feature");
2909 case Mips::FeatureDSP:
2910 setFeatureBits(Mips::FeatureDSP, "dsp");
2911 getTargetStreamer().emitDirectiveSetDsp();
2913 case Mips::FeatureMicroMips:
2914 getTargetStreamer().emitDirectiveSetMicroMips();
2916 case Mips::FeatureMips16:
2917 getTargetStreamer().emitDirectiveSetMips16();
2919 case Mips::FeatureMips1:
2920 selectArch("mips1");
2921 getTargetStreamer().emitDirectiveSetMips1();
2923 case Mips::FeatureMips2:
2924 selectArch("mips2");
2925 getTargetStreamer().emitDirectiveSetMips2();
2927 case Mips::FeatureMips3:
2928 selectArch("mips3");
2929 getTargetStreamer().emitDirectiveSetMips3();
2931 case Mips::FeatureMips4:
2932 selectArch("mips4");
2933 getTargetStreamer().emitDirectiveSetMips4();
2935 case Mips::FeatureMips5:
2936 selectArch("mips5");
2937 getTargetStreamer().emitDirectiveSetMips5();
2939 case Mips::FeatureMips32:
2940 selectArch("mips32");
2941 getTargetStreamer().emitDirectiveSetMips32();
2943 case Mips::FeatureMips32r2:
2944 selectArch("mips32r2");
2945 getTargetStreamer().emitDirectiveSetMips32R2();
2947 case Mips::FeatureMips32r6:
2948 selectArch("mips32r6");
2949 getTargetStreamer().emitDirectiveSetMips32R6();
2951 case Mips::FeatureMips64:
2952 selectArch("mips64");
2953 getTargetStreamer().emitDirectiveSetMips64();
2955 case Mips::FeatureMips64r2:
2956 selectArch("mips64r2");
2957 getTargetStreamer().emitDirectiveSetMips64R2();
2959 case Mips::FeatureMips64r6:
2960 selectArch("mips64r6");
2961 getTargetStreamer().emitDirectiveSetMips64R6();
2967 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2968 if (getLexer().isNot(AsmToken::Comma)) {
2969 SMLoc Loc = getLexer().getLoc();
2970 Parser.eatToEndOfStatement();
2971 return Error(Loc, ErrorStr);
2974 Parser.Lex(); // Eat the comma.
2978 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
2979 if (AssemblerOptions.back()->isReorder())
2980 Warning(Loc, ".cpload in reorder section");
2982 // FIXME: Warn if cpload is used in Mips16 mode.
2984 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2985 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
2986 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2987 reportParseError("expected register containing function address");
2991 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2992 if (!RegOpnd.isGPRAsmReg()) {
2993 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2997 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3001 bool MipsAsmParser::parseDirectiveCPSetup() {
3004 bool SaveIsReg = true;
3006 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3007 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3008 if (ResTy == MatchOperand_NoMatch) {
3009 reportParseError("expected register containing function address");
3010 Parser.eatToEndOfStatement();
3014 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3015 if (!FuncRegOpnd.isGPRAsmReg()) {
3016 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3017 Parser.eatToEndOfStatement();
3021 FuncReg = FuncRegOpnd.getGPR32Reg();
3024 if (!eatComma("unexpected token, expected comma"))
3027 ResTy = parseAnyRegister(TmpReg);
3028 if (ResTy == MatchOperand_NoMatch) {
3029 const AsmToken &Tok = Parser.getTok();
3030 if (Tok.is(AsmToken::Integer)) {
3031 Save = Tok.getIntVal();
3035 reportParseError("expected save register or stack offset");
3036 Parser.eatToEndOfStatement();
3040 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3041 if (!SaveOpnd.isGPRAsmReg()) {
3042 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3043 Parser.eatToEndOfStatement();
3046 Save = SaveOpnd.getGPR32Reg();
3049 if (!eatComma("unexpected token, expected comma"))
3053 if (Parser.parseIdentifier(Name))
3054 reportParseError("expected identifier");
3055 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3057 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3061 bool MipsAsmParser::parseDirectiveNaN() {
3062 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3063 const AsmToken &Tok = Parser.getTok();
3065 if (Tok.getString() == "2008") {
3067 getTargetStreamer().emitDirectiveNaN2008();
3069 } else if (Tok.getString() == "legacy") {
3071 getTargetStreamer().emitDirectiveNaNLegacy();
3075 // If we don't recognize the option passed to the .nan
3076 // directive (e.g. no option or unknown option), emit an error.
3077 reportParseError("invalid option in .nan directive");
3081 bool MipsAsmParser::parseDirectiveSet() {
3083 // Get the next token.
3084 const AsmToken &Tok = Parser.getTok();
3086 if (Tok.getString() == "noat") {
3087 return parseSetNoAtDirective();
3088 } else if (Tok.getString() == "at") {
3089 return parseSetAtDirective();
3090 } else if (Tok.getString() == "arch") {
3091 return parseSetArchDirective();
3092 } else if (Tok.getString() == "fp") {
3093 return parseSetFpDirective();
3094 } else if (Tok.getString() == "pop") {
3095 return parseSetPopDirective();
3096 } else if (Tok.getString() == "push") {
3097 return parseSetPushDirective();
3098 } else if (Tok.getString() == "reorder") {
3099 return parseSetReorderDirective();
3100 } else if (Tok.getString() == "noreorder") {
3101 return parseSetNoReorderDirective();
3102 } else if (Tok.getString() == "macro") {
3103 return parseSetMacroDirective();
3104 } else if (Tok.getString() == "nomacro") {
3105 return parseSetNoMacroDirective();
3106 } else if (Tok.getString() == "mips16") {
3107 return parseSetFeature(Mips::FeatureMips16);
3108 } else if (Tok.getString() == "nomips16") {
3109 return parseSetNoMips16Directive();
3110 } else if (Tok.getString() == "nomicromips") {
3111 getTargetStreamer().emitDirectiveSetNoMicroMips();
3112 Parser.eatToEndOfStatement();
3114 } else if (Tok.getString() == "micromips") {
3115 return parseSetFeature(Mips::FeatureMicroMips);
3116 } else if (Tok.getString() == "mips0") {
3117 return parseSetMips0Directive();
3118 } else if (Tok.getString() == "mips1") {
3119 return parseSetFeature(Mips::FeatureMips1);
3120 } else if (Tok.getString() == "mips2") {
3121 return parseSetFeature(Mips::FeatureMips2);
3122 } else if (Tok.getString() == "mips3") {
3123 return parseSetFeature(Mips::FeatureMips3);
3124 } else if (Tok.getString() == "mips4") {
3125 return parseSetFeature(Mips::FeatureMips4);
3126 } else if (Tok.getString() == "mips5") {
3127 return parseSetFeature(Mips::FeatureMips5);
3128 } else if (Tok.getString() == "mips32") {
3129 return parseSetFeature(Mips::FeatureMips32);
3130 } else if (Tok.getString() == "mips32r2") {
3131 return parseSetFeature(Mips::FeatureMips32r2);
3132 } else if (Tok.getString() == "mips32r6") {
3133 return parseSetFeature(Mips::FeatureMips32r6);
3134 } else if (Tok.getString() == "mips64") {
3135 return parseSetFeature(Mips::FeatureMips64);
3136 } else if (Tok.getString() == "mips64r2") {
3137 return parseSetFeature(Mips::FeatureMips64r2);
3138 } else if (Tok.getString() == "mips64r6") {
3139 return parseSetFeature(Mips::FeatureMips64r6);
3140 } else if (Tok.getString() == "dsp") {
3141 return parseSetFeature(Mips::FeatureDSP);
3142 } else if (Tok.getString() == "nodsp") {
3143 return parseSetNoDspDirective();
3144 } else if (Tok.getString() == "msa") {
3145 return parseSetMsaDirective();
3146 } else if (Tok.getString() == "nomsa") {
3147 return parseSetNoMsaDirective();
3149 // It is just an identifier, look for an assignment.
3150 parseSetAssignment();
3157 /// parseDataDirective
3158 /// ::= .word [ expression (, expression)* ]
3159 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3160 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3162 const MCExpr *Value;
3163 if (getParser().parseExpression(Value))
3166 getParser().getStreamer().EmitValue(Value, Size);
3168 if (getLexer().is(AsmToken::EndOfStatement))
3171 if (getLexer().isNot(AsmToken::Comma))
3172 return Error(L, "unexpected token, expected comma");
3181 /// parseDirectiveGpWord
3182 /// ::= .gpword local_sym
3183 bool MipsAsmParser::parseDirectiveGpWord() {
3184 const MCExpr *Value;
3185 // EmitGPRel32Value requires an expression, so we are using base class
3186 // method to evaluate the expression.
3187 if (getParser().parseExpression(Value))
3189 getParser().getStreamer().EmitGPRel32Value(Value);
3191 if (getLexer().isNot(AsmToken::EndOfStatement))
3192 return Error(getLexer().getLoc(),
3193 "unexpected token, expected end of statement");
3194 Parser.Lex(); // Eat EndOfStatement token.
3198 /// parseDirectiveGpDWord
3199 /// ::= .gpdword local_sym
3200 bool MipsAsmParser::parseDirectiveGpDWord() {
3201 const MCExpr *Value;
3202 // EmitGPRel64Value requires an expression, so we are using base class
3203 // method to evaluate the expression.
3204 if (getParser().parseExpression(Value))
3206 getParser().getStreamer().EmitGPRel64Value(Value);
3208 if (getLexer().isNot(AsmToken::EndOfStatement))
3209 return Error(getLexer().getLoc(),
3210 "unexpected token, expected end of statement");
3211 Parser.Lex(); // Eat EndOfStatement token.
3215 bool MipsAsmParser::parseDirectiveOption() {
3216 // Get the option token.
3217 AsmToken Tok = Parser.getTok();
3218 // At the moment only identifiers are supported.
3219 if (Tok.isNot(AsmToken::Identifier)) {
3220 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3221 Parser.eatToEndOfStatement();
3225 StringRef Option = Tok.getIdentifier();
3227 if (Option == "pic0") {
3228 getTargetStreamer().emitDirectiveOptionPic0();
3230 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3231 Error(Parser.getTok().getLoc(),
3232 "unexpected token, expected end of statement");
3233 Parser.eatToEndOfStatement();
3238 if (Option == "pic2") {
3239 getTargetStreamer().emitDirectiveOptionPic2();
3241 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3242 Error(Parser.getTok().getLoc(),
3243 "unexpected token, expected end of statement");
3244 Parser.eatToEndOfStatement();
3250 Warning(Parser.getTok().getLoc(),
3251 "unknown option, expected 'pic0' or 'pic2'");
3252 Parser.eatToEndOfStatement();
3256 /// parseDirectiveModule
3257 /// ::= .module oddspreg
3258 /// ::= .module nooddspreg
3259 /// ::= .module fp=value
3260 bool MipsAsmParser::parseDirectiveModule() {
3261 MCAsmLexer &Lexer = getLexer();
3262 SMLoc L = Lexer.getLoc();
3264 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3265 // TODO : get a better message.
3266 reportParseError(".module directive must appear before any code");
3270 if (Lexer.is(AsmToken::Identifier)) {
3271 StringRef Option = Parser.getTok().getString();
3274 if (Option == "oddspreg") {
3275 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3276 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3278 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3279 reportParseError("unexpected token, expected end of statement");
3284 } else if (Option == "nooddspreg") {
3286 Error(L, "'.module nooddspreg' requires the O32 ABI");
3290 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3291 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3293 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3294 reportParseError("unexpected token, expected end of statement");
3299 } else if (Option == "fp") {
3300 return parseDirectiveModuleFP();
3303 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3309 /// parseDirectiveModuleFP
3313 bool MipsAsmParser::parseDirectiveModuleFP() {
3314 MCAsmLexer &Lexer = getLexer();
3316 if (Lexer.isNot(AsmToken::Equal)) {
3317 reportParseError("unexpected token, expected equals sign '='");
3320 Parser.Lex(); // Eat '=' token.
3322 MipsABIFlagsSection::FpABIKind FpABI;
3323 if (!parseFpABIValue(FpABI, ".module"))
3326 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3327 reportParseError("unexpected token, expected end of statement");
3331 // Emit appropriate flags.
3332 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3333 Parser.Lex(); // Consume the EndOfStatement.
3337 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3338 StringRef Directive) {
3339 MCAsmLexer &Lexer = getLexer();
3341 if (Lexer.is(AsmToken::Identifier)) {
3342 StringRef Value = Parser.getTok().getString();
3345 if (Value != "xx") {
3346 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3351 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3355 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3359 if (Lexer.is(AsmToken::Integer)) {
3360 unsigned Value = Parser.getTok().getIntVal();
3363 if (Value != 32 && Value != 64) {
3364 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3370 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3374 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3376 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3384 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3385 StringRef IDVal = DirectiveID.getString();
3387 if (IDVal == ".cpload")
3388 return parseDirectiveCpLoad(DirectiveID.getLoc());
3389 if (IDVal == ".dword") {
3390 parseDataDirective(8, DirectiveID.getLoc());
3393 if (IDVal == ".ent") {
3394 StringRef SymbolName;
3396 if (Parser.parseIdentifier(SymbolName)) {
3397 reportParseError("expected identifier after .ent");
3401 // There's an undocumented extension that allows an integer to
3402 // follow the name of the procedure which AFAICS is ignored by GAS.
3403 // Example: .ent foo,2
3404 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3405 if (getLexer().isNot(AsmToken::Comma)) {
3406 // Even though we accept this undocumented extension for compatibility
3407 // reasons, the additional integer argument does not actually change
3408 // the behaviour of the '.ent' directive, so we would like to discourage
3409 // its use. We do this by not referring to the extended version in
3410 // error messages which are not directly related to its use.
3411 reportParseError("unexpected token, expected end of statement");
3414 Parser.Lex(); // Eat the comma.
3415 const MCExpr *DummyNumber;
3416 int64_t DummyNumberVal;
3417 // If the user was explicitly trying to use the extended version,
3418 // we still give helpful extension-related error messages.
3419 if (Parser.parseExpression(DummyNumber)) {
3420 reportParseError("expected number after comma");
3423 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3424 reportParseError("expected an absolute expression after comma");
3429 // If this is not the end of the statement, report an error.
3430 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3431 reportParseError("unexpected token, expected end of statement");
3435 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3437 getTargetStreamer().emitDirectiveEnt(*Sym);
3442 if (IDVal == ".end") {
3443 StringRef SymbolName;
3445 if (Parser.parseIdentifier(SymbolName)) {
3446 reportParseError("expected identifier after .end");
3450 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3451 reportParseError("unexpected token, expected end of statement");
3455 if (CurrentFn == nullptr) {
3456 reportParseError(".end used without .ent");
3460 if ((SymbolName != CurrentFn->getName())) {
3461 reportParseError(".end symbol does not match .ent symbol");
3465 getTargetStreamer().emitDirectiveEnd(SymbolName);
3466 CurrentFn = nullptr;
3470 if (IDVal == ".frame") {
3471 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3472 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3473 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3474 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3475 reportParseError("expected stack register");
3479 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3480 if (!StackRegOpnd.isGPRAsmReg()) {
3481 reportParseError(StackRegOpnd.getStartLoc(),
3482 "expected general purpose register");
3485 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3487 if (Parser.getTok().is(AsmToken::Comma))
3490 reportParseError("unexpected token, expected comma");
3494 // Parse the frame size.
3495 const MCExpr *FrameSize;
3496 int64_t FrameSizeVal;
3498 if (Parser.parseExpression(FrameSize)) {
3499 reportParseError("expected frame size value");
3503 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3504 reportParseError("frame size not an absolute expression");
3508 if (Parser.getTok().is(AsmToken::Comma))
3511 reportParseError("unexpected token, expected comma");
3515 // Parse the return register.
3517 ResTy = parseAnyRegister(TmpReg);
3518 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3519 reportParseError("expected return register");
3523 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3524 if (!ReturnRegOpnd.isGPRAsmReg()) {
3525 reportParseError(ReturnRegOpnd.getStartLoc(),
3526 "expected general purpose register");
3530 // If this is not the end of the statement, report an error.
3531 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3532 reportParseError("unexpected token, expected end of statement");
3536 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3537 ReturnRegOpnd.getGPR32Reg());
3541 if (IDVal == ".set") {
3542 return parseDirectiveSet();
3545 if (IDVal == ".mask" || IDVal == ".fmask") {
3546 // .mask bitmask, frame_offset
3547 // bitmask: One bit for each register used.
3548 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3549 // first register is expected to be saved.
3551 // .mask 0x80000000, -4
3552 // .fmask 0x80000000, -4
3555 // Parse the bitmask
3556 const MCExpr *BitMask;
3559 if (Parser.parseExpression(BitMask)) {
3560 reportParseError("expected bitmask value");
3564 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3565 reportParseError("bitmask not an absolute expression");
3569 if (Parser.getTok().is(AsmToken::Comma))
3572 reportParseError("unexpected token, expected comma");
3576 // Parse the frame_offset
3577 const MCExpr *FrameOffset;
3578 int64_t FrameOffsetVal;
3580 if (Parser.parseExpression(FrameOffset)) {
3581 reportParseError("expected frame offset value");
3585 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3586 reportParseError("frame offset not an absolute expression");
3590 // If this is not the end of the statement, report an error.
3591 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3592 reportParseError("unexpected token, expected end of statement");
3596 if (IDVal == ".mask")
3597 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3599 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3603 if (IDVal == ".nan")
3604 return parseDirectiveNaN();
3606 if (IDVal == ".gpword") {
3607 parseDirectiveGpWord();
3611 if (IDVal == ".gpdword") {
3612 parseDirectiveGpDWord();
3616 if (IDVal == ".word") {
3617 parseDataDirective(4, DirectiveID.getLoc());
3621 if (IDVal == ".option")
3622 return parseDirectiveOption();
3624 if (IDVal == ".abicalls") {
3625 getTargetStreamer().emitDirectiveAbiCalls();
3626 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3627 Error(Parser.getTok().getLoc(),
3628 "unexpected token, expected end of statement");
3630 Parser.eatToEndOfStatement();
3635 if (IDVal == ".cpsetup")
3636 return parseDirectiveCPSetup();
3638 if (IDVal == ".module")
3639 return parseDirectiveModule();
3644 extern "C" void LLVMInitializeMipsAsmParser() {
3645 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3646 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3647 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3648 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3651 #define GET_REGISTER_MATCHER
3652 #define GET_MATCHER_IMPLEMENTATION
3653 #include "MipsGenAsmMatcher.inc"