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 = *getParser().getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
104 // Print a warning along with its fix-it message at the given range.
105 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
106 SMRange Range, bool ShowColors = true);
108 #define GET_ASSEMBLER_HEADER
109 #include "MipsGenAsmMatcher.inc"
111 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
113 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
114 OperandVector &Operands, MCStreamer &Out,
116 bool MatchingInlineAsm) override;
118 /// Parse a register as used in CFI directives
119 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
121 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
123 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
125 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
126 SMLoc NameLoc, OperandVector &Operands) override;
128 bool ParseDirective(AsmToken DirectiveID) override;
130 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
134 StringRef Identifier, SMLoc S);
136 MipsAsmParser::OperandMatchResultTy
137 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
139 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
141 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
145 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
147 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
149 MipsAsmParser::OperandMatchResultTy
150 parseRegisterList (OperandVector &Operands);
152 bool searchSymbolAlias(OperandVector &Operands);
154 bool parseOperand(OperandVector &, StringRef Mnemonic);
156 bool needsExpansion(MCInst &Inst);
158 // Expands assembly pseudo instructions.
159 // Returns false on success, true otherwise.
160 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
161 SmallVectorImpl<MCInst> &Instructions);
163 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
164 SmallVectorImpl<MCInst> &Instructions);
166 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
167 SmallVectorImpl<MCInst> &Instructions);
169 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
170 SmallVectorImpl<MCInst> &Instructions);
172 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
173 SmallVectorImpl<MCInst> &Instructions);
175 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
176 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
178 bool reportParseError(Twine ErrorMsg);
179 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
181 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
182 bool parseRelocOperand(const MCExpr *&Res);
184 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
186 bool isEvaluated(const MCExpr *Expr);
187 bool parseSetMips0Directive();
188 bool parseSetArchDirective();
189 bool parseSetFeature(uint64_t Feature);
190 bool parseDirectiveCpLoad(SMLoc Loc);
191 bool parseDirectiveCPSetup();
192 bool parseDirectiveNaN();
193 bool parseDirectiveSet();
194 bool parseDirectiveOption();
196 bool parseSetAtDirective();
197 bool parseSetNoAtDirective();
198 bool parseSetMacroDirective();
199 bool parseSetNoMacroDirective();
200 bool parseSetMsaDirective();
201 bool parseSetNoMsaDirective();
202 bool parseSetNoDspDirective();
203 bool parseSetReorderDirective();
204 bool parseSetNoReorderDirective();
205 bool parseSetMips16Directive();
206 bool parseSetNoMips16Directive();
207 bool parseSetFpDirective();
208 bool parseSetPopDirective();
209 bool parseSetPushDirective();
211 bool parseSetAssignment();
213 bool parseDataDirective(unsigned Size, SMLoc L);
214 bool parseDirectiveGpWord();
215 bool parseDirectiveGpDWord();
216 bool parseDirectiveModule();
217 bool parseDirectiveModuleFP();
218 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
219 StringRef Directive);
221 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
223 bool eatComma(StringRef ErrorStr);
225 int matchCPURegisterName(StringRef Symbol);
227 int matchHWRegsRegisterName(StringRef Symbol);
229 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
231 int matchFPURegisterName(StringRef Name);
233 int matchFCCRegisterName(StringRef Name);
235 int matchACRegisterName(StringRef Name);
237 int matchMSA128RegisterName(StringRef Name);
239 int matchMSA128CtrlRegisterName(StringRef Name);
241 unsigned getReg(int RC, int RegNo);
243 unsigned getGPR(int RegNo);
245 int getATReg(SMLoc Loc);
247 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
248 SmallVectorImpl<MCInst> &Instructions);
250 // Helper function that checks if the value of a vector index is within the
251 // boundaries of accepted values for each RegisterKind
252 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
253 bool validateMSAIndex(int Val, int RegKind);
255 // Selects a new architecture by updating the FeatureBits with the necessary
256 // info including implied dependencies.
257 // Internally, it clears all the feature bits related to *any* architecture
258 // and selects the new one using the ToggleFeature functionality of the
259 // MCSubtargetInfo object that handles implied dependencies. The reason we
260 // clear all the arch related bits manually is because ToggleFeature only
261 // clears the features that imply the feature being cleared and not the
262 // features implied by the feature being cleared. This is easier to see
264 // --------------------------------------------------
265 // | Feature | Implies |
266 // | -------------------------------------------------|
267 // | FeatureMips1 | None |
268 // | FeatureMips2 | FeatureMips1 |
269 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
270 // | FeatureMips4 | FeatureMips3 |
272 // --------------------------------------------------
274 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
275 // FeatureMipsGP64 | FeatureMips1)
276 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
277 void selectArch(StringRef ArchFeature) {
278 uint64_t FeatureBits = STI.getFeatureBits();
279 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
280 STI.setFeatureBits(FeatureBits);
281 setAvailableFeatures(
282 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
283 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
286 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
287 if (!(STI.getFeatureBits() & Feature)) {
288 setAvailableFeatures(
289 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
291 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
294 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
295 if (STI.getFeatureBits() & Feature) {
296 setAvailableFeatures(
297 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
299 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
303 enum MipsMatchResultTy {
304 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
305 #define GET_OPERAND_DIAGNOSTIC_TYPES
306 #include "MipsGenAsmMatcher.inc"
307 #undef GET_OPERAND_DIAGNOSTIC_TYPES
311 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
312 const MCInstrInfo &MII, const MCTargetOptions &Options)
313 : MCTargetAsmParser(), STI(sti) {
314 MCAsmParserExtension::Initialize(parser);
316 // Initialize the set of available features.
317 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
319 // Remember the initial assembler options. The user can not modify these.
320 AssemblerOptions.push_back(
321 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
323 // Create an assembler options environment for the user to modify.
324 AssemblerOptions.push_back(
325 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
327 getTargetStreamer().updateABIInfo(*this);
329 // Assert exactly one ABI was chosen.
330 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
331 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
332 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
333 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
335 if (!isABI_O32() && !useOddSPReg() != 0)
336 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
341 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
342 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
344 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
345 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
346 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
347 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
348 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
349 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
351 bool useOddSPReg() const {
352 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
355 bool inMicroMipsMode() const {
356 return STI.getFeatureBits() & Mips::FeatureMicroMips;
358 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
359 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
360 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
361 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
362 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
363 bool hasMips32() const {
364 return (STI.getFeatureBits() & Mips::FeatureMips32);
366 bool hasMips64() const {
367 return (STI.getFeatureBits() & Mips::FeatureMips64);
369 bool hasMips32r2() const {
370 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
372 bool hasMips64r2() const {
373 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
375 bool hasMips32r6() const {
376 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
378 bool hasMips64r6() const {
379 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
381 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
382 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
383 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
385 bool inMips16Mode() const {
386 return STI.getFeatureBits() & Mips::FeatureMips16;
388 // TODO: see how can we get this info.
389 bool abiUsesSoftFloat() const { return false; }
391 /// Warn if RegNo is the current assembler temporary.
392 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
398 /// MipsOperand - Instances of this class represent a parsed Mips machine
400 class MipsOperand : public MCParsedAsmOperand {
402 /// Broad categories of register classes
403 /// The exact class is finalized by the render method.
405 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
406 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
408 RegKind_FCC = 4, /// FCC
409 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
410 RegKind_MSACtrl = 16, /// MSA control registers
411 RegKind_COP2 = 32, /// COP2
412 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
414 RegKind_CCR = 128, /// CCR
415 RegKind_HWRegs = 256, /// HWRegs
416 RegKind_COP3 = 512, /// COP3
418 /// Potentially any (e.g. $1)
419 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
420 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
421 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
426 k_Immediate, /// An immediate (possibly involving symbol references)
427 k_Memory, /// Base + Offset Memory Address
428 k_PhysRegister, /// A physical register from the Mips namespace
429 k_RegisterIndex, /// A register index in one or more RegKind.
430 k_Token, /// A simple token
431 k_RegList /// A physical register list
435 MipsOperand(KindTy K, MipsAsmParser &Parser)
436 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
439 /// For diagnostics, and checking the assembler temporary
440 MipsAsmParser &AsmParser;
448 unsigned Num; /// Register Number
452 unsigned Index; /// Index into the register class
453 RegKind Kind; /// Bitfield of the kinds it could possibly be
454 const MCRegisterInfo *RegInfo;
467 SmallVector<unsigned, 10> *List;
472 struct PhysRegOp PhysReg;
473 struct RegIdxOp RegIdx;
476 struct RegListOp RegList;
479 SMLoc StartLoc, EndLoc;
481 /// Internal constructor for register kinds
482 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
483 const MCRegisterInfo *RegInfo,
485 MipsAsmParser &Parser) {
486 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
487 Op->RegIdx.Index = Index;
488 Op->RegIdx.RegInfo = RegInfo;
489 Op->RegIdx.Kind = RegKind;
496 /// Coerce the register to GPR32 and return the real register for the current
498 unsigned getGPR32Reg() const {
499 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
500 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
501 unsigned ClassID = Mips::GPR32RegClassID;
502 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
505 /// Coerce the register to GPR32 and return the real register for the current
507 unsigned getGPRMM16Reg() const {
508 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
509 unsigned ClassID = Mips::GPR32RegClassID;
510 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
513 /// Coerce the register to GPR64 and return the real register for the current
515 unsigned getGPR64Reg() const {
516 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
517 unsigned ClassID = Mips::GPR64RegClassID;
518 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
522 /// Coerce the register to AFGR64 and return the real register for the current
524 unsigned getAFGR64Reg() const {
525 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
526 if (RegIdx.Index % 2 != 0)
527 AsmParser.Warning(StartLoc, "Float register should be even.");
528 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
529 .getRegister(RegIdx.Index / 2);
532 /// Coerce the register to FGR64 and return the real register for the current
534 unsigned getFGR64Reg() const {
535 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
536 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
537 .getRegister(RegIdx.Index);
540 /// Coerce the register to FGR32 and return the real register for the current
542 unsigned getFGR32Reg() const {
543 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
544 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
545 .getRegister(RegIdx.Index);
548 /// Coerce the register to FGRH32 and return the real register for the current
550 unsigned getFGRH32Reg() const {
551 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
552 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
553 .getRegister(RegIdx.Index);
556 /// Coerce the register to FCC and return the real register for the current
558 unsigned getFCCReg() const {
559 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
560 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
561 .getRegister(RegIdx.Index);
564 /// Coerce the register to MSA128 and return the real register for the current
566 unsigned getMSA128Reg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
568 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
570 unsigned ClassID = Mips::MSA128BRegClassID;
571 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
574 /// Coerce the register to MSACtrl and return the real register for the
576 unsigned getMSACtrlReg() const {
577 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
578 unsigned ClassID = Mips::MSACtrlRegClassID;
579 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
582 /// Coerce the register to COP2 and return the real register for the
584 unsigned getCOP2Reg() const {
585 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
586 unsigned ClassID = Mips::COP2RegClassID;
587 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
590 /// Coerce the register to COP3 and return the real register for the
592 unsigned getCOP3Reg() const {
593 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
594 unsigned ClassID = Mips::COP3RegClassID;
595 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
598 /// Coerce the register to ACC64DSP and return the real register for the
600 unsigned getACC64DSPReg() const {
601 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
602 unsigned ClassID = Mips::ACC64DSPRegClassID;
603 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
606 /// Coerce the register to HI32DSP and return the real register for the
608 unsigned getHI32DSPReg() const {
609 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
610 unsigned ClassID = Mips::HI32DSPRegClassID;
611 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
614 /// Coerce the register to LO32DSP and return the real register for the
616 unsigned getLO32DSPReg() const {
617 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
618 unsigned ClassID = Mips::LO32DSPRegClassID;
619 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
622 /// Coerce the register to CCR and return the real register for the
624 unsigned getCCRReg() const {
625 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
626 unsigned ClassID = Mips::CCRRegClassID;
627 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
630 /// Coerce the register to HWRegs and return the real register for the
632 unsigned getHWRegsReg() const {
633 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
634 unsigned ClassID = Mips::HWRegsRegClassID;
635 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
639 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
640 // Add as immediate when possible. Null MCExpr = 0.
642 Inst.addOperand(MCOperand::CreateImm(0));
643 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
644 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
646 Inst.addOperand(MCOperand::CreateExpr(Expr));
649 void addRegOperands(MCInst &Inst, unsigned N) const {
650 llvm_unreachable("Use a custom parser instead");
653 /// Render the operand to an MCInst as a GPR32
654 /// Asserts if the wrong number of operands are requested, or the operand
655 /// is not a k_RegisterIndex compatible with RegKind_GPR
656 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
661 void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
666 void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
667 assert(N == 1 && "Invalid number of operands!");
668 Inst.addOperand(MCOperand::CreateReg(getGPRMM16Reg()));
671 /// Render the operand to an MCInst as a GPR64
672 /// Asserts if the wrong number of operands are requested, or the operand
673 /// is not a k_RegisterIndex compatible with RegKind_GPR
674 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
675 assert(N == 1 && "Invalid number of operands!");
676 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
679 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
680 assert(N == 1 && "Invalid number of operands!");
681 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
684 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
685 assert(N == 1 && "Invalid number of operands!");
686 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
689 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
690 assert(N == 1 && "Invalid number of operands!");
691 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
692 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
693 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
694 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
698 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
699 assert(N == 1 && "Invalid number of operands!");
700 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
703 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
704 assert(N == 1 && "Invalid number of operands!");
705 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
708 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
709 assert(N == 1 && "Invalid number of operands!");
710 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
713 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
714 assert(N == 1 && "Invalid number of operands!");
715 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
718 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
719 assert(N == 1 && "Invalid number of operands!");
720 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
723 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
724 assert(N == 1 && "Invalid number of operands!");
725 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
728 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
729 assert(N == 1 && "Invalid number of operands!");
730 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
733 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
734 assert(N == 1 && "Invalid number of operands!");
735 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
738 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
739 assert(N == 1 && "Invalid number of operands!");
740 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
743 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
744 assert(N == 1 && "Invalid number of operands!");
745 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
748 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
749 assert(N == 1 && "Invalid number of operands!");
750 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
753 void addImmOperands(MCInst &Inst, unsigned N) const {
754 assert(N == 1 && "Invalid number of operands!");
755 const MCExpr *Expr = getImm();
759 void addMemOperands(MCInst &Inst, unsigned N) const {
760 assert(N == 2 && "Invalid number of operands!");
762 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
764 const MCExpr *Expr = getMemOff();
768 void addRegListOperands(MCInst &Inst, unsigned N) const {
769 assert(N == 1 && "Invalid number of operands!");
771 for (auto RegNo : getRegList())
772 Inst.addOperand(MCOperand::CreateReg(RegNo));
775 bool isReg() const override {
776 // As a special case until we sort out the definition of div/divu, pretend
777 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
778 if (isGPRAsmReg() && RegIdx.Index == 0)
781 return Kind == k_PhysRegister;
783 bool isRegIdx() const { return Kind == k_RegisterIndex; }
784 bool isImm() const override { return Kind == k_Immediate; }
785 bool isConstantImm() const {
786 return isImm() && dyn_cast<MCConstantExpr>(getImm());
788 bool isToken() const override {
789 // Note: It's not possible to pretend that other operand kinds are tokens.
790 // The matcher emitter checks tokens first.
791 return Kind == k_Token;
793 bool isMem() const override { return Kind == k_Memory; }
794 bool isConstantMemOff() const {
795 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
797 template <unsigned Bits> bool isMemWithSimmOffset() const {
798 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
800 bool isInvNum() const { return Kind == k_Immediate; }
801 bool isLSAImm() const {
802 if (!isConstantImm())
804 int64_t Val = getConstantImm();
805 return 1 <= Val && Val <= 4;
807 bool isRegList() const { return Kind == k_RegList; }
809 StringRef getToken() const {
810 assert(Kind == k_Token && "Invalid access!");
811 return StringRef(Tok.Data, Tok.Length);
814 unsigned getReg() const override {
815 // As a special case until we sort out the definition of div/divu, pretend
816 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
817 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
818 RegIdx.Kind & RegKind_GPR)
819 return getGPR32Reg(); // FIXME: GPR64 too
821 assert(Kind == k_PhysRegister && "Invalid access!");
825 const MCExpr *getImm() const {
826 assert((Kind == k_Immediate) && "Invalid access!");
830 int64_t getConstantImm() const {
831 const MCExpr *Val = getImm();
832 return static_cast<const MCConstantExpr *>(Val)->getValue();
835 MipsOperand *getMemBase() const {
836 assert((Kind == k_Memory) && "Invalid access!");
840 const MCExpr *getMemOff() const {
841 assert((Kind == k_Memory) && "Invalid access!");
845 int64_t getConstantMemOff() const {
846 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
849 const SmallVectorImpl<unsigned> &getRegList() const {
850 assert((Kind == k_RegList) && "Invalid access!");
851 return *(RegList.List);
854 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
855 MipsAsmParser &Parser) {
856 auto Op = make_unique<MipsOperand>(k_Token, Parser);
857 Op->Tok.Data = Str.data();
858 Op->Tok.Length = Str.size();
864 /// Create a numeric register (e.g. $1). The exact register remains
865 /// unresolved until an instruction successfully matches
866 static std::unique_ptr<MipsOperand>
867 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
868 SMLoc E, MipsAsmParser &Parser) {
869 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
870 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
873 /// Create a register that is definitely a GPR.
874 /// This is typically only used for named registers such as $gp.
875 static std::unique_ptr<MipsOperand>
876 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
877 MipsAsmParser &Parser) {
878 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
881 /// Create a register that is definitely a FGR.
882 /// This is typically only used for named registers such as $f0.
883 static std::unique_ptr<MipsOperand>
884 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
885 MipsAsmParser &Parser) {
886 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
889 /// Create a register that is definitely a HWReg.
890 /// This is typically only used for named registers such as $hwr_cpunum.
891 static std::unique_ptr<MipsOperand>
892 createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
893 SMLoc S, SMLoc E, MipsAsmParser &Parser) {
894 return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
897 /// Create a register that is definitely an FCC.
898 /// This is typically only used for named registers such as $fcc0.
899 static std::unique_ptr<MipsOperand>
900 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
901 MipsAsmParser &Parser) {
902 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
905 /// Create a register that is definitely an ACC.
906 /// This is typically only used for named registers such as $ac0.
907 static std::unique_ptr<MipsOperand>
908 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
909 MipsAsmParser &Parser) {
910 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
913 /// Create a register that is definitely an MSA128.
914 /// This is typically only used for named registers such as $w0.
915 static std::unique_ptr<MipsOperand>
916 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
917 SMLoc E, MipsAsmParser &Parser) {
918 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
921 /// Create a register that is definitely an MSACtrl.
922 /// This is typically only used for named registers such as $msaaccess.
923 static std::unique_ptr<MipsOperand>
924 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
925 SMLoc E, MipsAsmParser &Parser) {
926 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
929 static std::unique_ptr<MipsOperand>
930 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
931 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
938 static std::unique_ptr<MipsOperand>
939 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
940 SMLoc E, MipsAsmParser &Parser) {
941 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
942 Op->Mem.Base = Base.release();
949 static std::unique_ptr<MipsOperand>
950 CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
951 MipsAsmParser &Parser) {
952 assert (Regs.size() > 0 && "Empty list not allowed");
954 auto Op = make_unique<MipsOperand>(k_RegList, Parser);
955 Op->RegList.List = new SmallVector<unsigned, 10>();
956 for (auto Reg : Regs)
957 Op->RegList.List->push_back(Reg);
958 Op->StartLoc = StartLoc;
963 bool isGPRAsmReg() const {
964 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
966 bool isMM16AsmReg() const {
967 if (!(isRegIdx() && RegIdx.Kind))
969 return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
970 || RegIdx.Index == 16 || RegIdx.Index == 17);
972 bool isMM16AsmRegZero() const {
973 if (!(isRegIdx() && RegIdx.Kind))
975 return (RegIdx.Index == 0 ||
976 (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
979 bool isFGRAsmReg() const {
980 // AFGR64 is $0-$15 but we handle this in getAFGR64()
981 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
983 bool isHWRegsAsmReg() const {
984 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
986 bool isCCRAsmReg() const {
987 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
989 bool isFCCAsmReg() const {
990 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
992 if (!AsmParser.hasEightFccRegisters())
993 return RegIdx.Index == 0;
994 return RegIdx.Index <= 7;
996 bool isACCAsmReg() const {
997 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
999 bool isCOP2AsmReg() const {
1000 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
1002 bool isCOP3AsmReg() const {
1003 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1005 bool isMSA128AsmReg() const {
1006 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
1008 bool isMSACtrlAsmReg() const {
1009 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1012 /// getStartLoc - Get the location of the first token of this operand.
1013 SMLoc getStartLoc() const override { return StartLoc; }
1014 /// getEndLoc - Get the location of the last token of this operand.
1015 SMLoc getEndLoc() const override { return EndLoc; }
1017 virtual ~MipsOperand() {
1025 delete RegList.List;
1026 case k_PhysRegister:
1027 case k_RegisterIndex:
1033 void print(raw_ostream &OS) const override {
1042 Mem.Base->print(OS);
1047 case k_PhysRegister:
1048 OS << "PhysReg<" << PhysReg.Num << ">";
1050 case k_RegisterIndex:
1051 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
1058 for (auto Reg : (*RegList.List))
1064 }; // class MipsOperand
1068 extern const MCInstrDesc MipsInsts[];
1070 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
1071 return MipsInsts[Opcode];
1074 static bool hasShortDelaySlot(unsigned Opcode) {
1077 case Mips::JALRS_MM:
1078 case Mips::JALRS16_MM:
1079 case Mips::BGEZALS_MM:
1080 case Mips::BLTZALS_MM:
1087 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1088 SmallVectorImpl<MCInst> &Instructions) {
1089 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1093 if (MCID.isBranch() || MCID.isCall()) {
1094 const unsigned Opcode = Inst.getOpcode();
1104 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1105 Offset = Inst.getOperand(2);
1106 if (!Offset.isImm())
1107 break; // We'll deal with this situation later on when applying fixups.
1108 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1109 return Error(IDLoc, "branch target out of range");
1110 if (OffsetToAlignment(Offset.getImm(),
1111 1LL << (inMicroMipsMode() ? 1 : 2)))
1112 return Error(IDLoc, "branch to misaligned address");
1126 case Mips::BGEZAL_MM:
1127 case Mips::BLTZAL_MM:
1130 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1131 Offset = Inst.getOperand(1);
1132 if (!Offset.isImm())
1133 break; // We'll deal with this situation later on when applying fixups.
1134 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1135 return Error(IDLoc, "branch target out of range");
1136 if (OffsetToAlignment(Offset.getImm(),
1137 1LL << (inMicroMipsMode() ? 1 : 2)))
1138 return Error(IDLoc, "branch to misaligned address");
1143 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1144 // We still accept it but it is a normal nop.
1145 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1146 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1147 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1151 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1152 // If this instruction has a delay slot and .set reorder is active,
1153 // emit a NOP after it.
1154 Instructions.push_back(Inst);
1156 if (hasShortDelaySlot(Inst.getOpcode())) {
1157 NopInst.setOpcode(Mips::MOVE16_MM);
1158 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1159 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1161 NopInst.setOpcode(Mips::SLL);
1162 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1163 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1164 NopInst.addOperand(MCOperand::CreateImm(0));
1166 Instructions.push_back(NopInst);
1170 if (MCID.mayLoad() || MCID.mayStore()) {
1171 // Check the offset of memory operand, if it is a symbol
1172 // reference or immediate we may have to expand instructions.
1173 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1174 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1175 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1176 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1177 MCOperand &Op = Inst.getOperand(i);
1179 int MemOffset = Op.getImm();
1180 if (MemOffset < -32768 || MemOffset > 32767) {
1181 // Offset can't exceed 16bit value.
1182 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1185 } else if (Op.isExpr()) {
1186 const MCExpr *Expr = Op.getExpr();
1187 if (Expr->getKind() == MCExpr::SymbolRef) {
1188 const MCSymbolRefExpr *SR =
1189 static_cast<const MCSymbolRefExpr *>(Expr);
1190 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1192 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1195 } else if (!isEvaluated(Expr)) {
1196 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1204 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1205 if (inMicroMipsMode()) {
1209 switch (Inst.getOpcode()) {
1212 case Mips::ADDIUS5_MM:
1213 Opnd = Inst.getOperand(2);
1215 return Error(IDLoc, "expected immediate operand kind");
1216 Imm = Opnd.getImm();
1217 if (Imm < -8 || Imm > 7)
1218 return Error(IDLoc, "immediate operand value out of range");
1220 case Mips::ADDIUSP_MM:
1221 Opnd = Inst.getOperand(0);
1223 return Error(IDLoc, "expected immediate operand kind");
1224 Imm = Opnd.getImm();
1225 if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
1227 return Error(IDLoc, "immediate operand value out of range");
1229 case Mips::SLL16_MM:
1230 case Mips::SRL16_MM:
1231 Opnd = Inst.getOperand(2);
1233 return Error(IDLoc, "expected immediate operand kind");
1234 Imm = Opnd.getImm();
1235 if (Imm < 1 || Imm > 8)
1236 return Error(IDLoc, "immediate operand value out of range");
1239 Opnd = Inst.getOperand(1);
1241 return Error(IDLoc, "expected immediate operand kind");
1242 Imm = Opnd.getImm();
1243 if (Imm < -1 || Imm > 126)
1244 return Error(IDLoc, "immediate operand value out of range");
1246 case Mips::ADDIUR2_MM:
1247 Opnd = Inst.getOperand(2);
1249 return Error(IDLoc, "expected immediate operand kind");
1250 Imm = Opnd.getImm();
1251 if (!(Imm == 1 || Imm == -1 ||
1252 ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
1253 return Error(IDLoc, "immediate operand value out of range");
1255 case Mips::ADDIUR1SP_MM:
1256 Opnd = Inst.getOperand(1);
1258 return Error(IDLoc, "expected immediate operand kind");
1259 Imm = Opnd.getImm();
1260 if (OffsetToAlignment(Imm, 4LL))
1261 return Error(IDLoc, "misaligned immediate operand value");
1262 if (Imm < 0 || Imm > 255)
1263 return Error(IDLoc, "immediate operand value out of range");
1265 case Mips::ANDI16_MM:
1266 Opnd = Inst.getOperand(2);
1268 return Error(IDLoc, "expected immediate operand kind");
1269 Imm = Opnd.getImm();
1270 if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
1271 Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
1272 Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
1273 return Error(IDLoc, "immediate operand value out of range");
1278 if (needsExpansion(Inst))
1279 return expandInstruction(Inst, IDLoc, Instructions);
1281 Instructions.push_back(Inst);
1286 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1288 switch (Inst.getOpcode()) {
1289 case Mips::LoadImm32Reg:
1290 case Mips::LoadAddr32Imm:
1291 case Mips::LoadAddr32Reg:
1292 case Mips::LoadImm64Reg:
1299 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1300 SmallVectorImpl<MCInst> &Instructions) {
1301 switch (Inst.getOpcode()) {
1303 assert(0 && "unimplemented expansion");
1305 case Mips::LoadImm32Reg:
1306 return expandLoadImm(Inst, IDLoc, Instructions);
1307 case Mips::LoadImm64Reg:
1309 Error(IDLoc, "instruction requires a 64-bit architecture");
1312 return expandLoadImm(Inst, IDLoc, Instructions);
1313 case Mips::LoadAddr32Imm:
1314 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1315 case Mips::LoadAddr32Reg:
1316 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1321 template <bool PerformShift>
1322 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1323 SmallVectorImpl<MCInst> &Instructions) {
1326 tmpInst.setOpcode(Mips::DSLL);
1327 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1328 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1329 tmpInst.addOperand(MCOperand::CreateImm(16));
1330 tmpInst.setLoc(IDLoc);
1331 Instructions.push_back(tmpInst);
1334 tmpInst.setOpcode(Mips::ORi);
1335 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1336 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1337 tmpInst.addOperand(Operand);
1338 tmpInst.setLoc(IDLoc);
1339 Instructions.push_back(tmpInst);
1342 template <int Shift, bool PerformShift>
1343 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1344 SmallVectorImpl<MCInst> &Instructions) {
1345 createShiftOr<PerformShift>(
1346 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1347 IDLoc, Instructions);
1351 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1352 SmallVectorImpl<MCInst> &Instructions) {
1354 const MCOperand &ImmOp = Inst.getOperand(1);
1355 assert(ImmOp.isImm() && "expected immediate operand kind");
1356 const MCOperand &RegOp = Inst.getOperand(0);
1357 assert(RegOp.isReg() && "expected register operand kind");
1359 int64_t ImmValue = ImmOp.getImm();
1360 tmpInst.setLoc(IDLoc);
1361 // FIXME: gas has a special case for values that are 000...1111, which
1362 // becomes a li -1 and then a dsrl
1363 if (0 <= ImmValue && ImmValue <= 65535) {
1364 // For 0 <= j <= 65535.
1365 // li d,j => ori d,$zero,j
1366 tmpInst.setOpcode(Mips::ORi);
1367 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1368 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1369 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1370 Instructions.push_back(tmpInst);
1371 } else if (ImmValue < 0 && ImmValue >= -32768) {
1372 // For -32768 <= j < 0.
1373 // li d,j => addiu d,$zero,j
1374 tmpInst.setOpcode(Mips::ADDiu);
1375 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1376 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1377 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1378 Instructions.push_back(tmpInst);
1379 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1380 // For any value of j that is representable as a 32-bit integer, create
1382 // li d,j => lui d,hi16(j)
1384 tmpInst.setOpcode(Mips::LUi);
1385 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1386 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1387 Instructions.push_back(tmpInst);
1388 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1389 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1391 Error(IDLoc, "instruction requires a 64-bit architecture");
1395 // <------- lo32 ------>
1396 // <------- hi32 ------>
1397 // <- hi16 -> <- lo16 ->
1398 // _________________________________
1400 // | 16-bytes | 16-bytes | 16-bytes |
1401 // |__________|__________|__________|
1403 // For any value of j that is representable as a 48-bit integer, create
1405 // li d,j => lui d,hi16(j)
1406 // ori d,d,hi16(lo32(j))
1408 // ori d,d,lo16(lo32(j))
1409 tmpInst.setOpcode(Mips::LUi);
1410 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1412 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1413 Instructions.push_back(tmpInst);
1414 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1415 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1418 Error(IDLoc, "instruction requires a 64-bit architecture");
1422 // <------- hi32 ------> <------- lo32 ------>
1423 // <- hi16 -> <- lo16 ->
1424 // ___________________________________________
1426 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1427 // |__________|__________|__________|__________|
1429 // For any value of j that isn't representable as a 48-bit integer.
1430 // li d,j => lui d,hi16(j)
1431 // ori d,d,lo16(hi32(j))
1433 // ori d,d,hi16(lo32(j))
1435 // ori d,d,lo16(lo32(j))
1436 tmpInst.setOpcode(Mips::LUi);
1437 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1439 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1440 Instructions.push_back(tmpInst);
1441 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1442 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1443 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1449 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1450 SmallVectorImpl<MCInst> &Instructions) {
1452 const MCOperand &ImmOp = Inst.getOperand(2);
1453 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1454 "expected immediate operand kind");
1455 if (!ImmOp.isImm()) {
1456 expandLoadAddressSym(Inst, IDLoc, Instructions);
1459 const MCOperand &SrcRegOp = Inst.getOperand(1);
1460 assert(SrcRegOp.isReg() && "expected register operand kind");
1461 const MCOperand &DstRegOp = Inst.getOperand(0);
1462 assert(DstRegOp.isReg() && "expected register operand kind");
1463 int ImmValue = ImmOp.getImm();
1464 if (-32768 <= ImmValue && ImmValue <= 65535) {
1465 // For -32768 <= j <= 65535.
1466 // la d,j(s) => addiu d,s,j
1467 tmpInst.setOpcode(Mips::ADDiu);
1468 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1469 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1470 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1471 Instructions.push_back(tmpInst);
1473 // For any other value of j that is representable as a 32-bit integer.
1474 // la d,j(s) => lui d,hi16(j)
1477 tmpInst.setOpcode(Mips::LUi);
1478 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1479 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1480 Instructions.push_back(tmpInst);
1482 tmpInst.setOpcode(Mips::ORi);
1483 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1484 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1485 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1486 Instructions.push_back(tmpInst);
1488 tmpInst.setOpcode(Mips::ADDu);
1489 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1490 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1491 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1492 Instructions.push_back(tmpInst);
1498 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1499 SmallVectorImpl<MCInst> &Instructions) {
1501 const MCOperand &ImmOp = Inst.getOperand(1);
1502 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1503 "expected immediate operand kind");
1504 if (!ImmOp.isImm()) {
1505 expandLoadAddressSym(Inst, IDLoc, Instructions);
1508 const MCOperand &RegOp = Inst.getOperand(0);
1509 assert(RegOp.isReg() && "expected register operand kind");
1510 int ImmValue = ImmOp.getImm();
1511 if (-32768 <= ImmValue && ImmValue <= 65535) {
1512 // For -32768 <= j <= 65535.
1513 // la d,j => addiu d,$zero,j
1514 tmpInst.setOpcode(Mips::ADDiu);
1515 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1516 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1517 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1518 Instructions.push_back(tmpInst);
1520 // For any other value of j that is representable as a 32-bit integer.
1521 // la d,j => lui d,hi16(j)
1523 tmpInst.setOpcode(Mips::LUi);
1524 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1525 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1526 Instructions.push_back(tmpInst);
1528 tmpInst.setOpcode(Mips::ORi);
1529 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1530 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1531 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1532 Instructions.push_back(tmpInst);
1538 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1539 SmallVectorImpl<MCInst> &Instructions) {
1540 // FIXME: If we do have a valid at register to use, we should generate a
1541 // slightly shorter sequence here.
1543 int ExprOperandNo = 1;
1544 // Sometimes the assembly parser will get the immediate expression as
1545 // a $zero + an immediate.
1546 if (Inst.getNumOperands() == 3) {
1547 assert(Inst.getOperand(1).getReg() ==
1548 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1551 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1552 assert(SymOp.isExpr() && "expected symbol operand kind");
1553 const MCOperand &RegOp = Inst.getOperand(0);
1554 unsigned RegNo = RegOp.getReg();
1555 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1556 const MCSymbolRefExpr *HiExpr =
1557 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1558 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1559 const MCSymbolRefExpr *LoExpr =
1560 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1561 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1563 // If it's a 64-bit architecture, expand to:
1564 // la d,sym => lui d,highest(sym)
1565 // ori d,d,higher(sym)
1567 // ori d,d,hi16(sym)
1569 // ori d,d,lo16(sym)
1570 const MCSymbolRefExpr *HighestExpr =
1571 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1572 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1573 const MCSymbolRefExpr *HigherExpr =
1574 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1575 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1577 tmpInst.setOpcode(Mips::LUi);
1578 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1579 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1580 Instructions.push_back(tmpInst);
1582 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1584 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1586 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1589 // Otherwise, expand to:
1590 // la d,sym => lui d,hi16(sym)
1591 // ori d,d,lo16(sym)
1592 tmpInst.setOpcode(Mips::LUi);
1593 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1594 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1595 Instructions.push_back(tmpInst);
1597 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1602 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1603 SmallVectorImpl<MCInst> &Instructions,
1604 bool isLoad, bool isImmOpnd) {
1605 const MCSymbolRefExpr *SR;
1607 unsigned ImmOffset, HiOffset, LoOffset;
1608 const MCExpr *ExprOffset;
1610 // 1st operand is either the source or destination register.
1611 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1612 unsigned RegOpNum = Inst.getOperand(0).getReg();
1613 // 2nd operand is the base register.
1614 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1615 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1616 // 3rd operand is either an immediate or expression.
1618 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1619 ImmOffset = Inst.getOperand(2).getImm();
1620 LoOffset = ImmOffset & 0x0000ffff;
1621 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1622 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1623 if (LoOffset & 0x8000)
1626 ExprOffset = Inst.getOperand(2).getExpr();
1627 // All instructions will have the same location.
1628 TempInst.setLoc(IDLoc);
1629 // These are some of the types of expansions we perform here:
1630 // 1) lw $8, sym => lui $8, %hi(sym)
1631 // lw $8, %lo(sym)($8)
1632 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1634 // lw $8, %lo(offset)($9)
1635 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1637 // lw $8, %lo(offset)($at)
1638 // 4) sw $8, sym => lui $at, %hi(sym)
1639 // sw $8, %lo(sym)($at)
1640 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1642 // sw $8, %lo(offset)($at)
1643 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1644 // ldc1 $f0, %lo(sym)($at)
1646 // For load instructions we can use the destination register as a temporary
1647 // if base and dst are different (examples 1 and 2) and if the base register
1648 // is general purpose otherwise we must use $at (example 6) and error if it's
1649 // not available. For stores we must use $at (examples 4 and 5) because we
1650 // must not clobber the source register setting up the offset.
1651 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1652 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1653 unsigned RegClassIDOp0 =
1654 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1655 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1656 (RegClassIDOp0 == Mips::GPR64RegClassID);
1657 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1658 TmpRegNum = RegOpNum;
1660 int AT = getATReg(IDLoc);
1661 // At this point we need AT to perform the expansions and we exit if it is
1666 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1669 TempInst.setOpcode(Mips::LUi);
1670 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1672 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1674 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1675 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1676 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1677 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1679 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1681 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1682 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1685 // Add the instruction to the list.
1686 Instructions.push_back(TempInst);
1687 // Prepare TempInst for next instruction.
1689 // Add temp register to base.
1690 TempInst.setOpcode(Mips::ADDu);
1691 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1692 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1693 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1694 Instructions.push_back(TempInst);
1696 // And finally, create original instruction with low part
1697 // of offset and new base.
1698 TempInst.setOpcode(Inst.getOpcode());
1699 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1700 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1702 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1704 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1705 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1706 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1708 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1710 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1711 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1714 Instructions.push_back(TempInst);
1718 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1719 // As described by the Mips32r2 spec, the registers Rd and Rs for
1720 // jalr.hb must be different.
1721 unsigned Opcode = Inst.getOpcode();
1723 if (Opcode == Mips::JALR_HB &&
1724 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1725 return Match_RequiresDifferentSrcAndDst;
1727 return Match_Success;
1730 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1731 OperandVector &Operands,
1733 uint64_t &ErrorInfo,
1734 bool MatchingInlineAsm) {
1737 SmallVector<MCInst, 8> Instructions;
1738 unsigned MatchResult =
1739 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1741 switch (MatchResult) {
1744 case Match_Success: {
1745 if (processInstruction(Inst, IDLoc, Instructions))
1747 for (unsigned i = 0; i < Instructions.size(); i++)
1748 Out.EmitInstruction(Instructions[i], STI);
1751 case Match_MissingFeature:
1752 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1754 case Match_InvalidOperand: {
1755 SMLoc ErrorLoc = IDLoc;
1756 if (ErrorInfo != ~0ULL) {
1757 if (ErrorInfo >= Operands.size())
1758 return Error(IDLoc, "too few operands for instruction");
1760 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1761 if (ErrorLoc == SMLoc())
1765 return Error(ErrorLoc, "invalid operand for instruction");
1767 case Match_MnemonicFail:
1768 return Error(IDLoc, "invalid instruction");
1769 case Match_RequiresDifferentSrcAndDst:
1770 return Error(IDLoc, "source and destination must be different");
1775 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1776 if ((RegIndex != 0) &&
1777 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1779 Warning(Loc, "used $at without \".set noat\"");
1781 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1782 Twine(RegIndex) + "\"");
1787 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1788 SMRange Range, bool ShowColors) {
1789 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1790 Range, SMFixIt(Range, FixMsg),
1794 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1797 CC = StringSwitch<unsigned>(Name)
1833 if (!(isABI_N32() || isABI_N64()))
1836 if (12 <= CC && CC <= 15) {
1837 // Name is one of t4-t7
1838 AsmToken RegTok = getLexer().peekTok();
1839 SMRange RegRange = RegTok.getLocRange();
1841 StringRef FixedName = StringSwitch<StringRef>(Name)
1847 assert(FixedName != "" && "Register name is not one of t4-t7.");
1849 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1850 "Did you mean $" + FixedName + "?", RegRange);
1853 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1854 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1855 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1856 if (8 <= CC && CC <= 11)
1860 CC = StringSwitch<unsigned>(Name)
1872 int MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
1875 CC = StringSwitch<unsigned>(Name)
1876 .Case("hwr_cpunum", 0)
1877 .Case("hwr_synci_step", 1)
1879 .Case("hwr_ccres", 3)
1880 .Case("hwr_ulr", 29)
1886 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1888 if (Name[0] == 'f') {
1889 StringRef NumString = Name.substr(1);
1891 if (NumString.getAsInteger(10, IntVal))
1892 return -1; // This is not an integer.
1893 if (IntVal > 31) // Maximum index for fpu register.
1900 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1902 if (Name.startswith("fcc")) {
1903 StringRef NumString = Name.substr(3);
1905 if (NumString.getAsInteger(10, IntVal))
1906 return -1; // This is not an integer.
1907 if (IntVal > 7) // There are only 8 fcc registers.
1914 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1916 if (Name.startswith("ac")) {
1917 StringRef NumString = Name.substr(2);
1919 if (NumString.getAsInteger(10, IntVal))
1920 return -1; // This is not an integer.
1921 if (IntVal > 3) // There are only 3 acc registers.
1928 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1931 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1940 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1943 CC = StringSwitch<unsigned>(Name)
1946 .Case("msaaccess", 2)
1948 .Case("msamodify", 4)
1949 .Case("msarequest", 5)
1951 .Case("msaunmap", 7)
1957 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1965 int MipsAsmParser::getATReg(SMLoc Loc) {
1966 int AT = AssemblerOptions.back()->getATRegNum();
1968 reportParseError(Loc,
1969 "pseudo-instruction requires $at, which is not available");
1973 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1974 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1977 unsigned MipsAsmParser::getGPR(int RegNo) {
1978 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1982 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1984 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1987 return getReg(RegClass, RegNum);
1990 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1991 MCAsmParser &Parser = getParser();
1992 DEBUG(dbgs() << "parseOperand\n");
1994 // Check if the current operand has a custom associated parser, if so, try to
1995 // custom parse the operand, or fallback to the general approach.
1996 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1997 if (ResTy == MatchOperand_Success)
1999 // If there wasn't a custom match, try the generic matcher below. Otherwise,
2000 // there was a match, but an error occurred, in which case, just return that
2001 // the operand parsing failed.
2002 if (ResTy == MatchOperand_ParseFail)
2005 DEBUG(dbgs() << ".. Generic Parser\n");
2007 switch (getLexer().getKind()) {
2009 Error(Parser.getTok().getLoc(), "unexpected token in operand");
2011 case AsmToken::Dollar: {
2012 // Parse the register.
2013 SMLoc S = Parser.getTok().getLoc();
2015 // Almost all registers have been parsed by custom parsers. There is only
2016 // one exception to this. $zero (and it's alias $0) will reach this point
2017 // for div, divu, and similar instructions because it is not an operand
2018 // to the instruction definition but an explicit register. Special case
2019 // this situation for now.
2020 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
2023 // Maybe it is a symbol reference.
2024 StringRef Identifier;
2025 if (Parser.parseIdentifier(Identifier))
2028 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2029 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
2030 // Otherwise create a symbol reference.
2032 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
2034 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
2037 // Else drop to expression parsing.
2038 case AsmToken::LParen:
2039 case AsmToken::Minus:
2040 case AsmToken::Plus:
2041 case AsmToken::Integer:
2042 case AsmToken::Tilde:
2043 case AsmToken::String: {
2044 DEBUG(dbgs() << ".. generic integer\n");
2045 OperandMatchResultTy ResTy = parseImm(Operands);
2046 return ResTy != MatchOperand_Success;
2048 case AsmToken::Percent: {
2049 // It is a symbol reference or constant expression.
2050 const MCExpr *IdVal;
2051 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
2052 if (parseRelocOperand(IdVal))
2055 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2057 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2059 } // case AsmToken::Percent
2060 } // switch(getLexer().getKind())
2064 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
2065 StringRef RelocStr) {
2067 // Check the type of the expression.
2068 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
2069 // It's a constant, evaluate reloc value.
2071 switch (getVariantKind(RelocStr)) {
2072 case MCSymbolRefExpr::VK_Mips_ABS_LO:
2073 // Get the 1st 16-bits.
2074 Val = MCE->getValue() & 0xffff;
2076 case MCSymbolRefExpr::VK_Mips_ABS_HI:
2077 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
2078 // 16 bits being negative.
2079 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
2081 case MCSymbolRefExpr::VK_Mips_HIGHER:
2082 // Get the 3rd 16-bits.
2083 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
2085 case MCSymbolRefExpr::VK_Mips_HIGHEST:
2086 // Get the 4th 16-bits.
2087 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
2090 report_fatal_error("unsupported reloc value");
2092 return MCConstantExpr::Create(Val, getContext());
2095 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
2096 // It's a symbol, create a symbolic expression from the symbol.
2097 StringRef Symbol = MSRE->getSymbol().getName();
2098 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2099 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
2103 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2104 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
2106 // Try to create target expression.
2107 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
2108 return MipsMCExpr::Create(VK, Expr, getContext());
2110 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
2111 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
2112 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
2116 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
2117 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
2118 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
2121 // Just return the original expression.
2125 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
2127 switch (Expr->getKind()) {
2128 case MCExpr::Constant:
2130 case MCExpr::SymbolRef:
2131 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
2132 case MCExpr::Binary:
2133 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
2134 if (!isEvaluated(BE->getLHS()))
2136 return isEvaluated(BE->getRHS());
2139 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
2140 case MCExpr::Target:
2146 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
2147 MCAsmParser &Parser = getParser();
2148 Parser.Lex(); // Eat the % token.
2149 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
2150 if (Tok.isNot(AsmToken::Identifier))
2153 std::string Str = Tok.getIdentifier().str();
2155 Parser.Lex(); // Eat the identifier.
2156 // Now make an expression from the rest of the operand.
2157 const MCExpr *IdVal;
2160 if (getLexer().getKind() == AsmToken::LParen) {
2162 Parser.Lex(); // Eat the '(' token.
2163 if (getLexer().getKind() == AsmToken::Percent) {
2164 Parser.Lex(); // Eat the % token.
2165 const AsmToken &nextTok = Parser.getTok();
2166 if (nextTok.isNot(AsmToken::Identifier))
2169 Str += nextTok.getIdentifier();
2170 Parser.Lex(); // Eat the identifier.
2171 if (getLexer().getKind() != AsmToken::LParen)
2176 if (getParser().parseParenExpression(IdVal, EndLoc))
2179 while (getLexer().getKind() == AsmToken::RParen)
2180 Parser.Lex(); // Eat the ')' token.
2183 return true; // Parenthesis must follow the relocation operand.
2185 Res = evaluateRelocExpr(IdVal, Str);
2189 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2191 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2192 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2193 if (ResTy == MatchOperand_Success) {
2194 assert(Operands.size() == 1);
2195 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2196 StartLoc = Operand.getStartLoc();
2197 EndLoc = Operand.getEndLoc();
2199 // AFAIK, we only support numeric registers and named GPR's in CFI
2201 // Don't worry about eating tokens before failing. Using an unrecognised
2202 // register is a parse error.
2203 if (Operand.isGPRAsmReg()) {
2204 // Resolve to GPR32 or GPR64 appropriately.
2205 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2208 return (RegNo == (unsigned)-1);
2211 assert(Operands.size() == 0);
2212 return (RegNo == (unsigned)-1);
2215 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2216 MCAsmParser &Parser = getParser();
2220 while (getLexer().getKind() == AsmToken::LParen)
2223 switch (getLexer().getKind()) {
2226 case AsmToken::Identifier:
2227 case AsmToken::LParen:
2228 case AsmToken::Integer:
2229 case AsmToken::Minus:
2230 case AsmToken::Plus:
2232 Result = getParser().parseParenExpression(Res, S);
2234 Result = (getParser().parseExpression(Res));
2235 while (getLexer().getKind() == AsmToken::RParen)
2238 case AsmToken::Percent:
2239 Result = parseRelocOperand(Res);
2244 MipsAsmParser::OperandMatchResultTy
2245 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2246 MCAsmParser &Parser = getParser();
2247 DEBUG(dbgs() << "parseMemOperand\n");
2248 const MCExpr *IdVal = nullptr;
2250 bool isParenExpr = false;
2251 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2252 // First operand is the offset.
2253 S = Parser.getTok().getLoc();
2255 if (getLexer().getKind() == AsmToken::LParen) {
2260 if (getLexer().getKind() != AsmToken::Dollar) {
2261 if (parseMemOffset(IdVal, isParenExpr))
2262 return MatchOperand_ParseFail;
2264 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2265 if (Tok.isNot(AsmToken::LParen)) {
2266 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2267 if (Mnemonic.getToken() == "la") {
2269 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2270 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2271 return MatchOperand_Success;
2273 if (Tok.is(AsmToken::EndOfStatement)) {
2275 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2277 // Zero register assumed, add a memory operand with ZERO as its base.
2278 // "Base" will be managed by k_Memory.
2279 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2282 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2283 return MatchOperand_Success;
2285 Error(Parser.getTok().getLoc(), "'(' expected");
2286 return MatchOperand_ParseFail;
2289 Parser.Lex(); // Eat the '(' token.
2292 Res = parseAnyRegister(Operands);
2293 if (Res != MatchOperand_Success)
2296 if (Parser.getTok().isNot(AsmToken::RParen)) {
2297 Error(Parser.getTok().getLoc(), "')' expected");
2298 return MatchOperand_ParseFail;
2301 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2303 Parser.Lex(); // Eat the ')' token.
2306 IdVal = MCConstantExpr::Create(0, getContext());
2308 // Replace the register operand with the memory operand.
2309 std::unique_ptr<MipsOperand> op(
2310 static_cast<MipsOperand *>(Operands.back().release()));
2311 // Remove the register from the operands.
2312 // "op" will be managed by k_Memory.
2313 Operands.pop_back();
2314 // Add the memory operand.
2315 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2317 if (IdVal->EvaluateAsAbsolute(Imm))
2318 IdVal = MCConstantExpr::Create(Imm, getContext());
2319 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2320 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2324 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2325 return MatchOperand_Success;
2328 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2329 MCAsmParser &Parser = getParser();
2330 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2332 SMLoc S = Parser.getTok().getLoc();
2334 if (Sym->isVariable())
2335 Expr = Sym->getVariableValue();
2338 if (Expr->getKind() == MCExpr::SymbolRef) {
2339 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2340 StringRef DefSymbol = Ref->getSymbol().getName();
2341 if (DefSymbol.startswith("$")) {
2342 OperandMatchResultTy ResTy =
2343 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2344 if (ResTy == MatchOperand_Success) {
2347 } else if (ResTy == MatchOperand_ParseFail)
2348 llvm_unreachable("Should never ParseFail");
2351 } else if (Expr->getKind() == MCExpr::Constant) {
2353 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2355 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2362 MipsAsmParser::OperandMatchResultTy
2363 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2364 StringRef Identifier,
2366 int Index = matchCPURegisterName(Identifier);
2368 Operands.push_back(MipsOperand::createGPRReg(
2369 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2370 return MatchOperand_Success;
2373 Index = matchHWRegsRegisterName(Identifier);
2375 Operands.push_back(MipsOperand::createHWRegsReg(
2376 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2377 return MatchOperand_Success;
2380 Index = matchFPURegisterName(Identifier);
2382 Operands.push_back(MipsOperand::createFGRReg(
2383 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2384 return MatchOperand_Success;
2387 Index = matchFCCRegisterName(Identifier);
2389 Operands.push_back(MipsOperand::createFCCReg(
2390 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2391 return MatchOperand_Success;
2394 Index = matchACRegisterName(Identifier);
2396 Operands.push_back(MipsOperand::createACCReg(
2397 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2398 return MatchOperand_Success;
2401 Index = matchMSA128RegisterName(Identifier);
2403 Operands.push_back(MipsOperand::createMSA128Reg(
2404 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2405 return MatchOperand_Success;
2408 Index = matchMSA128CtrlRegisterName(Identifier);
2410 Operands.push_back(MipsOperand::createMSACtrlReg(
2411 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2412 return MatchOperand_Success;
2415 return MatchOperand_NoMatch;
2418 MipsAsmParser::OperandMatchResultTy
2419 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2420 MCAsmParser &Parser = getParser();
2421 auto Token = Parser.getLexer().peekTok(false);
2423 if (Token.is(AsmToken::Identifier)) {
2424 DEBUG(dbgs() << ".. identifier\n");
2425 StringRef Identifier = Token.getIdentifier();
2426 OperandMatchResultTy ResTy =
2427 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2429 } else if (Token.is(AsmToken::Integer)) {
2430 DEBUG(dbgs() << ".. integer\n");
2431 Operands.push_back(MipsOperand::createNumericReg(
2432 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2434 return MatchOperand_Success;
2437 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2439 return MatchOperand_NoMatch;
2442 MipsAsmParser::OperandMatchResultTy
2443 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2444 MCAsmParser &Parser = getParser();
2445 DEBUG(dbgs() << "parseAnyRegister\n");
2447 auto Token = Parser.getTok();
2449 SMLoc S = Token.getLoc();
2451 if (Token.isNot(AsmToken::Dollar)) {
2452 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2453 if (Token.is(AsmToken::Identifier)) {
2454 if (searchSymbolAlias(Operands))
2455 return MatchOperand_Success;
2457 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2458 return MatchOperand_NoMatch;
2460 DEBUG(dbgs() << ".. $\n");
2462 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2463 if (ResTy == MatchOperand_Success) {
2465 Parser.Lex(); // identifier
2470 MipsAsmParser::OperandMatchResultTy
2471 MipsAsmParser::parseImm(OperandVector &Operands) {
2472 MCAsmParser &Parser = getParser();
2473 switch (getLexer().getKind()) {
2475 return MatchOperand_NoMatch;
2476 case AsmToken::LParen:
2477 case AsmToken::Minus:
2478 case AsmToken::Plus:
2479 case AsmToken::Integer:
2480 case AsmToken::Tilde:
2481 case AsmToken::String:
2485 const MCExpr *IdVal;
2486 SMLoc S = Parser.getTok().getLoc();
2487 if (getParser().parseExpression(IdVal))
2488 return MatchOperand_ParseFail;
2490 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2491 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2492 return MatchOperand_Success;
2495 MipsAsmParser::OperandMatchResultTy
2496 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2497 MCAsmParser &Parser = getParser();
2498 DEBUG(dbgs() << "parseJumpTarget\n");
2500 SMLoc S = getLexer().getLoc();
2502 // Integers and expressions are acceptable
2503 OperandMatchResultTy ResTy = parseImm(Operands);
2504 if (ResTy != MatchOperand_NoMatch)
2507 // Registers are a valid target and have priority over symbols.
2508 ResTy = parseAnyRegister(Operands);
2509 if (ResTy != MatchOperand_NoMatch)
2512 const MCExpr *Expr = nullptr;
2513 if (Parser.parseExpression(Expr)) {
2514 // We have no way of knowing if a symbol was consumed so we must ParseFail
2515 return MatchOperand_ParseFail;
2518 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2519 return MatchOperand_Success;
2522 MipsAsmParser::OperandMatchResultTy
2523 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2524 MCAsmParser &Parser = getParser();
2525 const MCExpr *IdVal;
2526 // If the first token is '$' we may have register operand.
2527 if (Parser.getTok().is(AsmToken::Dollar))
2528 return MatchOperand_NoMatch;
2529 SMLoc S = Parser.getTok().getLoc();
2530 if (getParser().parseExpression(IdVal))
2531 return MatchOperand_ParseFail;
2532 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2533 assert(MCE && "Unexpected MCExpr type.");
2534 int64_t Val = MCE->getValue();
2535 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2536 Operands.push_back(MipsOperand::CreateImm(
2537 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2538 return MatchOperand_Success;
2541 MipsAsmParser::OperandMatchResultTy
2542 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2543 MCAsmParser &Parser = getParser();
2544 switch (getLexer().getKind()) {
2546 return MatchOperand_NoMatch;
2547 case AsmToken::LParen:
2548 case AsmToken::Plus:
2549 case AsmToken::Minus:
2550 case AsmToken::Integer:
2555 SMLoc S = Parser.getTok().getLoc();
2557 if (getParser().parseExpression(Expr))
2558 return MatchOperand_ParseFail;
2561 if (!Expr->EvaluateAsAbsolute(Val)) {
2562 Error(S, "expected immediate value");
2563 return MatchOperand_ParseFail;
2566 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2567 // and because the CPU always adds one to the immediate field, the allowed
2568 // range becomes 1..4. We'll only check the range here and will deal
2569 // with the addition/subtraction when actually decoding/encoding
2571 if (Val < 1 || Val > 4) {
2572 Error(S, "immediate not in range (1..4)");
2573 return MatchOperand_ParseFail;
2577 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2578 return MatchOperand_Success;
2581 MipsAsmParser::OperandMatchResultTy
2582 MipsAsmParser::parseRegisterList(OperandVector &Operands) {
2583 MCAsmParser &Parser = getParser();
2584 SmallVector<unsigned, 10> Regs;
2586 unsigned PrevReg = Mips::NoRegister;
2587 bool RegRange = false;
2588 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
2590 if (Parser.getTok().isNot(AsmToken::Dollar))
2591 return MatchOperand_ParseFail;
2593 SMLoc S = Parser.getTok().getLoc();
2594 while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
2595 SMLoc E = getLexer().getLoc();
2596 MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
2597 RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
2599 // Remove last register operand because registers from register range
2600 // should be inserted first.
2601 if (RegNo == Mips::RA) {
2602 Regs.push_back(RegNo);
2604 unsigned TmpReg = PrevReg + 1;
2605 while (TmpReg <= RegNo) {
2606 if ((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) {
2607 Error(E, "invalid register operand");
2608 return MatchOperand_ParseFail;
2612 Regs.push_back(TmpReg++);
2618 if ((PrevReg == Mips::NoRegister) && (RegNo != Mips::S0) &&
2619 (RegNo != Mips::RA)) {
2620 Error(E, "$16 or $31 expected");
2621 return MatchOperand_ParseFail;
2622 } else if (((RegNo < Mips::S0) || (RegNo > Mips::S7)) &&
2623 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2624 Error(E, "invalid register operand");
2625 return MatchOperand_ParseFail;
2626 } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
2627 (RegNo != Mips::FP) && (RegNo != Mips::RA)) {
2628 Error(E, "consecutive register numbers expected");
2629 return MatchOperand_ParseFail;
2632 Regs.push_back(RegNo);
2635 if (Parser.getTok().is(AsmToken::Minus))
2638 if (!Parser.getTok().isNot(AsmToken::Minus) &&
2639 !Parser.getTok().isNot(AsmToken::Comma)) {
2640 Error(E, "',' or '-' expected");
2641 return MatchOperand_ParseFail;
2644 Lex(); // Consume comma or minus
2645 if (Parser.getTok().isNot(AsmToken::Dollar))
2651 SMLoc E = Parser.getTok().getLoc();
2652 Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
2653 parseMemOperand(Operands);
2654 return MatchOperand_Success;
2657 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2659 MCSymbolRefExpr::VariantKind VK =
2660 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2661 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2662 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2663 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2664 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2665 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2666 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2667 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2668 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2669 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2670 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2671 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2672 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2673 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2674 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2675 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2676 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2677 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2678 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2679 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2680 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2681 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2682 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2683 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2684 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2685 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2686 .Default(MCSymbolRefExpr::VK_None);
2688 assert(VK != MCSymbolRefExpr::VK_None);
2693 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2695 /// ::= '(', register, ')'
2696 /// handle it before we iterate so we don't get tripped up by the lack of
2698 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2699 MCAsmParser &Parser = getParser();
2700 if (getLexer().is(AsmToken::LParen)) {
2702 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2704 if (parseOperand(Operands, Name)) {
2705 SMLoc Loc = getLexer().getLoc();
2706 Parser.eatToEndOfStatement();
2707 return Error(Loc, "unexpected token in argument list");
2709 if (Parser.getTok().isNot(AsmToken::RParen)) {
2710 SMLoc Loc = getLexer().getLoc();
2711 Parser.eatToEndOfStatement();
2712 return Error(Loc, "unexpected token, expected ')'");
2715 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2721 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2722 /// either one of these.
2723 /// ::= '[', register, ']'
2724 /// ::= '[', integer, ']'
2725 /// handle it before we iterate so we don't get tripped up by the lack of
2727 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2728 OperandVector &Operands) {
2729 MCAsmParser &Parser = getParser();
2730 if (getLexer().is(AsmToken::LBrac)) {
2732 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2734 if (parseOperand(Operands, Name)) {
2735 SMLoc Loc = getLexer().getLoc();
2736 Parser.eatToEndOfStatement();
2737 return Error(Loc, "unexpected token in argument list");
2739 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2740 SMLoc Loc = getLexer().getLoc();
2741 Parser.eatToEndOfStatement();
2742 return Error(Loc, "unexpected token, expected ']'");
2745 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2751 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2752 SMLoc NameLoc, OperandVector &Operands) {
2753 MCAsmParser &Parser = getParser();
2754 DEBUG(dbgs() << "ParseInstruction\n");
2756 // We have reached first instruction, module directive are now forbidden.
2757 getTargetStreamer().forbidModuleDirective();
2759 // Check if we have valid mnemonic
2760 if (!mnemonicIsValid(Name, 0)) {
2761 Parser.eatToEndOfStatement();
2762 return Error(NameLoc, "unknown instruction");
2764 // First operand in MCInst is instruction mnemonic.
2765 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2767 // Read the remaining operands.
2768 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2769 // Read the first operand.
2770 if (parseOperand(Operands, Name)) {
2771 SMLoc Loc = getLexer().getLoc();
2772 Parser.eatToEndOfStatement();
2773 return Error(Loc, "unexpected token in argument list");
2775 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2777 // AFAIK, parenthesis suffixes are never on the first operand
2779 while (getLexer().is(AsmToken::Comma)) {
2780 Parser.Lex(); // Eat the comma.
2781 // Parse and remember the operand.
2782 if (parseOperand(Operands, Name)) {
2783 SMLoc Loc = getLexer().getLoc();
2784 Parser.eatToEndOfStatement();
2785 return Error(Loc, "unexpected token in argument list");
2787 // Parse bracket and parenthesis suffixes before we iterate
2788 if (getLexer().is(AsmToken::LBrac)) {
2789 if (parseBracketSuffix(Name, Operands))
2791 } else if (getLexer().is(AsmToken::LParen) &&
2792 parseParenSuffix(Name, Operands))
2796 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2797 SMLoc Loc = getLexer().getLoc();
2798 Parser.eatToEndOfStatement();
2799 return Error(Loc, "unexpected token in argument list");
2801 Parser.Lex(); // Consume the EndOfStatement.
2805 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2806 MCAsmParser &Parser = getParser();
2807 SMLoc Loc = getLexer().getLoc();
2808 Parser.eatToEndOfStatement();
2809 return Error(Loc, ErrorMsg);
2812 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2813 return Error(Loc, ErrorMsg);
2816 bool MipsAsmParser::parseSetNoAtDirective() {
2817 MCAsmParser &Parser = getParser();
2818 // Line should look like: ".set noat".
2820 AssemblerOptions.back()->setATReg(0);
2823 // If this is not the end of the statement, report an error.
2824 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2825 reportParseError("unexpected token, expected end of statement");
2828 Parser.Lex(); // Consume the EndOfStatement.
2832 bool MipsAsmParser::parseSetAtDirective() {
2833 MCAsmParser &Parser = getParser();
2834 // Line can be .set at - defaults to $1
2838 if (getLexer().is(AsmToken::EndOfStatement)) {
2839 AssemblerOptions.back()->setATReg(1);
2840 Parser.Lex(); // Consume the EndOfStatement.
2842 } else if (getLexer().is(AsmToken::Equal)) {
2843 getParser().Lex(); // Eat the '='.
2844 if (getLexer().isNot(AsmToken::Dollar)) {
2845 reportParseError("unexpected token, expected dollar sign '$'");
2848 Parser.Lex(); // Eat the '$'.
2849 const AsmToken &Reg = Parser.getTok();
2850 if (Reg.is(AsmToken::Identifier)) {
2851 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2852 } else if (Reg.is(AsmToken::Integer)) {
2853 AtRegNo = Reg.getIntVal();
2855 reportParseError("unexpected token, expected identifier or integer");
2859 if (AtRegNo < 0 || AtRegNo > 31) {
2860 reportParseError("unexpected token in statement");
2864 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2865 reportParseError("invalid register");
2868 getParser().Lex(); // Eat the register.
2870 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2871 reportParseError("unexpected token, expected end of statement");
2874 Parser.Lex(); // Consume the EndOfStatement.
2877 reportParseError("unexpected token in statement");
2882 bool MipsAsmParser::parseSetReorderDirective() {
2883 MCAsmParser &Parser = getParser();
2885 // If this is not the end of the statement, report an error.
2886 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2887 reportParseError("unexpected token, expected end of statement");
2890 AssemblerOptions.back()->setReorder();
2891 getTargetStreamer().emitDirectiveSetReorder();
2892 Parser.Lex(); // Consume the EndOfStatement.
2896 bool MipsAsmParser::parseSetNoReorderDirective() {
2897 MCAsmParser &Parser = getParser();
2899 // If this is not the end of the statement, report an error.
2900 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2901 reportParseError("unexpected token, expected end of statement");
2904 AssemblerOptions.back()->setNoReorder();
2905 getTargetStreamer().emitDirectiveSetNoReorder();
2906 Parser.Lex(); // Consume the EndOfStatement.
2910 bool MipsAsmParser::parseSetMacroDirective() {
2911 MCAsmParser &Parser = getParser();
2913 // If this is not the end of the statement, report an error.
2914 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2915 reportParseError("unexpected token, expected end of statement");
2918 AssemblerOptions.back()->setMacro();
2919 Parser.Lex(); // Consume the EndOfStatement.
2923 bool MipsAsmParser::parseSetNoMacroDirective() {
2924 MCAsmParser &Parser = getParser();
2926 // If this is not the end of the statement, report an error.
2927 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2928 reportParseError("unexpected token, expected end of statement");
2931 if (AssemblerOptions.back()->isReorder()) {
2932 reportParseError("`noreorder' must be set before `nomacro'");
2935 AssemblerOptions.back()->setNoMacro();
2936 Parser.Lex(); // Consume the EndOfStatement.
2940 bool MipsAsmParser::parseSetMsaDirective() {
2941 MCAsmParser &Parser = getParser();
2944 // If this is not the end of the statement, report an error.
2945 if (getLexer().isNot(AsmToken::EndOfStatement))
2946 return reportParseError("unexpected token, expected end of statement");
2948 setFeatureBits(Mips::FeatureMSA, "msa");
2949 getTargetStreamer().emitDirectiveSetMsa();
2953 bool MipsAsmParser::parseSetNoMsaDirective() {
2954 MCAsmParser &Parser = getParser();
2957 // If this is not the end of the statement, report an error.
2958 if (getLexer().isNot(AsmToken::EndOfStatement))
2959 return reportParseError("unexpected token, expected end of statement");
2961 clearFeatureBits(Mips::FeatureMSA, "msa");
2962 getTargetStreamer().emitDirectiveSetNoMsa();
2966 bool MipsAsmParser::parseSetNoDspDirective() {
2967 MCAsmParser &Parser = getParser();
2968 Parser.Lex(); // Eat "nodsp".
2970 // If this is not the end of the statement, report an error.
2971 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2972 reportParseError("unexpected token, expected end of statement");
2976 clearFeatureBits(Mips::FeatureDSP, "dsp");
2977 getTargetStreamer().emitDirectiveSetNoDsp();
2981 bool MipsAsmParser::parseSetMips16Directive() {
2982 MCAsmParser &Parser = getParser();
2983 Parser.Lex(); // Eat "mips16".
2985 // If this is not the end of the statement, report an error.
2986 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2987 reportParseError("unexpected token, expected end of statement");
2991 setFeatureBits(Mips::FeatureMips16, "mips16");
2992 getTargetStreamer().emitDirectiveSetMips16();
2993 Parser.Lex(); // Consume the EndOfStatement.
2997 bool MipsAsmParser::parseSetNoMips16Directive() {
2998 MCAsmParser &Parser = getParser();
2999 Parser.Lex(); // Eat "nomips16".
3001 // If this is not the end of the statement, report an error.
3002 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3003 reportParseError("unexpected token, expected end of statement");
3007 clearFeatureBits(Mips::FeatureMips16, "mips16");
3008 getTargetStreamer().emitDirectiveSetNoMips16();
3009 Parser.Lex(); // Consume the EndOfStatement.
3013 bool MipsAsmParser::parseSetFpDirective() {
3014 MCAsmParser &Parser = getParser();
3015 MipsABIFlagsSection::FpABIKind FpAbiVal;
3016 // Line can be: .set fp=32
3019 Parser.Lex(); // Eat fp token
3020 AsmToken Tok = Parser.getTok();
3021 if (Tok.isNot(AsmToken::Equal)) {
3022 reportParseError("unexpected token, expected equals sign '='");
3025 Parser.Lex(); // Eat '=' token.
3026 Tok = Parser.getTok();
3028 if (!parseFpABIValue(FpAbiVal, ".set"))
3031 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3032 reportParseError("unexpected token, expected end of statement");
3035 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
3036 Parser.Lex(); // Consume the EndOfStatement.
3040 bool MipsAsmParser::parseSetPopDirective() {
3041 MCAsmParser &Parser = getParser();
3042 SMLoc Loc = getLexer().getLoc();
3045 if (getLexer().isNot(AsmToken::EndOfStatement))
3046 return reportParseError("unexpected token, expected end of statement");
3048 // Always keep an element on the options "stack" to prevent the user
3049 // from changing the initial options. This is how we remember them.
3050 if (AssemblerOptions.size() == 2)
3051 return reportParseError(Loc, ".set pop with no .set push");
3053 AssemblerOptions.pop_back();
3054 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
3056 getTargetStreamer().emitDirectiveSetPop();
3060 bool MipsAsmParser::parseSetPushDirective() {
3061 MCAsmParser &Parser = getParser();
3063 if (getLexer().isNot(AsmToken::EndOfStatement))
3064 return reportParseError("unexpected token, expected end of statement");
3066 // Create a copy of the current assembler options environment and push it.
3067 AssemblerOptions.push_back(
3068 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
3070 getTargetStreamer().emitDirectiveSetPush();
3074 bool MipsAsmParser::parseSetAssignment() {
3076 const MCExpr *Value;
3077 MCAsmParser &Parser = getParser();
3079 if (Parser.parseIdentifier(Name))
3080 reportParseError("expected identifier after .set");
3082 if (getLexer().isNot(AsmToken::Comma))
3083 return reportParseError("unexpected token, expected comma");
3086 if (Parser.parseExpression(Value))
3087 return reportParseError("expected valid expression after comma");
3089 // Check if the Name already exists as a symbol.
3090 MCSymbol *Sym = getContext().LookupSymbol(Name);
3092 return reportParseError("symbol already defined");
3093 Sym = getContext().GetOrCreateSymbol(Name);
3094 Sym->setVariableValue(Value);
3099 bool MipsAsmParser::parseSetMips0Directive() {
3100 MCAsmParser &Parser = getParser();
3102 if (getLexer().isNot(AsmToken::EndOfStatement))
3103 return reportParseError("unexpected token, expected end of statement");
3105 // Reset assembler options to their initial values.
3106 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
3107 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
3109 getTargetStreamer().emitDirectiveSetMips0();
3113 bool MipsAsmParser::parseSetArchDirective() {
3114 MCAsmParser &Parser = getParser();
3116 if (getLexer().isNot(AsmToken::Equal))
3117 return reportParseError("unexpected token, expected equals sign");
3121 if (Parser.parseIdentifier(Arch))
3122 return reportParseError("expected arch identifier");
3124 StringRef ArchFeatureName =
3125 StringSwitch<StringRef>(Arch)
3126 .Case("mips1", "mips1")
3127 .Case("mips2", "mips2")
3128 .Case("mips3", "mips3")
3129 .Case("mips4", "mips4")
3130 .Case("mips5", "mips5")
3131 .Case("mips32", "mips32")
3132 .Case("mips32r2", "mips32r2")
3133 .Case("mips32r6", "mips32r6")
3134 .Case("mips64", "mips64")
3135 .Case("mips64r2", "mips64r2")
3136 .Case("mips64r6", "mips64r6")
3137 .Case("cnmips", "cnmips")
3138 .Case("r4000", "mips3") // This is an implementation of Mips3.
3141 if (ArchFeatureName.empty())
3142 return reportParseError("unsupported architecture");
3144 selectArch(ArchFeatureName);
3145 getTargetStreamer().emitDirectiveSetArch(Arch);
3149 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
3150 MCAsmParser &Parser = getParser();
3152 if (getLexer().isNot(AsmToken::EndOfStatement))
3153 return reportParseError("unexpected token, expected end of statement");
3157 llvm_unreachable("Unimplemented feature");
3158 case Mips::FeatureDSP:
3159 setFeatureBits(Mips::FeatureDSP, "dsp");
3160 getTargetStreamer().emitDirectiveSetDsp();
3162 case Mips::FeatureMicroMips:
3163 getTargetStreamer().emitDirectiveSetMicroMips();
3165 case Mips::FeatureMips1:
3166 selectArch("mips1");
3167 getTargetStreamer().emitDirectiveSetMips1();
3169 case Mips::FeatureMips2:
3170 selectArch("mips2");
3171 getTargetStreamer().emitDirectiveSetMips2();
3173 case Mips::FeatureMips3:
3174 selectArch("mips3");
3175 getTargetStreamer().emitDirectiveSetMips3();
3177 case Mips::FeatureMips4:
3178 selectArch("mips4");
3179 getTargetStreamer().emitDirectiveSetMips4();
3181 case Mips::FeatureMips5:
3182 selectArch("mips5");
3183 getTargetStreamer().emitDirectiveSetMips5();
3185 case Mips::FeatureMips32:
3186 selectArch("mips32");
3187 getTargetStreamer().emitDirectiveSetMips32();
3189 case Mips::FeatureMips32r2:
3190 selectArch("mips32r2");
3191 getTargetStreamer().emitDirectiveSetMips32R2();
3193 case Mips::FeatureMips32r6:
3194 selectArch("mips32r6");
3195 getTargetStreamer().emitDirectiveSetMips32R6();
3197 case Mips::FeatureMips64:
3198 selectArch("mips64");
3199 getTargetStreamer().emitDirectiveSetMips64();
3201 case Mips::FeatureMips64r2:
3202 selectArch("mips64r2");
3203 getTargetStreamer().emitDirectiveSetMips64R2();
3205 case Mips::FeatureMips64r6:
3206 selectArch("mips64r6");
3207 getTargetStreamer().emitDirectiveSetMips64R6();
3213 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
3214 MCAsmParser &Parser = getParser();
3215 if (getLexer().isNot(AsmToken::Comma)) {
3216 SMLoc Loc = getLexer().getLoc();
3217 Parser.eatToEndOfStatement();
3218 return Error(Loc, ErrorStr);
3221 Parser.Lex(); // Eat the comma.
3225 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
3226 if (AssemblerOptions.back()->isReorder())
3227 Warning(Loc, ".cpload should be inside a noreorder section");
3229 if (inMips16Mode()) {
3230 reportParseError(".cpload is not supported in Mips16 mode");
3234 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
3235 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
3236 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3237 reportParseError("expected register containing function address");
3241 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
3242 if (!RegOpnd.isGPRAsmReg()) {
3243 reportParseError(RegOpnd.getStartLoc(), "invalid register");
3247 // If this is not the end of the statement, report an error.
3248 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3249 reportParseError("unexpected token, expected end of statement");
3253 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
3257 bool MipsAsmParser::parseDirectiveCPSetup() {
3258 MCAsmParser &Parser = getParser();
3261 bool SaveIsReg = true;
3263 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3264 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3265 if (ResTy == MatchOperand_NoMatch) {
3266 reportParseError("expected register containing function address");
3267 Parser.eatToEndOfStatement();
3271 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3272 if (!FuncRegOpnd.isGPRAsmReg()) {
3273 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
3274 Parser.eatToEndOfStatement();
3278 FuncReg = FuncRegOpnd.getGPR32Reg();
3281 if (!eatComma("unexpected token, expected comma"))
3284 ResTy = parseAnyRegister(TmpReg);
3285 if (ResTy == MatchOperand_NoMatch) {
3286 const AsmToken &Tok = Parser.getTok();
3287 if (Tok.is(AsmToken::Integer)) {
3288 Save = Tok.getIntVal();
3292 reportParseError("expected save register or stack offset");
3293 Parser.eatToEndOfStatement();
3297 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3298 if (!SaveOpnd.isGPRAsmReg()) {
3299 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3300 Parser.eatToEndOfStatement();
3303 Save = SaveOpnd.getGPR32Reg();
3306 if (!eatComma("unexpected token, expected comma"))
3310 if (Parser.parseIdentifier(Name))
3311 reportParseError("expected identifier");
3312 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3314 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3318 bool MipsAsmParser::parseDirectiveNaN() {
3319 MCAsmParser &Parser = getParser();
3320 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3321 const AsmToken &Tok = Parser.getTok();
3323 if (Tok.getString() == "2008") {
3325 getTargetStreamer().emitDirectiveNaN2008();
3327 } else if (Tok.getString() == "legacy") {
3329 getTargetStreamer().emitDirectiveNaNLegacy();
3333 // If we don't recognize the option passed to the .nan
3334 // directive (e.g. no option or unknown option), emit an error.
3335 reportParseError("invalid option in .nan directive");
3339 bool MipsAsmParser::parseDirectiveSet() {
3340 MCAsmParser &Parser = getParser();
3341 // Get the next token.
3342 const AsmToken &Tok = Parser.getTok();
3344 if (Tok.getString() == "noat") {
3345 return parseSetNoAtDirective();
3346 } else if (Tok.getString() == "at") {
3347 return parseSetAtDirective();
3348 } else if (Tok.getString() == "arch") {
3349 return parseSetArchDirective();
3350 } else if (Tok.getString() == "fp") {
3351 return parseSetFpDirective();
3352 } else if (Tok.getString() == "pop") {
3353 return parseSetPopDirective();
3354 } else if (Tok.getString() == "push") {
3355 return parseSetPushDirective();
3356 } else if (Tok.getString() == "reorder") {
3357 return parseSetReorderDirective();
3358 } else if (Tok.getString() == "noreorder") {
3359 return parseSetNoReorderDirective();
3360 } else if (Tok.getString() == "macro") {
3361 return parseSetMacroDirective();
3362 } else if (Tok.getString() == "nomacro") {
3363 return parseSetNoMacroDirective();
3364 } else if (Tok.getString() == "mips16") {
3365 return parseSetMips16Directive();
3366 } else if (Tok.getString() == "nomips16") {
3367 return parseSetNoMips16Directive();
3368 } else if (Tok.getString() == "nomicromips") {
3369 getTargetStreamer().emitDirectiveSetNoMicroMips();
3370 Parser.eatToEndOfStatement();
3372 } else if (Tok.getString() == "micromips") {
3373 return parseSetFeature(Mips::FeatureMicroMips);
3374 } else if (Tok.getString() == "mips0") {
3375 return parseSetMips0Directive();
3376 } else if (Tok.getString() == "mips1") {
3377 return parseSetFeature(Mips::FeatureMips1);
3378 } else if (Tok.getString() == "mips2") {
3379 return parseSetFeature(Mips::FeatureMips2);
3380 } else if (Tok.getString() == "mips3") {
3381 return parseSetFeature(Mips::FeatureMips3);
3382 } else if (Tok.getString() == "mips4") {
3383 return parseSetFeature(Mips::FeatureMips4);
3384 } else if (Tok.getString() == "mips5") {
3385 return parseSetFeature(Mips::FeatureMips5);
3386 } else if (Tok.getString() == "mips32") {
3387 return parseSetFeature(Mips::FeatureMips32);
3388 } else if (Tok.getString() == "mips32r2") {
3389 return parseSetFeature(Mips::FeatureMips32r2);
3390 } else if (Tok.getString() == "mips32r6") {
3391 return parseSetFeature(Mips::FeatureMips32r6);
3392 } else if (Tok.getString() == "mips64") {
3393 return parseSetFeature(Mips::FeatureMips64);
3394 } else if (Tok.getString() == "mips64r2") {
3395 return parseSetFeature(Mips::FeatureMips64r2);
3396 } else if (Tok.getString() == "mips64r6") {
3397 return parseSetFeature(Mips::FeatureMips64r6);
3398 } else if (Tok.getString() == "dsp") {
3399 return parseSetFeature(Mips::FeatureDSP);
3400 } else if (Tok.getString() == "nodsp") {
3401 return parseSetNoDspDirective();
3402 } else if (Tok.getString() == "msa") {
3403 return parseSetMsaDirective();
3404 } else if (Tok.getString() == "nomsa") {
3405 return parseSetNoMsaDirective();
3407 // It is just an identifier, look for an assignment.
3408 parseSetAssignment();
3415 /// parseDataDirective
3416 /// ::= .word [ expression (, expression)* ]
3417 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3418 MCAsmParser &Parser = getParser();
3419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3421 const MCExpr *Value;
3422 if (getParser().parseExpression(Value))
3425 getParser().getStreamer().EmitValue(Value, Size);
3427 if (getLexer().is(AsmToken::EndOfStatement))
3430 if (getLexer().isNot(AsmToken::Comma))
3431 return Error(L, "unexpected token, expected comma");
3440 /// parseDirectiveGpWord
3441 /// ::= .gpword local_sym
3442 bool MipsAsmParser::parseDirectiveGpWord() {
3443 MCAsmParser &Parser = getParser();
3444 const MCExpr *Value;
3445 // EmitGPRel32Value requires an expression, so we are using base class
3446 // method to evaluate the expression.
3447 if (getParser().parseExpression(Value))
3449 getParser().getStreamer().EmitGPRel32Value(Value);
3451 if (getLexer().isNot(AsmToken::EndOfStatement))
3452 return Error(getLexer().getLoc(),
3453 "unexpected token, expected end of statement");
3454 Parser.Lex(); // Eat EndOfStatement token.
3458 /// parseDirectiveGpDWord
3459 /// ::= .gpdword local_sym
3460 bool MipsAsmParser::parseDirectiveGpDWord() {
3461 MCAsmParser &Parser = getParser();
3462 const MCExpr *Value;
3463 // EmitGPRel64Value requires an expression, so we are using base class
3464 // method to evaluate the expression.
3465 if (getParser().parseExpression(Value))
3467 getParser().getStreamer().EmitGPRel64Value(Value);
3469 if (getLexer().isNot(AsmToken::EndOfStatement))
3470 return Error(getLexer().getLoc(),
3471 "unexpected token, expected end of statement");
3472 Parser.Lex(); // Eat EndOfStatement token.
3476 bool MipsAsmParser::parseDirectiveOption() {
3477 MCAsmParser &Parser = getParser();
3478 // Get the option token.
3479 AsmToken Tok = Parser.getTok();
3480 // At the moment only identifiers are supported.
3481 if (Tok.isNot(AsmToken::Identifier)) {
3482 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3483 Parser.eatToEndOfStatement();
3487 StringRef Option = Tok.getIdentifier();
3489 if (Option == "pic0") {
3490 getTargetStreamer().emitDirectiveOptionPic0();
3492 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3493 Error(Parser.getTok().getLoc(),
3494 "unexpected token, expected end of statement");
3495 Parser.eatToEndOfStatement();
3500 if (Option == "pic2") {
3501 getTargetStreamer().emitDirectiveOptionPic2();
3503 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3504 Error(Parser.getTok().getLoc(),
3505 "unexpected token, expected end of statement");
3506 Parser.eatToEndOfStatement();
3512 Warning(Parser.getTok().getLoc(),
3513 "unknown option, expected 'pic0' or 'pic2'");
3514 Parser.eatToEndOfStatement();
3518 /// parseDirectiveModule
3519 /// ::= .module oddspreg
3520 /// ::= .module nooddspreg
3521 /// ::= .module fp=value
3522 bool MipsAsmParser::parseDirectiveModule() {
3523 MCAsmParser &Parser = getParser();
3524 MCAsmLexer &Lexer = getLexer();
3525 SMLoc L = Lexer.getLoc();
3527 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3528 // TODO : get a better message.
3529 reportParseError(".module directive must appear before any code");
3533 if (Lexer.is(AsmToken::Identifier)) {
3534 StringRef Option = Parser.getTok().getString();
3537 if (Option == "oddspreg") {
3538 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3539 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3541 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3542 reportParseError("unexpected token, expected end of statement");
3547 } else if (Option == "nooddspreg") {
3549 Error(L, "'.module nooddspreg' requires the O32 ABI");
3553 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3554 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3556 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3557 reportParseError("unexpected token, expected end of statement");
3562 } else if (Option == "fp") {
3563 return parseDirectiveModuleFP();
3566 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3572 /// parseDirectiveModuleFP
3576 bool MipsAsmParser::parseDirectiveModuleFP() {
3577 MCAsmParser &Parser = getParser();
3578 MCAsmLexer &Lexer = getLexer();
3580 if (Lexer.isNot(AsmToken::Equal)) {
3581 reportParseError("unexpected token, expected equals sign '='");
3584 Parser.Lex(); // Eat '=' token.
3586 MipsABIFlagsSection::FpABIKind FpABI;
3587 if (!parseFpABIValue(FpABI, ".module"))
3590 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3591 reportParseError("unexpected token, expected end of statement");
3595 // Emit appropriate flags.
3596 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3597 Parser.Lex(); // Consume the EndOfStatement.
3601 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3602 StringRef Directive) {
3603 MCAsmParser &Parser = getParser();
3604 MCAsmLexer &Lexer = getLexer();
3606 if (Lexer.is(AsmToken::Identifier)) {
3607 StringRef Value = Parser.getTok().getString();
3610 if (Value != "xx") {
3611 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3616 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3620 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3624 if (Lexer.is(AsmToken::Integer)) {
3625 unsigned Value = Parser.getTok().getIntVal();
3628 if (Value != 32 && Value != 64) {
3629 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3635 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3639 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3641 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3649 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3650 MCAsmParser &Parser = getParser();
3651 StringRef IDVal = DirectiveID.getString();
3653 if (IDVal == ".cpload")
3654 return parseDirectiveCpLoad(DirectiveID.getLoc());
3655 if (IDVal == ".dword") {
3656 parseDataDirective(8, DirectiveID.getLoc());
3659 if (IDVal == ".ent") {
3660 StringRef SymbolName;
3662 if (Parser.parseIdentifier(SymbolName)) {
3663 reportParseError("expected identifier after .ent");
3667 // There's an undocumented extension that allows an integer to
3668 // follow the name of the procedure which AFAICS is ignored by GAS.
3669 // Example: .ent foo,2
3670 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3671 if (getLexer().isNot(AsmToken::Comma)) {
3672 // Even though we accept this undocumented extension for compatibility
3673 // reasons, the additional integer argument does not actually change
3674 // the behaviour of the '.ent' directive, so we would like to discourage
3675 // its use. We do this by not referring to the extended version in
3676 // error messages which are not directly related to its use.
3677 reportParseError("unexpected token, expected end of statement");
3680 Parser.Lex(); // Eat the comma.
3681 const MCExpr *DummyNumber;
3682 int64_t DummyNumberVal;
3683 // If the user was explicitly trying to use the extended version,
3684 // we still give helpful extension-related error messages.
3685 if (Parser.parseExpression(DummyNumber)) {
3686 reportParseError("expected number after comma");
3689 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3690 reportParseError("expected an absolute expression after comma");
3695 // If this is not the end of the statement, report an error.
3696 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3697 reportParseError("unexpected token, expected end of statement");
3701 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3703 getTargetStreamer().emitDirectiveEnt(*Sym);
3708 if (IDVal == ".end") {
3709 StringRef SymbolName;
3711 if (Parser.parseIdentifier(SymbolName)) {
3712 reportParseError("expected identifier after .end");
3716 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3717 reportParseError("unexpected token, expected end of statement");
3721 if (CurrentFn == nullptr) {
3722 reportParseError(".end used without .ent");
3726 if ((SymbolName != CurrentFn->getName())) {
3727 reportParseError(".end symbol does not match .ent symbol");
3731 getTargetStreamer().emitDirectiveEnd(SymbolName);
3732 CurrentFn = nullptr;
3736 if (IDVal == ".frame") {
3737 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3738 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3739 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3740 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3741 reportParseError("expected stack register");
3745 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3746 if (!StackRegOpnd.isGPRAsmReg()) {
3747 reportParseError(StackRegOpnd.getStartLoc(),
3748 "expected general purpose register");
3751 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3753 if (Parser.getTok().is(AsmToken::Comma))
3756 reportParseError("unexpected token, expected comma");
3760 // Parse the frame size.
3761 const MCExpr *FrameSize;
3762 int64_t FrameSizeVal;
3764 if (Parser.parseExpression(FrameSize)) {
3765 reportParseError("expected frame size value");
3769 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3770 reportParseError("frame size not an absolute expression");
3774 if (Parser.getTok().is(AsmToken::Comma))
3777 reportParseError("unexpected token, expected comma");
3781 // Parse the return register.
3783 ResTy = parseAnyRegister(TmpReg);
3784 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3785 reportParseError("expected return register");
3789 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3790 if (!ReturnRegOpnd.isGPRAsmReg()) {
3791 reportParseError(ReturnRegOpnd.getStartLoc(),
3792 "expected general purpose register");
3796 // If this is not the end of the statement, report an error.
3797 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3798 reportParseError("unexpected token, expected end of statement");
3802 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3803 ReturnRegOpnd.getGPR32Reg());
3807 if (IDVal == ".set") {
3808 return parseDirectiveSet();
3811 if (IDVal == ".mask" || IDVal == ".fmask") {
3812 // .mask bitmask, frame_offset
3813 // bitmask: One bit for each register used.
3814 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3815 // first register is expected to be saved.
3817 // .mask 0x80000000, -4
3818 // .fmask 0x80000000, -4
3821 // Parse the bitmask
3822 const MCExpr *BitMask;
3825 if (Parser.parseExpression(BitMask)) {
3826 reportParseError("expected bitmask value");
3830 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3831 reportParseError("bitmask not an absolute expression");
3835 if (Parser.getTok().is(AsmToken::Comma))
3838 reportParseError("unexpected token, expected comma");
3842 // Parse the frame_offset
3843 const MCExpr *FrameOffset;
3844 int64_t FrameOffsetVal;
3846 if (Parser.parseExpression(FrameOffset)) {
3847 reportParseError("expected frame offset value");
3851 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3852 reportParseError("frame offset not an absolute expression");
3856 // If this is not the end of the statement, report an error.
3857 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3858 reportParseError("unexpected token, expected end of statement");
3862 if (IDVal == ".mask")
3863 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3865 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3869 if (IDVal == ".nan")
3870 return parseDirectiveNaN();
3872 if (IDVal == ".gpword") {
3873 parseDirectiveGpWord();
3877 if (IDVal == ".gpdword") {
3878 parseDirectiveGpDWord();
3882 if (IDVal == ".word") {
3883 parseDataDirective(4, DirectiveID.getLoc());
3887 if (IDVal == ".option")
3888 return parseDirectiveOption();
3890 if (IDVal == ".abicalls") {
3891 getTargetStreamer().emitDirectiveAbiCalls();
3892 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3893 Error(Parser.getTok().getLoc(),
3894 "unexpected token, expected end of statement");
3896 Parser.eatToEndOfStatement();
3901 if (IDVal == ".cpsetup")
3902 return parseDirectiveCPSetup();
3904 if (IDVal == ".module")
3905 return parseDirectiveModule();
3910 extern "C" void LLVMInitializeMipsAsmParser() {
3911 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3912 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3913 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3914 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3917 #define GET_REGISTER_MATCHER
3918 #define GET_MATCHER_IMPLEMENTATION
3919 #include "MipsGenAsmMatcher.inc"