1 //===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "MCTargetDesc/MipsMCExpr.h"
11 #include "MCTargetDesc/MipsMCTargetDesc.h"
12 #include "MipsRegisterInfo.h"
13 #include "MipsTargetStreamer.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/StringSwitch.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/MC/MCContext.h"
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstBuilder.h"
21 #include "llvm/MC/MCParser/MCAsmLexer.h"
22 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
23 #include "llvm/MC/MCStreamer.h"
24 #include "llvm/MC/MCSubtargetInfo.h"
25 #include "llvm/MC/MCSymbol.h"
26 #include "llvm/MC/MCTargetAsmParser.h"
27 #include "llvm/Support/Debug.h"
28 #include "llvm/Support/MathExtras.h"
29 #include "llvm/Support/TargetRegistry.h"
30 #include "llvm/Support/SourceMgr.h"
35 #define DEBUG_TYPE "mips-asm-parser"
42 class MipsAssemblerOptions {
44 MipsAssemblerOptions(uint64_t Features_) :
45 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
47 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
48 ATReg = Opts->getATRegNum();
49 Reorder = Opts->isReorder();
50 Macro = Opts->isMacro();
51 Features = Opts->getFeatures();
54 unsigned getATRegNum() const { return ATReg; }
55 bool setATReg(unsigned Reg);
57 bool isReorder() const { return Reorder; }
58 void setReorder() { Reorder = true; }
59 void setNoReorder() { Reorder = false; }
61 bool isMacro() const { return Macro; }
62 void setMacro() { Macro = true; }
63 void setNoMacro() { Macro = false; }
65 uint64_t getFeatures() const { return Features; }
66 void setFeatures(uint64_t Features_) { Features = Features_; }
68 // Set of features that are either architecture features or referenced
69 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
70 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
71 // The reason we need this mask is explained in the selectArch function.
72 // FIXME: Ideally we would like TableGen to generate this information.
73 static const uint64_t AllArchRelatedMask =
74 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
75 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
76 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
77 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
78 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
79 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
80 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
91 class MipsAsmParser : public MCTargetAsmParser {
92 MipsTargetStreamer &getTargetStreamer() {
93 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
94 return static_cast<MipsTargetStreamer &>(TS);
99 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
100 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
101 // nullptr, which indicates that no function is currently
102 // selected. This usually happens after an '.end func'
105 // Print a warning along with its fix-it message at the given range.
106 void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
107 SMRange Range, bool ShowColors = true);
109 #define GET_ASSEMBLER_HEADER
110 #include "MipsGenAsmMatcher.inc"
112 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
114 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
115 OperandVector &Operands, MCStreamer &Out,
117 bool MatchingInlineAsm) override;
119 /// Parse a register as used in CFI directives
120 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
122 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
124 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
126 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
127 SMLoc NameLoc, OperandVector &Operands) override;
129 bool ParseDirective(AsmToken DirectiveID) override;
131 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
133 MipsAsmParser::OperandMatchResultTy
134 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
135 StringRef Identifier, SMLoc S);
137 MipsAsmParser::OperandMatchResultTy
138 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
140 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
142 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
144 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
146 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
148 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
150 bool searchSymbolAlias(OperandVector &Operands);
152 bool parseOperand(OperandVector &, StringRef Mnemonic);
154 bool needsExpansion(MCInst &Inst);
156 // Expands assembly pseudo instructions.
157 // Returns false on success, true otherwise.
158 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
159 SmallVectorImpl<MCInst> &Instructions);
161 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
162 SmallVectorImpl<MCInst> &Instructions);
164 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
165 SmallVectorImpl<MCInst> &Instructions);
167 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
168 SmallVectorImpl<MCInst> &Instructions);
170 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
171 SmallVectorImpl<MCInst> &Instructions);
173 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
174 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
176 bool reportParseError(Twine ErrorMsg);
177 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
179 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
180 bool parseRelocOperand(const MCExpr *&Res);
182 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
184 bool isEvaluated(const MCExpr *Expr);
185 bool parseSetMips0Directive();
186 bool parseSetArchDirective();
187 bool parseSetFeature(uint64_t Feature);
188 bool parseDirectiveCpLoad(SMLoc Loc);
189 bool parseDirectiveCPSetup();
190 bool parseDirectiveNaN();
191 bool parseDirectiveSet();
192 bool parseDirectiveOption();
194 bool parseSetAtDirective();
195 bool parseSetNoAtDirective();
196 bool parseSetMacroDirective();
197 bool parseSetNoMacroDirective();
198 bool parseSetMsaDirective();
199 bool parseSetNoMsaDirective();
200 bool parseSetNoDspDirective();
201 bool parseSetReorderDirective();
202 bool parseSetNoReorderDirective();
203 bool parseSetNoMips16Directive();
204 bool parseSetFpDirective();
205 bool parseSetPopDirective();
206 bool parseSetPushDirective();
208 bool parseSetAssignment();
210 bool parseDataDirective(unsigned Size, SMLoc L);
211 bool parseDirectiveGpWord();
212 bool parseDirectiveGpDWord();
213 bool parseDirectiveModule();
214 bool parseDirectiveModuleFP();
215 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
216 StringRef Directive);
218 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
220 bool eatComma(StringRef ErrorStr);
222 int matchCPURegisterName(StringRef Symbol);
224 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
226 int matchFPURegisterName(StringRef Name);
228 int matchFCCRegisterName(StringRef Name);
230 int matchACRegisterName(StringRef Name);
232 int matchMSA128RegisterName(StringRef Name);
234 int matchMSA128CtrlRegisterName(StringRef Name);
236 unsigned getReg(int RC, int RegNo);
238 unsigned getGPR(int RegNo);
240 int getATReg(SMLoc Loc);
242 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
243 SmallVectorImpl<MCInst> &Instructions);
245 // Helper function that checks if the value of a vector index is within the
246 // boundaries of accepted values for each RegisterKind
247 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
248 bool validateMSAIndex(int Val, int RegKind);
250 // Selects a new architecture by updating the FeatureBits with the necessary
251 // info including implied dependencies.
252 // Internally, it clears all the feature bits related to *any* architecture
253 // and selects the new one using the ToggleFeature functionality of the
254 // MCSubtargetInfo object that handles implied dependencies. The reason we
255 // clear all the arch related bits manually is because ToggleFeature only
256 // clears the features that imply the feature being cleared and not the
257 // features implied by the feature being cleared. This is easier to see
259 // --------------------------------------------------
260 // | Feature | Implies |
261 // | -------------------------------------------------|
262 // | FeatureMips1 | None |
263 // | FeatureMips2 | FeatureMips1 |
264 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
265 // | FeatureMips4 | FeatureMips3 |
267 // --------------------------------------------------
269 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
270 // FeatureMipsGP64 | FeatureMips1)
271 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
272 void selectArch(StringRef ArchFeature) {
273 uint64_t FeatureBits = STI.getFeatureBits();
274 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
275 STI.setFeatureBits(FeatureBits);
276 setAvailableFeatures(
277 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
278 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
281 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
282 if (!(STI.getFeatureBits() & Feature)) {
283 setAvailableFeatures(
284 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
286 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
289 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
290 if (STI.getFeatureBits() & Feature) {
291 setAvailableFeatures(
292 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
294 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
298 enum MipsMatchResultTy {
299 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
300 #define GET_OPERAND_DIAGNOSTIC_TYPES
301 #include "MipsGenAsmMatcher.inc"
302 #undef GET_OPERAND_DIAGNOSTIC_TYPES
306 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
307 const MCInstrInfo &MII, const MCTargetOptions &Options)
308 : MCTargetAsmParser(), STI(sti), Parser(parser) {
309 // Initialize the set of available features.
310 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
312 // Remember the initial assembler options. The user can not modify these.
313 AssemblerOptions.push_back(
314 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
316 // Create an assembler options environment for the user to modify.
317 AssemblerOptions.push_back(
318 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
320 getTargetStreamer().updateABIInfo(*this);
322 // Assert exactly one ABI was chosen.
323 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
324 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
325 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
326 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
328 if (!isABI_O32() && !useOddSPReg() != 0)
329 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
334 MCAsmParser &getParser() const { return Parser; }
335 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
337 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
338 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
340 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
341 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
342 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
343 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
344 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
345 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
347 bool useOddSPReg() const {
348 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
351 bool inMicroMipsMode() const {
352 return STI.getFeatureBits() & Mips::FeatureMicroMips;
354 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
355 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
356 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
357 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
358 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
359 bool hasMips32() const {
360 return (STI.getFeatureBits() & Mips::FeatureMips32);
362 bool hasMips64() const {
363 return (STI.getFeatureBits() & Mips::FeatureMips64);
365 bool hasMips32r2() const {
366 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
368 bool hasMips64r2() const {
369 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
371 bool hasMips32r6() const {
372 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
374 bool hasMips64r6() const {
375 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
377 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
378 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
379 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
381 bool inMips16Mode() const {
382 return STI.getFeatureBits() & Mips::FeatureMips16;
384 // TODO: see how can we get this info.
385 bool abiUsesSoftFloat() const { return false; }
387 /// Warn if RegNo is the current assembler temporary.
388 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
394 /// MipsOperand - Instances of this class represent a parsed Mips machine
396 class MipsOperand : public MCParsedAsmOperand {
398 /// Broad categories of register classes
399 /// The exact class is finalized by the render method.
401 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
402 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
404 RegKind_FCC = 4, /// FCC
405 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
406 RegKind_MSACtrl = 16, /// MSA control registers
407 RegKind_COP2 = 32, /// COP2
408 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
410 RegKind_CCR = 128, /// CCR
411 RegKind_HWRegs = 256, /// HWRegs
412 RegKind_COP3 = 512, /// COP3
414 /// Potentially any (e.g. $1)
415 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
416 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
417 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
422 k_Immediate, /// An immediate (possibly involving symbol references)
423 k_Memory, /// Base + Offset Memory Address
424 k_PhysRegister, /// A physical register from the Mips namespace
425 k_RegisterIndex, /// A register index in one or more RegKind.
426 k_Token /// A simple token
430 MipsOperand(KindTy K, MipsAsmParser &Parser)
431 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
434 /// For diagnostics, and checking the assembler temporary
435 MipsAsmParser &AsmParser;
443 unsigned Num; /// Register Number
447 unsigned Index; /// Index into the register class
448 RegKind Kind; /// Bitfield of the kinds it could possibly be
449 const MCRegisterInfo *RegInfo;
463 struct PhysRegOp PhysReg;
464 struct RegIdxOp RegIdx;
469 SMLoc StartLoc, EndLoc;
471 /// Internal constructor for register kinds
472 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
473 const MCRegisterInfo *RegInfo,
475 MipsAsmParser &Parser) {
476 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
477 Op->RegIdx.Index = Index;
478 Op->RegIdx.RegInfo = RegInfo;
479 Op->RegIdx.Kind = RegKind;
486 /// Coerce the register to GPR32 and return the real register for the current
488 unsigned getGPR32Reg() const {
489 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
490 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
491 unsigned ClassID = Mips::GPR32RegClassID;
492 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
495 /// Coerce the register to GPR64 and return the real register for the current
497 unsigned getGPR64Reg() const {
498 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
499 unsigned ClassID = Mips::GPR64RegClassID;
500 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
504 /// Coerce the register to AFGR64 and return the real register for the current
506 unsigned getAFGR64Reg() const {
507 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
508 if (RegIdx.Index % 2 != 0)
509 AsmParser.Warning(StartLoc, "Float register should be even.");
510 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
511 .getRegister(RegIdx.Index / 2);
514 /// Coerce the register to FGR64 and return the real register for the current
516 unsigned getFGR64Reg() const {
517 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
518 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
519 .getRegister(RegIdx.Index);
522 /// Coerce the register to FGR32 and return the real register for the current
524 unsigned getFGR32Reg() const {
525 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
526 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
527 .getRegister(RegIdx.Index);
530 /// Coerce the register to FGRH32 and return the real register for the current
532 unsigned getFGRH32Reg() const {
533 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
534 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
535 .getRegister(RegIdx.Index);
538 /// Coerce the register to FCC and return the real register for the current
540 unsigned getFCCReg() const {
541 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
542 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
543 .getRegister(RegIdx.Index);
546 /// Coerce the register to MSA128 and return the real register for the current
548 unsigned getMSA128Reg() const {
549 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
550 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
552 unsigned ClassID = Mips::MSA128BRegClassID;
553 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
556 /// Coerce the register to MSACtrl and return the real register for the
558 unsigned getMSACtrlReg() const {
559 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
560 unsigned ClassID = Mips::MSACtrlRegClassID;
561 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
564 /// Coerce the register to COP2 and return the real register for the
566 unsigned getCOP2Reg() const {
567 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
568 unsigned ClassID = Mips::COP2RegClassID;
569 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
572 /// Coerce the register to COP3 and return the real register for the
574 unsigned getCOP3Reg() const {
575 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
576 unsigned ClassID = Mips::COP3RegClassID;
577 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
580 /// Coerce the register to ACC64DSP and return the real register for the
582 unsigned getACC64DSPReg() const {
583 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
584 unsigned ClassID = Mips::ACC64DSPRegClassID;
585 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
588 /// Coerce the register to HI32DSP and return the real register for the
590 unsigned getHI32DSPReg() const {
591 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
592 unsigned ClassID = Mips::HI32DSPRegClassID;
593 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
596 /// Coerce the register to LO32DSP and return the real register for the
598 unsigned getLO32DSPReg() const {
599 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
600 unsigned ClassID = Mips::LO32DSPRegClassID;
601 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
604 /// Coerce the register to CCR and return the real register for the
606 unsigned getCCRReg() const {
607 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
608 unsigned ClassID = Mips::CCRRegClassID;
609 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
612 /// Coerce the register to HWRegs and return the real register for the
614 unsigned getHWRegsReg() const {
615 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
616 unsigned ClassID = Mips::HWRegsRegClassID;
617 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
621 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
622 // Add as immediate when possible. Null MCExpr = 0.
624 Inst.addOperand(MCOperand::CreateImm(0));
625 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
626 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
628 Inst.addOperand(MCOperand::CreateExpr(Expr));
631 void addRegOperands(MCInst &Inst, unsigned N) const {
632 llvm_unreachable("Use a custom parser instead");
635 /// Render the operand to an MCInst as a GPR32
636 /// Asserts if the wrong number of operands are requested, or the operand
637 /// is not a k_RegisterIndex compatible with RegKind_GPR
638 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
639 assert(N == 1 && "Invalid number of operands!");
640 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
643 /// Render the operand to an MCInst as a GPR64
644 /// Asserts if the wrong number of operands are requested, or the operand
645 /// is not a k_RegisterIndex compatible with RegKind_GPR
646 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
647 assert(N == 1 && "Invalid number of operands!");
648 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
651 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
656 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
661 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
662 assert(N == 1 && "Invalid number of operands!");
663 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
664 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
665 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
666 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
670 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
671 assert(N == 1 && "Invalid number of operands!");
672 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
675 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
676 assert(N == 1 && "Invalid number of operands!");
677 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
680 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
681 assert(N == 1 && "Invalid number of operands!");
682 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
685 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
690 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
695 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
696 assert(N == 1 && "Invalid number of operands!");
697 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
700 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
701 assert(N == 1 && "Invalid number of operands!");
702 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
705 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
706 assert(N == 1 && "Invalid number of operands!");
707 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
710 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
711 assert(N == 1 && "Invalid number of operands!");
712 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
715 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
716 assert(N == 1 && "Invalid number of operands!");
717 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
720 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
725 void addImmOperands(MCInst &Inst, unsigned N) const {
726 assert(N == 1 && "Invalid number of operands!");
727 const MCExpr *Expr = getImm();
731 void addMemOperands(MCInst &Inst, unsigned N) const {
732 assert(N == 2 && "Invalid number of operands!");
734 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
736 const MCExpr *Expr = getMemOff();
740 bool isReg() const override {
741 // As a special case until we sort out the definition of div/divu, pretend
742 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
743 if (isGPRAsmReg() && RegIdx.Index == 0)
746 return Kind == k_PhysRegister;
748 bool isRegIdx() const { return Kind == k_RegisterIndex; }
749 bool isImm() const override { return Kind == k_Immediate; }
750 bool isConstantImm() const {
751 return isImm() && dyn_cast<MCConstantExpr>(getImm());
753 bool isToken() const override {
754 // Note: It's not possible to pretend that other operand kinds are tokens.
755 // The matcher emitter checks tokens first.
756 return Kind == k_Token;
758 bool isMem() const override { return Kind == k_Memory; }
759 bool isConstantMemOff() const {
760 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
762 template <unsigned Bits> bool isMemWithSimmOffset() const {
763 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
765 bool isInvNum() const { return Kind == k_Immediate; }
766 bool isLSAImm() const {
767 if (!isConstantImm())
769 int64_t Val = getConstantImm();
770 return 1 <= Val && Val <= 4;
773 StringRef getToken() const {
774 assert(Kind == k_Token && "Invalid access!");
775 return StringRef(Tok.Data, Tok.Length);
778 unsigned getReg() const override {
779 // As a special case until we sort out the definition of div/divu, pretend
780 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
781 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
782 RegIdx.Kind & RegKind_GPR)
783 return getGPR32Reg(); // FIXME: GPR64 too
785 assert(Kind == k_PhysRegister && "Invalid access!");
789 const MCExpr *getImm() const {
790 assert((Kind == k_Immediate) && "Invalid access!");
794 int64_t getConstantImm() const {
795 const MCExpr *Val = getImm();
796 return static_cast<const MCConstantExpr *>(Val)->getValue();
799 MipsOperand *getMemBase() const {
800 assert((Kind == k_Memory) && "Invalid access!");
804 const MCExpr *getMemOff() const {
805 assert((Kind == k_Memory) && "Invalid access!");
809 int64_t getConstantMemOff() const {
810 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
813 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
814 MipsAsmParser &Parser) {
815 auto Op = make_unique<MipsOperand>(k_Token, Parser);
816 Op->Tok.Data = Str.data();
817 Op->Tok.Length = Str.size();
823 /// Create a numeric register (e.g. $1). The exact register remains
824 /// unresolved until an instruction successfully matches
825 static std::unique_ptr<MipsOperand>
826 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
827 SMLoc E, MipsAsmParser &Parser) {
828 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
829 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
832 /// Create a register that is definitely a GPR.
833 /// This is typically only used for named registers such as $gp.
834 static std::unique_ptr<MipsOperand>
835 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
836 MipsAsmParser &Parser) {
837 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
840 /// Create a register that is definitely a FGR.
841 /// This is typically only used for named registers such as $f0.
842 static std::unique_ptr<MipsOperand>
843 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
844 MipsAsmParser &Parser) {
845 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
848 /// Create a register that is definitely an FCC.
849 /// This is typically only used for named registers such as $fcc0.
850 static std::unique_ptr<MipsOperand>
851 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
852 MipsAsmParser &Parser) {
853 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
856 /// Create a register that is definitely an ACC.
857 /// This is typically only used for named registers such as $ac0.
858 static std::unique_ptr<MipsOperand>
859 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
860 MipsAsmParser &Parser) {
861 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
864 /// Create a register that is definitely an MSA128.
865 /// This is typically only used for named registers such as $w0.
866 static std::unique_ptr<MipsOperand>
867 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
868 SMLoc E, MipsAsmParser &Parser) {
869 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
872 /// Create a register that is definitely an MSACtrl.
873 /// This is typically only used for named registers such as $msaaccess.
874 static std::unique_ptr<MipsOperand>
875 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
876 SMLoc E, MipsAsmParser &Parser) {
877 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
880 static std::unique_ptr<MipsOperand>
881 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
882 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
889 static std::unique_ptr<MipsOperand>
890 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
891 SMLoc E, MipsAsmParser &Parser) {
892 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
893 Op->Mem.Base = Base.release();
900 bool isGPRAsmReg() const {
901 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
903 bool isFGRAsmReg() const {
904 // AFGR64 is $0-$15 but we handle this in getAFGR64()
905 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
907 bool isHWRegsAsmReg() const {
908 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
910 bool isCCRAsmReg() const {
911 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
913 bool isFCCAsmReg() const {
914 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
916 if (!AsmParser.hasEightFccRegisters())
917 return RegIdx.Index == 0;
918 return RegIdx.Index <= 7;
920 bool isACCAsmReg() const {
921 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
923 bool isCOP2AsmReg() const {
924 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
926 bool isCOP3AsmReg() const {
927 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
929 bool isMSA128AsmReg() const {
930 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
932 bool isMSACtrlAsmReg() const {
933 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
936 /// getStartLoc - Get the location of the first token of this operand.
937 SMLoc getStartLoc() const override { return StartLoc; }
938 /// getEndLoc - Get the location of the last token of this operand.
939 SMLoc getEndLoc() const override { return EndLoc; }
941 virtual ~MipsOperand() {
949 case k_RegisterIndex:
955 void print(raw_ostream &OS) const override {
970 OS << "PhysReg<" << PhysReg.Num << ">";
972 case k_RegisterIndex:
973 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
980 }; // class MipsOperand
984 extern const MCInstrDesc MipsInsts[];
986 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
987 return MipsInsts[Opcode];
990 static bool hasShortDelaySlot(unsigned Opcode) {
994 case Mips::JALRS16_MM:
995 case Mips::BGEZALS_MM:
996 case Mips::BLTZALS_MM:
1003 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1004 SmallVectorImpl<MCInst> &Instructions) {
1005 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1009 if (MCID.isBranch() || MCID.isCall()) {
1010 const unsigned Opcode = Inst.getOpcode();
1020 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1021 Offset = Inst.getOperand(2);
1022 if (!Offset.isImm())
1023 break; // We'll deal with this situation later on when applying fixups.
1024 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1025 return Error(IDLoc, "branch target out of range");
1026 if (OffsetToAlignment(Offset.getImm(),
1027 1LL << (inMicroMipsMode() ? 1 : 2)))
1028 return Error(IDLoc, "branch to misaligned address");
1042 case Mips::BGEZAL_MM:
1043 case Mips::BLTZAL_MM:
1046 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1047 Offset = Inst.getOperand(1);
1048 if (!Offset.isImm())
1049 break; // We'll deal with this situation later on when applying fixups.
1050 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1051 return Error(IDLoc, "branch target out of range");
1052 if (OffsetToAlignment(Offset.getImm(),
1053 1LL << (inMicroMipsMode() ? 1 : 2)))
1054 return Error(IDLoc, "branch to misaligned address");
1059 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1060 // We still accept it but it is a normal nop.
1061 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1062 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1063 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1067 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1068 // If this instruction has a delay slot and .set reorder is active,
1069 // emit a NOP after it.
1070 Instructions.push_back(Inst);
1072 if (hasShortDelaySlot(Inst.getOpcode())) {
1073 NopInst.setOpcode(Mips::MOVE16_MM);
1074 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1075 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1077 NopInst.setOpcode(Mips::SLL);
1078 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1079 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1080 NopInst.addOperand(MCOperand::CreateImm(0));
1082 Instructions.push_back(NopInst);
1086 if (MCID.mayLoad() || MCID.mayStore()) {
1087 // Check the offset of memory operand, if it is a symbol
1088 // reference or immediate we may have to expand instructions.
1089 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1090 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1091 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1092 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1093 MCOperand &Op = Inst.getOperand(i);
1095 int MemOffset = Op.getImm();
1096 if (MemOffset < -32768 || MemOffset > 32767) {
1097 // Offset can't exceed 16bit value.
1098 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1101 } else if (Op.isExpr()) {
1102 const MCExpr *Expr = Op.getExpr();
1103 if (Expr->getKind() == MCExpr::SymbolRef) {
1104 const MCSymbolRefExpr *SR =
1105 static_cast<const MCSymbolRefExpr *>(Expr);
1106 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1108 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1111 } else if (!isEvaluated(Expr)) {
1112 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1120 // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1121 if (inMicroMipsMode()) {
1125 switch (Inst.getOpcode()) {
1128 case Mips::ADDIUS5_MM:
1129 Opnd = Inst.getOperand(2);
1131 return Error(IDLoc, "expected immediate operand kind");
1132 Imm = Opnd.getImm();
1133 if (Imm < -8 || Imm > 7)
1134 return Error(IDLoc, "immediate operand value out of range");
1139 if (needsExpansion(Inst))
1140 return expandInstruction(Inst, IDLoc, Instructions);
1142 Instructions.push_back(Inst);
1147 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1149 switch (Inst.getOpcode()) {
1150 case Mips::LoadImm32Reg:
1151 case Mips::LoadAddr32Imm:
1152 case Mips::LoadAddr32Reg:
1153 case Mips::LoadImm64Reg:
1160 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1161 SmallVectorImpl<MCInst> &Instructions) {
1162 switch (Inst.getOpcode()) {
1164 assert(0 && "unimplemented expansion");
1166 case Mips::LoadImm32Reg:
1167 return expandLoadImm(Inst, IDLoc, Instructions);
1168 case Mips::LoadImm64Reg:
1170 Error(IDLoc, "instruction requires a 64-bit architecture");
1173 return expandLoadImm(Inst, IDLoc, Instructions);
1174 case Mips::LoadAddr32Imm:
1175 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1176 case Mips::LoadAddr32Reg:
1177 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1182 template <bool PerformShift>
1183 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1184 SmallVectorImpl<MCInst> &Instructions) {
1187 tmpInst.setOpcode(Mips::DSLL);
1188 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1189 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1190 tmpInst.addOperand(MCOperand::CreateImm(16));
1191 tmpInst.setLoc(IDLoc);
1192 Instructions.push_back(tmpInst);
1195 tmpInst.setOpcode(Mips::ORi);
1196 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1197 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1198 tmpInst.addOperand(Operand);
1199 tmpInst.setLoc(IDLoc);
1200 Instructions.push_back(tmpInst);
1203 template <int Shift, bool PerformShift>
1204 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1205 SmallVectorImpl<MCInst> &Instructions) {
1206 createShiftOr<PerformShift>(
1207 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1208 IDLoc, Instructions);
1212 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1213 SmallVectorImpl<MCInst> &Instructions) {
1215 const MCOperand &ImmOp = Inst.getOperand(1);
1216 assert(ImmOp.isImm() && "expected immediate operand kind");
1217 const MCOperand &RegOp = Inst.getOperand(0);
1218 assert(RegOp.isReg() && "expected register operand kind");
1220 int64_t ImmValue = ImmOp.getImm();
1221 tmpInst.setLoc(IDLoc);
1222 // FIXME: gas has a special case for values that are 000...1111, which
1223 // becomes a li -1 and then a dsrl
1224 if (0 <= ImmValue && ImmValue <= 65535) {
1225 // For 0 <= j <= 65535.
1226 // li d,j => ori d,$zero,j
1227 tmpInst.setOpcode(Mips::ORi);
1228 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1229 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1230 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1231 Instructions.push_back(tmpInst);
1232 } else if (ImmValue < 0 && ImmValue >= -32768) {
1233 // For -32768 <= j < 0.
1234 // li d,j => addiu d,$zero,j
1235 tmpInst.setOpcode(Mips::ADDiu);
1236 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1237 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1238 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1239 Instructions.push_back(tmpInst);
1240 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1241 // For any value of j that is representable as a 32-bit integer, create
1243 // li d,j => lui d,hi16(j)
1245 tmpInst.setOpcode(Mips::LUi);
1246 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1247 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1248 Instructions.push_back(tmpInst);
1249 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1250 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1252 Error(IDLoc, "instruction requires a 64-bit architecture");
1256 // <------- lo32 ------>
1257 // <------- hi32 ------>
1258 // <- hi16 -> <- lo16 ->
1259 // _________________________________
1261 // | 16-bytes | 16-bytes | 16-bytes |
1262 // |__________|__________|__________|
1264 // For any value of j that is representable as a 48-bit integer, create
1266 // li d,j => lui d,hi16(j)
1267 // ori d,d,hi16(lo32(j))
1269 // ori d,d,lo16(lo32(j))
1270 tmpInst.setOpcode(Mips::LUi);
1271 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1273 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1274 Instructions.push_back(tmpInst);
1275 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1276 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1279 Error(IDLoc, "instruction requires a 64-bit architecture");
1283 // <------- hi32 ------> <------- lo32 ------>
1284 // <- hi16 -> <- lo16 ->
1285 // ___________________________________________
1287 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1288 // |__________|__________|__________|__________|
1290 // For any value of j that isn't representable as a 48-bit integer.
1291 // li d,j => lui d,hi16(j)
1292 // ori d,d,lo16(hi32(j))
1294 // ori d,d,hi16(lo32(j))
1296 // ori d,d,lo16(lo32(j))
1297 tmpInst.setOpcode(Mips::LUi);
1298 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1300 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1301 Instructions.push_back(tmpInst);
1302 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1303 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1304 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1310 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1311 SmallVectorImpl<MCInst> &Instructions) {
1313 const MCOperand &ImmOp = Inst.getOperand(2);
1314 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1315 "expected immediate operand kind");
1316 if (!ImmOp.isImm()) {
1317 expandLoadAddressSym(Inst, IDLoc, Instructions);
1320 const MCOperand &SrcRegOp = Inst.getOperand(1);
1321 assert(SrcRegOp.isReg() && "expected register operand kind");
1322 const MCOperand &DstRegOp = Inst.getOperand(0);
1323 assert(DstRegOp.isReg() && "expected register operand kind");
1324 int ImmValue = ImmOp.getImm();
1325 if (-32768 <= ImmValue && ImmValue <= 65535) {
1326 // For -32768 <= j <= 65535.
1327 // la d,j(s) => addiu d,s,j
1328 tmpInst.setOpcode(Mips::ADDiu);
1329 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1330 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1331 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1332 Instructions.push_back(tmpInst);
1334 // For any other value of j that is representable as a 32-bit integer.
1335 // la d,j(s) => lui d,hi16(j)
1338 tmpInst.setOpcode(Mips::LUi);
1339 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1340 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1341 Instructions.push_back(tmpInst);
1343 tmpInst.setOpcode(Mips::ORi);
1344 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1345 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1346 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1347 Instructions.push_back(tmpInst);
1349 tmpInst.setOpcode(Mips::ADDu);
1350 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1351 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1352 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1353 Instructions.push_back(tmpInst);
1359 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1360 SmallVectorImpl<MCInst> &Instructions) {
1362 const MCOperand &ImmOp = Inst.getOperand(1);
1363 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1364 "expected immediate operand kind");
1365 if (!ImmOp.isImm()) {
1366 expandLoadAddressSym(Inst, IDLoc, Instructions);
1369 const MCOperand &RegOp = Inst.getOperand(0);
1370 assert(RegOp.isReg() && "expected register operand kind");
1371 int ImmValue = ImmOp.getImm();
1372 if (-32768 <= ImmValue && ImmValue <= 65535) {
1373 // For -32768 <= j <= 65535.
1374 // la d,j => addiu d,$zero,j
1375 tmpInst.setOpcode(Mips::ADDiu);
1376 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1377 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1378 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1379 Instructions.push_back(tmpInst);
1381 // For any other value of j that is representable as a 32-bit integer.
1382 // la 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);
1389 tmpInst.setOpcode(Mips::ORi);
1390 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1391 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1392 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1393 Instructions.push_back(tmpInst);
1399 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1400 SmallVectorImpl<MCInst> &Instructions) {
1401 // FIXME: If we do have a valid at register to use, we should generate a
1402 // slightly shorter sequence here.
1404 int ExprOperandNo = 1;
1405 // Sometimes the assembly parser will get the immediate expression as
1406 // a $zero + an immediate.
1407 if (Inst.getNumOperands() == 3) {
1408 assert(Inst.getOperand(1).getReg() ==
1409 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1412 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1413 assert(SymOp.isExpr() && "expected symbol operand kind");
1414 const MCOperand &RegOp = Inst.getOperand(0);
1415 unsigned RegNo = RegOp.getReg();
1416 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1417 const MCSymbolRefExpr *HiExpr =
1418 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1419 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1420 const MCSymbolRefExpr *LoExpr =
1421 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1422 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1424 // If it's a 64-bit architecture, expand to:
1425 // la d,sym => lui d,highest(sym)
1426 // ori d,d,higher(sym)
1428 // ori d,d,hi16(sym)
1430 // ori d,d,lo16(sym)
1431 const MCSymbolRefExpr *HighestExpr =
1432 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1433 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1434 const MCSymbolRefExpr *HigherExpr =
1435 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1436 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1438 tmpInst.setOpcode(Mips::LUi);
1439 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1440 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1441 Instructions.push_back(tmpInst);
1443 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1445 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1447 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1450 // Otherwise, expand to:
1451 // la d,sym => lui d,hi16(sym)
1452 // ori d,d,lo16(sym)
1453 tmpInst.setOpcode(Mips::LUi);
1454 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1455 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1456 Instructions.push_back(tmpInst);
1458 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1463 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1464 SmallVectorImpl<MCInst> &Instructions,
1465 bool isLoad, bool isImmOpnd) {
1466 const MCSymbolRefExpr *SR;
1468 unsigned ImmOffset, HiOffset, LoOffset;
1469 const MCExpr *ExprOffset;
1471 // 1st operand is either the source or destination register.
1472 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1473 unsigned RegOpNum = Inst.getOperand(0).getReg();
1474 // 2nd operand is the base register.
1475 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1476 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1477 // 3rd operand is either an immediate or expression.
1479 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1480 ImmOffset = Inst.getOperand(2).getImm();
1481 LoOffset = ImmOffset & 0x0000ffff;
1482 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1483 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1484 if (LoOffset & 0x8000)
1487 ExprOffset = Inst.getOperand(2).getExpr();
1488 // All instructions will have the same location.
1489 TempInst.setLoc(IDLoc);
1490 // These are some of the types of expansions we perform here:
1491 // 1) lw $8, sym => lui $8, %hi(sym)
1492 // lw $8, %lo(sym)($8)
1493 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1495 // lw $8, %lo(offset)($9)
1496 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1498 // lw $8, %lo(offset)($at)
1499 // 4) sw $8, sym => lui $at, %hi(sym)
1500 // sw $8, %lo(sym)($at)
1501 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1503 // sw $8, %lo(offset)($at)
1504 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1505 // ldc1 $f0, %lo(sym)($at)
1507 // For load instructions we can use the destination register as a temporary
1508 // if base and dst are different (examples 1 and 2) and if the base register
1509 // is general purpose otherwise we must use $at (example 6) and error if it's
1510 // not available. For stores we must use $at (examples 4 and 5) because we
1511 // must not clobber the source register setting up the offset.
1512 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1513 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1514 unsigned RegClassIDOp0 =
1515 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1516 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1517 (RegClassIDOp0 == Mips::GPR64RegClassID);
1518 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1519 TmpRegNum = RegOpNum;
1521 int AT = getATReg(IDLoc);
1522 // At this point we need AT to perform the expansions and we exit if it is
1527 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1530 TempInst.setOpcode(Mips::LUi);
1531 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1533 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1535 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1536 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1537 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1538 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1540 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1542 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1543 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1546 // Add the instruction to the list.
1547 Instructions.push_back(TempInst);
1548 // Prepare TempInst for next instruction.
1550 // Add temp register to base.
1551 TempInst.setOpcode(Mips::ADDu);
1552 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1553 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1554 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1555 Instructions.push_back(TempInst);
1557 // And finally, create original instruction with low part
1558 // of offset and new base.
1559 TempInst.setOpcode(Inst.getOpcode());
1560 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1561 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1563 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1565 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1566 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1567 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1569 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1571 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1572 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1575 Instructions.push_back(TempInst);
1579 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1580 // As described by the Mips32r2 spec, the registers Rd and Rs for
1581 // jalr.hb must be different.
1582 unsigned Opcode = Inst.getOpcode();
1584 if (Opcode == Mips::JALR_HB &&
1585 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1586 return Match_RequiresDifferentSrcAndDst;
1588 return Match_Success;
1591 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1592 OperandVector &Operands,
1594 uint64_t &ErrorInfo,
1595 bool MatchingInlineAsm) {
1598 SmallVector<MCInst, 8> Instructions;
1599 unsigned MatchResult =
1600 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1602 switch (MatchResult) {
1605 case Match_Success: {
1606 if (processInstruction(Inst, IDLoc, Instructions))
1608 for (unsigned i = 0; i < Instructions.size(); i++)
1609 Out.EmitInstruction(Instructions[i], STI);
1612 case Match_MissingFeature:
1613 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1615 case Match_InvalidOperand: {
1616 SMLoc ErrorLoc = IDLoc;
1617 if (ErrorInfo != ~0ULL) {
1618 if (ErrorInfo >= Operands.size())
1619 return Error(IDLoc, "too few operands for instruction");
1621 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1622 if (ErrorLoc == SMLoc())
1626 return Error(ErrorLoc, "invalid operand for instruction");
1628 case Match_MnemonicFail:
1629 return Error(IDLoc, "invalid instruction");
1630 case Match_RequiresDifferentSrcAndDst:
1631 return Error(IDLoc, "source and destination must be different");
1636 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1637 if ((RegIndex != 0) &&
1638 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1640 Warning(Loc, "used $at without \".set noat\"");
1642 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1643 Twine(RegIndex) + "\"");
1648 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1649 SMRange Range, bool ShowColors) {
1650 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1651 Range, SMFixIt(Range, FixMsg),
1655 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1658 CC = StringSwitch<unsigned>(Name)
1694 if (!(isABI_N32() || isABI_N64()))
1697 if (12 <= CC && CC <= 15) {
1698 // Name is one of t4-t7
1699 AsmToken RegTok = getLexer().peekTok();
1700 SMRange RegRange = RegTok.getLocRange();
1702 StringRef FixedName = StringSwitch<StringRef>(Name)
1708 assert(FixedName != "" && "Register name is not one of t4-t7.");
1710 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1711 "Did you mean $" + FixedName + "?", RegRange);
1714 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1715 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1716 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1717 if (8 <= CC && CC <= 11)
1721 CC = StringSwitch<unsigned>(Name)
1733 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1735 if (Name[0] == 'f') {
1736 StringRef NumString = Name.substr(1);
1738 if (NumString.getAsInteger(10, IntVal))
1739 return -1; // This is not an integer.
1740 if (IntVal > 31) // Maximum index for fpu register.
1747 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1749 if (Name.startswith("fcc")) {
1750 StringRef NumString = Name.substr(3);
1752 if (NumString.getAsInteger(10, IntVal))
1753 return -1; // This is not an integer.
1754 if (IntVal > 7) // There are only 8 fcc registers.
1761 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1763 if (Name.startswith("ac")) {
1764 StringRef NumString = Name.substr(2);
1766 if (NumString.getAsInteger(10, IntVal))
1767 return -1; // This is not an integer.
1768 if (IntVal > 3) // There are only 3 acc registers.
1775 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1778 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1787 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1790 CC = StringSwitch<unsigned>(Name)
1793 .Case("msaaccess", 2)
1795 .Case("msamodify", 4)
1796 .Case("msarequest", 5)
1798 .Case("msaunmap", 7)
1804 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1812 int MipsAsmParser::getATReg(SMLoc Loc) {
1813 int AT = AssemblerOptions.back()->getATRegNum();
1815 reportParseError(Loc,
1816 "pseudo-instruction requires $at, which is not available");
1820 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1821 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1824 unsigned MipsAsmParser::getGPR(int RegNo) {
1825 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1829 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1831 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1834 return getReg(RegClass, RegNum);
1837 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1838 DEBUG(dbgs() << "parseOperand\n");
1840 // Check if the current operand has a custom associated parser, if so, try to
1841 // custom parse the operand, or fallback to the general approach.
1842 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1843 if (ResTy == MatchOperand_Success)
1845 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1846 // there was a match, but an error occurred, in which case, just return that
1847 // the operand parsing failed.
1848 if (ResTy == MatchOperand_ParseFail)
1851 DEBUG(dbgs() << ".. Generic Parser\n");
1853 switch (getLexer().getKind()) {
1855 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1857 case AsmToken::Dollar: {
1858 // Parse the register.
1859 SMLoc S = Parser.getTok().getLoc();
1861 // Almost all registers have been parsed by custom parsers. There is only
1862 // one exception to this. $zero (and it's alias $0) will reach this point
1863 // for div, divu, and similar instructions because it is not an operand
1864 // to the instruction definition but an explicit register. Special case
1865 // this situation for now.
1866 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1869 // Maybe it is a symbol reference.
1870 StringRef Identifier;
1871 if (Parser.parseIdentifier(Identifier))
1874 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1875 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1876 // Otherwise create a symbol reference.
1878 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1880 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1883 // Else drop to expression parsing.
1884 case AsmToken::LParen:
1885 case AsmToken::Minus:
1886 case AsmToken::Plus:
1887 case AsmToken::Integer:
1888 case AsmToken::Tilde:
1889 case AsmToken::String: {
1890 DEBUG(dbgs() << ".. generic integer\n");
1891 OperandMatchResultTy ResTy = parseImm(Operands);
1892 return ResTy != MatchOperand_Success;
1894 case AsmToken::Percent: {
1895 // It is a symbol reference or constant expression.
1896 const MCExpr *IdVal;
1897 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1898 if (parseRelocOperand(IdVal))
1901 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1903 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1905 } // case AsmToken::Percent
1906 } // switch(getLexer().getKind())
1910 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1911 StringRef RelocStr) {
1913 // Check the type of the expression.
1914 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1915 // It's a constant, evaluate reloc value.
1917 switch (getVariantKind(RelocStr)) {
1918 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1919 // Get the 1st 16-bits.
1920 Val = MCE->getValue() & 0xffff;
1922 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1923 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1924 // 16 bits being negative.
1925 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1927 case MCSymbolRefExpr::VK_Mips_HIGHER:
1928 // Get the 3rd 16-bits.
1929 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1931 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1932 // Get the 4th 16-bits.
1933 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1936 report_fatal_error("unsupported reloc value");
1938 return MCConstantExpr::Create(Val, getContext());
1941 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1942 // It's a symbol, create a symbolic expression from the symbol.
1943 StringRef Symbol = MSRE->getSymbol().getName();
1944 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1945 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1949 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1950 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1952 // Try to create target expression.
1953 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1954 return MipsMCExpr::Create(VK, Expr, getContext());
1956 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1957 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1958 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1962 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1963 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1964 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1967 // Just return the original expression.
1971 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1973 switch (Expr->getKind()) {
1974 case MCExpr::Constant:
1976 case MCExpr::SymbolRef:
1977 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1978 case MCExpr::Binary:
1979 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1980 if (!isEvaluated(BE->getLHS()))
1982 return isEvaluated(BE->getRHS());
1985 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1986 case MCExpr::Target:
1992 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1993 Parser.Lex(); // Eat the % token.
1994 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1995 if (Tok.isNot(AsmToken::Identifier))
1998 std::string Str = Tok.getIdentifier().str();
2000 Parser.Lex(); // Eat the identifier.
2001 // Now make an expression from the rest of the operand.
2002 const MCExpr *IdVal;
2005 if (getLexer().getKind() == AsmToken::LParen) {
2007 Parser.Lex(); // Eat the '(' token.
2008 if (getLexer().getKind() == AsmToken::Percent) {
2009 Parser.Lex(); // Eat the % token.
2010 const AsmToken &nextTok = Parser.getTok();
2011 if (nextTok.isNot(AsmToken::Identifier))
2014 Str += nextTok.getIdentifier();
2015 Parser.Lex(); // Eat the identifier.
2016 if (getLexer().getKind() != AsmToken::LParen)
2021 if (getParser().parseParenExpression(IdVal, EndLoc))
2024 while (getLexer().getKind() == AsmToken::RParen)
2025 Parser.Lex(); // Eat the ')' token.
2028 return true; // Parenthesis must follow the relocation operand.
2030 Res = evaluateRelocExpr(IdVal, Str);
2034 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2036 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2037 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2038 if (ResTy == MatchOperand_Success) {
2039 assert(Operands.size() == 1);
2040 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2041 StartLoc = Operand.getStartLoc();
2042 EndLoc = Operand.getEndLoc();
2044 // AFAIK, we only support numeric registers and named GPR's in CFI
2046 // Don't worry about eating tokens before failing. Using an unrecognised
2047 // register is a parse error.
2048 if (Operand.isGPRAsmReg()) {
2049 // Resolve to GPR32 or GPR64 appropriately.
2050 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2053 return (RegNo == (unsigned)-1);
2056 assert(Operands.size() == 0);
2057 return (RegNo == (unsigned)-1);
2060 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2064 while (getLexer().getKind() == AsmToken::LParen)
2067 switch (getLexer().getKind()) {
2070 case AsmToken::Identifier:
2071 case AsmToken::LParen:
2072 case AsmToken::Integer:
2073 case AsmToken::Minus:
2074 case AsmToken::Plus:
2076 Result = getParser().parseParenExpression(Res, S);
2078 Result = (getParser().parseExpression(Res));
2079 while (getLexer().getKind() == AsmToken::RParen)
2082 case AsmToken::Percent:
2083 Result = parseRelocOperand(Res);
2088 MipsAsmParser::OperandMatchResultTy
2089 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2090 DEBUG(dbgs() << "parseMemOperand\n");
2091 const MCExpr *IdVal = nullptr;
2093 bool isParenExpr = false;
2094 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2095 // First operand is the offset.
2096 S = Parser.getTok().getLoc();
2098 if (getLexer().getKind() == AsmToken::LParen) {
2103 if (getLexer().getKind() != AsmToken::Dollar) {
2104 if (parseMemOffset(IdVal, isParenExpr))
2105 return MatchOperand_ParseFail;
2107 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2108 if (Tok.isNot(AsmToken::LParen)) {
2109 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2110 if (Mnemonic.getToken() == "la") {
2112 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2113 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2114 return MatchOperand_Success;
2116 if (Tok.is(AsmToken::EndOfStatement)) {
2118 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2120 // Zero register assumed, add a memory operand with ZERO as its base.
2121 // "Base" will be managed by k_Memory.
2122 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2125 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2126 return MatchOperand_Success;
2128 Error(Parser.getTok().getLoc(), "'(' expected");
2129 return MatchOperand_ParseFail;
2132 Parser.Lex(); // Eat the '(' token.
2135 Res = parseAnyRegister(Operands);
2136 if (Res != MatchOperand_Success)
2139 if (Parser.getTok().isNot(AsmToken::RParen)) {
2140 Error(Parser.getTok().getLoc(), "')' expected");
2141 return MatchOperand_ParseFail;
2144 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2146 Parser.Lex(); // Eat the ')' token.
2149 IdVal = MCConstantExpr::Create(0, getContext());
2151 // Replace the register operand with the memory operand.
2152 std::unique_ptr<MipsOperand> op(
2153 static_cast<MipsOperand *>(Operands.back().release()));
2154 // Remove the register from the operands.
2155 // "op" will be managed by k_Memory.
2156 Operands.pop_back();
2157 // Add the memory operand.
2158 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2160 if (IdVal->EvaluateAsAbsolute(Imm))
2161 IdVal = MCConstantExpr::Create(Imm, getContext());
2162 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2163 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2167 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2168 return MatchOperand_Success;
2171 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2173 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2175 SMLoc S = Parser.getTok().getLoc();
2177 if (Sym->isVariable())
2178 Expr = Sym->getVariableValue();
2181 if (Expr->getKind() == MCExpr::SymbolRef) {
2182 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2183 StringRef DefSymbol = Ref->getSymbol().getName();
2184 if (DefSymbol.startswith("$")) {
2185 OperandMatchResultTy ResTy =
2186 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2187 if (ResTy == MatchOperand_Success) {
2190 } else if (ResTy == MatchOperand_ParseFail)
2191 llvm_unreachable("Should never ParseFail");
2194 } else if (Expr->getKind() == MCExpr::Constant) {
2196 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2198 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2205 MipsAsmParser::OperandMatchResultTy
2206 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2207 StringRef Identifier,
2209 int Index = matchCPURegisterName(Identifier);
2211 Operands.push_back(MipsOperand::createGPRReg(
2212 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2213 return MatchOperand_Success;
2216 Index = matchFPURegisterName(Identifier);
2218 Operands.push_back(MipsOperand::createFGRReg(
2219 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2220 return MatchOperand_Success;
2223 Index = matchFCCRegisterName(Identifier);
2225 Operands.push_back(MipsOperand::createFCCReg(
2226 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2227 return MatchOperand_Success;
2230 Index = matchACRegisterName(Identifier);
2232 Operands.push_back(MipsOperand::createACCReg(
2233 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2234 return MatchOperand_Success;
2237 Index = matchMSA128RegisterName(Identifier);
2239 Operands.push_back(MipsOperand::createMSA128Reg(
2240 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2241 return MatchOperand_Success;
2244 Index = matchMSA128CtrlRegisterName(Identifier);
2246 Operands.push_back(MipsOperand::createMSACtrlReg(
2247 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2248 return MatchOperand_Success;
2251 return MatchOperand_NoMatch;
2254 MipsAsmParser::OperandMatchResultTy
2255 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2256 auto Token = Parser.getLexer().peekTok(false);
2258 if (Token.is(AsmToken::Identifier)) {
2259 DEBUG(dbgs() << ".. identifier\n");
2260 StringRef Identifier = Token.getIdentifier();
2261 OperandMatchResultTy ResTy =
2262 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2264 } else if (Token.is(AsmToken::Integer)) {
2265 DEBUG(dbgs() << ".. integer\n");
2266 Operands.push_back(MipsOperand::createNumericReg(
2267 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2269 return MatchOperand_Success;
2272 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2274 return MatchOperand_NoMatch;
2277 MipsAsmParser::OperandMatchResultTy
2278 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2279 DEBUG(dbgs() << "parseAnyRegister\n");
2281 auto Token = Parser.getTok();
2283 SMLoc S = Token.getLoc();
2285 if (Token.isNot(AsmToken::Dollar)) {
2286 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2287 if (Token.is(AsmToken::Identifier)) {
2288 if (searchSymbolAlias(Operands))
2289 return MatchOperand_Success;
2291 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2292 return MatchOperand_NoMatch;
2294 DEBUG(dbgs() << ".. $\n");
2296 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2297 if (ResTy == MatchOperand_Success) {
2299 Parser.Lex(); // identifier
2304 MipsAsmParser::OperandMatchResultTy
2305 MipsAsmParser::parseImm(OperandVector &Operands) {
2306 switch (getLexer().getKind()) {
2308 return MatchOperand_NoMatch;
2309 case AsmToken::LParen:
2310 case AsmToken::Minus:
2311 case AsmToken::Plus:
2312 case AsmToken::Integer:
2313 case AsmToken::Tilde:
2314 case AsmToken::String:
2318 const MCExpr *IdVal;
2319 SMLoc S = Parser.getTok().getLoc();
2320 if (getParser().parseExpression(IdVal))
2321 return MatchOperand_ParseFail;
2323 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2324 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2325 return MatchOperand_Success;
2328 MipsAsmParser::OperandMatchResultTy
2329 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2330 DEBUG(dbgs() << "parseJumpTarget\n");
2332 SMLoc S = getLexer().getLoc();
2334 // Integers and expressions are acceptable
2335 OperandMatchResultTy ResTy = parseImm(Operands);
2336 if (ResTy != MatchOperand_NoMatch)
2339 // Registers are a valid target and have priority over symbols.
2340 ResTy = parseAnyRegister(Operands);
2341 if (ResTy != MatchOperand_NoMatch)
2344 const MCExpr *Expr = nullptr;
2345 if (Parser.parseExpression(Expr)) {
2346 // We have no way of knowing if a symbol was consumed so we must ParseFail
2347 return MatchOperand_ParseFail;
2350 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2351 return MatchOperand_Success;
2354 MipsAsmParser::OperandMatchResultTy
2355 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2356 const MCExpr *IdVal;
2357 // If the first token is '$' we may have register operand.
2358 if (Parser.getTok().is(AsmToken::Dollar))
2359 return MatchOperand_NoMatch;
2360 SMLoc S = Parser.getTok().getLoc();
2361 if (getParser().parseExpression(IdVal))
2362 return MatchOperand_ParseFail;
2363 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2364 assert(MCE && "Unexpected MCExpr type.");
2365 int64_t Val = MCE->getValue();
2366 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2367 Operands.push_back(MipsOperand::CreateImm(
2368 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2369 return MatchOperand_Success;
2372 MipsAsmParser::OperandMatchResultTy
2373 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2374 switch (getLexer().getKind()) {
2376 return MatchOperand_NoMatch;
2377 case AsmToken::LParen:
2378 case AsmToken::Plus:
2379 case AsmToken::Minus:
2380 case AsmToken::Integer:
2385 SMLoc S = Parser.getTok().getLoc();
2387 if (getParser().parseExpression(Expr))
2388 return MatchOperand_ParseFail;
2391 if (!Expr->EvaluateAsAbsolute(Val)) {
2392 Error(S, "expected immediate value");
2393 return MatchOperand_ParseFail;
2396 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2397 // and because the CPU always adds one to the immediate field, the allowed
2398 // range becomes 1..4. We'll only check the range here and will deal
2399 // with the addition/subtraction when actually decoding/encoding
2401 if (Val < 1 || Val > 4) {
2402 Error(S, "immediate not in range (1..4)");
2403 return MatchOperand_ParseFail;
2407 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2408 return MatchOperand_Success;
2411 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2413 MCSymbolRefExpr::VariantKind VK =
2414 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2415 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2416 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2417 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2418 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2419 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2420 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2421 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2422 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2423 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2424 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2425 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2426 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2427 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2428 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2429 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2430 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2431 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2432 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2433 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2434 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2435 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2436 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2437 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2438 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2439 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2440 .Default(MCSymbolRefExpr::VK_None);
2442 assert(VK != MCSymbolRefExpr::VK_None);
2447 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2449 /// ::= '(', register, ')'
2450 /// handle it before we iterate so we don't get tripped up by the lack of
2452 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2453 if (getLexer().is(AsmToken::LParen)) {
2455 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2457 if (parseOperand(Operands, Name)) {
2458 SMLoc Loc = getLexer().getLoc();
2459 Parser.eatToEndOfStatement();
2460 return Error(Loc, "unexpected token in argument list");
2462 if (Parser.getTok().isNot(AsmToken::RParen)) {
2463 SMLoc Loc = getLexer().getLoc();
2464 Parser.eatToEndOfStatement();
2465 return Error(Loc, "unexpected token, expected ')'");
2468 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2474 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2475 /// either one of these.
2476 /// ::= '[', register, ']'
2477 /// ::= '[', integer, ']'
2478 /// handle it before we iterate so we don't get tripped up by the lack of
2480 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2481 OperandVector &Operands) {
2482 if (getLexer().is(AsmToken::LBrac)) {
2484 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2486 if (parseOperand(Operands, Name)) {
2487 SMLoc Loc = getLexer().getLoc();
2488 Parser.eatToEndOfStatement();
2489 return Error(Loc, "unexpected token in argument list");
2491 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2492 SMLoc Loc = getLexer().getLoc();
2493 Parser.eatToEndOfStatement();
2494 return Error(Loc, "unexpected token, expected ']'");
2497 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2503 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2504 SMLoc NameLoc, OperandVector &Operands) {
2505 DEBUG(dbgs() << "ParseInstruction\n");
2507 // We have reached first instruction, module directive are now forbidden.
2508 getTargetStreamer().forbidModuleDirective();
2510 // Check if we have valid mnemonic
2511 if (!mnemonicIsValid(Name, 0)) {
2512 Parser.eatToEndOfStatement();
2513 return Error(NameLoc, "unknown instruction");
2515 // First operand in MCInst is instruction mnemonic.
2516 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2518 // Read the remaining operands.
2519 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2520 // Read the first operand.
2521 if (parseOperand(Operands, Name)) {
2522 SMLoc Loc = getLexer().getLoc();
2523 Parser.eatToEndOfStatement();
2524 return Error(Loc, "unexpected token in argument list");
2526 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2528 // AFAIK, parenthesis suffixes are never on the first operand
2530 while (getLexer().is(AsmToken::Comma)) {
2531 Parser.Lex(); // Eat the comma.
2532 // Parse and remember the operand.
2533 if (parseOperand(Operands, Name)) {
2534 SMLoc Loc = getLexer().getLoc();
2535 Parser.eatToEndOfStatement();
2536 return Error(Loc, "unexpected token in argument list");
2538 // Parse bracket and parenthesis suffixes before we iterate
2539 if (getLexer().is(AsmToken::LBrac)) {
2540 if (parseBracketSuffix(Name, Operands))
2542 } else if (getLexer().is(AsmToken::LParen) &&
2543 parseParenSuffix(Name, Operands))
2547 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2548 SMLoc Loc = getLexer().getLoc();
2549 Parser.eatToEndOfStatement();
2550 return Error(Loc, "unexpected token in argument list");
2552 Parser.Lex(); // Consume the EndOfStatement.
2556 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2557 SMLoc Loc = getLexer().getLoc();
2558 Parser.eatToEndOfStatement();
2559 return Error(Loc, ErrorMsg);
2562 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2563 return Error(Loc, ErrorMsg);
2566 bool MipsAsmParser::parseSetNoAtDirective() {
2567 // Line should look like: ".set noat".
2569 AssemblerOptions.back()->setATReg(0);
2572 // If this is not the end of the statement, report an error.
2573 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2574 reportParseError("unexpected token, expected end of statement");
2577 Parser.Lex(); // Consume the EndOfStatement.
2581 bool MipsAsmParser::parseSetAtDirective() {
2582 // Line can be .set at - defaults to $1
2586 if (getLexer().is(AsmToken::EndOfStatement)) {
2587 AssemblerOptions.back()->setATReg(1);
2588 Parser.Lex(); // Consume the EndOfStatement.
2590 } else if (getLexer().is(AsmToken::Equal)) {
2591 getParser().Lex(); // Eat the '='.
2592 if (getLexer().isNot(AsmToken::Dollar)) {
2593 reportParseError("unexpected token, expected dollar sign '$'");
2596 Parser.Lex(); // Eat the '$'.
2597 const AsmToken &Reg = Parser.getTok();
2598 if (Reg.is(AsmToken::Identifier)) {
2599 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2600 } else if (Reg.is(AsmToken::Integer)) {
2601 AtRegNo = Reg.getIntVal();
2603 reportParseError("unexpected token, expected identifier or integer");
2607 if (AtRegNo < 0 || AtRegNo > 31) {
2608 reportParseError("unexpected token in statement");
2612 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2613 reportParseError("invalid register");
2616 getParser().Lex(); // Eat the register.
2618 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2619 reportParseError("unexpected token, expected end of statement");
2622 Parser.Lex(); // Consume the EndOfStatement.
2625 reportParseError("unexpected token in statement");
2630 bool MipsAsmParser::parseSetReorderDirective() {
2632 // If this is not the end of the statement, report an error.
2633 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2634 reportParseError("unexpected token, expected end of statement");
2637 AssemblerOptions.back()->setReorder();
2638 getTargetStreamer().emitDirectiveSetReorder();
2639 Parser.Lex(); // Consume the EndOfStatement.
2643 bool MipsAsmParser::parseSetNoReorderDirective() {
2645 // If this is not the end of the statement, report an error.
2646 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2647 reportParseError("unexpected token, expected end of statement");
2650 AssemblerOptions.back()->setNoReorder();
2651 getTargetStreamer().emitDirectiveSetNoReorder();
2652 Parser.Lex(); // Consume the EndOfStatement.
2656 bool MipsAsmParser::parseSetMacroDirective() {
2658 // If this is not the end of the statement, report an error.
2659 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2660 reportParseError("unexpected token, expected end of statement");
2663 AssemblerOptions.back()->setMacro();
2664 Parser.Lex(); // Consume the EndOfStatement.
2668 bool MipsAsmParser::parseSetNoMacroDirective() {
2670 // If this is not the end of the statement, report an error.
2671 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2672 reportParseError("unexpected token, expected end of statement");
2675 if (AssemblerOptions.back()->isReorder()) {
2676 reportParseError("`noreorder' must be set before `nomacro'");
2679 AssemblerOptions.back()->setNoMacro();
2680 Parser.Lex(); // Consume the EndOfStatement.
2684 bool MipsAsmParser::parseSetMsaDirective() {
2687 // If this is not the end of the statement, report an error.
2688 if (getLexer().isNot(AsmToken::EndOfStatement))
2689 return reportParseError("unexpected token, expected end of statement");
2691 setFeatureBits(Mips::FeatureMSA, "msa");
2692 getTargetStreamer().emitDirectiveSetMsa();
2696 bool MipsAsmParser::parseSetNoMsaDirective() {
2699 // If this is not the end of the statement, report an error.
2700 if (getLexer().isNot(AsmToken::EndOfStatement))
2701 return reportParseError("unexpected token, expected end of statement");
2703 clearFeatureBits(Mips::FeatureMSA, "msa");
2704 getTargetStreamer().emitDirectiveSetNoMsa();
2708 bool MipsAsmParser::parseSetNoDspDirective() {
2709 Parser.Lex(); // Eat "nodsp".
2711 // If this is not the end of the statement, report an error.
2712 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2713 reportParseError("unexpected token, expected end of statement");
2717 clearFeatureBits(Mips::FeatureDSP, "dsp");
2718 getTargetStreamer().emitDirectiveSetNoDsp();
2722 bool MipsAsmParser::parseSetNoMips16Directive() {
2724 // If this is not the end of the statement, report an error.
2725 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2726 reportParseError("unexpected token, expected end of statement");
2729 // For now do nothing.
2730 Parser.Lex(); // Consume the EndOfStatement.
2734 bool MipsAsmParser::parseSetFpDirective() {
2735 MipsABIFlagsSection::FpABIKind FpAbiVal;
2736 // Line can be: .set fp=32
2739 Parser.Lex(); // Eat fp token
2740 AsmToken Tok = Parser.getTok();
2741 if (Tok.isNot(AsmToken::Equal)) {
2742 reportParseError("unexpected token, expected equals sign '='");
2745 Parser.Lex(); // Eat '=' token.
2746 Tok = Parser.getTok();
2748 if (!parseFpABIValue(FpAbiVal, ".set"))
2751 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2752 reportParseError("unexpected token, expected end of statement");
2755 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2756 Parser.Lex(); // Consume the EndOfStatement.
2760 bool MipsAsmParser::parseSetPopDirective() {
2761 SMLoc Loc = getLexer().getLoc();
2764 if (getLexer().isNot(AsmToken::EndOfStatement))
2765 return reportParseError("unexpected token, expected end of statement");
2767 // Always keep an element on the options "stack" to prevent the user
2768 // from changing the initial options. This is how we remember them.
2769 if (AssemblerOptions.size() == 2)
2770 return reportParseError(Loc, ".set pop with no .set push");
2772 AssemblerOptions.pop_back();
2773 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2775 getTargetStreamer().emitDirectiveSetPop();
2779 bool MipsAsmParser::parseSetPushDirective() {
2781 if (getLexer().isNot(AsmToken::EndOfStatement))
2782 return reportParseError("unexpected token, expected end of statement");
2784 // Create a copy of the current assembler options environment and push it.
2785 AssemblerOptions.push_back(
2786 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2788 getTargetStreamer().emitDirectiveSetPush();
2792 bool MipsAsmParser::parseSetAssignment() {
2794 const MCExpr *Value;
2796 if (Parser.parseIdentifier(Name))
2797 reportParseError("expected identifier after .set");
2799 if (getLexer().isNot(AsmToken::Comma))
2800 return reportParseError("unexpected token, expected comma");
2803 if (Parser.parseExpression(Value))
2804 return reportParseError("expected valid expression after comma");
2806 // Check if the Name already exists as a symbol.
2807 MCSymbol *Sym = getContext().LookupSymbol(Name);
2809 return reportParseError("symbol already defined");
2810 Sym = getContext().GetOrCreateSymbol(Name);
2811 Sym->setVariableValue(Value);
2816 bool MipsAsmParser::parseSetMips0Directive() {
2818 if (getLexer().isNot(AsmToken::EndOfStatement))
2819 return reportParseError("unexpected token, expected end of statement");
2821 // Reset assembler options to their initial values.
2822 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2823 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2825 getTargetStreamer().emitDirectiveSetMips0();
2829 bool MipsAsmParser::parseSetArchDirective() {
2831 if (getLexer().isNot(AsmToken::Equal))
2832 return reportParseError("unexpected token, expected equals sign");
2836 if (Parser.parseIdentifier(Arch))
2837 return reportParseError("expected arch identifier");
2839 StringRef ArchFeatureName =
2840 StringSwitch<StringRef>(Arch)
2841 .Case("mips1", "mips1")
2842 .Case("mips2", "mips2")
2843 .Case("mips3", "mips3")
2844 .Case("mips4", "mips4")
2845 .Case("mips5", "mips5")
2846 .Case("mips32", "mips32")
2847 .Case("mips32r2", "mips32r2")
2848 .Case("mips32r6", "mips32r6")
2849 .Case("mips64", "mips64")
2850 .Case("mips64r2", "mips64r2")
2851 .Case("mips64r6", "mips64r6")
2852 .Case("cnmips", "cnmips")
2853 .Case("r4000", "mips3") // This is an implementation of Mips3.
2856 if (ArchFeatureName.empty())
2857 return reportParseError("unsupported architecture");
2859 selectArch(ArchFeatureName);
2860 getTargetStreamer().emitDirectiveSetArch(Arch);
2864 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2866 if (getLexer().isNot(AsmToken::EndOfStatement))
2867 return reportParseError("unexpected token, expected end of statement");
2871 llvm_unreachable("Unimplemented feature");
2872 case Mips::FeatureDSP:
2873 setFeatureBits(Mips::FeatureDSP, "dsp");
2874 getTargetStreamer().emitDirectiveSetDsp();
2876 case Mips::FeatureMicroMips:
2877 getTargetStreamer().emitDirectiveSetMicroMips();
2879 case Mips::FeatureMips16:
2880 getTargetStreamer().emitDirectiveSetMips16();
2882 case Mips::FeatureMips1:
2883 selectArch("mips1");
2884 getTargetStreamer().emitDirectiveSetMips1();
2886 case Mips::FeatureMips2:
2887 selectArch("mips2");
2888 getTargetStreamer().emitDirectiveSetMips2();
2890 case Mips::FeatureMips3:
2891 selectArch("mips3");
2892 getTargetStreamer().emitDirectiveSetMips3();
2894 case Mips::FeatureMips4:
2895 selectArch("mips4");
2896 getTargetStreamer().emitDirectiveSetMips4();
2898 case Mips::FeatureMips5:
2899 selectArch("mips5");
2900 getTargetStreamer().emitDirectiveSetMips5();
2902 case Mips::FeatureMips32:
2903 selectArch("mips32");
2904 getTargetStreamer().emitDirectiveSetMips32();
2906 case Mips::FeatureMips32r2:
2907 selectArch("mips32r2");
2908 getTargetStreamer().emitDirectiveSetMips32R2();
2910 case Mips::FeatureMips32r6:
2911 selectArch("mips32r6");
2912 getTargetStreamer().emitDirectiveSetMips32R6();
2914 case Mips::FeatureMips64:
2915 selectArch("mips64");
2916 getTargetStreamer().emitDirectiveSetMips64();
2918 case Mips::FeatureMips64r2:
2919 selectArch("mips64r2");
2920 getTargetStreamer().emitDirectiveSetMips64R2();
2922 case Mips::FeatureMips64r6:
2923 selectArch("mips64r6");
2924 getTargetStreamer().emitDirectiveSetMips64R6();
2930 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2931 if (getLexer().isNot(AsmToken::Comma)) {
2932 SMLoc Loc = getLexer().getLoc();
2933 Parser.eatToEndOfStatement();
2934 return Error(Loc, ErrorStr);
2937 Parser.Lex(); // Eat the comma.
2941 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
2942 if (AssemblerOptions.back()->isReorder())
2943 Warning(Loc, ".cpload in reorder section");
2945 // FIXME: Warn if cpload is used in Mips16 mode.
2947 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2948 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
2949 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2950 reportParseError("expected register containing function address");
2954 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2955 if (!RegOpnd.isGPRAsmReg()) {
2956 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2960 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
2964 bool MipsAsmParser::parseDirectiveCPSetup() {
2967 bool SaveIsReg = true;
2969 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2970 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
2971 if (ResTy == MatchOperand_NoMatch) {
2972 reportParseError("expected register containing function address");
2973 Parser.eatToEndOfStatement();
2977 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2978 if (!FuncRegOpnd.isGPRAsmReg()) {
2979 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2980 Parser.eatToEndOfStatement();
2984 FuncReg = FuncRegOpnd.getGPR32Reg();
2987 if (!eatComma("unexpected token, expected comma"))
2990 ResTy = parseAnyRegister(TmpReg);
2991 if (ResTy == MatchOperand_NoMatch) {
2992 const AsmToken &Tok = Parser.getTok();
2993 if (Tok.is(AsmToken::Integer)) {
2994 Save = Tok.getIntVal();
2998 reportParseError("expected save register or stack offset");
2999 Parser.eatToEndOfStatement();
3003 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3004 if (!SaveOpnd.isGPRAsmReg()) {
3005 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
3006 Parser.eatToEndOfStatement();
3009 Save = SaveOpnd.getGPR32Reg();
3012 if (!eatComma("unexpected token, expected comma"))
3016 if (Parser.parseIdentifier(Name))
3017 reportParseError("expected identifier");
3018 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3020 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3024 bool MipsAsmParser::parseDirectiveNaN() {
3025 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3026 const AsmToken &Tok = Parser.getTok();
3028 if (Tok.getString() == "2008") {
3030 getTargetStreamer().emitDirectiveNaN2008();
3032 } else if (Tok.getString() == "legacy") {
3034 getTargetStreamer().emitDirectiveNaNLegacy();
3038 // If we don't recognize the option passed to the .nan
3039 // directive (e.g. no option or unknown option), emit an error.
3040 reportParseError("invalid option in .nan directive");
3044 bool MipsAsmParser::parseDirectiveSet() {
3046 // Get the next token.
3047 const AsmToken &Tok = Parser.getTok();
3049 if (Tok.getString() == "noat") {
3050 return parseSetNoAtDirective();
3051 } else if (Tok.getString() == "at") {
3052 return parseSetAtDirective();
3053 } else if (Tok.getString() == "arch") {
3054 return parseSetArchDirective();
3055 } else if (Tok.getString() == "fp") {
3056 return parseSetFpDirective();
3057 } else if (Tok.getString() == "pop") {
3058 return parseSetPopDirective();
3059 } else if (Tok.getString() == "push") {
3060 return parseSetPushDirective();
3061 } else if (Tok.getString() == "reorder") {
3062 return parseSetReorderDirective();
3063 } else if (Tok.getString() == "noreorder") {
3064 return parseSetNoReorderDirective();
3065 } else if (Tok.getString() == "macro") {
3066 return parseSetMacroDirective();
3067 } else if (Tok.getString() == "nomacro") {
3068 return parseSetNoMacroDirective();
3069 } else if (Tok.getString() == "mips16") {
3070 return parseSetFeature(Mips::FeatureMips16);
3071 } else if (Tok.getString() == "nomips16") {
3072 return parseSetNoMips16Directive();
3073 } else if (Tok.getString() == "nomicromips") {
3074 getTargetStreamer().emitDirectiveSetNoMicroMips();
3075 Parser.eatToEndOfStatement();
3077 } else if (Tok.getString() == "micromips") {
3078 return parseSetFeature(Mips::FeatureMicroMips);
3079 } else if (Tok.getString() == "mips0") {
3080 return parseSetMips0Directive();
3081 } else if (Tok.getString() == "mips1") {
3082 return parseSetFeature(Mips::FeatureMips1);
3083 } else if (Tok.getString() == "mips2") {
3084 return parseSetFeature(Mips::FeatureMips2);
3085 } else if (Tok.getString() == "mips3") {
3086 return parseSetFeature(Mips::FeatureMips3);
3087 } else if (Tok.getString() == "mips4") {
3088 return parseSetFeature(Mips::FeatureMips4);
3089 } else if (Tok.getString() == "mips5") {
3090 return parseSetFeature(Mips::FeatureMips5);
3091 } else if (Tok.getString() == "mips32") {
3092 return parseSetFeature(Mips::FeatureMips32);
3093 } else if (Tok.getString() == "mips32r2") {
3094 return parseSetFeature(Mips::FeatureMips32r2);
3095 } else if (Tok.getString() == "mips32r6") {
3096 return parseSetFeature(Mips::FeatureMips32r6);
3097 } else if (Tok.getString() == "mips64") {
3098 return parseSetFeature(Mips::FeatureMips64);
3099 } else if (Tok.getString() == "mips64r2") {
3100 return parseSetFeature(Mips::FeatureMips64r2);
3101 } else if (Tok.getString() == "mips64r6") {
3102 return parseSetFeature(Mips::FeatureMips64r6);
3103 } else if (Tok.getString() == "dsp") {
3104 return parseSetFeature(Mips::FeatureDSP);
3105 } else if (Tok.getString() == "nodsp") {
3106 return parseSetNoDspDirective();
3107 } else if (Tok.getString() == "msa") {
3108 return parseSetMsaDirective();
3109 } else if (Tok.getString() == "nomsa") {
3110 return parseSetNoMsaDirective();
3112 // It is just an identifier, look for an assignment.
3113 parseSetAssignment();
3120 /// parseDataDirective
3121 /// ::= .word [ expression (, expression)* ]
3122 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3123 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3125 const MCExpr *Value;
3126 if (getParser().parseExpression(Value))
3129 getParser().getStreamer().EmitValue(Value, Size);
3131 if (getLexer().is(AsmToken::EndOfStatement))
3134 if (getLexer().isNot(AsmToken::Comma))
3135 return Error(L, "unexpected token, expected comma");
3144 /// parseDirectiveGpWord
3145 /// ::= .gpword local_sym
3146 bool MipsAsmParser::parseDirectiveGpWord() {
3147 const MCExpr *Value;
3148 // EmitGPRel32Value requires an expression, so we are using base class
3149 // method to evaluate the expression.
3150 if (getParser().parseExpression(Value))
3152 getParser().getStreamer().EmitGPRel32Value(Value);
3154 if (getLexer().isNot(AsmToken::EndOfStatement))
3155 return Error(getLexer().getLoc(),
3156 "unexpected token, expected end of statement");
3157 Parser.Lex(); // Eat EndOfStatement token.
3161 /// parseDirectiveGpDWord
3162 /// ::= .gpdword local_sym
3163 bool MipsAsmParser::parseDirectiveGpDWord() {
3164 const MCExpr *Value;
3165 // EmitGPRel64Value requires an expression, so we are using base class
3166 // method to evaluate the expression.
3167 if (getParser().parseExpression(Value))
3169 getParser().getStreamer().EmitGPRel64Value(Value);
3171 if (getLexer().isNot(AsmToken::EndOfStatement))
3172 return Error(getLexer().getLoc(),
3173 "unexpected token, expected end of statement");
3174 Parser.Lex(); // Eat EndOfStatement token.
3178 bool MipsAsmParser::parseDirectiveOption() {
3179 // Get the option token.
3180 AsmToken Tok = Parser.getTok();
3181 // At the moment only identifiers are supported.
3182 if (Tok.isNot(AsmToken::Identifier)) {
3183 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3184 Parser.eatToEndOfStatement();
3188 StringRef Option = Tok.getIdentifier();
3190 if (Option == "pic0") {
3191 getTargetStreamer().emitDirectiveOptionPic0();
3193 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3194 Error(Parser.getTok().getLoc(),
3195 "unexpected token, expected end of statement");
3196 Parser.eatToEndOfStatement();
3201 if (Option == "pic2") {
3202 getTargetStreamer().emitDirectiveOptionPic2();
3204 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3205 Error(Parser.getTok().getLoc(),
3206 "unexpected token, expected end of statement");
3207 Parser.eatToEndOfStatement();
3213 Warning(Parser.getTok().getLoc(),
3214 "unknown option, expected 'pic0' or 'pic2'");
3215 Parser.eatToEndOfStatement();
3219 /// parseDirectiveModule
3220 /// ::= .module oddspreg
3221 /// ::= .module nooddspreg
3222 /// ::= .module fp=value
3223 bool MipsAsmParser::parseDirectiveModule() {
3224 MCAsmLexer &Lexer = getLexer();
3225 SMLoc L = Lexer.getLoc();
3227 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3228 // TODO : get a better message.
3229 reportParseError(".module directive must appear before any code");
3233 if (Lexer.is(AsmToken::Identifier)) {
3234 StringRef Option = Parser.getTok().getString();
3237 if (Option == "oddspreg") {
3238 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3239 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3241 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3242 reportParseError("unexpected token, expected end of statement");
3247 } else if (Option == "nooddspreg") {
3249 Error(L, "'.module nooddspreg' requires the O32 ABI");
3253 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3254 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3256 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3257 reportParseError("unexpected token, expected end of statement");
3262 } else if (Option == "fp") {
3263 return parseDirectiveModuleFP();
3266 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3272 /// parseDirectiveModuleFP
3276 bool MipsAsmParser::parseDirectiveModuleFP() {
3277 MCAsmLexer &Lexer = getLexer();
3279 if (Lexer.isNot(AsmToken::Equal)) {
3280 reportParseError("unexpected token, expected equals sign '='");
3283 Parser.Lex(); // Eat '=' token.
3285 MipsABIFlagsSection::FpABIKind FpABI;
3286 if (!parseFpABIValue(FpABI, ".module"))
3289 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3290 reportParseError("unexpected token, expected end of statement");
3294 // Emit appropriate flags.
3295 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3296 Parser.Lex(); // Consume the EndOfStatement.
3300 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3301 StringRef Directive) {
3302 MCAsmLexer &Lexer = getLexer();
3304 if (Lexer.is(AsmToken::Identifier)) {
3305 StringRef Value = Parser.getTok().getString();
3308 if (Value != "xx") {
3309 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3314 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3318 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3322 if (Lexer.is(AsmToken::Integer)) {
3323 unsigned Value = Parser.getTok().getIntVal();
3326 if (Value != 32 && Value != 64) {
3327 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3333 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3337 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3339 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3347 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3348 StringRef IDVal = DirectiveID.getString();
3350 if (IDVal == ".cpload")
3351 return parseDirectiveCpLoad(DirectiveID.getLoc());
3352 if (IDVal == ".dword") {
3353 parseDataDirective(8, DirectiveID.getLoc());
3356 if (IDVal == ".ent") {
3357 StringRef SymbolName;
3359 if (Parser.parseIdentifier(SymbolName)) {
3360 reportParseError("expected identifier after .ent");
3364 // There's an undocumented extension that allows an integer to
3365 // follow the name of the procedure which AFAICS is ignored by GAS.
3366 // Example: .ent foo,2
3367 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3368 if (getLexer().isNot(AsmToken::Comma)) {
3369 // Even though we accept this undocumented extension for compatibility
3370 // reasons, the additional integer argument does not actually change
3371 // the behaviour of the '.ent' directive, so we would like to discourage
3372 // its use. We do this by not referring to the extended version in
3373 // error messages which are not directly related to its use.
3374 reportParseError("unexpected token, expected end of statement");
3377 Parser.Lex(); // Eat the comma.
3378 const MCExpr *DummyNumber;
3379 int64_t DummyNumberVal;
3380 // If the user was explicitly trying to use the extended version,
3381 // we still give helpful extension-related error messages.
3382 if (Parser.parseExpression(DummyNumber)) {
3383 reportParseError("expected number after comma");
3386 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3387 reportParseError("expected an absolute expression after comma");
3392 // If this is not the end of the statement, report an error.
3393 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3394 reportParseError("unexpected token, expected end of statement");
3398 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3400 getTargetStreamer().emitDirectiveEnt(*Sym);
3405 if (IDVal == ".end") {
3406 StringRef SymbolName;
3408 if (Parser.parseIdentifier(SymbolName)) {
3409 reportParseError("expected identifier after .end");
3413 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3414 reportParseError("unexpected token, expected end of statement");
3418 if (CurrentFn == nullptr) {
3419 reportParseError(".end used without .ent");
3423 if ((SymbolName != CurrentFn->getName())) {
3424 reportParseError(".end symbol does not match .ent symbol");
3428 getTargetStreamer().emitDirectiveEnd(SymbolName);
3429 CurrentFn = nullptr;
3433 if (IDVal == ".frame") {
3434 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3435 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3436 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3437 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3438 reportParseError("expected stack register");
3442 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3443 if (!StackRegOpnd.isGPRAsmReg()) {
3444 reportParseError(StackRegOpnd.getStartLoc(),
3445 "expected general purpose register");
3448 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3450 if (Parser.getTok().is(AsmToken::Comma))
3453 reportParseError("unexpected token, expected comma");
3457 // Parse the frame size.
3458 const MCExpr *FrameSize;
3459 int64_t FrameSizeVal;
3461 if (Parser.parseExpression(FrameSize)) {
3462 reportParseError("expected frame size value");
3466 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3467 reportParseError("frame size not an absolute expression");
3471 if (Parser.getTok().is(AsmToken::Comma))
3474 reportParseError("unexpected token, expected comma");
3478 // Parse the return register.
3480 ResTy = parseAnyRegister(TmpReg);
3481 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3482 reportParseError("expected return register");
3486 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3487 if (!ReturnRegOpnd.isGPRAsmReg()) {
3488 reportParseError(ReturnRegOpnd.getStartLoc(),
3489 "expected general purpose register");
3493 // If this is not the end of the statement, report an error.
3494 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3495 reportParseError("unexpected token, expected end of statement");
3499 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3500 ReturnRegOpnd.getGPR32Reg());
3504 if (IDVal == ".set") {
3505 return parseDirectiveSet();
3508 if (IDVal == ".mask" || IDVal == ".fmask") {
3509 // .mask bitmask, frame_offset
3510 // bitmask: One bit for each register used.
3511 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3512 // first register is expected to be saved.
3514 // .mask 0x80000000, -4
3515 // .fmask 0x80000000, -4
3518 // Parse the bitmask
3519 const MCExpr *BitMask;
3522 if (Parser.parseExpression(BitMask)) {
3523 reportParseError("expected bitmask value");
3527 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3528 reportParseError("bitmask not an absolute expression");
3532 if (Parser.getTok().is(AsmToken::Comma))
3535 reportParseError("unexpected token, expected comma");
3539 // Parse the frame_offset
3540 const MCExpr *FrameOffset;
3541 int64_t FrameOffsetVal;
3543 if (Parser.parseExpression(FrameOffset)) {
3544 reportParseError("expected frame offset value");
3548 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3549 reportParseError("frame offset not an absolute expression");
3553 // If this is not the end of the statement, report an error.
3554 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3555 reportParseError("unexpected token, expected end of statement");
3559 if (IDVal == ".mask")
3560 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3562 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3566 if (IDVal == ".nan")
3567 return parseDirectiveNaN();
3569 if (IDVal == ".gpword") {
3570 parseDirectiveGpWord();
3574 if (IDVal == ".gpdword") {
3575 parseDirectiveGpDWord();
3579 if (IDVal == ".word") {
3580 parseDataDirective(4, DirectiveID.getLoc());
3584 if (IDVal == ".option")
3585 return parseDirectiveOption();
3587 if (IDVal == ".abicalls") {
3588 getTargetStreamer().emitDirectiveAbiCalls();
3589 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3590 Error(Parser.getTok().getLoc(),
3591 "unexpected token, expected end of statement");
3593 Parser.eatToEndOfStatement();
3598 if (IDVal == ".cpsetup")
3599 return parseDirectiveCPSetup();
3601 if (IDVal == ".module")
3602 return parseDirectiveModule();
3607 extern "C" void LLVMInitializeMipsAsmParser() {
3608 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3609 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3610 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3611 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3614 #define GET_REGISTER_MATCHER
3615 #define GET_MATCHER_IMPLEMENTATION
3616 #include "MipsGenAsmMatcher.inc"