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"
34 #define DEBUG_TYPE "mips-asm-parser"
41 class MipsAssemblerOptions {
43 MipsAssemblerOptions(uint64_t Features_) :
44 ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
46 MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
47 ATReg = Opts->getATRegNum();
48 Reorder = Opts->isReorder();
49 Macro = Opts->isMacro();
50 Features = Opts->getFeatures();
53 unsigned getATRegNum() const { return ATReg; }
54 bool setATReg(unsigned Reg);
56 bool isReorder() const { return Reorder; }
57 void setReorder() { Reorder = true; }
58 void setNoReorder() { Reorder = false; }
60 bool isMacro() const { return Macro; }
61 void setMacro() { Macro = true; }
62 void setNoMacro() { Macro = false; }
64 uint64_t getFeatures() const { return Features; }
65 void setFeatures(uint64_t Features_) { Features = Features_; }
67 // Set of features that are either architecture features or referenced
68 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
69 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
70 // The reason we need this mask is explained in the selectArch function.
71 // FIXME: Ideally we would like TableGen to generate this information.
72 static const uint64_t AllArchRelatedMask =
73 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
74 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
75 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
76 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
77 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
78 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
79 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
90 class MipsAsmParser : public MCTargetAsmParser {
91 MipsTargetStreamer &getTargetStreamer() {
92 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
93 return static_cast<MipsTargetStreamer &>(TS);
98 SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
99 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
100 // nullptr, which indicates that no function is currently
101 // selected. This usually happens after an '.end func'
104 #define GET_ASSEMBLER_HEADER
105 #include "MipsGenAsmMatcher.inc"
107 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
109 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
110 OperandVector &Operands, MCStreamer &Out,
112 bool MatchingInlineAsm) override;
114 /// Parse a register as used in CFI directives
115 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
117 bool parseParenSuffix(StringRef Name, OperandVector &Operands);
119 bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
121 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
122 SMLoc NameLoc, OperandVector &Operands) override;
124 bool ParseDirective(AsmToken DirectiveID) override;
126 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
128 MipsAsmParser::OperandMatchResultTy
129 matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
130 StringRef Identifier, SMLoc S);
132 MipsAsmParser::OperandMatchResultTy
133 matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
135 MipsAsmParser::OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
137 MipsAsmParser::OperandMatchResultTy parseImm(OperandVector &Operands);
139 MipsAsmParser::OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
141 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
143 MipsAsmParser::OperandMatchResultTy parseLSAImm(OperandVector &Operands);
145 bool searchSymbolAlias(OperandVector &Operands);
147 bool parseOperand(OperandVector &, StringRef Mnemonic);
149 bool needsExpansion(MCInst &Inst);
151 // Expands assembly pseudo instructions.
152 // Returns false on success, true otherwise.
153 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
154 SmallVectorImpl<MCInst> &Instructions);
156 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
157 SmallVectorImpl<MCInst> &Instructions);
159 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
160 SmallVectorImpl<MCInst> &Instructions);
162 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
163 SmallVectorImpl<MCInst> &Instructions);
165 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
166 SmallVectorImpl<MCInst> &Instructions);
168 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
169 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
171 bool reportParseError(Twine ErrorMsg);
172 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
174 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
175 bool parseRelocOperand(const MCExpr *&Res);
177 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
179 bool isEvaluated(const MCExpr *Expr);
180 bool parseSetMips0Directive();
181 bool parseSetArchDirective();
182 bool parseSetFeature(uint64_t Feature);
183 bool parseDirectiveCpLoad(SMLoc Loc);
184 bool parseDirectiveCPSetup();
185 bool parseDirectiveNaN();
186 bool parseDirectiveSet();
187 bool parseDirectiveOption();
189 bool parseSetAtDirective();
190 bool parseSetNoAtDirective();
191 bool parseSetMacroDirective();
192 bool parseSetNoMacroDirective();
193 bool parseSetMsaDirective();
194 bool parseSetNoMsaDirective();
195 bool parseSetNoDspDirective();
196 bool parseSetReorderDirective();
197 bool parseSetNoReorderDirective();
198 bool parseSetNoMips16Directive();
199 bool parseSetFpDirective();
200 bool parseSetPopDirective();
201 bool parseSetPushDirective();
203 bool parseSetAssignment();
205 bool parseDataDirective(unsigned Size, SMLoc L);
206 bool parseDirectiveGpWord();
207 bool parseDirectiveGpDWord();
208 bool parseDirectiveModule();
209 bool parseDirectiveModuleFP();
210 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
211 StringRef Directive);
213 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
215 bool eatComma(StringRef ErrorStr);
217 int matchCPURegisterName(StringRef Symbol);
219 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
221 int matchFPURegisterName(StringRef Name);
223 int matchFCCRegisterName(StringRef Name);
225 int matchACRegisterName(StringRef Name);
227 int matchMSA128RegisterName(StringRef Name);
229 int matchMSA128CtrlRegisterName(StringRef Name);
231 unsigned getReg(int RC, int RegNo);
233 unsigned getGPR(int RegNo);
235 int getATReg(SMLoc Loc);
237 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
238 SmallVectorImpl<MCInst> &Instructions);
240 // Helper function that checks if the value of a vector index is within the
241 // boundaries of accepted values for each RegisterKind
242 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
243 bool validateMSAIndex(int Val, int RegKind);
245 // Selects a new architecture by updating the FeatureBits with the necessary
246 // info including implied dependencies.
247 // Internally, it clears all the feature bits related to *any* architecture
248 // and selects the new one using the ToggleFeature functionality of the
249 // MCSubtargetInfo object that handles implied dependencies. The reason we
250 // clear all the arch related bits manually is because ToggleFeature only
251 // clears the features that imply the feature being cleared and not the
252 // features implied by the feature being cleared. This is easier to see
254 // --------------------------------------------------
255 // | Feature | Implies |
256 // | -------------------------------------------------|
257 // | FeatureMips1 | None |
258 // | FeatureMips2 | FeatureMips1 |
259 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
260 // | FeatureMips4 | FeatureMips3 |
262 // --------------------------------------------------
264 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
265 // FeatureMipsGP64 | FeatureMips1)
266 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
267 void selectArch(StringRef ArchFeature) {
268 uint64_t FeatureBits = STI.getFeatureBits();
269 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
270 STI.setFeatureBits(FeatureBits);
271 setAvailableFeatures(
272 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
273 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
276 void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
277 if (!(STI.getFeatureBits() & Feature)) {
278 setAvailableFeatures(
279 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
281 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
284 void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
285 if (STI.getFeatureBits() & Feature) {
286 setAvailableFeatures(
287 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
289 AssemblerOptions.back()->setFeatures(getAvailableFeatures());
293 enum MipsMatchResultTy {
294 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
295 #define GET_OPERAND_DIAGNOSTIC_TYPES
296 #include "MipsGenAsmMatcher.inc"
297 #undef GET_OPERAND_DIAGNOSTIC_TYPES
301 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
302 const MCInstrInfo &MII, const MCTargetOptions &Options)
303 : MCTargetAsmParser(), STI(sti), Parser(parser) {
304 // Initialize the set of available features.
305 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
307 // Remember the initial assembler options. The user can not modify these.
308 AssemblerOptions.push_back(
309 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
311 // Create an assembler options environment for the user to modify.
312 AssemblerOptions.push_back(
313 make_unique<MipsAssemblerOptions>(getAvailableFeatures()));
315 getTargetStreamer().updateABIInfo(*this);
317 // Assert exactly one ABI was chosen.
318 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
319 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
320 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
321 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
323 if (!isABI_O32() && !useOddSPReg() != 0)
324 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
329 MCAsmParser &getParser() const { return Parser; }
330 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
332 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
333 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
335 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
336 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
337 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
338 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
339 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
340 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
342 bool useOddSPReg() const {
343 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
346 bool inMicroMipsMode() const {
347 return STI.getFeatureBits() & Mips::FeatureMicroMips;
349 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
350 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
351 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
352 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
353 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
354 bool hasMips32() const {
355 return (STI.getFeatureBits() & Mips::FeatureMips32);
357 bool hasMips64() const {
358 return (STI.getFeatureBits() & Mips::FeatureMips64);
360 bool hasMips32r2() const {
361 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
363 bool hasMips64r2() const {
364 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
366 bool hasMips32r6() const {
367 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
369 bool hasMips64r6() const {
370 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
372 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
373 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
374 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
376 bool inMips16Mode() const {
377 return STI.getFeatureBits() & Mips::FeatureMips16;
379 // TODO: see how can we get this info.
380 bool abiUsesSoftFloat() const { return false; }
382 /// Warn if RegNo is the current assembler temporary.
383 void warnIfAssemblerTemporary(int RegNo, SMLoc Loc);
389 /// MipsOperand - Instances of this class represent a parsed Mips machine
391 class MipsOperand : public MCParsedAsmOperand {
393 /// Broad categories of register classes
394 /// The exact class is finalized by the render method.
396 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
397 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
399 RegKind_FCC = 4, /// FCC
400 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
401 RegKind_MSACtrl = 16, /// MSA control registers
402 RegKind_COP2 = 32, /// COP2
403 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
405 RegKind_CCR = 128, /// CCR
406 RegKind_HWRegs = 256, /// HWRegs
407 RegKind_COP3 = 512, /// COP3
409 /// Potentially any (e.g. $1)
410 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
411 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
412 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
417 k_Immediate, /// An immediate (possibly involving symbol references)
418 k_Memory, /// Base + Offset Memory Address
419 k_PhysRegister, /// A physical register from the Mips namespace
420 k_RegisterIndex, /// A register index in one or more RegKind.
421 k_Token /// A simple token
425 MipsOperand(KindTy K, MipsAsmParser &Parser)
426 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
429 /// For diagnostics, and checking the assembler temporary
430 MipsAsmParser &AsmParser;
438 unsigned Num; /// Register Number
442 unsigned Index; /// Index into the register class
443 RegKind Kind; /// Bitfield of the kinds it could possibly be
444 const MCRegisterInfo *RegInfo;
458 struct PhysRegOp PhysReg;
459 struct RegIdxOp RegIdx;
464 SMLoc StartLoc, EndLoc;
466 /// Internal constructor for register kinds
467 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
468 const MCRegisterInfo *RegInfo,
470 MipsAsmParser &Parser) {
471 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
472 Op->RegIdx.Index = Index;
473 Op->RegIdx.RegInfo = RegInfo;
474 Op->RegIdx.Kind = RegKind;
481 /// Coerce the register to GPR32 and return the real register for the current
483 unsigned getGPR32Reg() const {
484 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
485 AsmParser.warnIfAssemblerTemporary(RegIdx.Index, StartLoc);
486 unsigned ClassID = Mips::GPR32RegClassID;
487 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
490 /// Coerce the register to GPR64 and return the real register for the current
492 unsigned getGPR64Reg() const {
493 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
494 unsigned ClassID = Mips::GPR64RegClassID;
495 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
499 /// Coerce the register to AFGR64 and return the real register for the current
501 unsigned getAFGR64Reg() const {
502 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
503 if (RegIdx.Index % 2 != 0)
504 AsmParser.Warning(StartLoc, "Float register should be even.");
505 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
506 .getRegister(RegIdx.Index / 2);
509 /// Coerce the register to FGR64 and return the real register for the current
511 unsigned getFGR64Reg() const {
512 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
513 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
514 .getRegister(RegIdx.Index);
517 /// Coerce the register to FGR32 and return the real register for the current
519 unsigned getFGR32Reg() const {
520 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
521 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
522 .getRegister(RegIdx.Index);
525 /// Coerce the register to FGRH32 and return the real register for the current
527 unsigned getFGRH32Reg() const {
528 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
529 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
530 .getRegister(RegIdx.Index);
533 /// Coerce the register to FCC and return the real register for the current
535 unsigned getFCCReg() const {
536 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
537 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
538 .getRegister(RegIdx.Index);
541 /// Coerce the register to MSA128 and return the real register for the current
543 unsigned getMSA128Reg() const {
544 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
545 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
547 unsigned ClassID = Mips::MSA128BRegClassID;
548 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
551 /// Coerce the register to MSACtrl and return the real register for the
553 unsigned getMSACtrlReg() const {
554 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
555 unsigned ClassID = Mips::MSACtrlRegClassID;
556 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
559 /// Coerce the register to COP2 and return the real register for the
561 unsigned getCOP2Reg() const {
562 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
563 unsigned ClassID = Mips::COP2RegClassID;
564 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
567 /// Coerce the register to COP3 and return the real register for the
569 unsigned getCOP3Reg() const {
570 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
571 unsigned ClassID = Mips::COP3RegClassID;
572 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
575 /// Coerce the register to ACC64DSP and return the real register for the
577 unsigned getACC64DSPReg() const {
578 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
579 unsigned ClassID = Mips::ACC64DSPRegClassID;
580 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
583 /// Coerce the register to HI32DSP and return the real register for the
585 unsigned getHI32DSPReg() const {
586 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
587 unsigned ClassID = Mips::HI32DSPRegClassID;
588 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
591 /// Coerce the register to LO32DSP and return the real register for the
593 unsigned getLO32DSPReg() const {
594 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
595 unsigned ClassID = Mips::LO32DSPRegClassID;
596 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
599 /// Coerce the register to CCR and return the real register for the
601 unsigned getCCRReg() const {
602 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
603 unsigned ClassID = Mips::CCRRegClassID;
604 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
607 /// Coerce the register to HWRegs and return the real register for the
609 unsigned getHWRegsReg() const {
610 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
611 unsigned ClassID = Mips::HWRegsRegClassID;
612 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
616 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
617 // Add as immediate when possible. Null MCExpr = 0.
619 Inst.addOperand(MCOperand::CreateImm(0));
620 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
621 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
623 Inst.addOperand(MCOperand::CreateExpr(Expr));
626 void addRegOperands(MCInst &Inst, unsigned N) const {
627 llvm_unreachable("Use a custom parser instead");
630 /// Render the operand to an MCInst as a GPR32
631 /// Asserts if the wrong number of operands are requested, or the operand
632 /// is not a k_RegisterIndex compatible with RegKind_GPR
633 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
634 assert(N == 1 && "Invalid number of operands!");
635 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
638 /// Render the operand to an MCInst as a GPR64
639 /// Asserts if the wrong number of operands are requested, or the operand
640 /// is not a k_RegisterIndex compatible with RegKind_GPR
641 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
642 assert(N == 1 && "Invalid number of operands!");
643 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
646 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
647 assert(N == 1 && "Invalid number of operands!");
648 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
651 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
652 assert(N == 1 && "Invalid number of operands!");
653 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
656 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
657 assert(N == 1 && "Invalid number of operands!");
658 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
659 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
660 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
661 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
665 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
666 assert(N == 1 && "Invalid number of operands!");
667 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
670 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
671 assert(N == 1 && "Invalid number of operands!");
672 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
675 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
676 assert(N == 1 && "Invalid number of operands!");
677 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
680 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
681 assert(N == 1 && "Invalid number of operands!");
682 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
685 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
690 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
695 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
696 assert(N == 1 && "Invalid number of operands!");
697 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
700 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
701 assert(N == 1 && "Invalid number of operands!");
702 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
705 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
706 assert(N == 1 && "Invalid number of operands!");
707 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
710 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
711 assert(N == 1 && "Invalid number of operands!");
712 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
715 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
716 assert(N == 1 && "Invalid number of operands!");
717 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
720 void addImmOperands(MCInst &Inst, unsigned N) const {
721 assert(N == 1 && "Invalid number of operands!");
722 const MCExpr *Expr = getImm();
726 void addMemOperands(MCInst &Inst, unsigned N) const {
727 assert(N == 2 && "Invalid number of operands!");
729 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
731 const MCExpr *Expr = getMemOff();
735 bool isReg() const override {
736 // As a special case until we sort out the definition of div/divu, pretend
737 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
738 if (isGPRAsmReg() && RegIdx.Index == 0)
741 return Kind == k_PhysRegister;
743 bool isRegIdx() const { return Kind == k_RegisterIndex; }
744 bool isImm() const override { return Kind == k_Immediate; }
745 bool isConstantImm() const {
746 return isImm() && dyn_cast<MCConstantExpr>(getImm());
748 bool isToken() const override {
749 // Note: It's not possible to pretend that other operand kinds are tokens.
750 // The matcher emitter checks tokens first.
751 return Kind == k_Token;
753 bool isMem() const override { return Kind == k_Memory; }
754 bool isConstantMemOff() const {
755 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
757 template <unsigned Bits> bool isMemWithSimmOffset() const {
758 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
760 bool isInvNum() const { return Kind == k_Immediate; }
761 bool isLSAImm() const {
762 if (!isConstantImm())
764 int64_t Val = getConstantImm();
765 return 1 <= Val && Val <= 4;
768 StringRef getToken() const {
769 assert(Kind == k_Token && "Invalid access!");
770 return StringRef(Tok.Data, Tok.Length);
773 unsigned getReg() const override {
774 // As a special case until we sort out the definition of div/divu, pretend
775 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
776 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
777 RegIdx.Kind & RegKind_GPR)
778 return getGPR32Reg(); // FIXME: GPR64 too
780 assert(Kind == k_PhysRegister && "Invalid access!");
784 const MCExpr *getImm() const {
785 assert((Kind == k_Immediate) && "Invalid access!");
789 int64_t getConstantImm() const {
790 const MCExpr *Val = getImm();
791 return static_cast<const MCConstantExpr *>(Val)->getValue();
794 MipsOperand *getMemBase() const {
795 assert((Kind == k_Memory) && "Invalid access!");
799 const MCExpr *getMemOff() const {
800 assert((Kind == k_Memory) && "Invalid access!");
804 int64_t getConstantMemOff() const {
805 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
808 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
809 MipsAsmParser &Parser) {
810 auto Op = make_unique<MipsOperand>(k_Token, Parser);
811 Op->Tok.Data = Str.data();
812 Op->Tok.Length = Str.size();
818 /// Create a numeric register (e.g. $1). The exact register remains
819 /// unresolved until an instruction successfully matches
820 static std::unique_ptr<MipsOperand>
821 createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
822 SMLoc E, MipsAsmParser &Parser) {
823 DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
824 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
827 /// Create a register that is definitely a GPR.
828 /// This is typically only used for named registers such as $gp.
829 static std::unique_ptr<MipsOperand>
830 createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
831 MipsAsmParser &Parser) {
832 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
835 /// Create a register that is definitely a FGR.
836 /// This is typically only used for named registers such as $f0.
837 static std::unique_ptr<MipsOperand>
838 createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
839 MipsAsmParser &Parser) {
840 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
843 /// Create a register that is definitely an FCC.
844 /// This is typically only used for named registers such as $fcc0.
845 static std::unique_ptr<MipsOperand>
846 createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
847 MipsAsmParser &Parser) {
848 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
851 /// Create a register that is definitely an ACC.
852 /// This is typically only used for named registers such as $ac0.
853 static std::unique_ptr<MipsOperand>
854 createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
855 MipsAsmParser &Parser) {
856 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
859 /// Create a register that is definitely an MSA128.
860 /// This is typically only used for named registers such as $w0.
861 static std::unique_ptr<MipsOperand>
862 createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
863 SMLoc E, MipsAsmParser &Parser) {
864 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
867 /// Create a register that is definitely an MSACtrl.
868 /// This is typically only used for named registers such as $msaaccess.
869 static std::unique_ptr<MipsOperand>
870 createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
871 SMLoc E, MipsAsmParser &Parser) {
872 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
875 static std::unique_ptr<MipsOperand>
876 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
877 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
884 static std::unique_ptr<MipsOperand>
885 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
886 SMLoc E, MipsAsmParser &Parser) {
887 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
888 Op->Mem.Base = Base.release();
895 bool isGPRAsmReg() const {
896 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
898 bool isFGRAsmReg() const {
899 // AFGR64 is $0-$15 but we handle this in getAFGR64()
900 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
902 bool isHWRegsAsmReg() const {
903 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
905 bool isCCRAsmReg() const {
906 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
908 bool isFCCAsmReg() const {
909 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
911 if (!AsmParser.hasEightFccRegisters())
912 return RegIdx.Index == 0;
913 return RegIdx.Index <= 7;
915 bool isACCAsmReg() const {
916 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
918 bool isCOP2AsmReg() const {
919 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
921 bool isCOP3AsmReg() const {
922 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
924 bool isMSA128AsmReg() const {
925 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
927 bool isMSACtrlAsmReg() const {
928 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
931 /// getStartLoc - Get the location of the first token of this operand.
932 SMLoc getStartLoc() const override { return StartLoc; }
933 /// getEndLoc - Get the location of the last token of this operand.
934 SMLoc getEndLoc() const override { return EndLoc; }
936 virtual ~MipsOperand() {
944 case k_RegisterIndex:
950 void print(raw_ostream &OS) const override {
965 OS << "PhysReg<" << PhysReg.Num << ">";
967 case k_RegisterIndex:
968 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
975 }; // class MipsOperand
979 extern const MCInstrDesc MipsInsts[];
981 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
982 return MipsInsts[Opcode];
985 static bool hasShortDelaySlot(unsigned Opcode) {
989 case Mips::BGEZALS_MM:
990 case Mips::BLTZALS_MM:
997 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
998 SmallVectorImpl<MCInst> &Instructions) {
999 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1003 if (MCID.isBranch() || MCID.isCall()) {
1004 const unsigned Opcode = Inst.getOpcode();
1014 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1015 Offset = Inst.getOperand(2);
1016 if (!Offset.isImm())
1017 break; // We'll deal with this situation later on when applying fixups.
1018 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1019 return Error(IDLoc, "branch target out of range");
1020 if (OffsetToAlignment(Offset.getImm(),
1021 1LL << (inMicroMipsMode() ? 1 : 2)))
1022 return Error(IDLoc, "branch to misaligned address");
1036 case Mips::BGEZAL_MM:
1037 case Mips::BLTZAL_MM:
1040 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1041 Offset = Inst.getOperand(1);
1042 if (!Offset.isImm())
1043 break; // We'll deal with this situation later on when applying fixups.
1044 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1045 return Error(IDLoc, "branch target out of range");
1046 if (OffsetToAlignment(Offset.getImm(),
1047 1LL << (inMicroMipsMode() ? 1 : 2)))
1048 return Error(IDLoc, "branch to misaligned address");
1053 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1054 // We still accept it but it is a normal nop.
1055 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1056 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1057 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1061 if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder()) {
1062 // If this instruction has a delay slot and .set reorder is active,
1063 // emit a NOP after it.
1064 Instructions.push_back(Inst);
1066 if (hasShortDelaySlot(Inst.getOpcode())) {
1067 NopInst.setOpcode(Mips::MOVE16_MM);
1068 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1069 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1071 NopInst.setOpcode(Mips::SLL);
1072 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1073 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1074 NopInst.addOperand(MCOperand::CreateImm(0));
1076 Instructions.push_back(NopInst);
1080 if (MCID.mayLoad() || MCID.mayStore()) {
1081 // Check the offset of memory operand, if it is a symbol
1082 // reference or immediate we may have to expand instructions.
1083 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1084 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1085 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1086 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1087 MCOperand &Op = Inst.getOperand(i);
1089 int MemOffset = Op.getImm();
1090 if (MemOffset < -32768 || MemOffset > 32767) {
1091 // Offset can't exceed 16bit value.
1092 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1095 } else if (Op.isExpr()) {
1096 const MCExpr *Expr = Op.getExpr();
1097 if (Expr->getKind() == MCExpr::SymbolRef) {
1098 const MCSymbolRefExpr *SR =
1099 static_cast<const MCSymbolRefExpr *>(Expr);
1100 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1102 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1105 } else if (!isEvaluated(Expr)) {
1106 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1114 if (needsExpansion(Inst))
1115 return expandInstruction(Inst, IDLoc, Instructions);
1117 Instructions.push_back(Inst);
1122 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1124 switch (Inst.getOpcode()) {
1125 case Mips::LoadImm32Reg:
1126 case Mips::LoadAddr32Imm:
1127 case Mips::LoadAddr32Reg:
1128 case Mips::LoadImm64Reg:
1135 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1136 SmallVectorImpl<MCInst> &Instructions) {
1137 switch (Inst.getOpcode()) {
1139 assert(0 && "unimplemented expansion");
1141 case Mips::LoadImm32Reg:
1142 return expandLoadImm(Inst, IDLoc, Instructions);
1143 case Mips::LoadImm64Reg:
1145 Error(IDLoc, "instruction requires a 64-bit architecture");
1148 return expandLoadImm(Inst, IDLoc, Instructions);
1149 case Mips::LoadAddr32Imm:
1150 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1151 case Mips::LoadAddr32Reg:
1152 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1157 template <bool PerformShift>
1158 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1159 SmallVectorImpl<MCInst> &Instructions) {
1162 tmpInst.setOpcode(Mips::DSLL);
1163 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1164 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1165 tmpInst.addOperand(MCOperand::CreateImm(16));
1166 tmpInst.setLoc(IDLoc);
1167 Instructions.push_back(tmpInst);
1170 tmpInst.setOpcode(Mips::ORi);
1171 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1172 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1173 tmpInst.addOperand(Operand);
1174 tmpInst.setLoc(IDLoc);
1175 Instructions.push_back(tmpInst);
1178 template <int Shift, bool PerformShift>
1179 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1180 SmallVectorImpl<MCInst> &Instructions) {
1181 createShiftOr<PerformShift>(
1182 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1183 IDLoc, Instructions);
1187 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1188 SmallVectorImpl<MCInst> &Instructions) {
1190 const MCOperand &ImmOp = Inst.getOperand(1);
1191 assert(ImmOp.isImm() && "expected immediate operand kind");
1192 const MCOperand &RegOp = Inst.getOperand(0);
1193 assert(RegOp.isReg() && "expected register operand kind");
1195 int64_t ImmValue = ImmOp.getImm();
1196 tmpInst.setLoc(IDLoc);
1197 // FIXME: gas has a special case for values that are 000...1111, which
1198 // becomes a li -1 and then a dsrl
1199 if (0 <= ImmValue && ImmValue <= 65535) {
1200 // For 0 <= j <= 65535.
1201 // li d,j => ori d,$zero,j
1202 tmpInst.setOpcode(Mips::ORi);
1203 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1204 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1205 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1206 Instructions.push_back(tmpInst);
1207 } else if (ImmValue < 0 && ImmValue >= -32768) {
1208 // For -32768 <= j < 0.
1209 // li d,j => addiu d,$zero,j
1210 tmpInst.setOpcode(Mips::ADDiu);
1211 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1212 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1213 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1214 Instructions.push_back(tmpInst);
1215 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1216 // For any value of j that is representable as a 32-bit integer, create
1218 // li d,j => lui d,hi16(j)
1220 tmpInst.setOpcode(Mips::LUi);
1221 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1222 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1223 Instructions.push_back(tmpInst);
1224 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1225 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1227 Error(IDLoc, "instruction requires a 64-bit architecture");
1231 // <------- lo32 ------>
1232 // <------- hi32 ------>
1233 // <- hi16 -> <- lo16 ->
1234 // _________________________________
1236 // | 16-bytes | 16-bytes | 16-bytes |
1237 // |__________|__________|__________|
1239 // For any value of j that is representable as a 48-bit integer, create
1241 // li d,j => lui d,hi16(j)
1242 // ori d,d,hi16(lo32(j))
1244 // ori d,d,lo16(lo32(j))
1245 tmpInst.setOpcode(Mips::LUi);
1246 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1248 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1249 Instructions.push_back(tmpInst);
1250 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1251 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1254 Error(IDLoc, "instruction requires a 64-bit architecture");
1258 // <------- hi32 ------> <------- lo32 ------>
1259 // <- hi16 -> <- lo16 ->
1260 // ___________________________________________
1262 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1263 // |__________|__________|__________|__________|
1265 // For any value of j that isn't representable as a 48-bit integer.
1266 // li d,j => lui d,hi16(j)
1267 // ori d,d,lo16(hi32(j))
1269 // ori d,d,hi16(lo32(j))
1271 // ori d,d,lo16(lo32(j))
1272 tmpInst.setOpcode(Mips::LUi);
1273 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1275 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1276 Instructions.push_back(tmpInst);
1277 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1278 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1279 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1285 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1286 SmallVectorImpl<MCInst> &Instructions) {
1288 const MCOperand &ImmOp = Inst.getOperand(2);
1289 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1290 "expected immediate operand kind");
1291 if (!ImmOp.isImm()) {
1292 expandLoadAddressSym(Inst, IDLoc, Instructions);
1295 const MCOperand &SrcRegOp = Inst.getOperand(1);
1296 assert(SrcRegOp.isReg() && "expected register operand kind");
1297 const MCOperand &DstRegOp = Inst.getOperand(0);
1298 assert(DstRegOp.isReg() && "expected register operand kind");
1299 int ImmValue = ImmOp.getImm();
1300 if (-32768 <= ImmValue && ImmValue <= 65535) {
1301 // For -32768 <= j <= 65535.
1302 // la d,j(s) => addiu d,s,j
1303 tmpInst.setOpcode(Mips::ADDiu);
1304 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1305 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1306 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1307 Instructions.push_back(tmpInst);
1309 // For any other value of j that is representable as a 32-bit integer.
1310 // la d,j(s) => lui d,hi16(j)
1313 tmpInst.setOpcode(Mips::LUi);
1314 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1315 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1316 Instructions.push_back(tmpInst);
1318 tmpInst.setOpcode(Mips::ORi);
1319 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1320 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1321 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1322 Instructions.push_back(tmpInst);
1324 tmpInst.setOpcode(Mips::ADDu);
1325 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1326 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1327 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1328 Instructions.push_back(tmpInst);
1334 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1335 SmallVectorImpl<MCInst> &Instructions) {
1337 const MCOperand &ImmOp = Inst.getOperand(1);
1338 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1339 "expected immediate operand kind");
1340 if (!ImmOp.isImm()) {
1341 expandLoadAddressSym(Inst, IDLoc, Instructions);
1344 const MCOperand &RegOp = Inst.getOperand(0);
1345 assert(RegOp.isReg() && "expected register operand kind");
1346 int ImmValue = ImmOp.getImm();
1347 if (-32768 <= ImmValue && ImmValue <= 65535) {
1348 // For -32768 <= j <= 65535.
1349 // la d,j => addiu d,$zero,j
1350 tmpInst.setOpcode(Mips::ADDiu);
1351 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1352 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1353 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1354 Instructions.push_back(tmpInst);
1356 // For any other value of j that is representable as a 32-bit integer.
1357 // la d,j => lui d,hi16(j)
1359 tmpInst.setOpcode(Mips::LUi);
1360 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1361 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1362 Instructions.push_back(tmpInst);
1364 tmpInst.setOpcode(Mips::ORi);
1365 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1366 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1367 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1368 Instructions.push_back(tmpInst);
1374 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1375 SmallVectorImpl<MCInst> &Instructions) {
1376 // FIXME: If we do have a valid at register to use, we should generate a
1377 // slightly shorter sequence here.
1379 int ExprOperandNo = 1;
1380 // Sometimes the assembly parser will get the immediate expression as
1381 // a $zero + an immediate.
1382 if (Inst.getNumOperands() == 3) {
1383 assert(Inst.getOperand(1).getReg() ==
1384 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1387 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1388 assert(SymOp.isExpr() && "expected symbol operand kind");
1389 const MCOperand &RegOp = Inst.getOperand(0);
1390 unsigned RegNo = RegOp.getReg();
1391 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1392 const MCSymbolRefExpr *HiExpr =
1393 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1394 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1395 const MCSymbolRefExpr *LoExpr =
1396 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1397 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1399 // If it's a 64-bit architecture, expand to:
1400 // la d,sym => lui d,highest(sym)
1401 // ori d,d,higher(sym)
1403 // ori d,d,hi16(sym)
1405 // ori d,d,lo16(sym)
1406 const MCSymbolRefExpr *HighestExpr =
1407 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1408 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1409 const MCSymbolRefExpr *HigherExpr =
1410 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1411 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1413 tmpInst.setOpcode(Mips::LUi);
1414 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1415 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1416 Instructions.push_back(tmpInst);
1418 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1420 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1422 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1425 // Otherwise, expand to:
1426 // la d,sym => lui d,hi16(sym)
1427 // ori d,d,lo16(sym)
1428 tmpInst.setOpcode(Mips::LUi);
1429 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1430 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1431 Instructions.push_back(tmpInst);
1433 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1438 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1439 SmallVectorImpl<MCInst> &Instructions,
1440 bool isLoad, bool isImmOpnd) {
1441 const MCSymbolRefExpr *SR;
1443 unsigned ImmOffset, HiOffset, LoOffset;
1444 const MCExpr *ExprOffset;
1446 // 1st operand is either the source or destination register.
1447 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1448 unsigned RegOpNum = Inst.getOperand(0).getReg();
1449 // 2nd operand is the base register.
1450 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1451 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1452 // 3rd operand is either an immediate or expression.
1454 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1455 ImmOffset = Inst.getOperand(2).getImm();
1456 LoOffset = ImmOffset & 0x0000ffff;
1457 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1458 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1459 if (LoOffset & 0x8000)
1462 ExprOffset = Inst.getOperand(2).getExpr();
1463 // All instructions will have the same location.
1464 TempInst.setLoc(IDLoc);
1465 // These are some of the types of expansions we perform here:
1466 // 1) lw $8, sym => lui $8, %hi(sym)
1467 // lw $8, %lo(sym)($8)
1468 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1470 // lw $8, %lo(offset)($9)
1471 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1473 // lw $8, %lo(offset)($at)
1474 // 4) sw $8, sym => lui $at, %hi(sym)
1475 // sw $8, %lo(sym)($at)
1476 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1478 // sw $8, %lo(offset)($at)
1479 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1480 // ldc1 $f0, %lo(sym)($at)
1482 // For load instructions we can use the destination register as a temporary
1483 // if base and dst are different (examples 1 and 2) and if the base register
1484 // is general purpose otherwise we must use $at (example 6) and error if it's
1485 // not available. For stores we must use $at (examples 4 and 5) because we
1486 // must not clobber the source register setting up the offset.
1487 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1488 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1489 unsigned RegClassIDOp0 =
1490 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1491 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1492 (RegClassIDOp0 == Mips::GPR64RegClassID);
1493 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1494 TmpRegNum = RegOpNum;
1496 int AT = getATReg(IDLoc);
1497 // At this point we need AT to perform the expansions and we exit if it is
1502 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1505 TempInst.setOpcode(Mips::LUi);
1506 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1508 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1510 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1511 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1512 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1513 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1515 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1517 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1518 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1521 // Add the instruction to the list.
1522 Instructions.push_back(TempInst);
1523 // Prepare TempInst for next instruction.
1525 // Add temp register to base.
1526 TempInst.setOpcode(Mips::ADDu);
1527 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1528 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1529 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1530 Instructions.push_back(TempInst);
1532 // And finally, create original instruction with low part
1533 // of offset and new base.
1534 TempInst.setOpcode(Inst.getOpcode());
1535 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1536 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1538 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1540 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1541 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1542 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1544 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1546 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1547 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1550 Instructions.push_back(TempInst);
1554 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1555 // As described by the Mips32r2 spec, the registers Rd and Rs for
1556 // jalr.hb must be different.
1557 unsigned Opcode = Inst.getOpcode();
1559 if (Opcode == Mips::JALR_HB &&
1560 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1561 return Match_RequiresDifferentSrcAndDst;
1563 return Match_Success;
1566 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1567 OperandVector &Operands,
1569 uint64_t &ErrorInfo,
1570 bool MatchingInlineAsm) {
1573 SmallVector<MCInst, 8> Instructions;
1574 unsigned MatchResult =
1575 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1577 switch (MatchResult) {
1580 case Match_Success: {
1581 if (processInstruction(Inst, IDLoc, Instructions))
1583 for (unsigned i = 0; i < Instructions.size(); i++)
1584 Out.EmitInstruction(Instructions[i], STI);
1587 case Match_MissingFeature:
1588 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1590 case Match_InvalidOperand: {
1591 SMLoc ErrorLoc = IDLoc;
1592 if (ErrorInfo != ~0ULL) {
1593 if (ErrorInfo >= Operands.size())
1594 return Error(IDLoc, "too few operands for instruction");
1596 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1597 if (ErrorLoc == SMLoc())
1601 return Error(ErrorLoc, "invalid operand for instruction");
1603 case Match_MnemonicFail:
1604 return Error(IDLoc, "invalid instruction");
1605 case Match_RequiresDifferentSrcAndDst:
1606 return Error(IDLoc, "source and destination must be different");
1611 void MipsAsmParser::warnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1612 if ((RegIndex != 0) &&
1613 ((int)AssemblerOptions.back()->getATRegNum() == RegIndex)) {
1615 Warning(Loc, "used $at without \".set noat\"");
1617 Warning(Loc, Twine("used $") + Twine(RegIndex) + " with \".set at=$" +
1618 Twine(RegIndex) + "\"");
1622 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1625 CC = StringSwitch<unsigned>(Name)
1661 if (!(isABI_N32() || isABI_N64()))
1664 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1665 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1666 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1667 if (8 <= CC && CC <= 11)
1671 CC = StringSwitch<unsigned>(Name)
1683 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1685 if (Name[0] == 'f') {
1686 StringRef NumString = Name.substr(1);
1688 if (NumString.getAsInteger(10, IntVal))
1689 return -1; // This is not an integer.
1690 if (IntVal > 31) // Maximum index for fpu register.
1697 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1699 if (Name.startswith("fcc")) {
1700 StringRef NumString = Name.substr(3);
1702 if (NumString.getAsInteger(10, IntVal))
1703 return -1; // This is not an integer.
1704 if (IntVal > 7) // There are only 8 fcc registers.
1711 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1713 if (Name.startswith("ac")) {
1714 StringRef NumString = Name.substr(2);
1716 if (NumString.getAsInteger(10, IntVal))
1717 return -1; // This is not an integer.
1718 if (IntVal > 3) // There are only 3 acc registers.
1725 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1728 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1737 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1740 CC = StringSwitch<unsigned>(Name)
1743 .Case("msaaccess", 2)
1745 .Case("msamodify", 4)
1746 .Case("msarequest", 5)
1748 .Case("msaunmap", 7)
1754 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1762 int MipsAsmParser::getATReg(SMLoc Loc) {
1763 int AT = AssemblerOptions.back()->getATRegNum();
1765 reportParseError(Loc,
1766 "pseudo-instruction requires $at, which is not available");
1770 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1771 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1774 unsigned MipsAsmParser::getGPR(int RegNo) {
1775 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1779 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1781 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1784 return getReg(RegClass, RegNum);
1787 bool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
1788 DEBUG(dbgs() << "parseOperand\n");
1790 // Check if the current operand has a custom associated parser, if so, try to
1791 // custom parse the operand, or fallback to the general approach.
1792 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1793 if (ResTy == MatchOperand_Success)
1795 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1796 // there was a match, but an error occurred, in which case, just return that
1797 // the operand parsing failed.
1798 if (ResTy == MatchOperand_ParseFail)
1801 DEBUG(dbgs() << ".. Generic Parser\n");
1803 switch (getLexer().getKind()) {
1805 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1807 case AsmToken::Dollar: {
1808 // Parse the register.
1809 SMLoc S = Parser.getTok().getLoc();
1811 // Almost all registers have been parsed by custom parsers. There is only
1812 // one exception to this. $zero (and it's alias $0) will reach this point
1813 // for div, divu, and similar instructions because it is not an operand
1814 // to the instruction definition but an explicit register. Special case
1815 // this situation for now.
1816 if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
1819 // Maybe it is a symbol reference.
1820 StringRef Identifier;
1821 if (Parser.parseIdentifier(Identifier))
1824 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1825 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1826 // Otherwise create a symbol reference.
1828 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1830 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1833 // Else drop to expression parsing.
1834 case AsmToken::LParen:
1835 case AsmToken::Minus:
1836 case AsmToken::Plus:
1837 case AsmToken::Integer:
1838 case AsmToken::Tilde:
1839 case AsmToken::String: {
1840 DEBUG(dbgs() << ".. generic integer\n");
1841 OperandMatchResultTy ResTy = parseImm(Operands);
1842 return ResTy != MatchOperand_Success;
1844 case AsmToken::Percent: {
1845 // It is a symbol reference or constant expression.
1846 const MCExpr *IdVal;
1847 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1848 if (parseRelocOperand(IdVal))
1851 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1853 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1855 } // case AsmToken::Percent
1856 } // switch(getLexer().getKind())
1860 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1861 StringRef RelocStr) {
1863 // Check the type of the expression.
1864 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1865 // It's a constant, evaluate reloc value.
1867 switch (getVariantKind(RelocStr)) {
1868 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1869 // Get the 1st 16-bits.
1870 Val = MCE->getValue() & 0xffff;
1872 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1873 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1874 // 16 bits being negative.
1875 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1877 case MCSymbolRefExpr::VK_Mips_HIGHER:
1878 // Get the 3rd 16-bits.
1879 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1881 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1882 // Get the 4th 16-bits.
1883 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1886 report_fatal_error("unsupported reloc value");
1888 return MCConstantExpr::Create(Val, getContext());
1891 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1892 // It's a symbol, create a symbolic expression from the symbol.
1893 StringRef Symbol = MSRE->getSymbol().getName();
1894 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1895 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1899 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1900 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1902 // Try to create target expression.
1903 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1904 return MipsMCExpr::Create(VK, Expr, getContext());
1906 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1907 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1908 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1912 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1913 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1914 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1917 // Just return the original expression.
1921 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1923 switch (Expr->getKind()) {
1924 case MCExpr::Constant:
1926 case MCExpr::SymbolRef:
1927 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1928 case MCExpr::Binary:
1929 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1930 if (!isEvaluated(BE->getLHS()))
1932 return isEvaluated(BE->getRHS());
1935 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1936 case MCExpr::Target:
1942 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1943 Parser.Lex(); // Eat the % token.
1944 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1945 if (Tok.isNot(AsmToken::Identifier))
1948 std::string Str = Tok.getIdentifier().str();
1950 Parser.Lex(); // Eat the identifier.
1951 // Now make an expression from the rest of the operand.
1952 const MCExpr *IdVal;
1955 if (getLexer().getKind() == AsmToken::LParen) {
1957 Parser.Lex(); // Eat the '(' token.
1958 if (getLexer().getKind() == AsmToken::Percent) {
1959 Parser.Lex(); // Eat the % token.
1960 const AsmToken &nextTok = Parser.getTok();
1961 if (nextTok.isNot(AsmToken::Identifier))
1964 Str += nextTok.getIdentifier();
1965 Parser.Lex(); // Eat the identifier.
1966 if (getLexer().getKind() != AsmToken::LParen)
1971 if (getParser().parseParenExpression(IdVal, EndLoc))
1974 while (getLexer().getKind() == AsmToken::RParen)
1975 Parser.Lex(); // Eat the ')' token.
1978 return true; // Parenthesis must follow the relocation operand.
1980 Res = evaluateRelocExpr(IdVal, Str);
1984 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1986 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1987 OperandMatchResultTy ResTy = parseAnyRegister(Operands);
1988 if (ResTy == MatchOperand_Success) {
1989 assert(Operands.size() == 1);
1990 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1991 StartLoc = Operand.getStartLoc();
1992 EndLoc = Operand.getEndLoc();
1994 // AFAIK, we only support numeric registers and named GPR's in CFI
1996 // Don't worry about eating tokens before failing. Using an unrecognised
1997 // register is a parse error.
1998 if (Operand.isGPRAsmReg()) {
1999 // Resolve to GPR32 or GPR64 appropriately.
2000 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
2003 return (RegNo == (unsigned)-1);
2006 assert(Operands.size() == 0);
2007 return (RegNo == (unsigned)-1);
2010 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
2014 while (getLexer().getKind() == AsmToken::LParen)
2017 switch (getLexer().getKind()) {
2020 case AsmToken::Identifier:
2021 case AsmToken::LParen:
2022 case AsmToken::Integer:
2023 case AsmToken::Minus:
2024 case AsmToken::Plus:
2026 Result = getParser().parseParenExpression(Res, S);
2028 Result = (getParser().parseExpression(Res));
2029 while (getLexer().getKind() == AsmToken::RParen)
2032 case AsmToken::Percent:
2033 Result = parseRelocOperand(Res);
2038 MipsAsmParser::OperandMatchResultTy
2039 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
2040 DEBUG(dbgs() << "parseMemOperand\n");
2041 const MCExpr *IdVal = nullptr;
2043 bool isParenExpr = false;
2044 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
2045 // First operand is the offset.
2046 S = Parser.getTok().getLoc();
2048 if (getLexer().getKind() == AsmToken::LParen) {
2053 if (getLexer().getKind() != AsmToken::Dollar) {
2054 if (parseMemOffset(IdVal, isParenExpr))
2055 return MatchOperand_ParseFail;
2057 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2058 if (Tok.isNot(AsmToken::LParen)) {
2059 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2060 if (Mnemonic.getToken() == "la") {
2062 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2063 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2064 return MatchOperand_Success;
2066 if (Tok.is(AsmToken::EndOfStatement)) {
2068 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2070 // Zero register assumed, add a memory operand with ZERO as its base.
2071 // "Base" will be managed by k_Memory.
2072 auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
2075 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2076 return MatchOperand_Success;
2078 Error(Parser.getTok().getLoc(), "'(' expected");
2079 return MatchOperand_ParseFail;
2082 Parser.Lex(); // Eat the '(' token.
2085 Res = parseAnyRegister(Operands);
2086 if (Res != MatchOperand_Success)
2089 if (Parser.getTok().isNot(AsmToken::RParen)) {
2090 Error(Parser.getTok().getLoc(), "')' expected");
2091 return MatchOperand_ParseFail;
2094 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2096 Parser.Lex(); // Eat the ')' token.
2099 IdVal = MCConstantExpr::Create(0, getContext());
2101 // Replace the register operand with the memory operand.
2102 std::unique_ptr<MipsOperand> op(
2103 static_cast<MipsOperand *>(Operands.back().release()));
2104 // Remove the register from the operands.
2105 // "op" will be managed by k_Memory.
2106 Operands.pop_back();
2107 // Add the memory operand.
2108 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2110 if (IdVal->EvaluateAsAbsolute(Imm))
2111 IdVal = MCConstantExpr::Create(Imm, getContext());
2112 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2113 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2117 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2118 return MatchOperand_Success;
2121 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2123 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2125 SMLoc S = Parser.getTok().getLoc();
2127 if (Sym->isVariable())
2128 Expr = Sym->getVariableValue();
2131 if (Expr->getKind() == MCExpr::SymbolRef) {
2132 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2133 StringRef DefSymbol = Ref->getSymbol().getName();
2134 if (DefSymbol.startswith("$")) {
2135 OperandMatchResultTy ResTy =
2136 matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2137 if (ResTy == MatchOperand_Success) {
2140 } else if (ResTy == MatchOperand_ParseFail)
2141 llvm_unreachable("Should never ParseFail");
2144 } else if (Expr->getKind() == MCExpr::Constant) {
2146 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2148 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2155 MipsAsmParser::OperandMatchResultTy
2156 MipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2157 StringRef Identifier,
2159 int Index = matchCPURegisterName(Identifier);
2161 Operands.push_back(MipsOperand::createGPRReg(
2162 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2163 return MatchOperand_Success;
2166 Index = matchFPURegisterName(Identifier);
2168 Operands.push_back(MipsOperand::createFGRReg(
2169 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2170 return MatchOperand_Success;
2173 Index = matchFCCRegisterName(Identifier);
2175 Operands.push_back(MipsOperand::createFCCReg(
2176 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2177 return MatchOperand_Success;
2180 Index = matchACRegisterName(Identifier);
2182 Operands.push_back(MipsOperand::createACCReg(
2183 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2184 return MatchOperand_Success;
2187 Index = matchMSA128RegisterName(Identifier);
2189 Operands.push_back(MipsOperand::createMSA128Reg(
2190 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2191 return MatchOperand_Success;
2194 Index = matchMSA128CtrlRegisterName(Identifier);
2196 Operands.push_back(MipsOperand::createMSACtrlReg(
2197 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2198 return MatchOperand_Success;
2201 return MatchOperand_NoMatch;
2204 MipsAsmParser::OperandMatchResultTy
2205 MipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2206 auto Token = Parser.getLexer().peekTok(false);
2208 if (Token.is(AsmToken::Identifier)) {
2209 DEBUG(dbgs() << ".. identifier\n");
2210 StringRef Identifier = Token.getIdentifier();
2211 OperandMatchResultTy ResTy =
2212 matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2214 } else if (Token.is(AsmToken::Integer)) {
2215 DEBUG(dbgs() << ".. integer\n");
2216 Operands.push_back(MipsOperand::createNumericReg(
2217 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2219 return MatchOperand_Success;
2222 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2224 return MatchOperand_NoMatch;
2227 MipsAsmParser::OperandMatchResultTy
2228 MipsAsmParser::parseAnyRegister(OperandVector &Operands) {
2229 DEBUG(dbgs() << "parseAnyRegister\n");
2231 auto Token = Parser.getTok();
2233 SMLoc S = Token.getLoc();
2235 if (Token.isNot(AsmToken::Dollar)) {
2236 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2237 if (Token.is(AsmToken::Identifier)) {
2238 if (searchSymbolAlias(Operands))
2239 return MatchOperand_Success;
2241 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2242 return MatchOperand_NoMatch;
2244 DEBUG(dbgs() << ".. $\n");
2246 OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
2247 if (ResTy == MatchOperand_Success) {
2249 Parser.Lex(); // identifier
2254 MipsAsmParser::OperandMatchResultTy
2255 MipsAsmParser::parseImm(OperandVector &Operands) {
2256 switch (getLexer().getKind()) {
2258 return MatchOperand_NoMatch;
2259 case AsmToken::LParen:
2260 case AsmToken::Minus:
2261 case AsmToken::Plus:
2262 case AsmToken::Integer:
2263 case AsmToken::Tilde:
2264 case AsmToken::String:
2268 const MCExpr *IdVal;
2269 SMLoc S = Parser.getTok().getLoc();
2270 if (getParser().parseExpression(IdVal))
2271 return MatchOperand_ParseFail;
2273 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2274 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2275 return MatchOperand_Success;
2278 MipsAsmParser::OperandMatchResultTy
2279 MipsAsmParser::parseJumpTarget(OperandVector &Operands) {
2280 DEBUG(dbgs() << "parseJumpTarget\n");
2282 SMLoc S = getLexer().getLoc();
2284 // Integers and expressions are acceptable
2285 OperandMatchResultTy ResTy = parseImm(Operands);
2286 if (ResTy != MatchOperand_NoMatch)
2289 // Registers are a valid target and have priority over symbols.
2290 ResTy = parseAnyRegister(Operands);
2291 if (ResTy != MatchOperand_NoMatch)
2294 const MCExpr *Expr = nullptr;
2295 if (Parser.parseExpression(Expr)) {
2296 // We have no way of knowing if a symbol was consumed so we must ParseFail
2297 return MatchOperand_ParseFail;
2300 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2301 return MatchOperand_Success;
2304 MipsAsmParser::OperandMatchResultTy
2305 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2306 const MCExpr *IdVal;
2307 // If the first token is '$' we may have register operand.
2308 if (Parser.getTok().is(AsmToken::Dollar))
2309 return MatchOperand_NoMatch;
2310 SMLoc S = Parser.getTok().getLoc();
2311 if (getParser().parseExpression(IdVal))
2312 return MatchOperand_ParseFail;
2313 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2314 assert(MCE && "Unexpected MCExpr type.");
2315 int64_t Val = MCE->getValue();
2316 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2317 Operands.push_back(MipsOperand::CreateImm(
2318 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2319 return MatchOperand_Success;
2322 MipsAsmParser::OperandMatchResultTy
2323 MipsAsmParser::parseLSAImm(OperandVector &Operands) {
2324 switch (getLexer().getKind()) {
2326 return MatchOperand_NoMatch;
2327 case AsmToken::LParen:
2328 case AsmToken::Plus:
2329 case AsmToken::Minus:
2330 case AsmToken::Integer:
2335 SMLoc S = Parser.getTok().getLoc();
2337 if (getParser().parseExpression(Expr))
2338 return MatchOperand_ParseFail;
2341 if (!Expr->EvaluateAsAbsolute(Val)) {
2342 Error(S, "expected immediate value");
2343 return MatchOperand_ParseFail;
2346 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2347 // and because the CPU always adds one to the immediate field, the allowed
2348 // range becomes 1..4. We'll only check the range here and will deal
2349 // with the addition/subtraction when actually decoding/encoding
2351 if (Val < 1 || Val > 4) {
2352 Error(S, "immediate not in range (1..4)");
2353 return MatchOperand_ParseFail;
2357 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2358 return MatchOperand_Success;
2361 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2363 MCSymbolRefExpr::VariantKind VK =
2364 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2365 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2366 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2367 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2368 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2369 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2370 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2371 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2372 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2373 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2374 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2375 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2376 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2377 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2378 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2379 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2380 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2381 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2382 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2383 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2384 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2385 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2386 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2387 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2388 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2389 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2390 .Default(MCSymbolRefExpr::VK_None);
2392 assert(VK != MCSymbolRefExpr::VK_None);
2397 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2399 /// ::= '(', register, ')'
2400 /// handle it before we iterate so we don't get tripped up by the lack of
2402 bool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
2403 if (getLexer().is(AsmToken::LParen)) {
2405 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2407 if (parseOperand(Operands, Name)) {
2408 SMLoc Loc = getLexer().getLoc();
2409 Parser.eatToEndOfStatement();
2410 return Error(Loc, "unexpected token in argument list");
2412 if (Parser.getTok().isNot(AsmToken::RParen)) {
2413 SMLoc Loc = getLexer().getLoc();
2414 Parser.eatToEndOfStatement();
2415 return Error(Loc, "unexpected token, expected ')'");
2418 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2424 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2425 /// either one of these.
2426 /// ::= '[', register, ']'
2427 /// ::= '[', integer, ']'
2428 /// handle it before we iterate so we don't get tripped up by the lack of
2430 bool MipsAsmParser::parseBracketSuffix(StringRef Name,
2431 OperandVector &Operands) {
2432 if (getLexer().is(AsmToken::LBrac)) {
2434 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2436 if (parseOperand(Operands, Name)) {
2437 SMLoc Loc = getLexer().getLoc();
2438 Parser.eatToEndOfStatement();
2439 return Error(Loc, "unexpected token in argument list");
2441 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2442 SMLoc Loc = getLexer().getLoc();
2443 Parser.eatToEndOfStatement();
2444 return Error(Loc, "unexpected token, expected ']'");
2447 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2453 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2454 SMLoc NameLoc, OperandVector &Operands) {
2455 DEBUG(dbgs() << "ParseInstruction\n");
2457 // We have reached first instruction, module directive are now forbidden.
2458 getTargetStreamer().forbidModuleDirective();
2460 // Check if we have valid mnemonic
2461 if (!mnemonicIsValid(Name, 0)) {
2462 Parser.eatToEndOfStatement();
2463 return Error(NameLoc, "unknown instruction");
2465 // First operand in MCInst is instruction mnemonic.
2466 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2468 // Read the remaining operands.
2469 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2470 // Read the first operand.
2471 if (parseOperand(Operands, Name)) {
2472 SMLoc Loc = getLexer().getLoc();
2473 Parser.eatToEndOfStatement();
2474 return Error(Loc, "unexpected token in argument list");
2476 if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
2478 // AFAIK, parenthesis suffixes are never on the first operand
2480 while (getLexer().is(AsmToken::Comma)) {
2481 Parser.Lex(); // Eat the comma.
2482 // Parse and remember the operand.
2483 if (parseOperand(Operands, Name)) {
2484 SMLoc Loc = getLexer().getLoc();
2485 Parser.eatToEndOfStatement();
2486 return Error(Loc, "unexpected token in argument list");
2488 // Parse bracket and parenthesis suffixes before we iterate
2489 if (getLexer().is(AsmToken::LBrac)) {
2490 if (parseBracketSuffix(Name, Operands))
2492 } else if (getLexer().is(AsmToken::LParen) &&
2493 parseParenSuffix(Name, Operands))
2497 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2498 SMLoc Loc = getLexer().getLoc();
2499 Parser.eatToEndOfStatement();
2500 return Error(Loc, "unexpected token in argument list");
2502 Parser.Lex(); // Consume the EndOfStatement.
2506 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2507 SMLoc Loc = getLexer().getLoc();
2508 Parser.eatToEndOfStatement();
2509 return Error(Loc, ErrorMsg);
2512 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2513 return Error(Loc, ErrorMsg);
2516 bool MipsAsmParser::parseSetNoAtDirective() {
2517 // Line should look like: ".set noat".
2519 AssemblerOptions.back()->setATReg(0);
2522 // If this is not the end of the statement, report an error.
2523 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2524 reportParseError("unexpected token, expected end of statement");
2527 Parser.Lex(); // Consume the EndOfStatement.
2531 bool MipsAsmParser::parseSetAtDirective() {
2532 // Line can be .set at - defaults to $1
2536 if (getLexer().is(AsmToken::EndOfStatement)) {
2537 AssemblerOptions.back()->setATReg(1);
2538 Parser.Lex(); // Consume the EndOfStatement.
2540 } else if (getLexer().is(AsmToken::Equal)) {
2541 getParser().Lex(); // Eat the '='.
2542 if (getLexer().isNot(AsmToken::Dollar)) {
2543 reportParseError("unexpected token, expected dollar sign '$'");
2546 Parser.Lex(); // Eat the '$'.
2547 const AsmToken &Reg = Parser.getTok();
2548 if (Reg.is(AsmToken::Identifier)) {
2549 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2550 } else if (Reg.is(AsmToken::Integer)) {
2551 AtRegNo = Reg.getIntVal();
2553 reportParseError("unexpected token, expected identifier or integer");
2557 if (AtRegNo < 0 || AtRegNo > 31) {
2558 reportParseError("unexpected token in statement");
2562 if (!AssemblerOptions.back()->setATReg(AtRegNo)) {
2563 reportParseError("invalid register");
2566 getParser().Lex(); // Eat the register.
2568 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2569 reportParseError("unexpected token, expected end of statement");
2572 Parser.Lex(); // Consume the EndOfStatement.
2575 reportParseError("unexpected token in statement");
2580 bool MipsAsmParser::parseSetReorderDirective() {
2582 // If this is not the end of the statement, report an error.
2583 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2584 reportParseError("unexpected token, expected end of statement");
2587 AssemblerOptions.back()->setReorder();
2588 getTargetStreamer().emitDirectiveSetReorder();
2589 Parser.Lex(); // Consume the EndOfStatement.
2593 bool MipsAsmParser::parseSetNoReorderDirective() {
2595 // If this is not the end of the statement, report an error.
2596 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2597 reportParseError("unexpected token, expected end of statement");
2600 AssemblerOptions.back()->setNoReorder();
2601 getTargetStreamer().emitDirectiveSetNoReorder();
2602 Parser.Lex(); // Consume the EndOfStatement.
2606 bool MipsAsmParser::parseSetMacroDirective() {
2608 // If this is not the end of the statement, report an error.
2609 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2610 reportParseError("unexpected token, expected end of statement");
2613 AssemblerOptions.back()->setMacro();
2614 Parser.Lex(); // Consume the EndOfStatement.
2618 bool MipsAsmParser::parseSetNoMacroDirective() {
2620 // If this is not the end of the statement, report an error.
2621 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2622 reportParseError("unexpected token, expected end of statement");
2625 if (AssemblerOptions.back()->isReorder()) {
2626 reportParseError("`noreorder' must be set before `nomacro'");
2629 AssemblerOptions.back()->setNoMacro();
2630 Parser.Lex(); // Consume the EndOfStatement.
2634 bool MipsAsmParser::parseSetMsaDirective() {
2637 // If this is not the end of the statement, report an error.
2638 if (getLexer().isNot(AsmToken::EndOfStatement))
2639 return reportParseError("unexpected token, expected end of statement");
2641 setFeatureBits(Mips::FeatureMSA, "msa");
2642 getTargetStreamer().emitDirectiveSetMsa();
2646 bool MipsAsmParser::parseSetNoMsaDirective() {
2649 // If this is not the end of the statement, report an error.
2650 if (getLexer().isNot(AsmToken::EndOfStatement))
2651 return reportParseError("unexpected token, expected end of statement");
2653 clearFeatureBits(Mips::FeatureMSA, "msa");
2654 getTargetStreamer().emitDirectiveSetNoMsa();
2658 bool MipsAsmParser::parseSetNoDspDirective() {
2659 Parser.Lex(); // Eat "nodsp".
2661 // If this is not the end of the statement, report an error.
2662 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2663 reportParseError("unexpected token, expected end of statement");
2667 clearFeatureBits(Mips::FeatureDSP, "dsp");
2668 getTargetStreamer().emitDirectiveSetNoDsp();
2672 bool MipsAsmParser::parseSetNoMips16Directive() {
2674 // If this is not the end of the statement, report an error.
2675 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2676 reportParseError("unexpected token, expected end of statement");
2679 // For now do nothing.
2680 Parser.Lex(); // Consume the EndOfStatement.
2684 bool MipsAsmParser::parseSetFpDirective() {
2685 MipsABIFlagsSection::FpABIKind FpAbiVal;
2686 // Line can be: .set fp=32
2689 Parser.Lex(); // Eat fp token
2690 AsmToken Tok = Parser.getTok();
2691 if (Tok.isNot(AsmToken::Equal)) {
2692 reportParseError("unexpected token, expected equals sign '='");
2695 Parser.Lex(); // Eat '=' token.
2696 Tok = Parser.getTok();
2698 if (!parseFpABIValue(FpAbiVal, ".set"))
2701 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2702 reportParseError("unexpected token, expected end of statement");
2705 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2706 Parser.Lex(); // Consume the EndOfStatement.
2710 bool MipsAsmParser::parseSetPopDirective() {
2711 SMLoc Loc = getLexer().getLoc();
2714 if (getLexer().isNot(AsmToken::EndOfStatement))
2715 return reportParseError("unexpected token, expected end of statement");
2717 // Always keep an element on the options "stack" to prevent the user
2718 // from changing the initial options. This is how we remember them.
2719 if (AssemblerOptions.size() == 2)
2720 return reportParseError(Loc, ".set pop with no .set push");
2722 AssemblerOptions.pop_back();
2723 setAvailableFeatures(AssemblerOptions.back()->getFeatures());
2725 getTargetStreamer().emitDirectiveSetPop();
2729 bool MipsAsmParser::parseSetPushDirective() {
2731 if (getLexer().isNot(AsmToken::EndOfStatement))
2732 return reportParseError("unexpected token, expected end of statement");
2734 // Create a copy of the current assembler options environment and push it.
2735 AssemblerOptions.push_back(
2736 make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
2738 getTargetStreamer().emitDirectiveSetPush();
2742 bool MipsAsmParser::parseSetAssignment() {
2744 const MCExpr *Value;
2746 if (Parser.parseIdentifier(Name))
2747 reportParseError("expected identifier after .set");
2749 if (getLexer().isNot(AsmToken::Comma))
2750 return reportParseError("unexpected token, expected comma");
2753 if (Parser.parseExpression(Value))
2754 return reportParseError("expected valid expression after comma");
2756 // Check if the Name already exists as a symbol.
2757 MCSymbol *Sym = getContext().LookupSymbol(Name);
2759 return reportParseError("symbol already defined");
2760 Sym = getContext().GetOrCreateSymbol(Name);
2761 Sym->setVariableValue(Value);
2766 bool MipsAsmParser::parseSetMips0Directive() {
2768 if (getLexer().isNot(AsmToken::EndOfStatement))
2769 return reportParseError("unexpected token, expected end of statement");
2771 // Reset assembler options to their initial values.
2772 setAvailableFeatures(AssemblerOptions.front()->getFeatures());
2773 AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
2775 getTargetStreamer().emitDirectiveSetMips0();
2779 bool MipsAsmParser::parseSetArchDirective() {
2781 if (getLexer().isNot(AsmToken::Equal))
2782 return reportParseError("unexpected token, expected equals sign");
2786 if (Parser.parseIdentifier(Arch))
2787 return reportParseError("expected arch identifier");
2789 StringRef ArchFeatureName =
2790 StringSwitch<StringRef>(Arch)
2791 .Case("mips1", "mips1")
2792 .Case("mips2", "mips2")
2793 .Case("mips3", "mips3")
2794 .Case("mips4", "mips4")
2795 .Case("mips5", "mips5")
2796 .Case("mips32", "mips32")
2797 .Case("mips32r2", "mips32r2")
2798 .Case("mips32r6", "mips32r6")
2799 .Case("mips64", "mips64")
2800 .Case("mips64r2", "mips64r2")
2801 .Case("mips64r6", "mips64r6")
2802 .Case("cnmips", "cnmips")
2803 .Case("r4000", "mips3") // This is an implementation of Mips3.
2806 if (ArchFeatureName.empty())
2807 return reportParseError("unsupported architecture");
2809 selectArch(ArchFeatureName);
2810 getTargetStreamer().emitDirectiveSetArch(Arch);
2814 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2816 if (getLexer().isNot(AsmToken::EndOfStatement))
2817 return reportParseError("unexpected token, expected end of statement");
2821 llvm_unreachable("Unimplemented feature");
2822 case Mips::FeatureDSP:
2823 setFeatureBits(Mips::FeatureDSP, "dsp");
2824 getTargetStreamer().emitDirectiveSetDsp();
2826 case Mips::FeatureMicroMips:
2827 getTargetStreamer().emitDirectiveSetMicroMips();
2829 case Mips::FeatureMips16:
2830 getTargetStreamer().emitDirectiveSetMips16();
2832 case Mips::FeatureMips1:
2833 selectArch("mips1");
2834 getTargetStreamer().emitDirectiveSetMips1();
2836 case Mips::FeatureMips2:
2837 selectArch("mips2");
2838 getTargetStreamer().emitDirectiveSetMips2();
2840 case Mips::FeatureMips3:
2841 selectArch("mips3");
2842 getTargetStreamer().emitDirectiveSetMips3();
2844 case Mips::FeatureMips4:
2845 selectArch("mips4");
2846 getTargetStreamer().emitDirectiveSetMips4();
2848 case Mips::FeatureMips5:
2849 selectArch("mips5");
2850 getTargetStreamer().emitDirectiveSetMips5();
2852 case Mips::FeatureMips32:
2853 selectArch("mips32");
2854 getTargetStreamer().emitDirectiveSetMips32();
2856 case Mips::FeatureMips32r2:
2857 selectArch("mips32r2");
2858 getTargetStreamer().emitDirectiveSetMips32R2();
2860 case Mips::FeatureMips32r6:
2861 selectArch("mips32r6");
2862 getTargetStreamer().emitDirectiveSetMips32R6();
2864 case Mips::FeatureMips64:
2865 selectArch("mips64");
2866 getTargetStreamer().emitDirectiveSetMips64();
2868 case Mips::FeatureMips64r2:
2869 selectArch("mips64r2");
2870 getTargetStreamer().emitDirectiveSetMips64R2();
2872 case Mips::FeatureMips64r6:
2873 selectArch("mips64r6");
2874 getTargetStreamer().emitDirectiveSetMips64R6();
2880 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2881 if (getLexer().isNot(AsmToken::Comma)) {
2882 SMLoc Loc = getLexer().getLoc();
2883 Parser.eatToEndOfStatement();
2884 return Error(Loc, ErrorStr);
2887 Parser.Lex(); // Eat the comma.
2891 bool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
2892 if (AssemblerOptions.back()->isReorder())
2893 Warning(Loc, ".cpload in reorder section");
2895 // FIXME: Warn if cpload is used in Mips16 mode.
2897 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2898 OperandMatchResultTy ResTy = parseAnyRegister(Reg);
2899 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2900 reportParseError("expected register containing function address");
2904 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2905 if (!RegOpnd.isGPRAsmReg()) {
2906 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2910 getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
2914 bool MipsAsmParser::parseDirectiveCPSetup() {
2917 bool SaveIsReg = true;
2919 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2920 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
2921 if (ResTy == MatchOperand_NoMatch) {
2922 reportParseError("expected register containing function address");
2923 Parser.eatToEndOfStatement();
2927 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2928 if (!FuncRegOpnd.isGPRAsmReg()) {
2929 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2930 Parser.eatToEndOfStatement();
2934 FuncReg = FuncRegOpnd.getGPR32Reg();
2937 if (!eatComma("unexpected token, expected comma"))
2940 ResTy = parseAnyRegister(TmpReg);
2941 if (ResTy == MatchOperand_NoMatch) {
2942 const AsmToken &Tok = Parser.getTok();
2943 if (Tok.is(AsmToken::Integer)) {
2944 Save = Tok.getIntVal();
2948 reportParseError("expected save register or stack offset");
2949 Parser.eatToEndOfStatement();
2953 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2954 if (!SaveOpnd.isGPRAsmReg()) {
2955 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2956 Parser.eatToEndOfStatement();
2959 Save = SaveOpnd.getGPR32Reg();
2962 if (!eatComma("unexpected token, expected comma"))
2966 if (Parser.parseIdentifier(Name))
2967 reportParseError("expected identifier");
2968 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2970 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2974 bool MipsAsmParser::parseDirectiveNaN() {
2975 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2976 const AsmToken &Tok = Parser.getTok();
2978 if (Tok.getString() == "2008") {
2980 getTargetStreamer().emitDirectiveNaN2008();
2982 } else if (Tok.getString() == "legacy") {
2984 getTargetStreamer().emitDirectiveNaNLegacy();
2988 // If we don't recognize the option passed to the .nan
2989 // directive (e.g. no option or unknown option), emit an error.
2990 reportParseError("invalid option in .nan directive");
2994 bool MipsAsmParser::parseDirectiveSet() {
2996 // Get the next token.
2997 const AsmToken &Tok = Parser.getTok();
2999 if (Tok.getString() == "noat") {
3000 return parseSetNoAtDirective();
3001 } else if (Tok.getString() == "at") {
3002 return parseSetAtDirective();
3003 } else if (Tok.getString() == "arch") {
3004 return parseSetArchDirective();
3005 } else if (Tok.getString() == "fp") {
3006 return parseSetFpDirective();
3007 } else if (Tok.getString() == "pop") {
3008 return parseSetPopDirective();
3009 } else if (Tok.getString() == "push") {
3010 return parseSetPushDirective();
3011 } else if (Tok.getString() == "reorder") {
3012 return parseSetReorderDirective();
3013 } else if (Tok.getString() == "noreorder") {
3014 return parseSetNoReorderDirective();
3015 } else if (Tok.getString() == "macro") {
3016 return parseSetMacroDirective();
3017 } else if (Tok.getString() == "nomacro") {
3018 return parseSetNoMacroDirective();
3019 } else if (Tok.getString() == "mips16") {
3020 return parseSetFeature(Mips::FeatureMips16);
3021 } else if (Tok.getString() == "nomips16") {
3022 return parseSetNoMips16Directive();
3023 } else if (Tok.getString() == "nomicromips") {
3024 getTargetStreamer().emitDirectiveSetNoMicroMips();
3025 Parser.eatToEndOfStatement();
3027 } else if (Tok.getString() == "micromips") {
3028 return parseSetFeature(Mips::FeatureMicroMips);
3029 } else if (Tok.getString() == "mips0") {
3030 return parseSetMips0Directive();
3031 } else if (Tok.getString() == "mips1") {
3032 return parseSetFeature(Mips::FeatureMips1);
3033 } else if (Tok.getString() == "mips2") {
3034 return parseSetFeature(Mips::FeatureMips2);
3035 } else if (Tok.getString() == "mips3") {
3036 return parseSetFeature(Mips::FeatureMips3);
3037 } else if (Tok.getString() == "mips4") {
3038 return parseSetFeature(Mips::FeatureMips4);
3039 } else if (Tok.getString() == "mips5") {
3040 return parseSetFeature(Mips::FeatureMips5);
3041 } else if (Tok.getString() == "mips32") {
3042 return parseSetFeature(Mips::FeatureMips32);
3043 } else if (Tok.getString() == "mips32r2") {
3044 return parseSetFeature(Mips::FeatureMips32r2);
3045 } else if (Tok.getString() == "mips32r6") {
3046 return parseSetFeature(Mips::FeatureMips32r6);
3047 } else if (Tok.getString() == "mips64") {
3048 return parseSetFeature(Mips::FeatureMips64);
3049 } else if (Tok.getString() == "mips64r2") {
3050 return parseSetFeature(Mips::FeatureMips64r2);
3051 } else if (Tok.getString() == "mips64r6") {
3052 return parseSetFeature(Mips::FeatureMips64r6);
3053 } else if (Tok.getString() == "dsp") {
3054 return parseSetFeature(Mips::FeatureDSP);
3055 } else if (Tok.getString() == "nodsp") {
3056 return parseSetNoDspDirective();
3057 } else if (Tok.getString() == "msa") {
3058 return parseSetMsaDirective();
3059 } else if (Tok.getString() == "nomsa") {
3060 return parseSetNoMsaDirective();
3062 // It is just an identifier, look for an assignment.
3063 parseSetAssignment();
3070 /// parseDataDirective
3071 /// ::= .word [ expression (, expression)* ]
3072 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
3073 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3075 const MCExpr *Value;
3076 if (getParser().parseExpression(Value))
3079 getParser().getStreamer().EmitValue(Value, Size);
3081 if (getLexer().is(AsmToken::EndOfStatement))
3084 if (getLexer().isNot(AsmToken::Comma))
3085 return Error(L, "unexpected token, expected comma");
3094 /// parseDirectiveGpWord
3095 /// ::= .gpword local_sym
3096 bool MipsAsmParser::parseDirectiveGpWord() {
3097 const MCExpr *Value;
3098 // EmitGPRel32Value requires an expression, so we are using base class
3099 // method to evaluate the expression.
3100 if (getParser().parseExpression(Value))
3102 getParser().getStreamer().EmitGPRel32Value(Value);
3104 if (getLexer().isNot(AsmToken::EndOfStatement))
3105 return Error(getLexer().getLoc(),
3106 "unexpected token, expected end of statement");
3107 Parser.Lex(); // Eat EndOfStatement token.
3111 /// parseDirectiveGpDWord
3112 /// ::= .gpdword local_sym
3113 bool MipsAsmParser::parseDirectiveGpDWord() {
3114 const MCExpr *Value;
3115 // EmitGPRel64Value requires an expression, so we are using base class
3116 // method to evaluate the expression.
3117 if (getParser().parseExpression(Value))
3119 getParser().getStreamer().EmitGPRel64Value(Value);
3121 if (getLexer().isNot(AsmToken::EndOfStatement))
3122 return Error(getLexer().getLoc(),
3123 "unexpected token, expected end of statement");
3124 Parser.Lex(); // Eat EndOfStatement token.
3128 bool MipsAsmParser::parseDirectiveOption() {
3129 // Get the option token.
3130 AsmToken Tok = Parser.getTok();
3131 // At the moment only identifiers are supported.
3132 if (Tok.isNot(AsmToken::Identifier)) {
3133 Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
3134 Parser.eatToEndOfStatement();
3138 StringRef Option = Tok.getIdentifier();
3140 if (Option == "pic0") {
3141 getTargetStreamer().emitDirectiveOptionPic0();
3143 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3144 Error(Parser.getTok().getLoc(),
3145 "unexpected token, expected end of statement");
3146 Parser.eatToEndOfStatement();
3151 if (Option == "pic2") {
3152 getTargetStreamer().emitDirectiveOptionPic2();
3154 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3155 Error(Parser.getTok().getLoc(),
3156 "unexpected token, expected end of statement");
3157 Parser.eatToEndOfStatement();
3163 Warning(Parser.getTok().getLoc(),
3164 "unknown option, expected 'pic0' or 'pic2'");
3165 Parser.eatToEndOfStatement();
3169 /// parseDirectiveModule
3170 /// ::= .module oddspreg
3171 /// ::= .module nooddspreg
3172 /// ::= .module fp=value
3173 bool MipsAsmParser::parseDirectiveModule() {
3174 MCAsmLexer &Lexer = getLexer();
3175 SMLoc L = Lexer.getLoc();
3177 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3178 // TODO : get a better message.
3179 reportParseError(".module directive must appear before any code");
3183 if (Lexer.is(AsmToken::Identifier)) {
3184 StringRef Option = Parser.getTok().getString();
3187 if (Option == "oddspreg") {
3188 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3189 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3191 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3192 reportParseError("unexpected token, expected end of statement");
3197 } else if (Option == "nooddspreg") {
3199 Error(L, "'.module nooddspreg' requires the O32 ABI");
3203 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3204 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3206 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3207 reportParseError("unexpected token, expected end of statement");
3212 } else if (Option == "fp") {
3213 return parseDirectiveModuleFP();
3216 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3222 /// parseDirectiveModuleFP
3226 bool MipsAsmParser::parseDirectiveModuleFP() {
3227 MCAsmLexer &Lexer = getLexer();
3229 if (Lexer.isNot(AsmToken::Equal)) {
3230 reportParseError("unexpected token, expected equals sign '='");
3233 Parser.Lex(); // Eat '=' token.
3235 MipsABIFlagsSection::FpABIKind FpABI;
3236 if (!parseFpABIValue(FpABI, ".module"))
3239 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3240 reportParseError("unexpected token, expected end of statement");
3244 // Emit appropriate flags.
3245 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3246 Parser.Lex(); // Consume the EndOfStatement.
3250 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3251 StringRef Directive) {
3252 MCAsmLexer &Lexer = getLexer();
3254 if (Lexer.is(AsmToken::Identifier)) {
3255 StringRef Value = Parser.getTok().getString();
3258 if (Value != "xx") {
3259 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3264 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3268 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3272 if (Lexer.is(AsmToken::Integer)) {
3273 unsigned Value = Parser.getTok().getIntVal();
3276 if (Value != 32 && Value != 64) {
3277 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3283 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3287 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3289 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3297 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3298 StringRef IDVal = DirectiveID.getString();
3300 if (IDVal == ".cpload")
3301 return parseDirectiveCpLoad(DirectiveID.getLoc());
3302 if (IDVal == ".dword") {
3303 parseDataDirective(8, DirectiveID.getLoc());
3306 if (IDVal == ".ent") {
3307 StringRef SymbolName;
3309 if (Parser.parseIdentifier(SymbolName)) {
3310 reportParseError("expected identifier after .ent");
3314 // There's an undocumented extension that allows an integer to
3315 // follow the name of the procedure which AFAICS is ignored by GAS.
3316 // Example: .ent foo,2
3317 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3318 if (getLexer().isNot(AsmToken::Comma)) {
3319 // Even though we accept this undocumented extension for compatibility
3320 // reasons, the additional integer argument does not actually change
3321 // the behaviour of the '.ent' directive, so we would like to discourage
3322 // its use. We do this by not referring to the extended version in
3323 // error messages which are not directly related to its use.
3324 reportParseError("unexpected token, expected end of statement");
3327 Parser.Lex(); // Eat the comma.
3328 const MCExpr *DummyNumber;
3329 int64_t DummyNumberVal;
3330 // If the user was explicitly trying to use the extended version,
3331 // we still give helpful extension-related error messages.
3332 if (Parser.parseExpression(DummyNumber)) {
3333 reportParseError("expected number after comma");
3336 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3337 reportParseError("expected an absolute expression after comma");
3342 // If this is not the end of the statement, report an error.
3343 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3344 reportParseError("unexpected token, expected end of statement");
3348 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3350 getTargetStreamer().emitDirectiveEnt(*Sym);
3355 if (IDVal == ".end") {
3356 StringRef SymbolName;
3358 if (Parser.parseIdentifier(SymbolName)) {
3359 reportParseError("expected identifier after .end");
3363 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3364 reportParseError("unexpected token, expected end of statement");
3368 if (CurrentFn == nullptr) {
3369 reportParseError(".end used without .ent");
3373 if ((SymbolName != CurrentFn->getName())) {
3374 reportParseError(".end symbol does not match .ent symbol");
3378 getTargetStreamer().emitDirectiveEnd(SymbolName);
3379 CurrentFn = nullptr;
3383 if (IDVal == ".frame") {
3384 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3385 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3386 OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
3387 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3388 reportParseError("expected stack register");
3392 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3393 if (!StackRegOpnd.isGPRAsmReg()) {
3394 reportParseError(StackRegOpnd.getStartLoc(),
3395 "expected general purpose register");
3398 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3400 if (Parser.getTok().is(AsmToken::Comma))
3403 reportParseError("unexpected token, expected comma");
3407 // Parse the frame size.
3408 const MCExpr *FrameSize;
3409 int64_t FrameSizeVal;
3411 if (Parser.parseExpression(FrameSize)) {
3412 reportParseError("expected frame size value");
3416 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3417 reportParseError("frame size not an absolute expression");
3421 if (Parser.getTok().is(AsmToken::Comma))
3424 reportParseError("unexpected token, expected comma");
3428 // Parse the return register.
3430 ResTy = parseAnyRegister(TmpReg);
3431 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3432 reportParseError("expected return register");
3436 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3437 if (!ReturnRegOpnd.isGPRAsmReg()) {
3438 reportParseError(ReturnRegOpnd.getStartLoc(),
3439 "expected general purpose register");
3443 // If this is not the end of the statement, report an error.
3444 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3445 reportParseError("unexpected token, expected end of statement");
3449 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3450 ReturnRegOpnd.getGPR32Reg());
3454 if (IDVal == ".set") {
3455 return parseDirectiveSet();
3458 if (IDVal == ".mask" || IDVal == ".fmask") {
3459 // .mask bitmask, frame_offset
3460 // bitmask: One bit for each register used.
3461 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3462 // first register is expected to be saved.
3464 // .mask 0x80000000, -4
3465 // .fmask 0x80000000, -4
3468 // Parse the bitmask
3469 const MCExpr *BitMask;
3472 if (Parser.parseExpression(BitMask)) {
3473 reportParseError("expected bitmask value");
3477 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3478 reportParseError("bitmask not an absolute expression");
3482 if (Parser.getTok().is(AsmToken::Comma))
3485 reportParseError("unexpected token, expected comma");
3489 // Parse the frame_offset
3490 const MCExpr *FrameOffset;
3491 int64_t FrameOffsetVal;
3493 if (Parser.parseExpression(FrameOffset)) {
3494 reportParseError("expected frame offset value");
3498 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3499 reportParseError("frame offset not an absolute expression");
3503 // If this is not the end of the statement, report an error.
3504 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3505 reportParseError("unexpected token, expected end of statement");
3509 if (IDVal == ".mask")
3510 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3512 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3516 if (IDVal == ".nan")
3517 return parseDirectiveNaN();
3519 if (IDVal == ".gpword") {
3520 parseDirectiveGpWord();
3524 if (IDVal == ".gpdword") {
3525 parseDirectiveGpDWord();
3529 if (IDVal == ".word") {
3530 parseDataDirective(4, DirectiveID.getLoc());
3534 if (IDVal == ".option")
3535 return parseDirectiveOption();
3537 if (IDVal == ".abicalls") {
3538 getTargetStreamer().emitDirectiveAbiCalls();
3539 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3540 Error(Parser.getTok().getLoc(),
3541 "unexpected token, expected end of statement");
3543 Parser.eatToEndOfStatement();
3548 if (IDVal == ".cpsetup")
3549 return parseDirectiveCPSetup();
3551 if (IDVal == ".module")
3552 return parseDirectiveModule();
3557 extern "C" void LLVMInitializeMipsAsmParser() {
3558 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3559 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3560 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3561 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3564 #define GET_REGISTER_MATCHER
3565 #define GET_MATCHER_IMPLEMENTATION
3566 #include "MipsGenAsmMatcher.inc"