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");
1174 Opnd = Inst.getOperand(1);
1176 return Error(IDLoc, "expected immediate operand kind");
1177 Imm = Opnd.getImm();
1178 if (Imm < -1 || Imm > 126)
1179 return Error(IDLoc, "immediate operand value out of range");
1181 case Mips::ADDIUR2_MM:
1182 Opnd = Inst.getOperand(2);
1184 return Error(IDLoc, "expected immediate operand kind");
1185 Imm = Opnd.getImm();
1186 if (!(Imm == 1 || Imm == -1 ||
1187 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1188 return Error(IDLoc, "immediate operand value out of range");
1190 case Mips::ADDIUR1SP_MM:
1191 Opnd = Inst.getOperand(1);
1193 return Error(IDLoc, "expected immediate operand kind");
1194 Imm = Opnd.getImm();
1195 if (OffsetToAlignment(Imm, 4LL))
1196 return Error(IDLoc, "misaligned immediate operand value");
1197 if (Imm < 0 || Imm > 255)
1198 return Error(IDLoc, "immediate operand value out of range");
1203 if (needsExpansion(Inst))
1204 return expandInstruction(Inst, IDLoc, Instructions);
1206 Instructions.push_back(Inst);
1211 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1213 switch (Inst.getOpcode()) {
1214 case Mips::LoadImm32Reg:
1215 case Mips::LoadAddr32Imm:
1216 case Mips::LoadAddr32Reg:
1217 case Mips::LoadImm64Reg:
1224 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1225 SmallVectorImpl<MCInst> &Instructions) {
1226 switch (Inst.getOpcode()) {
1228 assert(0 && "unimplemented expansion");
1230 case Mips::LoadImm32Reg:
1231 return expandLoadImm(Inst, IDLoc, Instructions);
1232 case Mips::LoadImm64Reg:
1234 Error(IDLoc, "instruction requires a 64-bit architecture");
1237 return expandLoadImm(Inst, IDLoc, Instructions);
1238 case Mips::LoadAddr32Imm:
1239 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1240 case Mips::LoadAddr32Reg:
1241 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1246 template <bool PerformShift>
1247 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1248 SmallVectorImpl<MCInst> &Instructions) {
1251 tmpInst.setOpcode(Mips::DSLL);
1252 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1253 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1254 tmpInst.addOperand(MCOperand::CreateImm(16));
1255 tmpInst.setLoc(IDLoc);
1256 Instructions.push_back(tmpInst);
1259 tmpInst.setOpcode(Mips::ORi);
1260 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1261 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1262 tmpInst.addOperand(Operand);
1263 tmpInst.setLoc(IDLoc);
1264 Instructions.push_back(tmpInst);
1267 template <int Shift, bool PerformShift>
1268 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1269 SmallVectorImpl<MCInst> &Instructions) {
1270 createShiftOr<PerformShift>(
1271 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1272 IDLoc, Instructions);
1276 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1277 SmallVectorImpl<MCInst> &Instructions) {
1279 const MCOperand &ImmOp = Inst.getOperand(1);
1280 assert(ImmOp.isImm() && "expected immediate operand kind");
1281 const MCOperand &RegOp = Inst.getOperand(0);
1282 assert(RegOp.isReg() && "expected register operand kind");
1284 int64_t ImmValue = ImmOp.getImm();
1285 tmpInst.setLoc(IDLoc);
1286 // FIXME: gas has a special case for values that are 000...1111, which
1287 // becomes a li -1 and then a dsrl
1288 if (0 <= ImmValue && ImmValue <= 65535) {
1289 // For 0 <= j <= 65535.
1290 // li d,j => ori d,$zero,j
1291 tmpInst.setOpcode(Mips::ORi);
1292 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1293 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1294 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1295 Instructions.push_back(tmpInst);
1296 } else if (ImmValue < 0 && ImmValue >= -32768) {
1297 // For -32768 <= j < 0.
1298 // li d,j => addiu d,$zero,j
1299 tmpInst.setOpcode(Mips::ADDiu);
1300 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1301 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1302 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1303 Instructions.push_back(tmpInst);
1304 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1305 // For any value of j that is representable as a 32-bit integer, create
1307 // li d,j => lui d,hi16(j)
1309 tmpInst.setOpcode(Mips::LUi);
1310 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1311 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1312 Instructions.push_back(tmpInst);
1313 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1314 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1316 Error(IDLoc, "instruction requires a 64-bit architecture");
1320 // <------- lo32 ------>
1321 // <------- hi32 ------>
1322 // <- hi16 -> <- lo16 ->
1323 // _________________________________
1325 // | 16-bytes | 16-bytes | 16-bytes |
1326 // |__________|__________|__________|
1328 // For any value of j that is representable as a 48-bit integer, create
1330 // li d,j => lui d,hi16(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 << 32)) >> 32));
1338 Instructions.push_back(tmpInst);
1339 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1340 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1343 Error(IDLoc, "instruction requires a 64-bit architecture");
1347 // <------- hi32 ------> <------- lo32 ------>
1348 // <- hi16 -> <- lo16 ->
1349 // ___________________________________________
1351 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1352 // |__________|__________|__________|__________|
1354 // For any value of j that isn't representable as a 48-bit integer.
1355 // li d,j => lui d,hi16(j)
1356 // ori d,d,lo16(hi32(j))
1358 // ori d,d,hi16(lo32(j))
1360 // ori d,d,lo16(lo32(j))
1361 tmpInst.setOpcode(Mips::LUi);
1362 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1364 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1365 Instructions.push_back(tmpInst);
1366 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1367 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1368 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1374 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1375 SmallVectorImpl<MCInst> &Instructions) {
1377 const MCOperand &ImmOp = Inst.getOperand(2);
1378 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1379 "expected immediate operand kind");
1380 if (!ImmOp.isImm()) {
1381 expandLoadAddressSym(Inst, IDLoc, Instructions);
1384 const MCOperand &SrcRegOp = Inst.getOperand(1);
1385 assert(SrcRegOp.isReg() && "expected register operand kind");
1386 const MCOperand &DstRegOp = Inst.getOperand(0);
1387 assert(DstRegOp.isReg() && "expected register operand kind");
1388 int ImmValue = ImmOp.getImm();
1389 if (-32768 <= ImmValue && ImmValue <= 65535) {
1390 // For -32768 <= j <= 65535.
1391 // la d,j(s) => addiu d,s,j
1392 tmpInst.setOpcode(Mips::ADDiu);
1393 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1394 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1395 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1396 Instructions.push_back(tmpInst);
1398 // For any other value of j that is representable as a 32-bit integer.
1399 // la d,j(s) => lui d,hi16(j)
1402 tmpInst.setOpcode(Mips::LUi);
1403 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1404 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1405 Instructions.push_back(tmpInst);
1407 tmpInst.setOpcode(Mips::ORi);
1408 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1409 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1410 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1411 Instructions.push_back(tmpInst);
1413 tmpInst.setOpcode(Mips::ADDu);
1414 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1415 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1416 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1417 Instructions.push_back(tmpInst);
1423 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1424 SmallVectorImpl<MCInst> &Instructions) {
1426 const MCOperand &ImmOp = Inst.getOperand(1);
1427 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1428 "expected immediate operand kind");
1429 if (!ImmOp.isImm()) {
1430 expandLoadAddressSym(Inst, IDLoc, Instructions);
1433 const MCOperand &RegOp = Inst.getOperand(0);
1434 assert(RegOp.isReg() && "expected register operand kind");
1435 int ImmValue = ImmOp.getImm();
1436 if (-32768 <= ImmValue && ImmValue <= 65535) {
1437 // For -32768 <= j <= 65535.
1438 // la d,j => addiu d,$zero,j
1439 tmpInst.setOpcode(Mips::ADDiu);
1440 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1441 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1442 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1443 Instructions.push_back(tmpInst);
1445 // For any other value of j that is representable as a 32-bit integer.
1446 // la d,j => lui d,hi16(j)
1448 tmpInst.setOpcode(Mips::LUi);
1449 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1450 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1451 Instructions.push_back(tmpInst);
1453 tmpInst.setOpcode(Mips::ORi);
1454 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1455 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1456 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1457 Instructions.push_back(tmpInst);
1463 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1464 SmallVectorImpl<MCInst> &Instructions) {
1465 // FIXME: If we do have a valid at register to use, we should generate a
1466 // slightly shorter sequence here.
1468 int ExprOperandNo = 1;
1469 // Sometimes the assembly parser will get the immediate expression as
1470 // a $zero + an immediate.
1471 if (Inst.getNumOperands() == 3) {
1472 assert(Inst.getOperand(1).getReg() ==
1473 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1476 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1477 assert(SymOp.isExpr() && "expected symbol operand kind");
1478 const MCOperand &RegOp = Inst.getOperand(0);
1479 unsigned RegNo = RegOp.getReg();
1480 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1481 const MCSymbolRefExpr *HiExpr =
1482 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1483 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1484 const MCSymbolRefExpr *LoExpr =
1485 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1486 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1488 // If it's a 64-bit architecture, expand to:
1489 // la d,sym => lui d,highest(sym)
1490 // ori d,d,higher(sym)
1492 // ori d,d,hi16(sym)
1494 // ori d,d,lo16(sym)
1495 const MCSymbolRefExpr *HighestExpr =
1496 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1497 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1498 const MCSymbolRefExpr *HigherExpr =
1499 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1500 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1502 tmpInst.setOpcode(Mips::LUi);
1503 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1504 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1505 Instructions.push_back(tmpInst);
1507 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1509 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1511 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1514 // Otherwise, expand to:
1515 // la d,sym => lui d,hi16(sym)
1516 // ori d,d,lo16(sym)
1517 tmpInst.setOpcode(Mips::LUi);
1518 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1519 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1520 Instructions.push_back(tmpInst);
1522 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1527 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1528 SmallVectorImpl<MCInst> &Instructions,
1529 bool isLoad, bool isImmOpnd) {
1530 const MCSymbolRefExpr *SR;
1532 unsigned ImmOffset, HiOffset, LoOffset;
1533 const MCExpr *ExprOffset;
1535 // 1st operand is either the source or destination register.
1536 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1537 unsigned RegOpNum = Inst.getOperand(0).getReg();
1538 // 2nd operand is the base register.
1539 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1540 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1541 // 3rd operand is either an immediate or expression.
1543 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1544 ImmOffset = Inst.getOperand(2).getImm();
1545 LoOffset = ImmOffset & 0x0000ffff;
1546 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1547 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1548 if (LoOffset & 0x8000)
1551 ExprOffset = Inst.getOperand(2).getExpr();
1552 // All instructions will have the same location.
1553 TempInst.setLoc(IDLoc);
1554 // These are some of the types of expansions we perform here:
1555 // 1) lw $8, sym => lui $8, %hi(sym)
1556 // lw $8, %lo(sym)($8)
1557 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1559 // lw $8, %lo(offset)($9)
1560 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1562 // lw $8, %lo(offset)($at)
1563 // 4) sw $8, sym => lui $at, %hi(sym)
1564 // sw $8, %lo(sym)($at)
1565 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1567 // sw $8, %lo(offset)($at)
1568 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1569 // ldc1 $f0, %lo(sym)($at)
1571 // For load instructions we can use the destination register as a temporary
1572 // if base and dst are different (examples 1 and 2) and if the base register
1573 // is general purpose otherwise we must use $at (example 6) and error if it's
1574 // not available. For stores we must use $at (examples 4 and 5) because we
1575 // must not clobber the source register setting up the offset.
1576 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1577 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1578 unsigned RegClassIDOp0 =
1579 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1580 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1581 (RegClassIDOp0 == Mips::GPR64RegClassID);
1582 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1583 TmpRegNum = RegOpNum;
1585 int AT = getATReg(IDLoc);
1586 // At this point we need AT to perform the expansions and we exit if it is
1591 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1594 TempInst.setOpcode(Mips::LUi);
1595 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1597 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1599 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1600 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1601 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1602 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1604 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1606 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1607 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1610 // Add the instruction to the list.
1611 Instructions.push_back(TempInst);
1612 // Prepare TempInst for next instruction.
1614 // Add temp register to base.
1615 TempInst.setOpcode(Mips::ADDu);
1616 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1617 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1618 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1619 Instructions.push_back(TempInst);
1621 // And finally, create original instruction with low part
1622 // of offset and new base.
1623 TempInst.setOpcode(Inst.getOpcode());
1624 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1625 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1627 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1629 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1630 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1631 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1633 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1635 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1636 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1639 Instructions.push_back(TempInst);
1643 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1644 // As described by the Mips32r2 spec, the registers Rd and Rs for
1645 // jalr.hb must be different.
1646 unsigned Opcode = Inst.getOpcode();
1648 if (Opcode == Mips::JALR_HB &&
1649 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1650 return Match_RequiresDifferentSrcAndDst;
1652 return Match_Success;
1655 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1656 OperandVector &Operands,
1658 uint64_t &ErrorInfo,
1659 bool MatchingInlineAsm) {
1662 SmallVector<MCInst, 8> Instructions;
1663 unsigned MatchResult =
1664 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1666 switch (MatchResult) {
1669 case Match_Success: {
1670 if (processInstruction(Inst, IDLoc, Instructions))
1672 for (unsigned i = 0; i < Instructions.size(); i++)
1673 Out.EmitInstruction(Instructions[i], STI);
1676 case Match_MissingFeature:
1677 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1679 case Match_InvalidOperand: {
1680 SMLoc ErrorLoc = IDLoc;
1681 if (ErrorInfo != ~0ULL) {
1682 if (ErrorInfo >= Operands.size())
1683 return Error(IDLoc, "too few operands for instruction");
1685 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1686 if (ErrorLoc == SMLoc())
1690 return Error(ErrorLoc, "invalid operand for instruction");
1692 case Match_MnemonicFail:
1693 return Error(IDLoc, "invalid instruction");
1694 case Match_RequiresDifferentSrcAndDst:
1695 return Error(IDLoc, "source and destination must be different");
1700 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1701 if ((RegIndex != 0) &&
1702 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1704 Warning(Loc, "used $at without \".set noat\"");
1706 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1707 Twine(RegIndex) + "\"");
1712 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1713 SMRange Range, bool ShowColors) {
1714 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1715 Range, SMFixIt(Range, FixMsg),
1719 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1722 CC = StringSwitch<unsigned>(Name)
1758 if (!(isABI_N32() || isABI_N64()))
1761 if (12 <= CC && CC <= 15) {
1762 // Name is one of t4-t7
1763 AsmToken RegTok = getLexer().peekTok();
1764 SMRange RegRange = RegTok.getLocRange();
1766 StringRef FixedName = StringSwitch<StringRef>(Name)
1772 assert(FixedName != "" && "Register name is not one of t4-t7.");
1774 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1775 "Did you mean $" + FixedName + "?", RegRange);
1778 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1779 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1780 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1781 if (8 <= CC && CC <= 11)
1785 CC = StringSwitch<unsigned>(Name)
1797 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1799 if (Name[0] == 'f') {
1800 StringRef NumString = Name.substr(1);
1802 if (NumString.getAsInteger(10, IntVal))
1803 return -1; // This is not an integer.
1804 if (IntVal > 31) // Maximum index for fpu register.
1811 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1813 if (Name.startswith("fcc")) {
1814 StringRef NumString = Name.substr(3);
1816 if (NumString.getAsInteger(10, IntVal))
1817 return -1; // This is not an integer.
1818 if (IntVal > 7) // There are only 8 fcc registers.
1825 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1827 if (Name.startswith("ac")) {
1828 StringRef NumString = Name.substr(2);
1830 if (NumString.getAsInteger(10, IntVal))
1831 return -1; // This is not an integer.
1832 if (IntVal > 3) // There are only 3 acc registers.
1839 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1842 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1851 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1854 CC = StringSwitch<unsigned>(Name)
1857 .Case("msaaccess", 2)
1859 .Case("msamodify", 4)
1860 .Case("msarequest", 5)
1862 .Case("msaunmap", 7)
1868 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1876 int MipsAsmParser::getATReg(SMLoc Loc) {
1877 int AT = AssemblerOptions.back()->getATRegNum();
1879 reportParseError(Loc,
1880 "pseudo-instruction requires $at, which is not available");
1884 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1885 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1888 unsigned MipsAsmParser::getGPR(int RegNo) {
1889 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1893 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1895 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1898 return getReg(RegClass, RegNum);
1901 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1902 DEBUG(dbgs() << "parseOperand\n");
1904 // Check if the current operand has a custom associated parser, if so, try to
1905 // custom parse the operand, or fallback to the general approach.
1906 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1907 if (ResTy == MatchOperand_Success)
1909 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1910 // there was a match, but an error occurred, in which case, just return that
1911 // the operand parsing failed.
1912 if (ResTy == MatchOperand_ParseFail)
1915 DEBUG(dbgs() << ".. Generic Parser\n");
1917 switch (getLexer().getKind()) {
1919 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1921 case AsmToken::Dollar: {
1922 // Parse the register.
1923 SMLoc S = Parser.getTok().getLoc();
1925 // Almost all registers have been parsed by custom parsers. There is only
1926 // one exception to this. $zero (and it's alias $0) will reach this point
1927 // for div, divu, and similar instructions because it is not an operand
1928 // to the instruction definition but an explicit register. Special case
1929 // this situation for now.
1930 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1933 // Maybe it is a symbol reference.
1934 StringRef Identifier;
1935 if (Parser.parseIdentifier(Identifier))
1938 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1939 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1940 // Otherwise create a symbol reference.
1942 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1944 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1947 // Else drop to expression parsing.
1948 case AsmToken::LParen:
1949 case AsmToken::Minus:
1950 case AsmToken::Plus:
1951 case AsmToken::Integer:
1952 case AsmToken::Tilde:
1953 case AsmToken::String: {
1954 DEBUG(dbgs() << ".. generic integer\n");
1955 OperandMatchResultTy ResTy = parseImm(Operands);
1956 return ResTy != MatchOperand_Success;
1958 case AsmToken::Percent: {
1959 // It is a symbol reference or constant expression.
1960 const MCExpr *IdVal;
1961 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1962 if (parseRelocOperand(IdVal))
1965 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1967 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1969 } // case AsmToken::Percent
1970 } // switch(getLexer().getKind())
1974 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1975 StringRef RelocStr) {
1977 // Check the type of the expression.
1978 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1979 // It's a constant, evaluate reloc value.
1981 switch (getVariantKind(RelocStr)) {
1982 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1983 // Get the 1st 16-bits.
1984 Val = MCE->getValue() & 0xffff;
1986 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1987 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1988 // 16 bits being negative.
1989 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1991 case MCSymbolRefExpr::VK_Mips_HIGHER:
1992 // Get the 3rd 16-bits.
1993 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1995 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1996 // Get the 4th 16-bits.
1997 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2000 report_fatal_error("unsupported reloc value");
2002 return MCConstantExpr::Create(Val, getContext());
2005 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2006 // It's a symbol, create a symbolic expression from the symbol.
2007 StringRef Symbol = MSRE->getSymbol().getName();
2008 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2009 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2013 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2014 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2016 // Try to create target expression.
2017 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2018 return MipsMCExpr::Create(VK, Expr, getContext());
2020 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2021 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2022 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2026 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2027 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2028 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2031 // Just return the original expression.
2035 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2037 switch (Expr->getKind()) {
2038 case MCExpr::Constant:
2040 case MCExpr::SymbolRef:
2041 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2042 case MCExpr::Binary:
2043 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2044 if (!isEvaluated(BE->getLHS()))
2046 return isEvaluated(BE->getRHS());
2049 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2050 case MCExpr::Target:
2056 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2057 Parser.Lex(); // Eat the % token.
2058 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2059 if (Tok.isNot(AsmToken::Identifier))
2062 std::string Str = Tok.getIdentifier().str();
2064 Parser.Lex(); // Eat the identifier.
2065 // Now make an expression from the rest of the operand.
2066 const MCExpr *IdVal;
2069 if (getLexer().getKind() == AsmToken::LParen) {
2071 Parser.Lex(); // Eat the '(' token.
2072 if (getLexer().getKind() == AsmToken::Percent) {
2073 Parser.Lex(); // Eat the % token.
2074 const AsmToken &nextTok = Parser.getTok();
2075 if (nextTok.isNot(AsmToken::Identifier))
2078 Str += nextTok.getIdentifier();
2079 Parser.Lex(); // Eat the identifier.
2080 if (getLexer().getKind() != AsmToken::LParen)
2085 if (getParser().parseParenExpression(IdVal, EndLoc))
2088 while (getLexer().getKind() == AsmToken::RParen)
2089 Parser.Lex(); // Eat the ')' token.
2092 return true; // Parenthesis must follow the relocation operand.
2094 Res = evaluateRelocExpr(IdVal, Str);
2098 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2100 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2101 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2102 if (ResTy == MatchOperand_Success) {
2103 assert(Operands.size() == 1);
2104 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2105 StartLoc = Operand.getStartLoc();
2106 EndLoc = Operand.getEndLoc();
2108 // AFAIK, we only support numeric registers and named GPR's in CFI
2110 // Don't worry about eating tokens before failing. Using an unrecognised
2111 // register is a parse error.
2112 if (Operand.isGPRAsmReg()) {
2113 // Resolve to GPR32 or GPR64 appropriately.
2114 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2117 return (RegNo == (unsigned)-1);
2120 assert(Operands.size() == 0);
2121 return (RegNo == (unsigned)-1);
2124 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2128 while (getLexer().getKind() == AsmToken::LParen)
2131 switch (getLexer().getKind()) {
2134 case AsmToken::Identifier:
2135 case AsmToken::LParen:
2136 case AsmToken::Integer:
2137 case AsmToken::Minus:
2138 case AsmToken::Plus:
2140 Result = getParser().parseParenExpression(Res, S);
2142 Result = (getParser().parseExpression(Res));
2143 while (getLexer().getKind() == AsmToken::RParen)
2146 case AsmToken::Percent:
2147 Result = parseRelocOperand(Res);
2152 MipsAsmParser::OperandMatchResultTy
2153 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2154 DEBUG(dbgs() << "parseMemOperand\n");
2155 const MCExpr *IdVal = nullptr;
2157 bool isParenExpr = false;
2158 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2159 // First operand is the offset.
2160 S = Parser.getTok().getLoc();
2162 if (getLexer().getKind() == AsmToken::LParen) {
2167 if (getLexer().getKind() != AsmToken::Dollar) {
2168 if (parseMemOffset(IdVal, isParenExpr))
2169 return MatchOperand_ParseFail;
2171 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2172 if (Tok.isNot(AsmToken::LParen)) {
2173 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2174 if (Mnemonic.getToken() == "la") {
2176 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2177 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2178 return MatchOperand_Success;
2180 if (Tok.is(AsmToken::EndOfStatement)) {
2182 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2184 // Zero register assumed, add a memory operand with ZERO as its base.
2185 // "Base" will be managed by k_Memory.
2186 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2189 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2190 return MatchOperand_Success;
2192 Error(Parser.getTok().getLoc(), "'(' expected");
2193 return MatchOperand_ParseFail;
2196 Parser.Lex(); // Eat the '(' token.
2199 Res = parseAnyRegister(Operands);
2200 if (Res != MatchOperand_Success)
2203 if (Parser.getTok().isNot(AsmToken::RParen)) {
2204 Error(Parser.getTok().getLoc(), "')' expected");
2205 return MatchOperand_ParseFail;
2208 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2210 Parser.Lex(); // Eat the ')' token.
2213 IdVal = MCConstantExpr::Create(0, getContext());
2215 // Replace the register operand with the memory operand.
2216 std::unique_ptr<MipsOperand> op(
2217 static_cast<MipsOperand *>(Operands.back().release()));
2218 // Remove the register from the operands.
2219 // "op" will be managed by k_Memory.
2220 Operands.pop_back();
2221 // Add the memory operand.
2222 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2224 if (IdVal->EvaluateAsAbsolute(Imm))
2225 IdVal = MCConstantExpr::Create(Imm, getContext());
2226 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2227 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2231 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2232 return MatchOperand_Success;
2235 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2237 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2239 SMLoc S = Parser.getTok().getLoc();
2241 if (Sym->isVariable())
2242 Expr = Sym->getVariableValue();
2245 if (Expr->getKind() == MCExpr::SymbolRef) {
2246 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2247 StringRef DefSymbol = Ref->getSymbol().getName();
2248 if (DefSymbol.startswith("$")) {
2249 OperandMatchResultTy ResTy =
2250 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2251 if (ResTy == MatchOperand_Success) {
2254 } else if (ResTy == MatchOperand_ParseFail)
2255 llvm_unreachable("Should never ParseFail");
2258 } else if (Expr->getKind() == MCExpr::Constant) {
2260 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2262 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2269 MipsAsmParser::OperandMatchResultTy
2270 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2271 StringRef Identifier,
2273 int Index = matchCPURegisterName(Identifier);
2275 Operands.push_back(MipsOperand::createGPRReg(
2276 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2277 return MatchOperand_Success;
2280 Index = matchFPURegisterName(Identifier);
2282 Operands.push_back(MipsOperand::createFGRReg(
2283 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2284 return MatchOperand_Success;
2287 Index = matchFCCRegisterName(Identifier);
2289 Operands.push_back(MipsOperand::createFCCReg(
2290 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2291 return MatchOperand_Success;
2294 Index = matchACRegisterName(Identifier);
2296 Operands.push_back(MipsOperand::createACCReg(
2297 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2298 return MatchOperand_Success;
2301 Index = matchMSA128RegisterName(Identifier);
2303 Operands.push_back(MipsOperand::createMSA128Reg(
2304 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2305 return MatchOperand_Success;
2308 Index = matchMSA128CtrlRegisterName(Identifier);
2310 Operands.push_back(MipsOperand::createMSACtrlReg(
2311 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2312 return MatchOperand_Success;
2315 return MatchOperand_NoMatch;
2318 MipsAsmParser::OperandMatchResultTy
2319 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2320 auto Token = Parser.getLexer().peekTok(false);
2322 if (Token.is(AsmToken::Identifier)) {
2323 DEBUG(dbgs() << ".. identifier\n");
2324 StringRef Identifier = Token.getIdentifier();
2325 OperandMatchResultTy ResTy =
2326 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2328 } else if (Token.is(AsmToken::Integer)) {
2329 DEBUG(dbgs() << ".. integer\n");
2330 Operands.push_back(MipsOperand::createNumericReg(
2331 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2333 return MatchOperand_Success;
2336 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2338 return MatchOperand_NoMatch;
2341 MipsAsmParser::OperandMatchResultTy
2342 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2343 DEBUG(dbgs() << "parseAnyRegister\n");
2345 auto Token = Parser.getTok();
2347 SMLoc S = Token.getLoc();
2349 if (Token.isNot(AsmToken::Dollar)) {
2350 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2351 if (Token.is(AsmToken::Identifier)) {
2352 if (searchSymbolAlias(Operands))
2353 return MatchOperand_Success;
2355 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2356 return MatchOperand_NoMatch;
2358 DEBUG(dbgs() << ".. $\n");
2360 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2361 if (ResTy == MatchOperand_Success) {
2363 Parser.Lex(); // identifier
2368 MipsAsmParser::OperandMatchResultTy
2369 MipsAsmParser::parseImm(OperandVector &Operands) {
2370 switch (getLexer().getKind()) {
2372 return MatchOperand_NoMatch;
2373 case AsmToken::LParen:
2374 case AsmToken::Minus:
2375 case AsmToken::Plus:
2376 case AsmToken::Integer:
2377 case AsmToken::Tilde:
2378 case AsmToken::String:
2382 const MCExpr *IdVal;
2383 SMLoc S = Parser.getTok().getLoc();
2384 if (getParser().parseExpression(IdVal))
2385 return MatchOperand_ParseFail;
2387 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2388 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2389 return MatchOperand_Success;
2392 MipsAsmParser::OperandMatchResultTy
2393 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2394 DEBUG(dbgs() << "parseJumpTarget\n");
2396 SMLoc S = getLexer().getLoc();
2398 // Integers and expressions are acceptable
2399 OperandMatchResultTy ResTy = parseImm(Operands);
2400 if (ResTy != MatchOperand_NoMatch)
2403 // Registers are a valid target and have priority over symbols.
2404 ResTy = parseAnyRegister(Operands);
2405 if (ResTy != MatchOperand_NoMatch)
2408 const MCExpr *Expr = nullptr;
2409 if (Parser.parseExpression(Expr)) {
2410 // We have no way of knowing if a symbol was consumed so we must ParseFail
2411 return MatchOperand_ParseFail;
2414 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2415 return MatchOperand_Success;
2418 MipsAsmParser::OperandMatchResultTy
2419 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2420 const MCExpr *IdVal;
2421 // If the first token is '$' we may have register operand.
2422 if (Parser.getTok().is(AsmToken::Dollar))
2423 return MatchOperand_NoMatch;
2424 SMLoc S = Parser.getTok().getLoc();
2425 if (getParser().parseExpression(IdVal))
2426 return MatchOperand_ParseFail;
2427 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2428 assert(MCE && "Unexpected MCExpr type.");
2429 int64_t Val = MCE->getValue();
2430 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2431 Operands.push_back(MipsOperand::CreateImm(
2432 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2433 return MatchOperand_Success;
2436 MipsAsmParser::OperandMatchResultTy
2437 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2438 switch (getLexer().getKind()) {
2440 return MatchOperand_NoMatch;
2441 case AsmToken::LParen:
2442 case AsmToken::Plus:
2443 case AsmToken::Minus:
2444 case AsmToken::Integer:
2449 SMLoc S = Parser.getTok().getLoc();
2451 if (getParser().parseExpression(Expr))
2452 return MatchOperand_ParseFail;
2455 if (!Expr->EvaluateAsAbsolute(Val)) {
2456 Error(S, "expected immediate value");
2457 return MatchOperand_ParseFail;
2460 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2461 // and because the CPU always adds one to the immediate field, the allowed
2462 // range becomes 1..4. We'll only check the range here and will deal
2463 // with the addition/subtraction when actually decoding/encoding
2465 if (Val < 1 || Val > 4) {
2466 Error(S, "immediate not in range (1..4)");
2467 return MatchOperand_ParseFail;
2471 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2472 return MatchOperand_Success;
2475 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2477 MCSymbolRefExpr::VariantKind VK =
2478 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2479 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2480 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2481 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2482 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2483 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2484 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2485 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2486 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2487 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2488 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2489 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2490 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2491 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2492 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2493 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2494 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2495 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2496 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2497 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2498 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2499 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2500 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2501 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2502 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2503 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2504 .Default(MCSymbolRefExpr::VK_None);
2506 assert(VK != MCSymbolRefExpr::VK_None);
2511 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2513 /// ::= '(', register, ')'
2514 /// handle it before we iterate so we don't get tripped up by the lack of
2516 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2517 if (getLexer().is(AsmToken::LParen)) {
2519 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2521 if (parseOperand(Operands, Name)) {
2522 SMLoc Loc = getLexer().getLoc();
2523 Parser.eatToEndOfStatement();
2524 return Error(Loc, "unexpected token in argument list");
2526 if (Parser.getTok().isNot(AsmToken::RParen)) {
2527 SMLoc Loc = getLexer().getLoc();
2528 Parser.eatToEndOfStatement();
2529 return Error(Loc, "unexpected token, expected ')'");
2532 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2538 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2539 /// either one of these.
2540 /// ::= '[', register, ']'
2541 /// ::= '[', integer, ']'
2542 /// handle it before we iterate so we don't get tripped up by the lack of
2544 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2545 OperandVector &Operands) {
2546 if (getLexer().is(AsmToken::LBrac)) {
2548 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2550 if (parseOperand(Operands, Name)) {
2551 SMLoc Loc = getLexer().getLoc();
2552 Parser.eatToEndOfStatement();
2553 return Error(Loc, "unexpected token in argument list");
2555 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2556 SMLoc Loc = getLexer().getLoc();
2557 Parser.eatToEndOfStatement();
2558 return Error(Loc, "unexpected token, expected ']'");
2561 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2567 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2568 SMLoc NameLoc, OperandVector &Operands) {
2569 DEBUG(dbgs() << "ParseInstruction\n");
2571 // We have reached first instruction, module directive are now forbidden.
2572 getTargetStreamer().forbidModuleDirective();
2574 // Check if we have valid mnemonic
2575 if (!mnemonicIsValid(Name, 0)) {
2576 Parser.eatToEndOfStatement();
2577 return Error(NameLoc, "unknown instruction");
2579 // First operand in MCInst is instruction mnemonic.
2580 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2582 // Read the remaining operands.
2583 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2584 // Read the first operand.
2585 if (parseOperand(Operands, Name)) {
2586 SMLoc Loc = getLexer().getLoc();
2587 Parser.eatToEndOfStatement();
2588 return Error(Loc, "unexpected token in argument list");
2590 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2592 // AFAIK, parenthesis suffixes are never on the first operand
2594 while (getLexer().is(AsmToken::Comma)) {
2595 Parser.Lex(); // Eat the comma.
2596 // Parse and remember the operand.
2597 if (parseOperand(Operands, Name)) {
2598 SMLoc Loc = getLexer().getLoc();
2599 Parser.eatToEndOfStatement();
2600 return Error(Loc, "unexpected token in argument list");
2602 // Parse bracket and parenthesis suffixes before we iterate
2603 if (getLexer().is(AsmToken::LBrac)) {
2604 if (parseBracketSuffix(Name, Operands))
2606 } else if (getLexer().is(AsmToken::LParen) &&
2607 parseParenSuffix(Name, Operands))
2611 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2612 SMLoc Loc = getLexer().getLoc();
2613 Parser.eatToEndOfStatement();
2614 return Error(Loc, "unexpected token in argument list");
2616 Parser.Lex(); // Consume the EndOfStatement.
2620 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2621 SMLoc Loc = getLexer().getLoc();
2622 Parser.eatToEndOfStatement();
2623 return Error(Loc, ErrorMsg);
2626 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2627 return Error(Loc, ErrorMsg);
2630 bool MipsAsmParser::parseSetNoAtDirective() {
2631 // Line should look like: ".set noat".
2633 AssemblerOptions.back()->setATReg(0);
2636 // If this is not the end of the statement, report an error.
2637 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2638 reportParseError("unexpected token, expected end of statement");
2641 Parser.Lex(); // Consume the EndOfStatement.
2645 bool MipsAsmParser::parseSetAtDirective() {
2646 // Line can be .set at - defaults to $1
2650 if (getLexer().is(AsmToken::EndOfStatement)) {
2651 AssemblerOptions.back()->setATReg(1);
2652 Parser.Lex(); // Consume the EndOfStatement.
2654 } else if (getLexer().is(AsmToken::Equal)) {
2655 getParser().Lex(); // Eat the '='.
2656 if (getLexer().isNot(AsmToken::Dollar)) {
2657 reportParseError("unexpected token, expected dollar sign '$'");
2660 Parser.Lex(); // Eat the '$'.
2661 const AsmToken &Reg = Parser.getTok();
2662 if (Reg.is(AsmToken::Identifier)) {
2663 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2664 } else if (Reg.is(AsmToken::Integer)) {
2665 AtRegNo = Reg.getIntVal();
2667 reportParseError("unexpected token, expected identifier or integer");
2671 if (AtRegNo < 0 || AtRegNo > 31) {
2672 reportParseError("unexpected token in statement");
2676 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2677 reportParseError("invalid register");
2680 getParser().Lex(); // Eat the register.
2682 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2683 reportParseError("unexpected token, expected end of statement");
2686 Parser.Lex(); // Consume the EndOfStatement.
2689 reportParseError("unexpected token in statement");
2694 bool MipsAsmParser::parseSetReorderDirective() {
2696 // If this is not the end of the statement, report an error.
2697 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2698 reportParseError("unexpected token, expected end of statement");
2701 AssemblerOptions.back()->setReorder();
2702 getTargetStreamer().emitDirectiveSetReorder();
2703 Parser.Lex(); // Consume the EndOfStatement.
2707 bool MipsAsmParser::parseSetNoReorderDirective() {
2709 // If this is not the end of the statement, report an error.
2710 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2711 reportParseError("unexpected token, expected end of statement");
2714 AssemblerOptions.back()->setNoReorder();
2715 getTargetStreamer().emitDirectiveSetNoReorder();
2716 Parser.Lex(); // Consume the EndOfStatement.
2720 bool MipsAsmParser::parseSetMacroDirective() {
2722 // If this is not the end of the statement, report an error.
2723 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2724 reportParseError("unexpected token, expected end of statement");
2727 AssemblerOptions.back()->setMacro();
2728 Parser.Lex(); // Consume the EndOfStatement.
2732 bool MipsAsmParser::parseSetNoMacroDirective() {
2734 // If this is not the end of the statement, report an error.
2735 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2736 reportParseError("unexpected token, expected end of statement");
2739 if (AssemblerOptions.back()->isReorder()) {
2740 reportParseError("`noreorder' must be set before `nomacro'");
2743 AssemblerOptions.back()->setNoMacro();
2744 Parser.Lex(); // Consume the EndOfStatement.
2748 bool MipsAsmParser::parseSetMsaDirective() {
2751 // If this is not the end of the statement, report an error.
2752 if (getLexer().isNot(AsmToken::EndOfStatement))
2753 return reportParseError("unexpected token, expected end of statement");
2755 setFeatureBits(Mips::FeatureMSA, "msa");
2756 getTargetStreamer().emitDirectiveSetMsa();
2760 bool MipsAsmParser::parseSetNoMsaDirective() {
2763 // If this is not the end of the statement, report an error.
2764 if (getLexer().isNot(AsmToken::EndOfStatement))
2765 return reportParseError("unexpected token, expected end of statement");
2767 clearFeatureBits(Mips::FeatureMSA, "msa");
2768 getTargetStreamer().emitDirectiveSetNoMsa();
2772 bool MipsAsmParser::parseSetNoDspDirective() {
2773 Parser.Lex(); // Eat "nodsp".
2775 // If this is not the end of the statement, report an error.
2776 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2777 reportParseError("unexpected token, expected end of statement");
2781 clearFeatureBits(Mips::FeatureDSP, "dsp");
2782 getTargetStreamer().emitDirectiveSetNoDsp();
2786 bool MipsAsmParser::parseSetNoMips16Directive() {
2788 // If this is not the end of the statement, report an error.
2789 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2790 reportParseError("unexpected token, expected end of statement");
2793 // For now do nothing.
2794 Parser.Lex(); // Consume the EndOfStatement.
2798 bool MipsAsmParser::parseSetFpDirective() {
2799 MipsABIFlagsSection::FpABIKind FpAbiVal;
2800 // Line can be: .set fp=32
2803 Parser.Lex(); // Eat fp token
2804 AsmToken Tok = Parser.getTok();
2805 if (Tok.isNot(AsmToken::Equal)) {
2806 reportParseError("unexpected token, expected equals sign '='");
2809 Parser.Lex(); // Eat '=' token.
2810 Tok = Parser.getTok();
2812 if (!parseFpABIValue(FpAbiVal, ".set"))
2815 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2816 reportParseError("unexpected token, expected end of statement");
2819 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2820 Parser.Lex(); // Consume the EndOfStatement.
2824 bool MipsAsmParser::parseSetPopDirective() {
2825 SMLoc Loc = getLexer().getLoc();
2828 if (getLexer().isNot(AsmToken::EndOfStatement))
2829 return reportParseError("unexpected token, expected end of statement");
2831 // Always keep an element on the options "stack" to prevent the user
2832 // from changing the initial options. This is how we remember them.
2833 if (AssemblerOptions.size() == 2)
2834 return reportParseError(Loc, ".set pop with no .set push");
2836 AssemblerOptions.pop_back();
2837 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2839 getTargetStreamer().emitDirectiveSetPop();
2843 bool MipsAsmParser::parseSetPushDirective() {
2845 if (getLexer().isNot(AsmToken::EndOfStatement))
2846 return reportParseError("unexpected token, expected end of statement");
2848 // Create a copy of the current assembler options environment and push it.
2849 AssemblerOptions.push_back(
2850 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2852 getTargetStreamer().emitDirectiveSetPush();
2856 bool MipsAsmParser::parseSetAssignment() {
2858 const MCExpr *Value;
2860 if (Parser.parseIdentifier(Name))
2861 reportParseError("expected identifier after .set");
2863 if (getLexer().isNot(AsmToken::Comma))
2864 return reportParseError("unexpected token, expected comma");
2867 if (Parser.parseExpression(Value))
2868 return reportParseError("expected valid expression after comma");
2870 // Check if the Name already exists as a symbol.
2871 MCSymbol *Sym = getContext().LookupSymbol(Name);
2873 return reportParseError("symbol already defined");
2874 Sym = getContext().GetOrCreateSymbol(Name);
2875 Sym->setVariableValue(Value);
2880 bool MipsAsmParser::parseSetMips0Directive() {
2882 if (getLexer().isNot(AsmToken::EndOfStatement))
2883 return reportParseError("unexpected token, expected end of statement");
2885 // Reset assembler options to their initial values.
2886 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2887 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2889 getTargetStreamer().emitDirectiveSetMips0();
2893 bool MipsAsmParser::parseSetArchDirective() {
2895 if (getLexer().isNot(AsmToken::Equal))
2896 return reportParseError("unexpected token, expected equals sign");
2900 if (Parser.parseIdentifier(Arch))
2901 return reportParseError("expected arch identifier");
2903 StringRef ArchFeatureName =
2904 StringSwitch<StringRef>(Arch)
2905 .Case("mips1", "mips1")
2906 .Case("mips2", "mips2")
2907 .Case("mips3", "mips3")
2908 .Case("mips4", "mips4")
2909 .Case("mips5", "mips5")
2910 .Case("mips32", "mips32")
2911 .Case("mips32r2", "mips32r2")
2912 .Case("mips32r6", "mips32r6")
2913 .Case("mips64", "mips64")
2914 .Case("mips64r2", "mips64r2")
2915 .Case("mips64r6", "mips64r6")
2916 .Case("cnmips", "cnmips")
2917 .Case("r4000", "mips3") // This is an implementation of Mips3.
2920 if (ArchFeatureName.empty())
2921 return reportParseError("unsupported architecture");
2923 selectArch(ArchFeatureName);
2924 getTargetStreamer().emitDirectiveSetArch(Arch);
2928 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2930 if (getLexer().isNot(AsmToken::EndOfStatement))
2931 return reportParseError("unexpected token, expected end of statement");
2935 llvm_unreachable("Unimplemented feature");
2936 case Mips::FeatureDSP:
2937 setFeatureBits(Mips::FeatureDSP, "dsp");
2938 getTargetStreamer().emitDirectiveSetDsp();
2940 case Mips::FeatureMicroMips:
2941 getTargetStreamer().emitDirectiveSetMicroMips();
2943 case Mips::FeatureMips16:
2944 getTargetStreamer().emitDirectiveSetMips16();
2946 case Mips::FeatureMips1:
2947 selectArch("mips1");
2948 getTargetStreamer().emitDirectiveSetMips1();
2950 case Mips::FeatureMips2:
2951 selectArch("mips2");
2952 getTargetStreamer().emitDirectiveSetMips2();
2954 case Mips::FeatureMips3:
2955 selectArch("mips3");
2956 getTargetStreamer().emitDirectiveSetMips3();
2958 case Mips::FeatureMips4:
2959 selectArch("mips4");
2960 getTargetStreamer().emitDirectiveSetMips4();
2962 case Mips::FeatureMips5:
2963 selectArch("mips5");
2964 getTargetStreamer().emitDirectiveSetMips5();
2966 case Mips::FeatureMips32:
2967 selectArch("mips32");
2968 getTargetStreamer().emitDirectiveSetMips32();
2970 case Mips::FeatureMips32r2:
2971 selectArch("mips32r2");
2972 getTargetStreamer().emitDirectiveSetMips32R2();
2974 case Mips::FeatureMips32r6:
2975 selectArch("mips32r6");
2976 getTargetStreamer().emitDirectiveSetMips32R6();
2978 case Mips::FeatureMips64:
2979 selectArch("mips64");
2980 getTargetStreamer().emitDirectiveSetMips64();
2982 case Mips::FeatureMips64r2:
2983 selectArch("mips64r2");
2984 getTargetStreamer().emitDirectiveSetMips64R2();
2986 case Mips::FeatureMips64r6:
2987 selectArch("mips64r6");
2988 getTargetStreamer().emitDirectiveSetMips64R6();
2994 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2995 if (getLexer().isNot(AsmToken::Comma)) {
2996 SMLoc Loc = getLexer().getLoc();
2997 Parser.eatToEndOfStatement();
2998 return Error(Loc, ErrorStr);
3001 Parser.Lex(); // Eat the comma.
3005 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3006 if (AssemblerOptions.back()->isReorder())
3007 Warning(Loc, ".cpload in reorder section");
3009 // FIXME: Warn if cpload is used in Mips16 mode.
3011 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3012 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3013 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3014 reportParseError("expected register containing function address");
3018 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3019 if (!RegOpnd.isGPRAsmReg()) {
3020 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3024 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3028 bool MipsAsmParser::parseDirectiveCPSetup() {
3031 bool SaveIsReg = true;
3033 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3034 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3035 if (ResTy == MatchOperand_NoMatch) {
3036 reportParseError("expected register containing function address");
3037 Parser.eatToEndOfStatement();
3041 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3042 if (!FuncRegOpnd.isGPRAsmReg()) {
3043 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3044 Parser.eatToEndOfStatement();
3048 FuncReg = FuncRegOpnd.getGPR32Reg();
3051 if (!eatComma("unexpected token, expected comma"))
3054 ResTy = parseAnyRegister(TmpReg);
3055 if (ResTy == MatchOperand_NoMatch) {
3056 const AsmToken &Tok = Parser.getTok();
3057 if (Tok.is(AsmToken::Integer)) {
3058 Save = Tok.getIntVal();
3062 reportParseError("expected save register or stack offset");
3063 Parser.eatToEndOfStatement();
3067 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3068 if (!SaveOpnd.isGPRAsmReg()) {
3069 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3070 Parser.eatToEndOfStatement();
3073 Save = SaveOpnd.getGPR32Reg();
3076 if (!eatComma("unexpected token, expected comma"))
3080 if (Parser.parseIdentifier(Name))
3081 reportParseError("expected identifier");
3082 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3084 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3088 bool MipsAsmParser::parseDirectiveNaN() {
3089 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3090 const AsmToken &Tok = Parser.getTok();
3092 if (Tok.getString() == "2008") {
3094 getTargetStreamer().emitDirectiveNaN2008();
3096 } else if (Tok.getString() == "legacy") {
3098 getTargetStreamer().emitDirectiveNaNLegacy();
3102 // If we don't recognize the option passed to the .nan
3103 // directive (e.g. no option or unknown option), emit an error.
3104 reportParseError("invalid option in .nan directive");
3108 bool MipsAsmParser::parseDirectiveSet() {
3110 // Get the next token.
3111 const AsmToken &Tok = Parser.getTok();
3113 if (Tok.getString() == "noat") {
3114 return parseSetNoAtDirective();
3115 } else if (Tok.getString() == "at") {
3116 return parseSetAtDirective();
3117 } else if (Tok.getString() == "arch") {
3118 return parseSetArchDirective();
3119 } else if (Tok.getString() == "fp") {
3120 return parseSetFpDirective();
3121 } else if (Tok.getString() == "pop") {
3122 return parseSetPopDirective();
3123 } else if (Tok.getString() == "push") {
3124 return parseSetPushDirective();
3125 } else if (Tok.getString() == "reorder") {
3126 return parseSetReorderDirective();
3127 } else if (Tok.getString() == "noreorder") {
3128 return parseSetNoReorderDirective();
3129 } else if (Tok.getString() == "macro") {
3130 return parseSetMacroDirective();
3131 } else if (Tok.getString() == "nomacro") {
3132 return parseSetNoMacroDirective();
3133 } else if (Tok.getString() == "mips16") {
3134 return parseSetFeature(Mips::FeatureMips16);
3135 } else if (Tok.getString() == "nomips16") {
3136 return parseSetNoMips16Directive();
3137 } else if (Tok.getString() == "nomicromips") {
3138 getTargetStreamer().emitDirectiveSetNoMicroMips();
3139 Parser.eatToEndOfStatement();
3141 } else if (Tok.getString() == "micromips") {
3142 return parseSetFeature(Mips::FeatureMicroMips);
3143 } else if (Tok.getString() == "mips0") {
3144 return parseSetMips0Directive();
3145 } else if (Tok.getString() == "mips1") {
3146 return parseSetFeature(Mips::FeatureMips1);
3147 } else if (Tok.getString() == "mips2") {
3148 return parseSetFeature(Mips::FeatureMips2);
3149 } else if (Tok.getString() == "mips3") {
3150 return parseSetFeature(Mips::FeatureMips3);
3151 } else if (Tok.getString() == "mips4") {
3152 return parseSetFeature(Mips::FeatureMips4);
3153 } else if (Tok.getString() == "mips5") {
3154 return parseSetFeature(Mips::FeatureMips5);
3155 } else if (Tok.getString() == "mips32") {
3156 return parseSetFeature(Mips::FeatureMips32);
3157 } else if (Tok.getString() == "mips32r2") {
3158 return parseSetFeature(Mips::FeatureMips32r2);
3159 } else if (Tok.getString() == "mips32r6") {
3160 return parseSetFeature(Mips::FeatureMips32r6);
3161 } else if (Tok.getString() == "mips64") {
3162 return parseSetFeature(Mips::FeatureMips64);
3163 } else if (Tok.getString() == "mips64r2") {
3164 return parseSetFeature(Mips::FeatureMips64r2);
3165 } else if (Tok.getString() == "mips64r6") {
3166 return parseSetFeature(Mips::FeatureMips64r6);
3167 } else if (Tok.getString() == "dsp") {
3168 return parseSetFeature(Mips::FeatureDSP);
3169 } else if (Tok.getString() == "nodsp") {
3170 return parseSetNoDspDirective();
3171 } else if (Tok.getString() == "msa") {
3172 return parseSetMsaDirective();
3173 } else if (Tok.getString() == "nomsa") {
3174 return parseSetNoMsaDirective();
3176 // It is just an identifier, look for an assignment.
3177 parseSetAssignment();
3184 /// parseDataDirective
3185 /// ::= .word [ expression (, expression)* ]
3186 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3189 const MCExpr *Value;
3190 if (getParser().parseExpression(Value))
3193 getParser().getStreamer().EmitValue(Value, Size);
3195 if (getLexer().is(AsmToken::EndOfStatement))
3198 if (getLexer().isNot(AsmToken::Comma))
3199 return Error(L, "unexpected token, expected comma");
3208 /// parseDirectiveGpWord
3209 /// ::= .gpword local_sym
3210 bool MipsAsmParser::parseDirectiveGpWord() {
3211 const MCExpr *Value;
3212 // EmitGPRel32Value requires an expression, so we are using base class
3213 // method to evaluate the expression.
3214 if (getParser().parseExpression(Value))
3216 getParser().getStreamer().EmitGPRel32Value(Value);
3218 if (getLexer().isNot(AsmToken::EndOfStatement))
3219 return Error(getLexer().getLoc(),
3220 "unexpected token, expected end of statement");
3221 Parser.Lex(); // Eat EndOfStatement token.
3225 /// parseDirectiveGpDWord
3226 /// ::= .gpdword local_sym
3227 bool MipsAsmParser::parseDirectiveGpDWord() {
3228 const MCExpr *Value;
3229 // EmitGPRel64Value requires an expression, so we are using base class
3230 // method to evaluate the expression.
3231 if (getParser().parseExpression(Value))
3233 getParser().getStreamer().EmitGPRel64Value(Value);
3235 if (getLexer().isNot(AsmToken::EndOfStatement))
3236 return Error(getLexer().getLoc(),
3237 "unexpected token, expected end of statement");
3238 Parser.Lex(); // Eat EndOfStatement token.
3242 bool MipsAsmParser::parseDirectiveOption() {
3243 // Get the option token.
3244 AsmToken Tok = Parser.getTok();
3245 // At the moment only identifiers are supported.
3246 if (Tok.isNot(AsmToken::Identifier)) {
3247 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3248 Parser.eatToEndOfStatement();
3252 StringRef Option = Tok.getIdentifier();
3254 if (Option == "pic0") {
3255 getTargetStreamer().emitDirectiveOptionPic0();
3257 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3258 Error(Parser.getTok().getLoc(),
3259 "unexpected token, expected end of statement");
3260 Parser.eatToEndOfStatement();
3265 if (Option == "pic2") {
3266 getTargetStreamer().emitDirectiveOptionPic2();
3268 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3269 Error(Parser.getTok().getLoc(),
3270 "unexpected token, expected end of statement");
3271 Parser.eatToEndOfStatement();
3277 Warning(Parser.getTok().getLoc(),
3278 "unknown option, expected 'pic0' or 'pic2'");
3279 Parser.eatToEndOfStatement();
3283 /// parseDirectiveModule
3284 /// ::= .module oddspreg
3285 /// ::= .module nooddspreg
3286 /// ::= .module fp=value
3287 bool MipsAsmParser::parseDirectiveModule() {
3288 MCAsmLexer &Lexer = getLexer();
3289 SMLoc L = Lexer.getLoc();
3291 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3292 // TODO : get a better message.
3293 reportParseError(".module directive must appear before any code");
3297 if (Lexer.is(AsmToken::Identifier)) {
3298 StringRef Option = Parser.getTok().getString();
3301 if (Option == "oddspreg") {
3302 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3303 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3305 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3306 reportParseError("unexpected token, expected end of statement");
3311 } else if (Option == "nooddspreg") {
3313 Error(L, "'.module nooddspreg' requires the O32 ABI");
3317 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3318 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3320 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3321 reportParseError("unexpected token, expected end of statement");
3326 } else if (Option == "fp") {
3327 return parseDirectiveModuleFP();
3330 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3336 /// parseDirectiveModuleFP
3340 bool MipsAsmParser::parseDirectiveModuleFP() {
3341 MCAsmLexer &Lexer = getLexer();
3343 if (Lexer.isNot(AsmToken::Equal)) {
3344 reportParseError("unexpected token, expected equals sign '='");
3347 Parser.Lex(); // Eat '=' token.
3349 MipsABIFlagsSection::FpABIKind FpABI;
3350 if (!parseFpABIValue(FpABI, ".module"))
3353 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3354 reportParseError("unexpected token, expected end of statement");
3358 // Emit appropriate flags.
3359 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3360 Parser.Lex(); // Consume the EndOfStatement.
3364 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3365 StringRef Directive) {
3366 MCAsmLexer &Lexer = getLexer();
3368 if (Lexer.is(AsmToken::Identifier)) {
3369 StringRef Value = Parser.getTok().getString();
3372 if (Value != "xx") {
3373 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3378 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3382 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3386 if (Lexer.is(AsmToken::Integer)) {
3387 unsigned Value = Parser.getTok().getIntVal();
3390 if (Value != 32 && Value != 64) {
3391 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3397 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3401 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3403 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3411 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3412 StringRef IDVal = DirectiveID.getString();
3414 if (IDVal == ".cpload")
3415 return parseDirectiveCpLoad(DirectiveID.getLoc());
3416 if (IDVal == ".dword") {
3417 parseDataDirective(8, DirectiveID.getLoc());
3420 if (IDVal == ".ent") {
3421 StringRef SymbolName;
3423 if (Parser.parseIdentifier(SymbolName)) {
3424 reportParseError("expected identifier after .ent");
3428 // There's an undocumented extension that allows an integer to
3429 // follow the name of the procedure which AFAICS is ignored by GAS.
3430 // Example: .ent foo,2
3431 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3432 if (getLexer().isNot(AsmToken::Comma)) {
3433 // Even though we accept this undocumented extension for compatibility
3434 // reasons, the additional integer argument does not actually change
3435 // the behaviour of the '.ent' directive, so we would like to discourage
3436 // its use. We do this by not referring to the extended version in
3437 // error messages which are not directly related to its use.
3438 reportParseError("unexpected token, expected end of statement");
3441 Parser.Lex(); // Eat the comma.
3442 const MCExpr *DummyNumber;
3443 int64_t DummyNumberVal;
3444 // If the user was explicitly trying to use the extended version,
3445 // we still give helpful extension-related error messages.
3446 if (Parser.parseExpression(DummyNumber)) {
3447 reportParseError("expected number after comma");
3450 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3451 reportParseError("expected an absolute expression after comma");
3456 // If this is not the end of the statement, report an error.
3457 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3458 reportParseError("unexpected token, expected end of statement");
3462 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3464 getTargetStreamer().emitDirectiveEnt(*Sym);
3469 if (IDVal == ".end") {
3470 StringRef SymbolName;
3472 if (Parser.parseIdentifier(SymbolName)) {
3473 reportParseError("expected identifier after .end");
3477 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3478 reportParseError("unexpected token, expected end of statement");
3482 if (CurrentFn == nullptr) {
3483 reportParseError(".end used without .ent");
3487 if ((SymbolName != CurrentFn->getName())) {
3488 reportParseError(".end symbol does not match .ent symbol");
3492 getTargetStreamer().emitDirectiveEnd(SymbolName);
3493 CurrentFn = nullptr;
3497 if (IDVal == ".frame") {
3498 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3499 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3500 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3501 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3502 reportParseError("expected stack register");
3506 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3507 if (!StackRegOpnd.isGPRAsmReg()) {
3508 reportParseError(StackRegOpnd.getStartLoc(),
3509 "expected general purpose register");
3512 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3514 if (Parser.getTok().is(AsmToken::Comma))
3517 reportParseError("unexpected token, expected comma");
3521 // Parse the frame size.
3522 const MCExpr *FrameSize;
3523 int64_t FrameSizeVal;
3525 if (Parser.parseExpression(FrameSize)) {
3526 reportParseError("expected frame size value");
3530 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3531 reportParseError("frame size not an absolute expression");
3535 if (Parser.getTok().is(AsmToken::Comma))
3538 reportParseError("unexpected token, expected comma");
3542 // Parse the return register.
3544 ResTy = parseAnyRegister(TmpReg);
3545 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3546 reportParseError("expected return register");
3550 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3551 if (!ReturnRegOpnd.isGPRAsmReg()) {
3552 reportParseError(ReturnRegOpnd.getStartLoc(),
3553 "expected general purpose register");
3557 // If this is not the end of the statement, report an error.
3558 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3559 reportParseError("unexpected token, expected end of statement");
3563 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3564 ReturnRegOpnd.getGPR32Reg());
3568 if (IDVal == ".set") {
3569 return parseDirectiveSet();
3572 if (IDVal == ".mask" || IDVal == ".fmask") {
3573 // .mask bitmask, frame_offset
3574 // bitmask: One bit for each register used.
3575 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3576 // first register is expected to be saved.
3578 // .mask 0x80000000, -4
3579 // .fmask 0x80000000, -4
3582 // Parse the bitmask
3583 const MCExpr *BitMask;
3586 if (Parser.parseExpression(BitMask)) {
3587 reportParseError("expected bitmask value");
3591 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3592 reportParseError("bitmask not an absolute expression");
3596 if (Parser.getTok().is(AsmToken::Comma))
3599 reportParseError("unexpected token, expected comma");
3603 // Parse the frame_offset
3604 const MCExpr *FrameOffset;
3605 int64_t FrameOffsetVal;
3607 if (Parser.parseExpression(FrameOffset)) {
3608 reportParseError("expected frame offset value");
3612 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3613 reportParseError("frame offset not an absolute expression");
3617 // If this is not the end of the statement, report an error.
3618 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3619 reportParseError("unexpected token, expected end of statement");
3623 if (IDVal == ".mask")
3624 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3626 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3630 if (IDVal == ".nan")
3631 return parseDirectiveNaN();
3633 if (IDVal == ".gpword") {
3634 parseDirectiveGpWord();
3638 if (IDVal == ".gpdword") {
3639 parseDirectiveGpDWord();
3643 if (IDVal == ".word") {
3644 parseDataDirective(4, DirectiveID.getLoc());
3648 if (IDVal == ".option")
3649 return parseDirectiveOption();
3651 if (IDVal == ".abicalls") {
3652 getTargetStreamer().emitDirectiveAbiCalls();
3653 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3654 Error(Parser.getTok().getLoc(),
3655 "unexpected token, expected end of statement");
3657 Parser.eatToEndOfStatement();
3662 if (IDVal == ".cpsetup")
3663 return parseDirectiveCPSetup();
3665 if (IDVal == ".module")
3666 return parseDirectiveModule();
3671 extern "C" void LLVMInitializeMipsAsmParser() {
3672 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3673 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3674 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3675 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3678 #define GET_REGISTER_MATCHER
3679 #define GET_MATCHER_IMPLEMENTATION
3680 #include "MipsGenAsmMatcher.inc"