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 if (needsExpansion(Inst))
1121 return expandInstruction(Inst, IDLoc, Instructions);
1123 Instructions.push_back(Inst);
1128 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1130 switch (Inst.getOpcode()) {
1131 case Mips::LoadImm32Reg:
1132 case Mips::LoadAddr32Imm:
1133 case Mips::LoadAddr32Reg:
1134 case Mips::LoadImm64Reg:
1141 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1142 SmallVectorImpl<MCInst> &Instructions) {
1143 switch (Inst.getOpcode()) {
1145 assert(0 && "unimplemented expansion");
1147 case Mips::LoadImm32Reg:
1148 return expandLoadImm(Inst, IDLoc, Instructions);
1149 case Mips::LoadImm64Reg:
1151 Error(IDLoc, "instruction requires a 64-bit architecture");
1154 return expandLoadImm(Inst, IDLoc, Instructions);
1155 case Mips::LoadAddr32Imm:
1156 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1157 case Mips::LoadAddr32Reg:
1158 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1163 template <bool PerformShift>
1164 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1165 SmallVectorImpl<MCInst> &Instructions) {
1168 tmpInst.setOpcode(Mips::DSLL);
1169 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1170 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1171 tmpInst.addOperand(MCOperand::CreateImm(16));
1172 tmpInst.setLoc(IDLoc);
1173 Instructions.push_back(tmpInst);
1176 tmpInst.setOpcode(Mips::ORi);
1177 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1178 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1179 tmpInst.addOperand(Operand);
1180 tmpInst.setLoc(IDLoc);
1181 Instructions.push_back(tmpInst);
1184 template <int Shift, bool PerformShift>
1185 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1186 SmallVectorImpl<MCInst> &Instructions) {
1187 createShiftOr<PerformShift>(
1188 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1189 IDLoc, Instructions);
1193 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1194 SmallVectorImpl<MCInst> &Instructions) {
1196 const MCOperand &ImmOp = Inst.getOperand(1);
1197 assert(ImmOp.isImm() && "expected immediate operand kind");
1198 const MCOperand &RegOp = Inst.getOperand(0);
1199 assert(RegOp.isReg() && "expected register operand kind");
1201 int64_t ImmValue = ImmOp.getImm();
1202 tmpInst.setLoc(IDLoc);
1203 // FIXME: gas has a special case for values that are 000...1111, which
1204 // becomes a li -1 and then a dsrl
1205 if (0 <= ImmValue && ImmValue <= 65535) {
1206 // For 0 <= j <= 65535.
1207 // li d,j => ori d,$zero,j
1208 tmpInst.setOpcode(Mips::ORi);
1209 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1210 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1211 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1212 Instructions.push_back(tmpInst);
1213 } else if (ImmValue < 0 && ImmValue >= -32768) {
1214 // For -32768 <= j < 0.
1215 // li d,j => addiu d,$zero,j
1216 tmpInst.setOpcode(Mips::ADDiu);
1217 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1218 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1219 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1220 Instructions.push_back(tmpInst);
1221 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1222 // For any value of j that is representable as a 32-bit integer, create
1224 // li d,j => lui d,hi16(j)
1226 tmpInst.setOpcode(Mips::LUi);
1227 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1228 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1229 Instructions.push_back(tmpInst);
1230 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1231 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1233 Error(IDLoc, "instruction requires a 64-bit architecture");
1237 // <------- lo32 ------>
1238 // <------- hi32 ------>
1239 // <- hi16 -> <- lo16 ->
1240 // _________________________________
1242 // | 16-bytes | 16-bytes | 16-bytes |
1243 // |__________|__________|__________|
1245 // For any value of j that is representable as a 48-bit integer, create
1247 // li d,j => lui d,hi16(j)
1248 // ori d,d,hi16(lo32(j))
1250 // ori d,d,lo16(lo32(j))
1251 tmpInst.setOpcode(Mips::LUi);
1252 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1254 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1255 Instructions.push_back(tmpInst);
1256 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1257 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1260 Error(IDLoc, "instruction requires a 64-bit architecture");
1264 // <------- hi32 ------> <------- lo32 ------>
1265 // <- hi16 -> <- lo16 ->
1266 // ___________________________________________
1268 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1269 // |__________|__________|__________|__________|
1271 // For any value of j that isn't representable as a 48-bit integer.
1272 // li d,j => lui d,hi16(j)
1273 // ori d,d,lo16(hi32(j))
1275 // ori d,d,hi16(lo32(j))
1277 // ori d,d,lo16(lo32(j))
1278 tmpInst.setOpcode(Mips::LUi);
1279 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1281 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1282 Instructions.push_back(tmpInst);
1283 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1284 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1285 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1291 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1292 SmallVectorImpl<MCInst> &Instructions) {
1294 const MCOperand &ImmOp = Inst.getOperand(2);
1295 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1296 "expected immediate operand kind");
1297 if (!ImmOp.isImm()) {
1298 expandLoadAddressSym(Inst, IDLoc, Instructions);
1301 const MCOperand &SrcRegOp = Inst.getOperand(1);
1302 assert(SrcRegOp.isReg() && "expected register operand kind");
1303 const MCOperand &DstRegOp = Inst.getOperand(0);
1304 assert(DstRegOp.isReg() && "expected register operand kind");
1305 int ImmValue = ImmOp.getImm();
1306 if (-32768 <= ImmValue && ImmValue <= 65535) {
1307 // For -32768 <= j <= 65535.
1308 // la d,j(s) => addiu d,s,j
1309 tmpInst.setOpcode(Mips::ADDiu);
1310 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1311 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1312 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1313 Instructions.push_back(tmpInst);
1315 // For any other value of j that is representable as a 32-bit integer.
1316 // la d,j(s) => lui d,hi16(j)
1319 tmpInst.setOpcode(Mips::LUi);
1320 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1321 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1322 Instructions.push_back(tmpInst);
1324 tmpInst.setOpcode(Mips::ORi);
1325 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1326 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1327 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1328 Instructions.push_back(tmpInst);
1330 tmpInst.setOpcode(Mips::ADDu);
1331 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1332 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1333 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1334 Instructions.push_back(tmpInst);
1340 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1341 SmallVectorImpl<MCInst> &Instructions) {
1343 const MCOperand &ImmOp = Inst.getOperand(1);
1344 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1345 "expected immediate operand kind");
1346 if (!ImmOp.isImm()) {
1347 expandLoadAddressSym(Inst, IDLoc, Instructions);
1350 const MCOperand &RegOp = Inst.getOperand(0);
1351 assert(RegOp.isReg() && "expected register operand kind");
1352 int ImmValue = ImmOp.getImm();
1353 if (-32768 <= ImmValue && ImmValue <= 65535) {
1354 // For -32768 <= j <= 65535.
1355 // la d,j => addiu d,$zero,j
1356 tmpInst.setOpcode(Mips::ADDiu);
1357 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1358 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1359 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1360 Instructions.push_back(tmpInst);
1362 // For any other value of j that is representable as a 32-bit integer.
1363 // la d,j => lui d,hi16(j)
1365 tmpInst.setOpcode(Mips::LUi);
1366 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1367 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1368 Instructions.push_back(tmpInst);
1370 tmpInst.setOpcode(Mips::ORi);
1371 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1372 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1373 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1374 Instructions.push_back(tmpInst);
1380 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1381 SmallVectorImpl<MCInst> &Instructions) {
1382 // FIXME: If we do have a valid at register to use, we should generate a
1383 // slightly shorter sequence here.
1385 int ExprOperandNo = 1;
1386 // Sometimes the assembly parser will get the immediate expression as
1387 // a $zero + an immediate.
1388 if (Inst.getNumOperands() == 3) {
1389 assert(Inst.getOperand(1).getReg() ==
1390 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1393 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1394 assert(SymOp.isExpr() && "expected symbol operand kind");
1395 const MCOperand &RegOp = Inst.getOperand(0);
1396 unsigned RegNo = RegOp.getReg();
1397 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1398 const MCSymbolRefExpr *HiExpr =
1399 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1400 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1401 const MCSymbolRefExpr *LoExpr =
1402 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1403 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1405 // If it's a 64-bit architecture, expand to:
1406 // la d,sym => lui d,highest(sym)
1407 // ori d,d,higher(sym)
1409 // ori d,d,hi16(sym)
1411 // ori d,d,lo16(sym)
1412 const MCSymbolRefExpr *HighestExpr =
1413 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1414 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1415 const MCSymbolRefExpr *HigherExpr =
1416 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1417 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1419 tmpInst.setOpcode(Mips::LUi);
1420 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1421 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1422 Instructions.push_back(tmpInst);
1424 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1426 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1428 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1431 // Otherwise, expand to:
1432 // la d,sym => lui d,hi16(sym)
1433 // ori d,d,lo16(sym)
1434 tmpInst.setOpcode(Mips::LUi);
1435 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1436 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1437 Instructions.push_back(tmpInst);
1439 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1444 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1445 SmallVectorImpl<MCInst> &Instructions,
1446 bool isLoad, bool isImmOpnd) {
1447 const MCSymbolRefExpr *SR;
1449 unsigned ImmOffset, HiOffset, LoOffset;
1450 const MCExpr *ExprOffset;
1452 // 1st operand is either the source or destination register.
1453 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1454 unsigned RegOpNum = Inst.getOperand(0).getReg();
1455 // 2nd operand is the base register.
1456 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1457 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1458 // 3rd operand is either an immediate or expression.
1460 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1461 ImmOffset = Inst.getOperand(2).getImm();
1462 LoOffset = ImmOffset & 0x0000ffff;
1463 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1464 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1465 if (LoOffset & 0x8000)
1468 ExprOffset = Inst.getOperand(2).getExpr();
1469 // All instructions will have the same location.
1470 TempInst.setLoc(IDLoc);
1471 // These are some of the types of expansions we perform here:
1472 // 1) lw $8, sym => lui $8, %hi(sym)
1473 // lw $8, %lo(sym)($8)
1474 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1476 // lw $8, %lo(offset)($9)
1477 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1479 // lw $8, %lo(offset)($at)
1480 // 4) sw $8, sym => lui $at, %hi(sym)
1481 // sw $8, %lo(sym)($at)
1482 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1484 // sw $8, %lo(offset)($at)
1485 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1486 // ldc1 $f0, %lo(sym)($at)
1488 // For load instructions we can use the destination register as a temporary
1489 // if base and dst are different (examples 1 and 2) and if the base register
1490 // is general purpose otherwise we must use $at (example 6) and error if it's
1491 // not available. For stores we must use $at (examples 4 and 5) because we
1492 // must not clobber the source register setting up the offset.
1493 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1494 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1495 unsigned RegClassIDOp0 =
1496 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1497 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1498 (RegClassIDOp0 == Mips::GPR64RegClassID);
1499 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1500 TmpRegNum = RegOpNum;
1502 int AT = getATReg(IDLoc);
1503 // At this point we need AT to perform the expansions and we exit if it is
1508 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1511 TempInst.setOpcode(Mips::LUi);
1512 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1514 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1516 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1517 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1518 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1519 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1521 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1523 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1524 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1527 // Add the instruction to the list.
1528 Instructions.push_back(TempInst);
1529 // Prepare TempInst for next instruction.
1531 // Add temp register to base.
1532 TempInst.setOpcode(Mips::ADDu);
1533 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1534 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1535 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1536 Instructions.push_back(TempInst);
1538 // And finally, create original instruction with low part
1539 // of offset and new base.
1540 TempInst.setOpcode(Inst.getOpcode());
1541 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1542 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1544 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1546 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1547 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1548 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1550 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1552 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1553 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1556 Instructions.push_back(TempInst);
1560 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1561 // As described by the Mips32r2 spec, the registers Rd and Rs for
1562 // jalr.hb must be different.
1563 unsigned Opcode = Inst.getOpcode();
1565 if (Opcode == Mips::JALR_HB &&
1566 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1567 return Match_RequiresDifferentSrcAndDst;
1569 return Match_Success;
1572 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1573 OperandVector &Operands,
1575 uint64_t &ErrorInfo,
1576 bool MatchingInlineAsm) {
1579 SmallVector<MCInst, 8> Instructions;
1580 unsigned MatchResult =
1581 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1583 switch (MatchResult) {
1586 case Match_Success: {
1587 if (processInstruction(Inst, IDLoc, Instructions))
1589 for (unsigned i = 0; i < Instructions.size(); i++)
1590 Out.EmitInstruction(Instructions[i], STI);
1593 case Match_MissingFeature:
1594 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1596 case Match_InvalidOperand: {
1597 SMLoc ErrorLoc = IDLoc;
1598 if (ErrorInfo != ~0ULL) {
1599 if (ErrorInfo >= Operands.size())
1600 return Error(IDLoc, "too few operands for instruction");
1602 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1603 if (ErrorLoc == SMLoc())
1607 return Error(ErrorLoc, "invalid operand for instruction");
1609 case Match_MnemonicFail:
1610 return Error(IDLoc, "invalid instruction");
1611 case Match_RequiresDifferentSrcAndDst:
1612 return Error(IDLoc, "source and destination must be different");
1617 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1618 if ((RegIndex != 0) &&
1619 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1621 Warning(Loc, "used $at without \".set noat\"");
1623 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1624 Twine(RegIndex) + "\"");
1629 MipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
1630 SMRange Range, bool ShowColors) {
1631 getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
1632 Range, SMFixIt(Range, FixMsg),
1636 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1639 CC = StringSwitch<unsigned>(Name)
1675 if (!(isABI_N32() || isABI_N64()))
1678 if (12 <= CC && CC <= 15) {
1679 // Name is one of t4-t7
1680 AsmToken RegTok = getLexer().peekTok();
1681 SMRange RegRange = RegTok.getLocRange();
1683 StringRef FixedName = StringSwitch<StringRef>(Name)
1689 assert(FixedName != "" && "Register name is not one of t4-t7.");
1691 printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
1692 "Did you mean $" + FixedName + "?", RegRange);
1695 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1696 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1697 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1698 if (8 <= CC && CC <= 11)
1702 CC = StringSwitch<unsigned>(Name)
1714 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1716 if (Name[0] == 'f') {
1717 StringRef NumString = Name.substr(1);
1719 if (NumString.getAsInteger(10, IntVal))
1720 return -1; // This is not an integer.
1721 if (IntVal > 31) // Maximum index for fpu register.
1728 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1730 if (Name.startswith("fcc")) {
1731 StringRef NumString = Name.substr(3);
1733 if (NumString.getAsInteger(10, IntVal))
1734 return -1; // This is not an integer.
1735 if (IntVal > 7) // There are only 8 fcc registers.
1742 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1744 if (Name.startswith("ac")) {
1745 StringRef NumString = Name.substr(2);
1747 if (NumString.getAsInteger(10, IntVal))
1748 return -1; // This is not an integer.
1749 if (IntVal > 3) // There are only 3 acc registers.
1756 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1759 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1768 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1771 CC = StringSwitch<unsigned>(Name)
1774 .Case("msaaccess", 2)
1776 .Case("msamodify", 4)
1777 .Case("msarequest", 5)
1779 .Case("msaunmap", 7)
1785 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1793 int MipsAsmParser::getATReg(SMLoc Loc) {
1794 int AT = AssemblerOptions.back()->getATRegNum();
1796 reportParseError(Loc,
1797 "pseudo-instruction requires $at, which is not available");
1801 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1802 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1805 unsigned MipsAsmParser::getGPR(int RegNo) {
1806 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1810 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1812 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1815 return getReg(RegClass, RegNum);
1818 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1819 DEBUG(dbgs() << "parseOperand\n");
1821 // Check if the current operand has a custom associated parser, if so, try to
1822 // custom parse the operand, or fallback to the general approach.
1823 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1824 if (ResTy == MatchOperand_Success)
1826 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1827 // there was a match, but an error occurred, in which case, just return that
1828 // the operand parsing failed.
1829 if (ResTy == MatchOperand_ParseFail)
1832 DEBUG(dbgs() << ".. Generic Parser\n");
1834 switch (getLexer().getKind()) {
1836 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1838 case AsmToken::Dollar: {
1839 // Parse the register.
1840 SMLoc S = Parser.getTok().getLoc();
1842 // Almost all registers have been parsed by custom parsers. There is only
1843 // one exception to this. $zero (and it's alias $0) will reach this point
1844 // for div, divu, and similar instructions because it is not an operand
1845 // to the instruction definition but an explicit register. Special case
1846 // this situation for now.
1847 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1850 // Maybe it is a symbol reference.
1851 StringRef Identifier;
1852 if (Parser.parseIdentifier(Identifier))
1855 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1856 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1857 // Otherwise create a symbol reference.
1859 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1861 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1864 // Else drop to expression parsing.
1865 case AsmToken::LParen:
1866 case AsmToken::Minus:
1867 case AsmToken::Plus:
1868 case AsmToken::Integer:
1869 case AsmToken::Tilde:
1870 case AsmToken::String: {
1871 DEBUG(dbgs() << ".. generic integer\n");
1872 OperandMatchResultTy ResTy = parseImm(Operands);
1873 return ResTy != MatchOperand_Success;
1875 case AsmToken::Percent: {
1876 // It is a symbol reference or constant expression.
1877 const MCExpr *IdVal;
1878 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1879 if (parseRelocOperand(IdVal))
1882 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1884 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1886 } // case AsmToken::Percent
1887 } // switch(getLexer().getKind())
1891 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1892 StringRef RelocStr) {
1894 // Check the type of the expression.
1895 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1896 // It's a constant, evaluate reloc value.
1898 switch (getVariantKind(RelocStr)) {
1899 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1900 // Get the 1st 16-bits.
1901 Val = MCE->getValue() & 0xffff;
1903 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1904 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1905 // 16 bits being negative.
1906 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1908 case MCSymbolRefExpr::VK_Mips_HIGHER:
1909 // Get the 3rd 16-bits.
1910 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1912 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1913 // Get the 4th 16-bits.
1914 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1917 report_fatal_error("unsupported reloc value");
1919 return MCConstantExpr::Create(Val, getContext());
1922 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1923 // It's a symbol, create a symbolic expression from the symbol.
1924 StringRef Symbol = MSRE->getSymbol().getName();
1925 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1926 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1930 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1931 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1933 // Try to create target expression.
1934 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1935 return MipsMCExpr::Create(VK, Expr, getContext());
1937 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1938 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1939 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1943 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1944 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1945 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1948 // Just return the original expression.
1952 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1954 switch (Expr->getKind()) {
1955 case MCExpr::Constant:
1957 case MCExpr::SymbolRef:
1958 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1959 case MCExpr::Binary:
1960 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1961 if (!isEvaluated(BE->getLHS()))
1963 return isEvaluated(BE->getRHS());
1966 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1967 case MCExpr::Target:
1973 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1974 Parser.Lex(); // Eat the % token.
1975 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1976 if (Tok.isNot(AsmToken::Identifier))
1979 std::string Str = Tok.getIdentifier().str();
1981 Parser.Lex(); // Eat the identifier.
1982 // Now make an expression from the rest of the operand.
1983 const MCExpr *IdVal;
1986 if (getLexer().getKind() == AsmToken::LParen) {
1988 Parser.Lex(); // Eat the '(' token.
1989 if (getLexer().getKind() == AsmToken::Percent) {
1990 Parser.Lex(); // Eat the % token.
1991 const AsmToken &nextTok = Parser.getTok();
1992 if (nextTok.isNot(AsmToken::Identifier))
1995 Str += nextTok.getIdentifier();
1996 Parser.Lex(); // Eat the identifier.
1997 if (getLexer().getKind() != AsmToken::LParen)
2002 if (getParser().parseParenExpression(IdVal, EndLoc))
2005 while (getLexer().getKind() == AsmToken::RParen)
2006 Parser.Lex(); // Eat the ')' token.
2009 return true; // Parenthesis must follow the relocation operand.
2011 Res = evaluateRelocExpr(IdVal, Str);
2015 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
2017 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
2018 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
2019 if (ResTy == MatchOperand_Success) {
2020 assert(Operands.size() == 1);
2021 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
2022 StartLoc = Operand.getStartLoc();
2023 EndLoc = Operand.getEndLoc();
2025 // AFAIK, we only support numeric registers and named GPR's in CFI
2027 // Don't worry about eating tokens before failing. Using an unrecognised
2028 // register is a parse error.
2029 if (Operand.isGPRAsmReg()) {
2030 // Resolve to GPR32 or GPR64 appropriately.
2031 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2034 return (RegNo == (unsigned)-1);
2037 assert(Operands.size() == 0);
2038 return (RegNo == (unsigned)-1);
2041 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2045 while (getLexer().getKind() == AsmToken::LParen)
2048 switch (getLexer().getKind()) {
2051 case AsmToken::Identifier:
2052 case AsmToken::LParen:
2053 case AsmToken::Integer:
2054 case AsmToken::Minus:
2055 case AsmToken::Plus:
2057 Result = getParser().parseParenExpression(Res, S);
2059 Result = (getParser().parseExpression(Res));
2060 while (getLexer().getKind() == AsmToken::RParen)
2063 case AsmToken::Percent:
2064 Result = parseRelocOperand(Res);
2069 MipsAsmParser::OperandMatchResultTy
2070 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2071 DEBUG(dbgs() << "parseMemOperand\n");
2072 const MCExpr *IdVal = nullptr;
2074 bool isParenExpr = false;
2075 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2076 // First operand is the offset.
2077 S = Parser.getTok().getLoc();
2079 if (getLexer().getKind() == AsmToken::LParen) {
2084 if (getLexer().getKind() != AsmToken::Dollar) {
2085 if (parseMemOffset(IdVal, isParenExpr))
2086 return MatchOperand_ParseFail;
2088 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2089 if (Tok.isNot(AsmToken::LParen)) {
2090 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2091 if (Mnemonic.getToken() == "la") {
2093 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2094 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2095 return MatchOperand_Success;
2097 if (Tok.is(AsmToken::EndOfStatement)) {
2099 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2101 // Zero register assumed, add a memory operand with ZERO as its base.
2102 // "Base" will be managed by k_Memory.
2103 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2106 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2107 return MatchOperand_Success;
2109 Error(Parser.getTok().getLoc(), "'(' expected");
2110 return MatchOperand_ParseFail;
2113 Parser.Lex(); // Eat the '(' token.
2116 Res = parseAnyRegister(Operands);
2117 if (Res != MatchOperand_Success)
2120 if (Parser.getTok().isNot(AsmToken::RParen)) {
2121 Error(Parser.getTok().getLoc(), "')' expected");
2122 return MatchOperand_ParseFail;
2125 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2127 Parser.Lex(); // Eat the ')' token.
2130 IdVal = MCConstantExpr::Create(0, getContext());
2132 // Replace the register operand with the memory operand.
2133 std::unique_ptr<MipsOperand> op(
2134 static_cast<MipsOperand *>(Operands.back().release()));
2135 // Remove the register from the operands.
2136 // "op" will be managed by k_Memory.
2137 Operands.pop_back();
2138 // Add the memory operand.
2139 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2141 if (IdVal->EvaluateAsAbsolute(Imm))
2142 IdVal = MCConstantExpr::Create(Imm, getContext());
2143 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2144 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2148 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2149 return MatchOperand_Success;
2152 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2154 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2156 SMLoc S = Parser.getTok().getLoc();
2158 if (Sym->isVariable())
2159 Expr = Sym->getVariableValue();
2162 if (Expr->getKind() == MCExpr::SymbolRef) {
2163 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2164 StringRef DefSymbol = Ref->getSymbol().getName();
2165 if (DefSymbol.startswith("$")) {
2166 OperandMatchResultTy ResTy =
2167 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2168 if (ResTy == MatchOperand_Success) {
2171 } else if (ResTy == MatchOperand_ParseFail)
2172 llvm_unreachable("Should never ParseFail");
2175 } else if (Expr->getKind() == MCExpr::Constant) {
2177 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2179 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2186 MipsAsmParser::OperandMatchResultTy
2187 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2188 StringRef Identifier,
2190 int Index = matchCPURegisterName(Identifier);
2192 Operands.push_back(MipsOperand::createGPRReg(
2193 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2194 return MatchOperand_Success;
2197 Index = matchFPURegisterName(Identifier);
2199 Operands.push_back(MipsOperand::createFGRReg(
2200 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2201 return MatchOperand_Success;
2204 Index = matchFCCRegisterName(Identifier);
2206 Operands.push_back(MipsOperand::createFCCReg(
2207 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2208 return MatchOperand_Success;
2211 Index = matchACRegisterName(Identifier);
2213 Operands.push_back(MipsOperand::createACCReg(
2214 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2215 return MatchOperand_Success;
2218 Index = matchMSA128RegisterName(Identifier);
2220 Operands.push_back(MipsOperand::createMSA128Reg(
2221 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2222 return MatchOperand_Success;
2225 Index = matchMSA128CtrlRegisterName(Identifier);
2227 Operands.push_back(MipsOperand::createMSACtrlReg(
2228 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2229 return MatchOperand_Success;
2232 return MatchOperand_NoMatch;
2235 MipsAsmParser::OperandMatchResultTy
2236 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2237 auto Token = Parser.getLexer().peekTok(false);
2239 if (Token.is(AsmToken::Identifier)) {
2240 DEBUG(dbgs() << ".. identifier\n");
2241 StringRef Identifier = Token.getIdentifier();
2242 OperandMatchResultTy ResTy =
2243 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2245 } else if (Token.is(AsmToken::Integer)) {
2246 DEBUG(dbgs() << ".. integer\n");
2247 Operands.push_back(MipsOperand::createNumericReg(
2248 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2250 return MatchOperand_Success;
2253 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2255 return MatchOperand_NoMatch;
2258 MipsAsmParser::OperandMatchResultTy
2259 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2260 DEBUG(dbgs() << "parseAnyRegister\n");
2262 auto Token = Parser.getTok();
2264 SMLoc S = Token.getLoc();
2266 if (Token.isNot(AsmToken::Dollar)) {
2267 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2268 if (Token.is(AsmToken::Identifier)) {
2269 if (searchSymbolAlias(Operands))
2270 return MatchOperand_Success;
2272 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2273 return MatchOperand_NoMatch;
2275 DEBUG(dbgs() << ".. $\n");
2277 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2278 if (ResTy == MatchOperand_Success) {
2280 Parser.Lex(); // identifier
2285 MipsAsmParser::OperandMatchResultTy
2286 MipsAsmParser::parseImm(OperandVector &Operands) {
2287 switch (getLexer().getKind()) {
2289 return MatchOperand_NoMatch;
2290 case AsmToken::LParen:
2291 case AsmToken::Minus:
2292 case AsmToken::Plus:
2293 case AsmToken::Integer:
2294 case AsmToken::Tilde:
2295 case AsmToken::String:
2299 const MCExpr *IdVal;
2300 SMLoc S = Parser.getTok().getLoc();
2301 if (getParser().parseExpression(IdVal))
2302 return MatchOperand_ParseFail;
2304 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2305 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2306 return MatchOperand_Success;
2309 MipsAsmParser::OperandMatchResultTy
2310 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2311 DEBUG(dbgs() << "parseJumpTarget\n");
2313 SMLoc S = getLexer().getLoc();
2315 // Integers and expressions are acceptable
2316 OperandMatchResultTy ResTy = parseImm(Operands);
2317 if (ResTy != MatchOperand_NoMatch)
2320 // Registers are a valid target and have priority over symbols.
2321 ResTy = parseAnyRegister(Operands);
2322 if (ResTy != MatchOperand_NoMatch)
2325 const MCExpr *Expr = nullptr;
2326 if (Parser.parseExpression(Expr)) {
2327 // We have no way of knowing if a symbol was consumed so we must ParseFail
2328 return MatchOperand_ParseFail;
2331 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2332 return MatchOperand_Success;
2335 MipsAsmParser::OperandMatchResultTy
2336 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2337 const MCExpr *IdVal;
2338 // If the first token is '$' we may have register operand.
2339 if (Parser.getTok().is(AsmToken::Dollar))
2340 return MatchOperand_NoMatch;
2341 SMLoc S = Parser.getTok().getLoc();
2342 if (getParser().parseExpression(IdVal))
2343 return MatchOperand_ParseFail;
2344 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2345 assert(MCE && "Unexpected MCExpr type.");
2346 int64_t Val = MCE->getValue();
2347 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2348 Operands.push_back(MipsOperand::CreateImm(
2349 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2350 return MatchOperand_Success;
2353 MipsAsmParser::OperandMatchResultTy
2354 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2355 switch (getLexer().getKind()) {
2357 return MatchOperand_NoMatch;
2358 case AsmToken::LParen:
2359 case AsmToken::Plus:
2360 case AsmToken::Minus:
2361 case AsmToken::Integer:
2366 SMLoc S = Parser.getTok().getLoc();
2368 if (getParser().parseExpression(Expr))
2369 return MatchOperand_ParseFail;
2372 if (!Expr->EvaluateAsAbsolute(Val)) {
2373 Error(S, "expected immediate value");
2374 return MatchOperand_ParseFail;
2377 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2378 // and because the CPU always adds one to the immediate field, the allowed
2379 // range becomes 1..4. We'll only check the range here and will deal
2380 // with the addition/subtraction when actually decoding/encoding
2382 if (Val < 1 || Val > 4) {
2383 Error(S, "immediate not in range (1..4)");
2384 return MatchOperand_ParseFail;
2388 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2389 return MatchOperand_Success;
2392 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2394 MCSymbolRefExpr::VariantKind VK =
2395 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2396 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2397 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2398 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2399 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2400 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2401 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2402 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2403 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2404 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2405 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2406 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2407 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2408 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2409 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2410 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2411 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2412 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2413 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2414 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2415 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2416 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2417 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2418 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2419 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2420 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2421 .Default(MCSymbolRefExpr::VK_None);
2423 assert(VK != MCSymbolRefExpr::VK_None);
2428 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2430 /// ::= '(', register, ')'
2431 /// handle it before we iterate so we don't get tripped up by the lack of
2433 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2434 if (getLexer().is(AsmToken::LParen)) {
2436 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2438 if (parseOperand(Operands, Name)) {
2439 SMLoc Loc = getLexer().getLoc();
2440 Parser.eatToEndOfStatement();
2441 return Error(Loc, "unexpected token in argument list");
2443 if (Parser.getTok().isNot(AsmToken::RParen)) {
2444 SMLoc Loc = getLexer().getLoc();
2445 Parser.eatToEndOfStatement();
2446 return Error(Loc, "unexpected token, expected ')'");
2449 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2455 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2456 /// either one of these.
2457 /// ::= '[', register, ']'
2458 /// ::= '[', integer, ']'
2459 /// handle it before we iterate so we don't get tripped up by the lack of
2461 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2462 OperandVector &Operands) {
2463 if (getLexer().is(AsmToken::LBrac)) {
2465 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2467 if (parseOperand(Operands, Name)) {
2468 SMLoc Loc = getLexer().getLoc();
2469 Parser.eatToEndOfStatement();
2470 return Error(Loc, "unexpected token in argument list");
2472 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2473 SMLoc Loc = getLexer().getLoc();
2474 Parser.eatToEndOfStatement();
2475 return Error(Loc, "unexpected token, expected ']'");
2478 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2484 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2485 SMLoc NameLoc, OperandVector &Operands) {
2486 DEBUG(dbgs() << "ParseInstruction\n");
2488 // We have reached first instruction, module directive are now forbidden.
2489 getTargetStreamer().forbidModuleDirective();
2491 // Check if we have valid mnemonic
2492 if (!mnemonicIsValid(Name, 0)) {
2493 Parser.eatToEndOfStatement();
2494 return Error(NameLoc, "unknown instruction");
2496 // First operand in MCInst is instruction mnemonic.
2497 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2499 // Read the remaining operands.
2500 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2501 // Read the first operand.
2502 if (parseOperand(Operands, Name)) {
2503 SMLoc Loc = getLexer().getLoc();
2504 Parser.eatToEndOfStatement();
2505 return Error(Loc, "unexpected token in argument list");
2507 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2509 // AFAIK, parenthesis suffixes are never on the first operand
2511 while (getLexer().is(AsmToken::Comma)) {
2512 Parser.Lex(); // Eat the comma.
2513 // Parse and remember the operand.
2514 if (parseOperand(Operands, Name)) {
2515 SMLoc Loc = getLexer().getLoc();
2516 Parser.eatToEndOfStatement();
2517 return Error(Loc, "unexpected token in argument list");
2519 // Parse bracket and parenthesis suffixes before we iterate
2520 if (getLexer().is(AsmToken::LBrac)) {
2521 if (parseBracketSuffix(Name, Operands))
2523 } else if (getLexer().is(AsmToken::LParen) &&
2524 parseParenSuffix(Name, Operands))
2528 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2529 SMLoc Loc = getLexer().getLoc();
2530 Parser.eatToEndOfStatement();
2531 return Error(Loc, "unexpected token in argument list");
2533 Parser.Lex(); // Consume the EndOfStatement.
2537 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2538 SMLoc Loc = getLexer().getLoc();
2539 Parser.eatToEndOfStatement();
2540 return Error(Loc, ErrorMsg);
2543 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2544 return Error(Loc, ErrorMsg);
2547 bool MipsAsmParser::parseSetNoAtDirective() {
2548 // Line should look like: ".set noat".
2550 AssemblerOptions.back()->setATReg(0);
2553 // If this is not the end of the statement, report an error.
2554 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2555 reportParseError("unexpected token, expected end of statement");
2558 Parser.Lex(); // Consume the EndOfStatement.
2562 bool MipsAsmParser::parseSetAtDirective() {
2563 // Line can be .set at - defaults to $1
2567 if (getLexer().is(AsmToken::EndOfStatement)) {
2568 AssemblerOptions.back()->setATReg(1);
2569 Parser.Lex(); // Consume the EndOfStatement.
2571 } else if (getLexer().is(AsmToken::Equal)) {
2572 getParser().Lex(); // Eat the '='.
2573 if (getLexer().isNot(AsmToken::Dollar)) {
2574 reportParseError("unexpected token, expected dollar sign '$'");
2577 Parser.Lex(); // Eat the '$'.
2578 const AsmToken &Reg = Parser.getTok();
2579 if (Reg.is(AsmToken::Identifier)) {
2580 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2581 } else if (Reg.is(AsmToken::Integer)) {
2582 AtRegNo = Reg.getIntVal();
2584 reportParseError("unexpected token, expected identifier or integer");
2588 if (AtRegNo < 0 || AtRegNo > 31) {
2589 reportParseError("unexpected token in statement");
2593 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2594 reportParseError("invalid register");
2597 getParser().Lex(); // Eat the register.
2599 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2600 reportParseError("unexpected token, expected end of statement");
2603 Parser.Lex(); // Consume the EndOfStatement.
2606 reportParseError("unexpected token in statement");
2611 bool MipsAsmParser::parseSetReorderDirective() {
2613 // If this is not the end of the statement, report an error.
2614 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2615 reportParseError("unexpected token, expected end of statement");
2618 AssemblerOptions.back()->setReorder();
2619 getTargetStreamer().emitDirectiveSetReorder();
2620 Parser.Lex(); // Consume the EndOfStatement.
2624 bool MipsAsmParser::parseSetNoReorderDirective() {
2626 // If this is not the end of the statement, report an error.
2627 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2628 reportParseError("unexpected token, expected end of statement");
2631 AssemblerOptions.back()->setNoReorder();
2632 getTargetStreamer().emitDirectiveSetNoReorder();
2633 Parser.Lex(); // Consume the EndOfStatement.
2637 bool MipsAsmParser::parseSetMacroDirective() {
2639 // If this is not the end of the statement, report an error.
2640 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2641 reportParseError("unexpected token, expected end of statement");
2644 AssemblerOptions.back()->setMacro();
2645 Parser.Lex(); // Consume the EndOfStatement.
2649 bool MipsAsmParser::parseSetNoMacroDirective() {
2651 // If this is not the end of the statement, report an error.
2652 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2653 reportParseError("unexpected token, expected end of statement");
2656 if (AssemblerOptions.back()->isReorder()) {
2657 reportParseError("`noreorder' must be set before `nomacro'");
2660 AssemblerOptions.back()->setNoMacro();
2661 Parser.Lex(); // Consume the EndOfStatement.
2665 bool MipsAsmParser::parseSetMsaDirective() {
2668 // If this is not the end of the statement, report an error.
2669 if (getLexer().isNot(AsmToken::EndOfStatement))
2670 return reportParseError("unexpected token, expected end of statement");
2672 setFeatureBits(Mips::FeatureMSA, "msa");
2673 getTargetStreamer().emitDirectiveSetMsa();
2677 bool MipsAsmParser::parseSetNoMsaDirective() {
2680 // If this is not the end of the statement, report an error.
2681 if (getLexer().isNot(AsmToken::EndOfStatement))
2682 return reportParseError("unexpected token, expected end of statement");
2684 clearFeatureBits(Mips::FeatureMSA, "msa");
2685 getTargetStreamer().emitDirectiveSetNoMsa();
2689 bool MipsAsmParser::parseSetNoDspDirective() {
2690 Parser.Lex(); // Eat "nodsp".
2692 // If this is not the end of the statement, report an error.
2693 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2694 reportParseError("unexpected token, expected end of statement");
2698 clearFeatureBits(Mips::FeatureDSP, "dsp");
2699 getTargetStreamer().emitDirectiveSetNoDsp();
2703 bool MipsAsmParser::parseSetNoMips16Directive() {
2705 // If this is not the end of the statement, report an error.
2706 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2707 reportParseError("unexpected token, expected end of statement");
2710 // For now do nothing.
2711 Parser.Lex(); // Consume the EndOfStatement.
2715 bool MipsAsmParser::parseSetFpDirective() {
2716 MipsABIFlagsSection::FpABIKind FpAbiVal;
2717 // Line can be: .set fp=32
2720 Parser.Lex(); // Eat fp token
2721 AsmToken Tok = Parser.getTok();
2722 if (Tok.isNot(AsmToken::Equal)) {
2723 reportParseError("unexpected token, expected equals sign '='");
2726 Parser.Lex(); // Eat '=' token.
2727 Tok = Parser.getTok();
2729 if (!parseFpABIValue(FpAbiVal, ".set"))
2732 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2733 reportParseError("unexpected token, expected end of statement");
2736 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2737 Parser.Lex(); // Consume the EndOfStatement.
2741 bool MipsAsmParser::parseSetPopDirective() {
2742 SMLoc Loc = getLexer().getLoc();
2745 if (getLexer().isNot(AsmToken::EndOfStatement))
2746 return reportParseError("unexpected token, expected end of statement");
2748 // Always keep an element on the options "stack" to prevent the user
2749 // from changing the initial options. This is how we remember them.
2750 if (AssemblerOptions.size() == 2)
2751 return reportParseError(Loc, ".set pop with no .set push");
2753 AssemblerOptions.pop_back();
2754 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2756 getTargetStreamer().emitDirectiveSetPop();
2760 bool MipsAsmParser::parseSetPushDirective() {
2762 if (getLexer().isNot(AsmToken::EndOfStatement))
2763 return reportParseError("unexpected token, expected end of statement");
2765 // Create a copy of the current assembler options environment and push it.
2766 AssemblerOptions.push_back(
2767 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2769 getTargetStreamer().emitDirectiveSetPush();
2773 bool MipsAsmParser::parseSetAssignment() {
2775 const MCExpr *Value;
2777 if (Parser.parseIdentifier(Name))
2778 reportParseError("expected identifier after .set");
2780 if (getLexer().isNot(AsmToken::Comma))
2781 return reportParseError("unexpected token, expected comma");
2784 if (Parser.parseExpression(Value))
2785 return reportParseError("expected valid expression after comma");
2787 // Check if the Name already exists as a symbol.
2788 MCSymbol *Sym = getContext().LookupSymbol(Name);
2790 return reportParseError("symbol already defined");
2791 Sym = getContext().GetOrCreateSymbol(Name);
2792 Sym->setVariableValue(Value);
2797 bool MipsAsmParser::parseSetMips0Directive() {
2799 if (getLexer().isNot(AsmToken::EndOfStatement))
2800 return reportParseError("unexpected token, expected end of statement");
2802 // Reset assembler options to their initial values.
2803 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2804 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2806 getTargetStreamer().emitDirectiveSetMips0();
2810 bool MipsAsmParser::parseSetArchDirective() {
2812 if (getLexer().isNot(AsmToken::Equal))
2813 return reportParseError("unexpected token, expected equals sign");
2817 if (Parser.parseIdentifier(Arch))
2818 return reportParseError("expected arch identifier");
2820 StringRef ArchFeatureName =
2821 StringSwitch<StringRef>(Arch)
2822 .Case("mips1", "mips1")
2823 .Case("mips2", "mips2")
2824 .Case("mips3", "mips3")
2825 .Case("mips4", "mips4")
2826 .Case("mips5", "mips5")
2827 .Case("mips32", "mips32")
2828 .Case("mips32r2", "mips32r2")
2829 .Case("mips32r6", "mips32r6")
2830 .Case("mips64", "mips64")
2831 .Case("mips64r2", "mips64r2")
2832 .Case("mips64r6", "mips64r6")
2833 .Case("cnmips", "cnmips")
2834 .Case("r4000", "mips3") // This is an implementation of Mips3.
2837 if (ArchFeatureName.empty())
2838 return reportParseError("unsupported architecture");
2840 selectArch(ArchFeatureName);
2841 getTargetStreamer().emitDirectiveSetArch(Arch);
2845 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2847 if (getLexer().isNot(AsmToken::EndOfStatement))
2848 return reportParseError("unexpected token, expected end of statement");
2852 llvm_unreachable("Unimplemented feature");
2853 case Mips::FeatureDSP:
2854 setFeatureBits(Mips::FeatureDSP, "dsp");
2855 getTargetStreamer().emitDirectiveSetDsp();
2857 case Mips::FeatureMicroMips:
2858 getTargetStreamer().emitDirectiveSetMicroMips();
2860 case Mips::FeatureMips16:
2861 getTargetStreamer().emitDirectiveSetMips16();
2863 case Mips::FeatureMips1:
2864 selectArch("mips1");
2865 getTargetStreamer().emitDirectiveSetMips1();
2867 case Mips::FeatureMips2:
2868 selectArch("mips2");
2869 getTargetStreamer().emitDirectiveSetMips2();
2871 case Mips::FeatureMips3:
2872 selectArch("mips3");
2873 getTargetStreamer().emitDirectiveSetMips3();
2875 case Mips::FeatureMips4:
2876 selectArch("mips4");
2877 getTargetStreamer().emitDirectiveSetMips4();
2879 case Mips::FeatureMips5:
2880 selectArch("mips5");
2881 getTargetStreamer().emitDirectiveSetMips5();
2883 case Mips::FeatureMips32:
2884 selectArch("mips32");
2885 getTargetStreamer().emitDirectiveSetMips32();
2887 case Mips::FeatureMips32r2:
2888 selectArch("mips32r2");
2889 getTargetStreamer().emitDirectiveSetMips32R2();
2891 case Mips::FeatureMips32r6:
2892 selectArch("mips32r6");
2893 getTargetStreamer().emitDirectiveSetMips32R6();
2895 case Mips::FeatureMips64:
2896 selectArch("mips64");
2897 getTargetStreamer().emitDirectiveSetMips64();
2899 case Mips::FeatureMips64r2:
2900 selectArch("mips64r2");
2901 getTargetStreamer().emitDirectiveSetMips64R2();
2903 case Mips::FeatureMips64r6:
2904 selectArch("mips64r6");
2905 getTargetStreamer().emitDirectiveSetMips64R6();
2911 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2912 if (getLexer().isNot(AsmToken::Comma)) {
2913 SMLoc Loc = getLexer().getLoc();
2914 Parser.eatToEndOfStatement();
2915 return Error(Loc, ErrorStr);
2918 Parser.Lex(); // Eat the comma.
2922 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
2923 if (AssemblerOptions.back()->isReorder())
2924 Warning(Loc, ".cpload in reorder section");
2926 // FIXME: Warn if cpload is used in Mips16 mode.
2928 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2929 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
2930 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2931 reportParseError("expected register containing function address");
2935 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2936 if (!RegOpnd.isGPRAsmReg()) {
2937 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2941 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
2945 bool MipsAsmParser::parseDirectiveCPSetup() {
2948 bool SaveIsReg = true;
2950 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2951 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
2952 if (ResTy == MatchOperand_NoMatch) {
2953 reportParseError("expected register containing function address");
2954 Parser.eatToEndOfStatement();
2958 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2959 if (!FuncRegOpnd.isGPRAsmReg()) {
2960 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2961 Parser.eatToEndOfStatement();
2965 FuncReg = FuncRegOpnd.getGPR32Reg();
2968 if (!eatComma("unexpected token, expected comma"))
2971 ResTy = parseAnyRegister(TmpReg);
2972 if (ResTy == MatchOperand_NoMatch) {
2973 const AsmToken &Tok = Parser.getTok();
2974 if (Tok.is(AsmToken::Integer)) {
2975 Save = Tok.getIntVal();
2979 reportParseError("expected save register or stack offset");
2980 Parser.eatToEndOfStatement();
2984 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2985 if (!SaveOpnd.isGPRAsmReg()) {
2986 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2987 Parser.eatToEndOfStatement();
2990 Save = SaveOpnd.getGPR32Reg();
2993 if (!eatComma("unexpected token, expected comma"))
2997 if (Parser.parseIdentifier(Name))
2998 reportParseError("expected identifier");
2999 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
3001 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
3005 bool MipsAsmParser::parseDirectiveNaN() {
3006 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3007 const AsmToken &Tok = Parser.getTok();
3009 if (Tok.getString() == "2008") {
3011 getTargetStreamer().emitDirectiveNaN2008();
3013 } else if (Tok.getString() == "legacy") {
3015 getTargetStreamer().emitDirectiveNaNLegacy();
3019 // If we don't recognize the option passed to the .nan
3020 // directive (e.g. no option or unknown option), emit an error.
3021 reportParseError("invalid option in .nan directive");
3025 bool MipsAsmParser::parseDirectiveSet() {
3027 // Get the next token.
3028 const AsmToken &Tok = Parser.getTok();
3030 if (Tok.getString() == "noat") {
3031 return parseSetNoAtDirective();
3032 } else if (Tok.getString() == "at") {
3033 return parseSetAtDirective();
3034 } else if (Tok.getString() == "arch") {
3035 return parseSetArchDirective();
3036 } else if (Tok.getString() == "fp") {
3037 return parseSetFpDirective();
3038 } else if (Tok.getString() == "pop") {
3039 return parseSetPopDirective();
3040 } else if (Tok.getString() == "push") {
3041 return parseSetPushDirective();
3042 } else if (Tok.getString() == "reorder") {
3043 return parseSetReorderDirective();
3044 } else if (Tok.getString() == "noreorder") {
3045 return parseSetNoReorderDirective();
3046 } else if (Tok.getString() == "macro") {
3047 return parseSetMacroDirective();
3048 } else if (Tok.getString() == "nomacro") {
3049 return parseSetNoMacroDirective();
3050 } else if (Tok.getString() == "mips16") {
3051 return parseSetFeature(Mips::FeatureMips16);
3052 } else if (Tok.getString() == "nomips16") {
3053 return parseSetNoMips16Directive();
3054 } else if (Tok.getString() == "nomicromips") {
3055 getTargetStreamer().emitDirectiveSetNoMicroMips();
3056 Parser.eatToEndOfStatement();
3058 } else if (Tok.getString() == "micromips") {
3059 return parseSetFeature(Mips::FeatureMicroMips);
3060 } else if (Tok.getString() == "mips0") {
3061 return parseSetMips0Directive();
3062 } else if (Tok.getString() == "mips1") {
3063 return parseSetFeature(Mips::FeatureMips1);
3064 } else if (Tok.getString() == "mips2") {
3065 return parseSetFeature(Mips::FeatureMips2);
3066 } else if (Tok.getString() == "mips3") {
3067 return parseSetFeature(Mips::FeatureMips3);
3068 } else if (Tok.getString() == "mips4") {
3069 return parseSetFeature(Mips::FeatureMips4);
3070 } else if (Tok.getString() == "mips5") {
3071 return parseSetFeature(Mips::FeatureMips5);
3072 } else if (Tok.getString() == "mips32") {
3073 return parseSetFeature(Mips::FeatureMips32);
3074 } else if (Tok.getString() == "mips32r2") {
3075 return parseSetFeature(Mips::FeatureMips32r2);
3076 } else if (Tok.getString() == "mips32r6") {
3077 return parseSetFeature(Mips::FeatureMips32r6);
3078 } else if (Tok.getString() == "mips64") {
3079 return parseSetFeature(Mips::FeatureMips64);
3080 } else if (Tok.getString() == "mips64r2") {
3081 return parseSetFeature(Mips::FeatureMips64r2);
3082 } else if (Tok.getString() == "mips64r6") {
3083 return parseSetFeature(Mips::FeatureMips64r6);
3084 } else if (Tok.getString() == "dsp") {
3085 return parseSetFeature(Mips::FeatureDSP);
3086 } else if (Tok.getString() == "nodsp") {
3087 return parseSetNoDspDirective();
3088 } else if (Tok.getString() == "msa") {
3089 return parseSetMsaDirective();
3090 } else if (Tok.getString() == "nomsa") {
3091 return parseSetNoMsaDirective();
3093 // It is just an identifier, look for an assignment.
3094 parseSetAssignment();
3101 /// parseDataDirective
3102 /// ::= .word [ expression (, expression)* ]
3103 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3104 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3106 const MCExpr *Value;
3107 if (getParser().parseExpression(Value))
3110 getParser().getStreamer().EmitValue(Value, Size);
3112 if (getLexer().is(AsmToken::EndOfStatement))
3115 if (getLexer().isNot(AsmToken::Comma))
3116 return Error(L, "unexpected token, expected comma");
3125 /// parseDirectiveGpWord
3126 /// ::= .gpword local_sym
3127 bool MipsAsmParser::parseDirectiveGpWord() {
3128 const MCExpr *Value;
3129 // EmitGPRel32Value requires an expression, so we are using base class
3130 // method to evaluate the expression.
3131 if (getParser().parseExpression(Value))
3133 getParser().getStreamer().EmitGPRel32Value(Value);
3135 if (getLexer().isNot(AsmToken::EndOfStatement))
3136 return Error(getLexer().getLoc(),
3137 "unexpected token, expected end of statement");
3138 Parser.Lex(); // Eat EndOfStatement token.
3142 /// parseDirectiveGpDWord
3143 /// ::= .gpdword local_sym
3144 bool MipsAsmParser::parseDirectiveGpDWord() {
3145 const MCExpr *Value;
3146 // EmitGPRel64Value requires an expression, so we are using base class
3147 // method to evaluate the expression.
3148 if (getParser().parseExpression(Value))
3150 getParser().getStreamer().EmitGPRel64Value(Value);
3152 if (getLexer().isNot(AsmToken::EndOfStatement))
3153 return Error(getLexer().getLoc(),
3154 "unexpected token, expected end of statement");
3155 Parser.Lex(); // Eat EndOfStatement token.
3159 bool MipsAsmParser::parseDirectiveOption() {
3160 // Get the option token.
3161 AsmToken Tok = Parser.getTok();
3162 // At the moment only identifiers are supported.
3163 if (Tok.isNot(AsmToken::Identifier)) {
3164 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3165 Parser.eatToEndOfStatement();
3169 StringRef Option = Tok.getIdentifier();
3171 if (Option == "pic0") {
3172 getTargetStreamer().emitDirectiveOptionPic0();
3174 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3175 Error(Parser.getTok().getLoc(),
3176 "unexpected token, expected end of statement");
3177 Parser.eatToEndOfStatement();
3182 if (Option == "pic2") {
3183 getTargetStreamer().emitDirectiveOptionPic2();
3185 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3186 Error(Parser.getTok().getLoc(),
3187 "unexpected token, expected end of statement");
3188 Parser.eatToEndOfStatement();
3194 Warning(Parser.getTok().getLoc(),
3195 "unknown option, expected 'pic0' or 'pic2'");
3196 Parser.eatToEndOfStatement();
3200 /// parseDirectiveModule
3201 /// ::= .module oddspreg
3202 /// ::= .module nooddspreg
3203 /// ::= .module fp=value
3204 bool MipsAsmParser::parseDirectiveModule() {
3205 MCAsmLexer &Lexer = getLexer();
3206 SMLoc L = Lexer.getLoc();
3208 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3209 // TODO : get a better message.
3210 reportParseError(".module directive must appear before any code");
3214 if (Lexer.is(AsmToken::Identifier)) {
3215 StringRef Option = Parser.getTok().getString();
3218 if (Option == "oddspreg") {
3219 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3220 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3222 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3223 reportParseError("unexpected token, expected end of statement");
3228 } else if (Option == "nooddspreg") {
3230 Error(L, "'.module nooddspreg' requires the O32 ABI");
3234 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3235 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3237 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3238 reportParseError("unexpected token, expected end of statement");
3243 } else if (Option == "fp") {
3244 return parseDirectiveModuleFP();
3247 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3253 /// parseDirectiveModuleFP
3257 bool MipsAsmParser::parseDirectiveModuleFP() {
3258 MCAsmLexer &Lexer = getLexer();
3260 if (Lexer.isNot(AsmToken::Equal)) {
3261 reportParseError("unexpected token, expected equals sign '='");
3264 Parser.Lex(); // Eat '=' token.
3266 MipsABIFlagsSection::FpABIKind FpABI;
3267 if (!parseFpABIValue(FpABI, ".module"))
3270 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3271 reportParseError("unexpected token, expected end of statement");
3275 // Emit appropriate flags.
3276 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3277 Parser.Lex(); // Consume the EndOfStatement.
3281 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3282 StringRef Directive) {
3283 MCAsmLexer &Lexer = getLexer();
3285 if (Lexer.is(AsmToken::Identifier)) {
3286 StringRef Value = Parser.getTok().getString();
3289 if (Value != "xx") {
3290 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3295 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3299 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3303 if (Lexer.is(AsmToken::Integer)) {
3304 unsigned Value = Parser.getTok().getIntVal();
3307 if (Value != 32 && Value != 64) {
3308 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3314 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3318 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3320 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3328 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3329 StringRef IDVal = DirectiveID.getString();
3331 if (IDVal == ".cpload")
3332 return parseDirectiveCpLoad(DirectiveID.getLoc());
3333 if (IDVal == ".dword") {
3334 parseDataDirective(8, DirectiveID.getLoc());
3337 if (IDVal == ".ent") {
3338 StringRef SymbolName;
3340 if (Parser.parseIdentifier(SymbolName)) {
3341 reportParseError("expected identifier after .ent");
3345 // There's an undocumented extension that allows an integer to
3346 // follow the name of the procedure which AFAICS is ignored by GAS.
3347 // Example: .ent foo,2
3348 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3349 if (getLexer().isNot(AsmToken::Comma)) {
3350 // Even though we accept this undocumented extension for compatibility
3351 // reasons, the additional integer argument does not actually change
3352 // the behaviour of the '.ent' directive, so we would like to discourage
3353 // its use. We do this by not referring to the extended version in
3354 // error messages which are not directly related to its use.
3355 reportParseError("unexpected token, expected end of statement");
3358 Parser.Lex(); // Eat the comma.
3359 const MCExpr *DummyNumber;
3360 int64_t DummyNumberVal;
3361 // If the user was explicitly trying to use the extended version,
3362 // we still give helpful extension-related error messages.
3363 if (Parser.parseExpression(DummyNumber)) {
3364 reportParseError("expected number after comma");
3367 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3368 reportParseError("expected an absolute expression after comma");
3373 // If this is not the end of the statement, report an error.
3374 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3375 reportParseError("unexpected token, expected end of statement");
3379 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3381 getTargetStreamer().emitDirectiveEnt(*Sym);
3386 if (IDVal == ".end") {
3387 StringRef SymbolName;
3389 if (Parser.parseIdentifier(SymbolName)) {
3390 reportParseError("expected identifier after .end");
3394 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3395 reportParseError("unexpected token, expected end of statement");
3399 if (CurrentFn == nullptr) {
3400 reportParseError(".end used without .ent");
3404 if ((SymbolName != CurrentFn->getName())) {
3405 reportParseError(".end symbol does not match .ent symbol");
3409 getTargetStreamer().emitDirectiveEnd(SymbolName);
3410 CurrentFn = nullptr;
3414 if (IDVal == ".frame") {
3415 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3416 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3417 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3418 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3419 reportParseError("expected stack register");
3423 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3424 if (!StackRegOpnd.isGPRAsmReg()) {
3425 reportParseError(StackRegOpnd.getStartLoc(),
3426 "expected general purpose register");
3429 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3431 if (Parser.getTok().is(AsmToken::Comma))
3434 reportParseError("unexpected token, expected comma");
3438 // Parse the frame size.
3439 const MCExpr *FrameSize;
3440 int64_t FrameSizeVal;
3442 if (Parser.parseExpression(FrameSize)) {
3443 reportParseError("expected frame size value");
3447 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3448 reportParseError("frame size not an absolute expression");
3452 if (Parser.getTok().is(AsmToken::Comma))
3455 reportParseError("unexpected token, expected comma");
3459 // Parse the return register.
3461 ResTy = parseAnyRegister(TmpReg);
3462 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3463 reportParseError("expected return register");
3467 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3468 if (!ReturnRegOpnd.isGPRAsmReg()) {
3469 reportParseError(ReturnRegOpnd.getStartLoc(),
3470 "expected general purpose register");
3474 // If this is not the end of the statement, report an error.
3475 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3476 reportParseError("unexpected token, expected end of statement");
3480 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3481 ReturnRegOpnd.getGPR32Reg());
3485 if (IDVal == ".set") {
3486 return parseDirectiveSet();
3489 if (IDVal == ".mask" || IDVal == ".fmask") {
3490 // .mask bitmask, frame_offset
3491 // bitmask: One bit for each register used.
3492 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3493 // first register is expected to be saved.
3495 // .mask 0x80000000, -4
3496 // .fmask 0x80000000, -4
3499 // Parse the bitmask
3500 const MCExpr *BitMask;
3503 if (Parser.parseExpression(BitMask)) {
3504 reportParseError("expected bitmask value");
3508 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3509 reportParseError("bitmask not an absolute expression");
3513 if (Parser.getTok().is(AsmToken::Comma))
3516 reportParseError("unexpected token, expected comma");
3520 // Parse the frame_offset
3521 const MCExpr *FrameOffset;
3522 int64_t FrameOffsetVal;
3524 if (Parser.parseExpression(FrameOffset)) {
3525 reportParseError("expected frame offset value");
3529 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3530 reportParseError("frame offset not an absolute expression");
3534 // If this is not the end of the statement, report an error.
3535 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3536 reportParseError("unexpected token, expected end of statement");
3540 if (IDVal == ".mask")
3541 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3543 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3547 if (IDVal == ".nan")
3548 return parseDirectiveNaN();
3550 if (IDVal == ".gpword") {
3551 parseDirectiveGpWord();
3555 if (IDVal == ".gpdword") {
3556 parseDirectiveGpDWord();
3560 if (IDVal == ".word") {
3561 parseDataDirective(4, DirectiveID.getLoc());
3565 if (IDVal == ".option")
3566 return parseDirectiveOption();
3568 if (IDVal == ".abicalls") {
3569 getTargetStreamer().emitDirectiveAbiCalls();
3570 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3571 Error(Parser.getTok().getLoc(),
3572 "unexpected token, expected end of statement");
3574 Parser.eatToEndOfStatement();
3579 if (IDVal == ".cpsetup")
3580 return parseDirectiveCPSetup();
3582 if (IDVal == ".module")
3583 return parseDirectiveModule();
3588 extern "C" void LLVMInitializeMipsAsmParser() {
3589 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3590 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3591 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3592 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3595 #define GET_REGISTER_MATCHER
3596 #define GET_MATCHER_IMPLEMENTATION
3597 #include "MipsGenAsmMatcher.inc"