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/MC/MCContext.h"
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstBuilder.h"
20 #include "llvm/MC/MCParser/MCAsmLexer.h"
21 #include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22 #include "llvm/MC/MCStreamer.h"
23 #include "llvm/MC/MCSubtargetInfo.h"
24 #include "llvm/MC/MCSymbol.h"
25 #include "llvm/MC/MCTargetAsmParser.h"
26 #include "llvm/Support/Debug.h"
27 #include "llvm/Support/MathExtras.h"
28 #include "llvm/Support/TargetRegistry.h"
32 #define DEBUG_TYPE "mips-asm-parser"
39 class MipsAssemblerOptions {
41 MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
43 unsigned getATRegNum() { return aTReg; }
44 bool setATReg(unsigned Reg);
46 bool isReorder() { return reorder; }
47 void setReorder() { reorder = true; }
48 void setNoreorder() { reorder = false; }
50 bool isMacro() { return macro; }
51 void setMacro() { macro = true; }
52 void setNomacro() { macro = false; }
54 // Set of features that are either architecture features or referenced
55 // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
56 // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
57 // The reason we need this mask is explained in the selectArch function.
58 // FIXME: Ideally we would like TableGen to generate this information.
59 static const uint64_t AllArchRelatedMask =
60 Mips::FeatureMips1 | Mips::FeatureMips2 | Mips::FeatureMips3 |
61 Mips::FeatureMips3_32 | Mips::FeatureMips3_32r2 | Mips::FeatureMips4 |
62 Mips::FeatureMips4_32 | Mips::FeatureMips4_32r2 | Mips::FeatureMips5 |
63 Mips::FeatureMips5_32r2 | Mips::FeatureMips32 | Mips::FeatureMips32r2 |
64 Mips::FeatureMips32r6 | Mips::FeatureMips64 | Mips::FeatureMips64r2 |
65 Mips::FeatureMips64r6 | Mips::FeatureCnMips | Mips::FeatureFP64Bit |
66 Mips::FeatureGP64Bit | Mips::FeatureNaN2008;
76 class MipsAsmParser : public MCTargetAsmParser {
77 MipsTargetStreamer &getTargetStreamer() {
78 MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
79 return static_cast<MipsTargetStreamer &>(TS);
84 MipsAssemblerOptions Options;
85 MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
86 // nullptr, which indicates that no function is currently
87 // selected. This usually happens after an '.end func'
90 #define GET_ASSEMBLER_HEADER
91 #include "MipsGenAsmMatcher.inc"
93 unsigned checkTargetMatchPredicate(MCInst &Inst) override;
95 bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
96 OperandVector &Operands, MCStreamer &Out,
98 bool MatchingInlineAsm) override;
100 /// Parse a register as used in CFI directives
101 bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
103 bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
105 bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
107 bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
108 SMLoc NameLoc, OperandVector &Operands) override;
110 bool ParseDirective(AsmToken DirectiveID) override;
112 MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
114 MipsAsmParser::OperandMatchResultTy
115 MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
116 StringRef Identifier, SMLoc S);
118 MipsAsmParser::OperandMatchResultTy
119 MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
121 MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
123 MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
125 MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
127 MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
129 MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
131 bool searchSymbolAlias(OperandVector &Operands);
133 bool ParseOperand(OperandVector &, StringRef Mnemonic);
135 bool needsExpansion(MCInst &Inst);
137 // Expands assembly pseudo instructions.
138 // Returns false on success, true otherwise.
139 bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
140 SmallVectorImpl<MCInst> &Instructions);
142 bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
143 SmallVectorImpl<MCInst> &Instructions);
145 bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
146 SmallVectorImpl<MCInst> &Instructions);
148 bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
149 SmallVectorImpl<MCInst> &Instructions);
151 void expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
152 SmallVectorImpl<MCInst> &Instructions);
154 void expandMemInst(MCInst &Inst, SMLoc IDLoc,
155 SmallVectorImpl<MCInst> &Instructions, bool isLoad,
157 bool reportParseError(Twine ErrorMsg);
158 bool reportParseError(SMLoc Loc, Twine ErrorMsg);
160 bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
161 bool parseRelocOperand(const MCExpr *&Res);
163 const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
165 bool isEvaluated(const MCExpr *Expr);
166 bool parseSetFeature(uint64_t Feature);
167 bool parseDirectiveCPLoad(SMLoc Loc);
168 bool parseDirectiveCPSetup();
169 bool parseDirectiveNaN();
170 bool parseDirectiveSet();
171 bool parseDirectiveOption();
173 bool parseSetAtDirective();
174 bool parseSetNoAtDirective();
175 bool parseSetMacroDirective();
176 bool parseSetNoMacroDirective();
177 bool parseSetMsaDirective();
178 bool parseSetNoMsaDirective();
179 bool parseSetReorderDirective();
180 bool parseSetNoReorderDirective();
181 bool parseSetNoMips16Directive();
182 bool parseSetFpDirective();
184 bool parseSetAssignment();
186 bool parseDataDirective(unsigned Size, SMLoc L);
187 bool parseDirectiveGpWord();
188 bool parseDirectiveGpDWord();
189 bool parseDirectiveModule();
190 bool parseDirectiveModuleFP();
191 bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
192 StringRef Directive);
194 MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
196 bool eatComma(StringRef ErrorStr);
198 int matchCPURegisterName(StringRef Symbol);
200 int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
202 int matchFPURegisterName(StringRef Name);
204 int matchFCCRegisterName(StringRef Name);
206 int matchACRegisterName(StringRef Name);
208 int matchMSA128RegisterName(StringRef Name);
210 int matchMSA128CtrlRegisterName(StringRef Name);
212 unsigned getReg(int RC, int RegNo);
214 unsigned getGPR(int RegNo);
216 int getATReg(SMLoc Loc);
218 bool processInstruction(MCInst &Inst, SMLoc IDLoc,
219 SmallVectorImpl<MCInst> &Instructions);
221 // Helper function that checks if the value of a vector index is within the
222 // boundaries of accepted values for each RegisterKind
223 // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
224 bool validateMSAIndex(int Val, int RegKind);
226 // Selects a new architecture by updating the FeatureBits with the necessary
227 // info including implied dependencies.
228 // Internally, it clears all the feature bits related to *any* architecture
229 // and selects the new one using the ToggleFeature functionality of the
230 // MCSubtargetInfo object that handles implied dependencies. The reason we
231 // clear all the arch related bits manually is because ToggleFeature only
232 // clears the features that imply the feature being cleared and not the
233 // features implied by the feature being cleared. This is easier to see
235 // --------------------------------------------------
236 // | Feature | Implies |
237 // | -------------------------------------------------|
238 // | FeatureMips1 | None |
239 // | FeatureMips2 | FeatureMips1 |
240 // | FeatureMips3 | FeatureMips2 | FeatureMipsGP64 |
241 // | FeatureMips4 | FeatureMips3 |
243 // --------------------------------------------------
245 // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
246 // FeatureMipsGP64 | FeatureMips1)
247 // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
248 void selectArch(StringRef ArchFeature) {
249 uint64_t FeatureBits = STI.getFeatureBits();
250 FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
251 STI.setFeatureBits(FeatureBits);
252 setAvailableFeatures(
253 ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
256 void setFeatureBits(unsigned Feature, StringRef FeatureString) {
257 if (!(STI.getFeatureBits() & Feature)) {
258 setAvailableFeatures(
259 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
263 void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
264 if (STI.getFeatureBits() & Feature) {
265 setAvailableFeatures(
266 ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
271 enum MipsMatchResultTy {
272 Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
273 #define GET_OPERAND_DIAGNOSTIC_TYPES
274 #include "MipsGenAsmMatcher.inc"
275 #undef GET_OPERAND_DIAGNOSTIC_TYPES
279 MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
280 const MCInstrInfo &MII, const MCTargetOptions &Options)
281 : MCTargetAsmParser(), STI(sti), Parser(parser) {
282 // Initialize the set of available features.
283 setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
285 getTargetStreamer().updateABIInfo(*this);
287 // Assert exactly one ABI was chosen.
288 assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
289 ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
290 ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
291 ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
293 if (!isABI_O32() && !useOddSPReg() != 0)
294 report_fatal_error("-mno-odd-spreg requires the O32 ABI");
299 MCAsmParser &getParser() const { return Parser; }
300 MCAsmLexer &getLexer() const { return Parser.getLexer(); }
302 /// True if all of $fcc0 - $fcc7 exist for the current ISA.
303 bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
305 bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
306 bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
307 bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
308 bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
309 bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
310 bool isABI_FPXX() const { return STI.getFeatureBits() & Mips::FeatureFPXX; }
312 bool useOddSPReg() const {
313 return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
316 bool inMicroMipsMode() const {
317 return STI.getFeatureBits() & Mips::FeatureMicroMips;
319 bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
320 bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
321 bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
322 bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
323 bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
324 bool hasMips32() const {
325 return (STI.getFeatureBits() & Mips::FeatureMips32);
327 bool hasMips64() const {
328 return (STI.getFeatureBits() & Mips::FeatureMips64);
330 bool hasMips32r2() const {
331 return (STI.getFeatureBits() & Mips::FeatureMips32r2);
333 bool hasMips64r2() const {
334 return (STI.getFeatureBits() & Mips::FeatureMips64r2);
336 bool hasMips32r6() const {
337 return (STI.getFeatureBits() & Mips::FeatureMips32r6);
339 bool hasMips64r6() const {
340 return (STI.getFeatureBits() & Mips::FeatureMips64r6);
342 bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
343 bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
344 bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
346 bool inMips16Mode() const {
347 return STI.getFeatureBits() & Mips::FeatureMips16;
349 // TODO: see how can we get this info.
350 bool abiUsesSoftFloat() const { return false; }
352 /// Warn if RegNo is the current assembler temporary.
353 void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
359 /// MipsOperand - Instances of this class represent a parsed Mips machine
361 class MipsOperand : public MCParsedAsmOperand {
363 /// Broad categories of register classes
364 /// The exact class is finalized by the render method.
366 RegKind_GPR = 1, /// GPR32 and GPR64 (depending on isGP64bit())
367 RegKind_FGR = 2, /// FGR32, FGR64, AFGR64 (depending on context and
369 RegKind_FCC = 4, /// FCC
370 RegKind_MSA128 = 8, /// MSA128[BHWD] (makes no difference which)
371 RegKind_MSACtrl = 16, /// MSA control registers
372 RegKind_COP2 = 32, /// COP2
373 RegKind_ACC = 64, /// HI32DSP, LO32DSP, and ACC64DSP (depending on
375 RegKind_CCR = 128, /// CCR
376 RegKind_HWRegs = 256, /// HWRegs
377 RegKind_COP3 = 512, /// COP3
379 /// Potentially any (e.g. $1)
380 RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
381 RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
382 RegKind_CCR | RegKind_HWRegs | RegKind_COP3
387 k_Immediate, /// An immediate (possibly involving symbol references)
388 k_Memory, /// Base + Offset Memory Address
389 k_PhysRegister, /// A physical register from the Mips namespace
390 k_RegisterIndex, /// A register index in one or more RegKind.
391 k_Token /// A simple token
395 MipsOperand(KindTy K, MipsAsmParser &Parser)
396 : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
399 /// For diagnostics, and checking the assembler temporary
400 MipsAsmParser &AsmParser;
408 unsigned Num; /// Register Number
412 unsigned Index; /// Index into the register class
413 RegKind Kind; /// Bitfield of the kinds it could possibly be
414 const MCRegisterInfo *RegInfo;
428 struct PhysRegOp PhysReg;
429 struct RegIdxOp RegIdx;
434 SMLoc StartLoc, EndLoc;
436 /// Internal constructor for register kinds
437 static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
438 const MCRegisterInfo *RegInfo,
440 MipsAsmParser &Parser) {
441 auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
442 Op->RegIdx.Index = Index;
443 Op->RegIdx.RegInfo = RegInfo;
444 Op->RegIdx.Kind = RegKind;
451 /// Coerce the register to GPR32 and return the real register for the current
453 unsigned getGPR32Reg() const {
454 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
455 AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
456 unsigned ClassID = Mips::GPR32RegClassID;
457 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
460 /// Coerce the register to GPR64 and return the real register for the current
462 unsigned getGPR64Reg() const {
463 assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
464 unsigned ClassID = Mips::GPR64RegClassID;
465 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
469 /// Coerce the register to AFGR64 and return the real register for the current
471 unsigned getAFGR64Reg() const {
472 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
473 if (RegIdx.Index % 2 != 0)
474 AsmParser.Warning(StartLoc, "Float register should be even.");
475 return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
476 .getRegister(RegIdx.Index / 2);
479 /// Coerce the register to FGR64 and return the real register for the current
481 unsigned getFGR64Reg() const {
482 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
483 return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
484 .getRegister(RegIdx.Index);
487 /// Coerce the register to FGR32 and return the real register for the current
489 unsigned getFGR32Reg() const {
490 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
491 return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
492 .getRegister(RegIdx.Index);
495 /// Coerce the register to FGRH32 and return the real register for the current
497 unsigned getFGRH32Reg() const {
498 assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
499 return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
500 .getRegister(RegIdx.Index);
503 /// Coerce the register to FCC and return the real register for the current
505 unsigned getFCCReg() const {
506 assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
507 return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
508 .getRegister(RegIdx.Index);
511 /// Coerce the register to MSA128 and return the real register for the current
513 unsigned getMSA128Reg() const {
514 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
515 // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
517 unsigned ClassID = Mips::MSA128BRegClassID;
518 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
521 /// Coerce the register to MSACtrl and return the real register for the
523 unsigned getMSACtrlReg() const {
524 assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
525 unsigned ClassID = Mips::MSACtrlRegClassID;
526 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
529 /// Coerce the register to COP2 and return the real register for the
531 unsigned getCOP2Reg() const {
532 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
533 unsigned ClassID = Mips::COP2RegClassID;
534 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
537 /// Coerce the register to COP3 and return the real register for the
539 unsigned getCOP3Reg() const {
540 assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
541 unsigned ClassID = Mips::COP3RegClassID;
542 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
545 /// Coerce the register to ACC64DSP and return the real register for the
547 unsigned getACC64DSPReg() const {
548 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
549 unsigned ClassID = Mips::ACC64DSPRegClassID;
550 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
553 /// Coerce the register to HI32DSP and return the real register for the
555 unsigned getHI32DSPReg() const {
556 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
557 unsigned ClassID = Mips::HI32DSPRegClassID;
558 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
561 /// Coerce the register to LO32DSP and return the real register for the
563 unsigned getLO32DSPReg() const {
564 assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
565 unsigned ClassID = Mips::LO32DSPRegClassID;
566 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
569 /// Coerce the register to CCR and return the real register for the
571 unsigned getCCRReg() const {
572 assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
573 unsigned ClassID = Mips::CCRRegClassID;
574 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
577 /// Coerce the register to HWRegs and return the real register for the
579 unsigned getHWRegsReg() const {
580 assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
581 unsigned ClassID = Mips::HWRegsRegClassID;
582 return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
586 void addExpr(MCInst &Inst, const MCExpr *Expr) const {
587 // Add as immediate when possible. Null MCExpr = 0.
589 Inst.addOperand(MCOperand::CreateImm(0));
590 else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
591 Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
593 Inst.addOperand(MCOperand::CreateExpr(Expr));
596 void addRegOperands(MCInst &Inst, unsigned N) const {
597 llvm_unreachable("Use a custom parser instead");
600 /// Render the operand to an MCInst as a GPR32
601 /// Asserts if the wrong number of operands are requested, or the operand
602 /// is not a k_RegisterIndex compatible with RegKind_GPR
603 void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
604 assert(N == 1 && "Invalid number of operands!");
605 Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
608 /// Render the operand to an MCInst as a GPR64
609 /// Asserts if the wrong number of operands are requested, or the operand
610 /// is not a k_RegisterIndex compatible with RegKind_GPR
611 void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
612 assert(N == 1 && "Invalid number of operands!");
613 Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
616 void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
617 assert(N == 1 && "Invalid number of operands!");
618 Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
621 void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
622 assert(N == 1 && "Invalid number of operands!");
623 Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
626 void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
627 assert(N == 1 && "Invalid number of operands!");
628 Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
629 // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
630 if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
631 AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
635 void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
636 assert(N == 1 && "Invalid number of operands!");
637 Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
640 void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
641 assert(N == 1 && "Invalid number of operands!");
642 Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
645 void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
646 assert(N == 1 && "Invalid number of operands!");
647 Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
650 void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
651 assert(N == 1 && "Invalid number of operands!");
652 Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
655 void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
656 assert(N == 1 && "Invalid number of operands!");
657 Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
660 void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
661 assert(N == 1 && "Invalid number of operands!");
662 Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
665 void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
666 assert(N == 1 && "Invalid number of operands!");
667 Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
670 void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
671 assert(N == 1 && "Invalid number of operands!");
672 Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
675 void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
676 assert(N == 1 && "Invalid number of operands!");
677 Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
680 void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
681 assert(N == 1 && "Invalid number of operands!");
682 Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
685 void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
686 assert(N == 1 && "Invalid number of operands!");
687 Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
690 void addImmOperands(MCInst &Inst, unsigned N) const {
691 assert(N == 1 && "Invalid number of operands!");
692 const MCExpr *Expr = getImm();
696 void addMemOperands(MCInst &Inst, unsigned N) const {
697 assert(N == 2 && "Invalid number of operands!");
699 Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
701 const MCExpr *Expr = getMemOff();
705 bool isReg() const override {
706 // As a special case until we sort out the definition of div/divu, pretend
707 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
708 if (isGPRAsmReg() && RegIdx.Index == 0)
711 return Kind == k_PhysRegister;
713 bool isRegIdx() const { return Kind == k_RegisterIndex; }
714 bool isImm() const override { return Kind == k_Immediate; }
715 bool isConstantImm() const {
716 return isImm() && dyn_cast<MCConstantExpr>(getImm());
718 bool isToken() const override {
719 // Note: It's not possible to pretend that other operand kinds are tokens.
720 // The matcher emitter checks tokens first.
721 return Kind == k_Token;
723 bool isMem() const override { return Kind == k_Memory; }
724 bool isConstantMemOff() const {
725 return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
727 template <unsigned Bits> bool isMemWithSimmOffset() const {
728 return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
730 bool isInvNum() const { return Kind == k_Immediate; }
731 bool isLSAImm() const {
732 if (!isConstantImm())
734 int64_t Val = getConstantImm();
735 return 1 <= Val && Val <= 4;
738 StringRef getToken() const {
739 assert(Kind == k_Token && "Invalid access!");
740 return StringRef(Tok.Data, Tok.Length);
743 unsigned getReg() const override {
744 // As a special case until we sort out the definition of div/divu, pretend
745 // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
746 if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
747 RegIdx.Kind & RegKind_GPR)
748 return getGPR32Reg(); // FIXME: GPR64 too
750 assert(Kind == k_PhysRegister && "Invalid access!");
754 const MCExpr *getImm() const {
755 assert((Kind == k_Immediate) && "Invalid access!");
759 int64_t getConstantImm() const {
760 const MCExpr *Val = getImm();
761 return static_cast<const MCConstantExpr *>(Val)->getValue();
764 MipsOperand *getMemBase() const {
765 assert((Kind == k_Memory) && "Invalid access!");
769 const MCExpr *getMemOff() const {
770 assert((Kind == k_Memory) && "Invalid access!");
774 int64_t getConstantMemOff() const {
775 return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
778 static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
779 MipsAsmParser &Parser) {
780 auto Op = make_unique<MipsOperand>(k_Token, Parser);
781 Op->Tok.Data = Str.data();
782 Op->Tok.Length = Str.size();
788 /// Create a numeric register (e.g. $1). The exact register remains
789 /// unresolved until an instruction successfully matches
790 static std::unique_ptr<MipsOperand>
791 CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
792 SMLoc E, MipsAsmParser &Parser) {
793 DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
794 return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
797 /// Create a register that is definitely a GPR.
798 /// This is typically only used for named registers such as $gp.
799 static std::unique_ptr<MipsOperand>
800 CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
801 MipsAsmParser &Parser) {
802 return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
805 /// Create a register that is definitely a FGR.
806 /// This is typically only used for named registers such as $f0.
807 static std::unique_ptr<MipsOperand>
808 CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
809 MipsAsmParser &Parser) {
810 return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
813 /// Create a register that is definitely an FCC.
814 /// This is typically only used for named registers such as $fcc0.
815 static std::unique_ptr<MipsOperand>
816 CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
817 MipsAsmParser &Parser) {
818 return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
821 /// Create a register that is definitely an ACC.
822 /// This is typically only used for named registers such as $ac0.
823 static std::unique_ptr<MipsOperand>
824 CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
825 MipsAsmParser &Parser) {
826 return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
829 /// Create a register that is definitely an MSA128.
830 /// This is typically only used for named registers such as $w0.
831 static std::unique_ptr<MipsOperand>
832 CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
833 SMLoc E, MipsAsmParser &Parser) {
834 return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
837 /// Create a register that is definitely an MSACtrl.
838 /// This is typically only used for named registers such as $msaaccess.
839 static std::unique_ptr<MipsOperand>
840 CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
841 SMLoc E, MipsAsmParser &Parser) {
842 return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
845 static std::unique_ptr<MipsOperand>
846 CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
847 auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
854 static std::unique_ptr<MipsOperand>
855 CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
856 SMLoc E, MipsAsmParser &Parser) {
857 auto Op = make_unique<MipsOperand>(k_Memory, Parser);
858 Op->Mem.Base = Base.release();
865 bool isGPRAsmReg() const {
866 return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
868 bool isFGRAsmReg() const {
869 // AFGR64 is $0-$15 but we handle this in getAFGR64()
870 return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
872 bool isHWRegsAsmReg() const {
873 return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
875 bool isCCRAsmReg() const {
876 return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
878 bool isFCCAsmReg() const {
879 if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
881 if (!AsmParser.hasEightFccRegisters())
882 return RegIdx.Index == 0;
883 return RegIdx.Index <= 7;
885 bool isACCAsmReg() const {
886 return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
888 bool isCOP2AsmReg() const {
889 return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
891 bool isCOP3AsmReg() const {
892 return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
894 bool isMSA128AsmReg() const {
895 return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
897 bool isMSACtrlAsmReg() const {
898 return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
901 /// getStartLoc - Get the location of the first token of this operand.
902 SMLoc getStartLoc() const override { return StartLoc; }
903 /// getEndLoc - Get the location of the last token of this operand.
904 SMLoc getEndLoc() const override { return EndLoc; }
906 virtual ~MipsOperand() {
914 case k_RegisterIndex:
920 void print(raw_ostream &OS) const override {
935 OS << "PhysReg<" << PhysReg.Num << ">";
937 case k_RegisterIndex:
938 OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
945 }; // class MipsOperand
949 extern const MCInstrDesc MipsInsts[];
951 static const MCInstrDesc &getInstDesc(unsigned Opcode) {
952 return MipsInsts[Opcode];
955 bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
956 SmallVectorImpl<MCInst> &Instructions) {
957 const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
961 if (MCID.isBranch() || MCID.isCall()) {
962 const unsigned Opcode = Inst.getOpcode();
972 assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
973 Offset = Inst.getOperand(2);
975 break; // We'll deal with this situation later on when applying fixups.
976 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
977 return Error(IDLoc, "branch target out of range");
978 if (OffsetToAlignment(Offset.getImm(),
979 1LL << (inMicroMipsMode() ? 1 : 2)))
980 return Error(IDLoc, "branch to misaligned address");
994 case Mips::BGEZAL_MM:
995 case Mips::BLTZAL_MM:
998 assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
999 Offset = Inst.getOperand(1);
1000 if (!Offset.isImm())
1001 break; // We'll deal with this situation later on when applying fixups.
1002 if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
1003 return Error(IDLoc, "branch target out of range");
1004 if (OffsetToAlignment(Offset.getImm(),
1005 1LL << (inMicroMipsMode() ? 1 : 2)))
1006 return Error(IDLoc, "branch to misaligned address");
1011 // SSNOP is deprecated on MIPS32r6/MIPS64r6
1012 // We still accept it but it is a normal nop.
1013 if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1014 std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1015 Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1019 if (MCID.hasDelaySlot() && Options.isReorder()) {
1020 // If this instruction has a delay slot and .set reorder is active,
1021 // emit a NOP after it.
1022 Instructions.push_back(Inst);
1024 NopInst.setOpcode(Mips::SLL);
1025 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1026 NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1027 NopInst.addOperand(MCOperand::CreateImm(0));
1028 Instructions.push_back(NopInst);
1032 if (MCID.mayLoad() || MCID.mayStore()) {
1033 // Check the offset of memory operand, if it is a symbol
1034 // reference or immediate we may have to expand instructions.
1035 for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1036 const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1037 if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1038 (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1039 MCOperand &Op = Inst.getOperand(i);
1041 int MemOffset = Op.getImm();
1042 if (MemOffset < -32768 || MemOffset > 32767) {
1043 // Offset can't exceed 16bit value.
1044 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
1047 } else if (Op.isExpr()) {
1048 const MCExpr *Expr = Op.getExpr();
1049 if (Expr->getKind() == MCExpr::SymbolRef) {
1050 const MCSymbolRefExpr *SR =
1051 static_cast<const MCSymbolRefExpr *>(Expr);
1052 if (SR->getKind() == MCSymbolRefExpr::VK_None) {
1054 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1057 } else if (!isEvaluated(Expr)) {
1058 expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1066 if (needsExpansion(Inst))
1067 return expandInstruction(Inst, IDLoc, Instructions);
1069 Instructions.push_back(Inst);
1074 bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1076 switch (Inst.getOpcode()) {
1077 case Mips::LoadImm32Reg:
1078 case Mips::LoadAddr32Imm:
1079 case Mips::LoadAddr32Reg:
1080 case Mips::LoadImm64Reg:
1087 bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1088 SmallVectorImpl<MCInst> &Instructions) {
1089 switch (Inst.getOpcode()) {
1091 assert(0 && "unimplemented expansion");
1093 case Mips::LoadImm32Reg:
1094 return expandLoadImm(Inst, IDLoc, Instructions);
1095 case Mips::LoadImm64Reg:
1097 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1100 return expandLoadImm(Inst, IDLoc, Instructions);
1101 case Mips::LoadAddr32Imm:
1102 return expandLoadAddressImm(Inst, IDLoc, Instructions);
1103 case Mips::LoadAddr32Reg:
1104 return expandLoadAddressReg(Inst, IDLoc, Instructions);
1109 template <bool PerformShift>
1110 void createShiftOr(MCOperand Operand, unsigned RegNo, SMLoc IDLoc,
1111 SmallVectorImpl<MCInst> &Instructions) {
1114 tmpInst.setOpcode(Mips::DSLL);
1115 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1116 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1117 tmpInst.addOperand(MCOperand::CreateImm(16));
1118 tmpInst.setLoc(IDLoc);
1119 Instructions.push_back(tmpInst);
1122 tmpInst.setOpcode(Mips::ORi);
1123 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1124 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1125 tmpInst.addOperand(Operand);
1126 tmpInst.setLoc(IDLoc);
1127 Instructions.push_back(tmpInst);
1130 template <int Shift, bool PerformShift>
1131 void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1132 SmallVectorImpl<MCInst> &Instructions) {
1133 createShiftOr<PerformShift>(
1134 MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)), RegNo,
1135 IDLoc, Instructions);
1139 bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1140 SmallVectorImpl<MCInst> &Instructions) {
1142 const MCOperand &ImmOp = Inst.getOperand(1);
1143 assert(ImmOp.isImm() && "expected immediate operand kind");
1144 const MCOperand &RegOp = Inst.getOperand(0);
1145 assert(RegOp.isReg() && "expected register operand kind");
1147 int64_t ImmValue = ImmOp.getImm();
1148 tmpInst.setLoc(IDLoc);
1149 // FIXME: gas has a special case for values that are 000...1111, which
1150 // becomes a li -1 and then a dsrl
1151 if (0 <= ImmValue && ImmValue <= 65535) {
1152 // For 0 <= j <= 65535.
1153 // li d,j => ori d,$zero,j
1154 tmpInst.setOpcode(Mips::ORi);
1155 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1156 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1157 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1158 Instructions.push_back(tmpInst);
1159 } else if (ImmValue < 0 && ImmValue >= -32768) {
1160 // For -32768 <= j < 0.
1161 // li d,j => addiu d,$zero,j
1162 tmpInst.setOpcode(Mips::ADDiu);
1163 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1164 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1165 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1166 Instructions.push_back(tmpInst);
1167 } else if ((ImmValue & 0xffffffff) == ImmValue) {
1168 // For any value of j that is representable as a 32-bit integer, create
1170 // li d,j => lui d,hi16(j)
1172 tmpInst.setOpcode(Mips::LUi);
1173 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1174 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1175 Instructions.push_back(tmpInst);
1176 createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1177 } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1179 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1183 // <------- lo32 ------>
1184 // <------- hi32 ------>
1185 // <- hi16 -> <- lo16 ->
1186 // _________________________________
1188 // | 16-bytes | 16-bytes | 16-bytes |
1189 // |__________|__________|__________|
1191 // For any value of j that is representable as a 48-bit integer, create
1193 // li d,j => lui d,hi16(j)
1194 // ori d,d,hi16(lo32(j))
1196 // ori d,d,lo16(lo32(j))
1197 tmpInst.setOpcode(Mips::LUi);
1198 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1200 MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1201 Instructions.push_back(tmpInst);
1202 createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1203 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1206 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1210 // <------- hi32 ------> <------- lo32 ------>
1211 // <- hi16 -> <- lo16 ->
1212 // ___________________________________________
1214 // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1215 // |__________|__________|__________|__________|
1217 // For any value of j that isn't representable as a 48-bit integer.
1218 // li d,j => lui d,hi16(j)
1219 // ori d,d,lo16(hi32(j))
1221 // ori d,d,hi16(lo32(j))
1223 // ori d,d,lo16(lo32(j))
1224 tmpInst.setOpcode(Mips::LUi);
1225 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1227 MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1228 Instructions.push_back(tmpInst);
1229 createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1230 createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1231 createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1237 MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1238 SmallVectorImpl<MCInst> &Instructions) {
1240 const MCOperand &ImmOp = Inst.getOperand(2);
1241 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1242 "expected immediate operand kind");
1243 if (!ImmOp.isImm()) {
1244 expandLoadAddressSym(Inst, IDLoc, Instructions);
1247 const MCOperand &SrcRegOp = Inst.getOperand(1);
1248 assert(SrcRegOp.isReg() && "expected register operand kind");
1249 const MCOperand &DstRegOp = Inst.getOperand(0);
1250 assert(DstRegOp.isReg() && "expected register operand kind");
1251 int ImmValue = ImmOp.getImm();
1252 if (-32768 <= ImmValue && ImmValue <= 65535) {
1253 // For -32768 <= j <= 65535.
1254 // la d,j(s) => addiu d,s,j
1255 tmpInst.setOpcode(Mips::ADDiu);
1256 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1257 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1258 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1259 Instructions.push_back(tmpInst);
1261 // For any other value of j that is representable as a 32-bit integer.
1262 // la d,j(s) => lui d,hi16(j)
1265 tmpInst.setOpcode(Mips::LUi);
1266 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1267 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1268 Instructions.push_back(tmpInst);
1270 tmpInst.setOpcode(Mips::ORi);
1271 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1272 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1273 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1274 Instructions.push_back(tmpInst);
1276 tmpInst.setOpcode(Mips::ADDu);
1277 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1278 tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1279 tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1280 Instructions.push_back(tmpInst);
1286 MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1287 SmallVectorImpl<MCInst> &Instructions) {
1289 const MCOperand &ImmOp = Inst.getOperand(1);
1290 assert((ImmOp.isImm() || ImmOp.isExpr()) &&
1291 "expected immediate operand kind");
1292 if (!ImmOp.isImm()) {
1293 expandLoadAddressSym(Inst, IDLoc, Instructions);
1296 const MCOperand &RegOp = Inst.getOperand(0);
1297 assert(RegOp.isReg() && "expected register operand kind");
1298 int ImmValue = ImmOp.getImm();
1299 if (-32768 <= ImmValue && ImmValue <= 65535) {
1300 // For -32768 <= j <= 65535.
1301 // la d,j => addiu d,$zero,j
1302 tmpInst.setOpcode(Mips::ADDiu);
1303 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1304 tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1305 tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1306 Instructions.push_back(tmpInst);
1308 // For any other value of j that is representable as a 32-bit integer.
1309 // la d,j => lui d,hi16(j)
1311 tmpInst.setOpcode(Mips::LUi);
1312 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1313 tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1314 Instructions.push_back(tmpInst);
1316 tmpInst.setOpcode(Mips::ORi);
1317 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1318 tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1319 tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1320 Instructions.push_back(tmpInst);
1326 MipsAsmParser::expandLoadAddressSym(MCInst &Inst, SMLoc IDLoc,
1327 SmallVectorImpl<MCInst> &Instructions) {
1328 // FIXME: If we do have a valid at register to use, we should generate a
1329 // slightly shorter sequence here.
1331 int ExprOperandNo = 1;
1332 // Sometimes the assembly parser will get the immediate expression as
1333 // a $zero + an immediate.
1334 if (Inst.getNumOperands() == 3) {
1335 assert(Inst.getOperand(1).getReg() ==
1336 (isGP64bit() ? Mips::ZERO_64 : Mips::ZERO));
1339 const MCOperand &SymOp = Inst.getOperand(ExprOperandNo);
1340 assert(SymOp.isExpr() && "expected symbol operand kind");
1341 const MCOperand &RegOp = Inst.getOperand(0);
1342 unsigned RegNo = RegOp.getReg();
1343 const MCSymbolRefExpr *Symbol = cast<MCSymbolRefExpr>(SymOp.getExpr());
1344 const MCSymbolRefExpr *HiExpr =
1345 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1346 MCSymbolRefExpr::VK_Mips_ABS_HI, getContext());
1347 const MCSymbolRefExpr *LoExpr =
1348 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1349 MCSymbolRefExpr::VK_Mips_ABS_LO, getContext());
1351 // If it's a 64-bit architecture, expand to:
1352 // la d,sym => lui d,highest(sym)
1353 // ori d,d,higher(sym)
1355 // ori d,d,hi16(sym)
1357 // ori d,d,lo16(sym)
1358 const MCSymbolRefExpr *HighestExpr =
1359 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1360 MCSymbolRefExpr::VK_Mips_HIGHEST, getContext());
1361 const MCSymbolRefExpr *HigherExpr =
1362 MCSymbolRefExpr::Create(Symbol->getSymbol().getName(),
1363 MCSymbolRefExpr::VK_Mips_HIGHER, getContext());
1365 tmpInst.setOpcode(Mips::LUi);
1366 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1367 tmpInst.addOperand(MCOperand::CreateExpr(HighestExpr));
1368 Instructions.push_back(tmpInst);
1370 createShiftOr<false>(MCOperand::CreateExpr(HigherExpr), RegNo, SMLoc(),
1372 createShiftOr<true>(MCOperand::CreateExpr(HiExpr), RegNo, SMLoc(),
1374 createShiftOr<true>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1377 // Otherwise, expand to:
1378 // la d,sym => lui d,hi16(sym)
1379 // ori d,d,lo16(sym)
1380 tmpInst.setOpcode(Mips::LUi);
1381 tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1382 tmpInst.addOperand(MCOperand::CreateExpr(HiExpr));
1383 Instructions.push_back(tmpInst);
1385 createShiftOr<false>(MCOperand::CreateExpr(LoExpr), RegNo, SMLoc(),
1390 void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1391 SmallVectorImpl<MCInst> &Instructions,
1392 bool isLoad, bool isImmOpnd) {
1393 const MCSymbolRefExpr *SR;
1395 unsigned ImmOffset, HiOffset, LoOffset;
1396 const MCExpr *ExprOffset;
1398 // 1st operand is either the source or destination register.
1399 assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1400 unsigned RegOpNum = Inst.getOperand(0).getReg();
1401 // 2nd operand is the base register.
1402 assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1403 unsigned BaseRegNum = Inst.getOperand(1).getReg();
1404 // 3rd operand is either an immediate or expression.
1406 assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1407 ImmOffset = Inst.getOperand(2).getImm();
1408 LoOffset = ImmOffset & 0x0000ffff;
1409 HiOffset = (ImmOffset & 0xffff0000) >> 16;
1410 // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1411 if (LoOffset & 0x8000)
1414 ExprOffset = Inst.getOperand(2).getExpr();
1415 // All instructions will have the same location.
1416 TempInst.setLoc(IDLoc);
1417 // These are some of the types of expansions we perform here:
1418 // 1) lw $8, sym => lui $8, %hi(sym)
1419 // lw $8, %lo(sym)($8)
1420 // 2) lw $8, offset($9) => lui $8, %hi(offset)
1422 // lw $8, %lo(offset)($9)
1423 // 3) lw $8, offset($8) => lui $at, %hi(offset)
1425 // lw $8, %lo(offset)($at)
1426 // 4) sw $8, sym => lui $at, %hi(sym)
1427 // sw $8, %lo(sym)($at)
1428 // 5) sw $8, offset($8) => lui $at, %hi(offset)
1430 // sw $8, %lo(offset)($at)
1431 // 6) ldc1 $f0, sym => lui $at, %hi(sym)
1432 // ldc1 $f0, %lo(sym)($at)
1434 // For load instructions we can use the destination register as a temporary
1435 // if base and dst are different (examples 1 and 2) and if the base register
1436 // is general purpose otherwise we must use $at (example 6) and error if it's
1437 // not available. For stores we must use $at (examples 4 and 5) because we
1438 // must not clobber the source register setting up the offset.
1439 const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1440 int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1441 unsigned RegClassIDOp0 =
1442 getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1443 bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1444 (RegClassIDOp0 == Mips::GPR64RegClassID);
1445 if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1446 TmpRegNum = RegOpNum;
1448 int AT = getATReg(IDLoc);
1449 // At this point we need AT to perform the expansions and we exit if it is
1454 (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1457 TempInst.setOpcode(Mips::LUi);
1458 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1460 TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1462 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1463 SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1464 const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1465 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1467 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1469 const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1470 TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1473 // Add the instruction to the list.
1474 Instructions.push_back(TempInst);
1475 // Prepare TempInst for next instruction.
1477 // Add temp register to base.
1478 TempInst.setOpcode(Mips::ADDu);
1479 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1480 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1481 TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1482 Instructions.push_back(TempInst);
1484 // And finally, create original instruction with low part
1485 // of offset and new base.
1486 TempInst.setOpcode(Inst.getOpcode());
1487 TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1488 TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1490 TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1492 if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1493 const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1494 SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1496 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1498 const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1499 TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1502 Instructions.push_back(TempInst);
1506 unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1507 // As described by the Mips32r2 spec, the registers Rd and Rs for
1508 // jalr.hb must be different.
1509 unsigned Opcode = Inst.getOpcode();
1511 if (Opcode == Mips::JALR_HB &&
1512 (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1513 return Match_RequiresDifferentSrcAndDst;
1515 return Match_Success;
1518 bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1519 OperandVector &Operands,
1521 unsigned &ErrorInfo,
1522 bool MatchingInlineAsm) {
1525 SmallVector<MCInst, 8> Instructions;
1526 unsigned MatchResult =
1527 MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1529 switch (MatchResult) {
1532 case Match_Success: {
1533 if (processInstruction(Inst, IDLoc, Instructions))
1535 for (unsigned i = 0; i < Instructions.size(); i++)
1536 Out.EmitInstruction(Instructions[i], STI);
1539 case Match_MissingFeature:
1540 Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1542 case Match_InvalidOperand: {
1543 SMLoc ErrorLoc = IDLoc;
1544 if (ErrorInfo != ~0U) {
1545 if (ErrorInfo >= Operands.size())
1546 return Error(IDLoc, "too few operands for instruction");
1548 ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1549 if (ErrorLoc == SMLoc())
1553 return Error(ErrorLoc, "invalid operand for instruction");
1555 case Match_MnemonicFail:
1556 return Error(IDLoc, "invalid instruction");
1557 case Match_RequiresDifferentSrcAndDst:
1558 return Error(IDLoc, "source and destination must be different");
1563 void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1564 if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1566 Warning(Loc, "Used $at without \".set noat\"");
1568 Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1569 Twine(RegIndex) + "\"");
1573 int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1576 CC = StringSwitch<unsigned>(Name)
1612 if (isABI_N32() || isABI_N64()) {
1613 // Although SGI documentation just cuts out t0-t3 for n32/n64,
1614 // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1615 // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1616 if (8 <= CC && CC <= 11)
1620 CC = StringSwitch<unsigned>(Name)
1633 int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1635 if (Name[0] == 'f') {
1636 StringRef NumString = Name.substr(1);
1638 if (NumString.getAsInteger(10, IntVal))
1639 return -1; // This is not an integer.
1640 if (IntVal > 31) // Maximum index for fpu register.
1647 int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1649 if (Name.startswith("fcc")) {
1650 StringRef NumString = Name.substr(3);
1652 if (NumString.getAsInteger(10, IntVal))
1653 return -1; // This is not an integer.
1654 if (IntVal > 7) // There are only 8 fcc registers.
1661 int MipsAsmParser::matchACRegisterName(StringRef Name) {
1663 if (Name.startswith("ac")) {
1664 StringRef NumString = Name.substr(2);
1666 if (NumString.getAsInteger(10, IntVal))
1667 return -1; // This is not an integer.
1668 if (IntVal > 3) // There are only 3 acc registers.
1675 int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1678 if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1687 int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1690 CC = StringSwitch<unsigned>(Name)
1693 .Case("msaaccess", 2)
1695 .Case("msamodify", 4)
1696 .Case("msarequest", 5)
1698 .Case("msaunmap", 7)
1704 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1712 int MipsAsmParser::getATReg(SMLoc Loc) {
1713 int AT = Options.getATRegNum();
1715 reportParseError(Loc,
1716 "Pseudo instruction requires $at, which is not available");
1720 unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1721 return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1724 unsigned MipsAsmParser::getGPR(int RegNo) {
1725 return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1729 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1731 getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1734 return getReg(RegClass, RegNum);
1737 bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1738 DEBUG(dbgs() << "ParseOperand\n");
1740 // Check if the current operand has a custom associated parser, if so, try to
1741 // custom parse the operand, or fallback to the general approach.
1742 OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1743 if (ResTy == MatchOperand_Success)
1745 // If there wasn't a custom match, try the generic matcher below. Otherwise,
1746 // there was a match, but an error occurred, in which case, just return that
1747 // the operand parsing failed.
1748 if (ResTy == MatchOperand_ParseFail)
1751 DEBUG(dbgs() << ".. Generic Parser\n");
1753 switch (getLexer().getKind()) {
1755 Error(Parser.getTok().getLoc(), "unexpected token in operand");
1757 case AsmToken::Dollar: {
1758 // Parse the register.
1759 SMLoc S = Parser.getTok().getLoc();
1761 // Almost all registers have been parsed by custom parsers. There is only
1762 // one exception to this. $zero (and it's alias $0) will reach this point
1763 // for div, divu, and similar instructions because it is not an operand
1764 // to the instruction definition but an explicit register. Special case
1765 // this situation for now.
1766 if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1769 // Maybe it is a symbol reference.
1770 StringRef Identifier;
1771 if (Parser.parseIdentifier(Identifier))
1774 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1775 MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1776 // Otherwise create a symbol reference.
1778 MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1780 Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1783 // Else drop to expression parsing.
1784 case AsmToken::LParen:
1785 case AsmToken::Minus:
1786 case AsmToken::Plus:
1787 case AsmToken::Integer:
1788 case AsmToken::Tilde:
1789 case AsmToken::String: {
1790 DEBUG(dbgs() << ".. generic integer\n");
1791 OperandMatchResultTy ResTy = ParseImm(Operands);
1792 return ResTy != MatchOperand_Success;
1794 case AsmToken::Percent: {
1795 // It is a symbol reference or constant expression.
1796 const MCExpr *IdVal;
1797 SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1798 if (parseRelocOperand(IdVal))
1801 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1803 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1805 } // case AsmToken::Percent
1806 } // switch(getLexer().getKind())
1810 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1811 StringRef RelocStr) {
1813 // Check the type of the expression.
1814 if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1815 // It's a constant, evaluate reloc value.
1817 switch (getVariantKind(RelocStr)) {
1818 case MCSymbolRefExpr::VK_Mips_ABS_LO:
1819 // Get the 1st 16-bits.
1820 Val = MCE->getValue() & 0xffff;
1822 case MCSymbolRefExpr::VK_Mips_ABS_HI:
1823 // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1824 // 16 bits being negative.
1825 Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1827 case MCSymbolRefExpr::VK_Mips_HIGHER:
1828 // Get the 3rd 16-bits.
1829 Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1831 case MCSymbolRefExpr::VK_Mips_HIGHEST:
1832 // Get the 4th 16-bits.
1833 Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1836 report_fatal_error("Unsupported reloc value!");
1838 return MCConstantExpr::Create(Val, getContext());
1841 if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1842 // It's a symbol, create a symbolic expression from the symbol.
1843 StringRef Symbol = MSRE->getSymbol().getName();
1844 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1845 Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1849 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1850 MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1852 // Try to create target expression.
1853 if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1854 return MipsMCExpr::Create(VK, Expr, getContext());
1856 const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1857 const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1858 Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1862 if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1863 const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1864 Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1867 // Just return the original expression.
1871 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1873 switch (Expr->getKind()) {
1874 case MCExpr::Constant:
1876 case MCExpr::SymbolRef:
1877 return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1878 case MCExpr::Binary:
1879 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1880 if (!isEvaluated(BE->getLHS()))
1882 return isEvaluated(BE->getRHS());
1885 return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1886 case MCExpr::Target:
1892 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1893 Parser.Lex(); // Eat the % token.
1894 const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1895 if (Tok.isNot(AsmToken::Identifier))
1898 std::string Str = Tok.getIdentifier().str();
1900 Parser.Lex(); // Eat the identifier.
1901 // Now make an expression from the rest of the operand.
1902 const MCExpr *IdVal;
1905 if (getLexer().getKind() == AsmToken::LParen) {
1907 Parser.Lex(); // Eat the '(' token.
1908 if (getLexer().getKind() == AsmToken::Percent) {
1909 Parser.Lex(); // Eat the % token.
1910 const AsmToken &nextTok = Parser.getTok();
1911 if (nextTok.isNot(AsmToken::Identifier))
1914 Str += nextTok.getIdentifier();
1915 Parser.Lex(); // Eat the identifier.
1916 if (getLexer().getKind() != AsmToken::LParen)
1921 if (getParser().parseParenExpression(IdVal, EndLoc))
1924 while (getLexer().getKind() == AsmToken::RParen)
1925 Parser.Lex(); // Eat the ')' token.
1928 return true; // Parenthesis must follow the relocation operand.
1930 Res = evaluateRelocExpr(IdVal, Str);
1934 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1936 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1937 OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1938 if (ResTy == MatchOperand_Success) {
1939 assert(Operands.size() == 1);
1940 MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1941 StartLoc = Operand.getStartLoc();
1942 EndLoc = Operand.getEndLoc();
1944 // AFAIK, we only support numeric registers and named GPR's in CFI
1946 // Don't worry about eating tokens before failing. Using an unrecognised
1947 // register is a parse error.
1948 if (Operand.isGPRAsmReg()) {
1949 // Resolve to GPR32 or GPR64 appropriately.
1950 RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1953 return (RegNo == (unsigned)-1);
1956 assert(Operands.size() == 0);
1957 return (RegNo == (unsigned)-1);
1960 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1964 while (getLexer().getKind() == AsmToken::LParen)
1967 switch (getLexer().getKind()) {
1970 case AsmToken::Identifier:
1971 case AsmToken::LParen:
1972 case AsmToken::Integer:
1973 case AsmToken::Minus:
1974 case AsmToken::Plus:
1976 Result = getParser().parseParenExpression(Res, S);
1978 Result = (getParser().parseExpression(Res));
1979 while (getLexer().getKind() == AsmToken::RParen)
1982 case AsmToken::Percent:
1983 Result = parseRelocOperand(Res);
1988 MipsAsmParser::OperandMatchResultTy
1989 MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1990 DEBUG(dbgs() << "parseMemOperand\n");
1991 const MCExpr *IdVal = nullptr;
1993 bool isParenExpr = false;
1994 MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1995 // First operand is the offset.
1996 S = Parser.getTok().getLoc();
1998 if (getLexer().getKind() == AsmToken::LParen) {
2003 if (getLexer().getKind() != AsmToken::Dollar) {
2004 if (parseMemOffset(IdVal, isParenExpr))
2005 return MatchOperand_ParseFail;
2007 const AsmToken &Tok = Parser.getTok(); // Get the next token.
2008 if (Tok.isNot(AsmToken::LParen)) {
2009 MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
2010 if (Mnemonic.getToken() == "la") {
2012 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2013 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2014 return MatchOperand_Success;
2016 if (Tok.is(AsmToken::EndOfStatement)) {
2018 SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2020 // Zero register assumed, add a memory operand with ZERO as its base.
2021 // "Base" will be managed by k_Memory.
2022 auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
2025 MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
2026 return MatchOperand_Success;
2028 Error(Parser.getTok().getLoc(), "'(' expected");
2029 return MatchOperand_ParseFail;
2032 Parser.Lex(); // Eat the '(' token.
2035 Res = ParseAnyRegister(Operands);
2036 if (Res != MatchOperand_Success)
2039 if (Parser.getTok().isNot(AsmToken::RParen)) {
2040 Error(Parser.getTok().getLoc(), "')' expected");
2041 return MatchOperand_ParseFail;
2044 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2046 Parser.Lex(); // Eat the ')' token.
2049 IdVal = MCConstantExpr::Create(0, getContext());
2051 // Replace the register operand with the memory operand.
2052 std::unique_ptr<MipsOperand> op(
2053 static_cast<MipsOperand *>(Operands.back().release()));
2054 // Remove the register from the operands.
2055 // "op" will be managed by k_Memory.
2056 Operands.pop_back();
2057 // Add the memory operand.
2058 if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
2060 if (IdVal->EvaluateAsAbsolute(Imm))
2061 IdVal = MCConstantExpr::Create(Imm, getContext());
2062 else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
2063 IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
2067 Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
2068 return MatchOperand_Success;
2071 bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
2073 MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
2075 SMLoc S = Parser.getTok().getLoc();
2077 if (Sym->isVariable())
2078 Expr = Sym->getVariableValue();
2081 if (Expr->getKind() == MCExpr::SymbolRef) {
2082 const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
2083 const StringRef DefSymbol = Ref->getSymbol().getName();
2084 if (DefSymbol.startswith("$")) {
2085 OperandMatchResultTy ResTy =
2086 MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
2087 if (ResTy == MatchOperand_Success) {
2090 } else if (ResTy == MatchOperand_ParseFail)
2091 llvm_unreachable("Should never ParseFail");
2094 } else if (Expr->getKind() == MCExpr::Constant) {
2096 const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2098 MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
2105 MipsAsmParser::OperandMatchResultTy
2106 MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
2107 StringRef Identifier,
2109 int Index = matchCPURegisterName(Identifier);
2111 Operands.push_back(MipsOperand::CreateGPRReg(
2112 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2113 return MatchOperand_Success;
2116 Index = matchFPURegisterName(Identifier);
2118 Operands.push_back(MipsOperand::CreateFGRReg(
2119 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2120 return MatchOperand_Success;
2123 Index = matchFCCRegisterName(Identifier);
2125 Operands.push_back(MipsOperand::CreateFCCReg(
2126 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2127 return MatchOperand_Success;
2130 Index = matchACRegisterName(Identifier);
2132 Operands.push_back(MipsOperand::CreateACCReg(
2133 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2134 return MatchOperand_Success;
2137 Index = matchMSA128RegisterName(Identifier);
2139 Operands.push_back(MipsOperand::CreateMSA128Reg(
2140 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2141 return MatchOperand_Success;
2144 Index = matchMSA128CtrlRegisterName(Identifier);
2146 Operands.push_back(MipsOperand::CreateMSACtrlReg(
2147 Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2148 return MatchOperand_Success;
2151 return MatchOperand_NoMatch;
2154 MipsAsmParser::OperandMatchResultTy
2155 MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2156 auto Token = Parser.getLexer().peekTok(false);
2158 if (Token.is(AsmToken::Identifier)) {
2159 DEBUG(dbgs() << ".. identifier\n");
2160 StringRef Identifier = Token.getIdentifier();
2161 OperandMatchResultTy ResTy =
2162 MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2164 } else if (Token.is(AsmToken::Integer)) {
2165 DEBUG(dbgs() << ".. integer\n");
2166 Operands.push_back(MipsOperand::CreateNumericReg(
2167 Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2169 return MatchOperand_Success;
2172 DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2174 return MatchOperand_NoMatch;
2177 MipsAsmParser::OperandMatchResultTy
2178 MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2179 DEBUG(dbgs() << "ParseAnyRegister\n");
2181 auto Token = Parser.getTok();
2183 SMLoc S = Token.getLoc();
2185 if (Token.isNot(AsmToken::Dollar)) {
2186 DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2187 if (Token.is(AsmToken::Identifier)) {
2188 if (searchSymbolAlias(Operands))
2189 return MatchOperand_Success;
2191 DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2192 return MatchOperand_NoMatch;
2194 DEBUG(dbgs() << ".. $\n");
2196 OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2197 if (ResTy == MatchOperand_Success) {
2199 Parser.Lex(); // identifier
2204 MipsAsmParser::OperandMatchResultTy
2205 MipsAsmParser::ParseImm(OperandVector &Operands) {
2206 switch (getLexer().getKind()) {
2208 return MatchOperand_NoMatch;
2209 case AsmToken::LParen:
2210 case AsmToken::Minus:
2211 case AsmToken::Plus:
2212 case AsmToken::Integer:
2213 case AsmToken::Tilde:
2214 case AsmToken::String:
2218 const MCExpr *IdVal;
2219 SMLoc S = Parser.getTok().getLoc();
2220 if (getParser().parseExpression(IdVal))
2221 return MatchOperand_ParseFail;
2223 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2224 Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2225 return MatchOperand_Success;
2228 MipsAsmParser::OperandMatchResultTy
2229 MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2230 DEBUG(dbgs() << "ParseJumpTarget\n");
2232 SMLoc S = getLexer().getLoc();
2234 // Integers and expressions are acceptable
2235 OperandMatchResultTy ResTy = ParseImm(Operands);
2236 if (ResTy != MatchOperand_NoMatch)
2239 // Registers are a valid target and have priority over symbols.
2240 ResTy = ParseAnyRegister(Operands);
2241 if (ResTy != MatchOperand_NoMatch)
2244 const MCExpr *Expr = nullptr;
2245 if (Parser.parseExpression(Expr)) {
2246 // We have no way of knowing if a symbol was consumed so we must ParseFail
2247 return MatchOperand_ParseFail;
2250 MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2251 return MatchOperand_Success;
2254 MipsAsmParser::OperandMatchResultTy
2255 MipsAsmParser::parseInvNum(OperandVector &Operands) {
2256 const MCExpr *IdVal;
2257 // If the first token is '$' we may have register operand.
2258 if (Parser.getTok().is(AsmToken::Dollar))
2259 return MatchOperand_NoMatch;
2260 SMLoc S = Parser.getTok().getLoc();
2261 if (getParser().parseExpression(IdVal))
2262 return MatchOperand_ParseFail;
2263 const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2264 assert(MCE && "Unexpected MCExpr type.");
2265 int64_t Val = MCE->getValue();
2266 SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2267 Operands.push_back(MipsOperand::CreateImm(
2268 MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2269 return MatchOperand_Success;
2272 MipsAsmParser::OperandMatchResultTy
2273 MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2274 switch (getLexer().getKind()) {
2276 return MatchOperand_NoMatch;
2277 case AsmToken::LParen:
2278 case AsmToken::Plus:
2279 case AsmToken::Minus:
2280 case AsmToken::Integer:
2285 SMLoc S = Parser.getTok().getLoc();
2287 if (getParser().parseExpression(Expr))
2288 return MatchOperand_ParseFail;
2291 if (!Expr->EvaluateAsAbsolute(Val)) {
2292 Error(S, "expected immediate value");
2293 return MatchOperand_ParseFail;
2296 // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2297 // and because the CPU always adds one to the immediate field, the allowed
2298 // range becomes 1..4. We'll only check the range here and will deal
2299 // with the addition/subtraction when actually decoding/encoding
2301 if (Val < 1 || Val > 4) {
2302 Error(S, "immediate not in range (1..4)");
2303 return MatchOperand_ParseFail;
2307 MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2308 return MatchOperand_Success;
2311 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2313 MCSymbolRefExpr::VariantKind VK =
2314 StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2315 .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2316 .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2317 .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2318 .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2319 .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2320 .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2321 .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2322 .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2323 .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2324 .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2325 .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2326 .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2327 .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2328 .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2329 .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2330 .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2331 .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2332 .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2333 .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2334 .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2335 .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2336 .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2337 .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2338 .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2339 .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2340 .Default(MCSymbolRefExpr::VK_None);
2342 assert(VK != MCSymbolRefExpr::VK_None);
2347 /// Sometimes (i.e. load/stores) the operand may be followed immediately by
2349 /// ::= '(', register, ')'
2350 /// handle it before we iterate so we don't get tripped up by the lack of
2352 bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2353 if (getLexer().is(AsmToken::LParen)) {
2355 MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2357 if (ParseOperand(Operands, Name)) {
2358 SMLoc Loc = getLexer().getLoc();
2359 Parser.eatToEndOfStatement();
2360 return Error(Loc, "unexpected token in argument list");
2362 if (Parser.getTok().isNot(AsmToken::RParen)) {
2363 SMLoc Loc = getLexer().getLoc();
2364 Parser.eatToEndOfStatement();
2365 return Error(Loc, "unexpected token, expected ')'");
2368 MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2374 /// Sometimes (i.e. in MSA) the operand may be followed immediately by
2375 /// either one of these.
2376 /// ::= '[', register, ']'
2377 /// ::= '[', integer, ']'
2378 /// handle it before we iterate so we don't get tripped up by the lack of
2380 bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2381 OperandVector &Operands) {
2382 if (getLexer().is(AsmToken::LBrac)) {
2384 MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2386 if (ParseOperand(Operands, Name)) {
2387 SMLoc Loc = getLexer().getLoc();
2388 Parser.eatToEndOfStatement();
2389 return Error(Loc, "unexpected token in argument list");
2391 if (Parser.getTok().isNot(AsmToken::RBrac)) {
2392 SMLoc Loc = getLexer().getLoc();
2393 Parser.eatToEndOfStatement();
2394 return Error(Loc, "unexpected token, expected ']'");
2397 MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2403 bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2404 SMLoc NameLoc, OperandVector &Operands) {
2405 DEBUG(dbgs() << "ParseInstruction\n");
2407 // We have reached first instruction, module directive are now forbidden.
2408 getTargetStreamer().forbidModuleDirective();
2410 // Check if we have valid mnemonic
2411 if (!mnemonicIsValid(Name, 0)) {
2412 Parser.eatToEndOfStatement();
2413 return Error(NameLoc, "Unknown instruction");
2415 // First operand in MCInst is instruction mnemonic.
2416 Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2418 // Read the remaining operands.
2419 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2420 // Read the first operand.
2421 if (ParseOperand(Operands, Name)) {
2422 SMLoc Loc = getLexer().getLoc();
2423 Parser.eatToEndOfStatement();
2424 return Error(Loc, "unexpected token in argument list");
2426 if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2428 // AFAIK, parenthesis suffixes are never on the first operand
2430 while (getLexer().is(AsmToken::Comma)) {
2431 Parser.Lex(); // Eat the comma.
2432 // Parse and remember the operand.
2433 if (ParseOperand(Operands, Name)) {
2434 SMLoc Loc = getLexer().getLoc();
2435 Parser.eatToEndOfStatement();
2436 return Error(Loc, "unexpected token in argument list");
2438 // Parse bracket and parenthesis suffixes before we iterate
2439 if (getLexer().is(AsmToken::LBrac)) {
2440 if (ParseBracketSuffix(Name, Operands))
2442 } else if (getLexer().is(AsmToken::LParen) &&
2443 ParseParenSuffix(Name, Operands))
2447 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2448 SMLoc Loc = getLexer().getLoc();
2449 Parser.eatToEndOfStatement();
2450 return Error(Loc, "unexpected token in argument list");
2452 Parser.Lex(); // Consume the EndOfStatement.
2456 bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2457 SMLoc Loc = getLexer().getLoc();
2458 Parser.eatToEndOfStatement();
2459 return Error(Loc, ErrorMsg);
2462 bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2463 return Error(Loc, ErrorMsg);
2466 bool MipsAsmParser::parseSetNoAtDirective() {
2467 // Line should look like: ".set noat".
2469 Options.setATReg(0);
2472 // If this is not the end of the statement, report an error.
2473 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2474 reportParseError("unexpected token in statement");
2477 Parser.Lex(); // Consume the EndOfStatement.
2481 bool MipsAsmParser::parseSetAtDirective() {
2482 // Line can be .set at - defaults to $1
2486 if (getLexer().is(AsmToken::EndOfStatement)) {
2487 Options.setATReg(1);
2488 Parser.Lex(); // Consume the EndOfStatement.
2490 } else if (getLexer().is(AsmToken::Equal)) {
2491 getParser().Lex(); // Eat the '='.
2492 if (getLexer().isNot(AsmToken::Dollar)) {
2493 reportParseError("unexpected token in statement");
2496 Parser.Lex(); // Eat the '$'.
2497 const AsmToken &Reg = Parser.getTok();
2498 if (Reg.is(AsmToken::Identifier)) {
2499 AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2500 } else if (Reg.is(AsmToken::Integer)) {
2501 AtRegNo = Reg.getIntVal();
2503 reportParseError("unexpected token in statement");
2507 if (AtRegNo < 0 || AtRegNo > 31) {
2508 reportParseError("unexpected token in statement");
2512 if (!Options.setATReg(AtRegNo)) {
2513 reportParseError("unexpected token in statement");
2516 getParser().Lex(); // Eat the register.
2518 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2519 reportParseError("unexpected token in statement");
2522 Parser.Lex(); // Consume the EndOfStatement.
2525 reportParseError("unexpected token in statement");
2530 bool MipsAsmParser::parseSetReorderDirective() {
2532 // If this is not the end of the statement, report an error.
2533 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2534 reportParseError("unexpected token in statement");
2537 Options.setReorder();
2538 getTargetStreamer().emitDirectiveSetReorder();
2539 Parser.Lex(); // Consume the EndOfStatement.
2543 bool MipsAsmParser::parseSetNoReorderDirective() {
2545 // If this is not the end of the statement, report an error.
2546 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2547 reportParseError("unexpected token in statement");
2550 Options.setNoreorder();
2551 getTargetStreamer().emitDirectiveSetNoReorder();
2552 Parser.Lex(); // Consume the EndOfStatement.
2556 bool MipsAsmParser::parseSetMacroDirective() {
2558 // If this is not the end of the statement, report an error.
2559 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2560 reportParseError("unexpected token in statement");
2564 Parser.Lex(); // Consume the EndOfStatement.
2568 bool MipsAsmParser::parseSetNoMacroDirective() {
2570 // If this is not the end of the statement, report an error.
2571 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2572 reportParseError("`noreorder' must be set before `nomacro'");
2575 if (Options.isReorder()) {
2576 reportParseError("`noreorder' must be set before `nomacro'");
2579 Options.setNomacro();
2580 Parser.Lex(); // Consume the EndOfStatement.
2584 bool MipsAsmParser::parseSetMsaDirective() {
2587 // If this is not the end of the statement, report an error.
2588 if (getLexer().isNot(AsmToken::EndOfStatement))
2589 return reportParseError("unexpected token in statement");
2591 setFeatureBits(Mips::FeatureMSA, "msa");
2592 getTargetStreamer().emitDirectiveSetMsa();
2596 bool MipsAsmParser::parseSetNoMsaDirective() {
2599 // If this is not the end of the statement, report an error.
2600 if (getLexer().isNot(AsmToken::EndOfStatement))
2601 return reportParseError("unexpected token in statement");
2603 clearFeatureBits(Mips::FeatureMSA, "msa");
2604 getTargetStreamer().emitDirectiveSetNoMsa();
2608 bool MipsAsmParser::parseSetNoMips16Directive() {
2610 // If this is not the end of the statement, report an error.
2611 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2612 reportParseError("unexpected token in statement");
2615 // For now do nothing.
2616 Parser.Lex(); // Consume the EndOfStatement.
2620 bool MipsAsmParser::parseSetFpDirective() {
2621 MipsABIFlagsSection::FpABIKind FpAbiVal;
2622 // Line can be: .set fp=32
2625 Parser.Lex(); // Eat fp token
2626 AsmToken Tok = Parser.getTok();
2627 if (Tok.isNot(AsmToken::Equal)) {
2628 reportParseError("unexpected token in statement");
2631 Parser.Lex(); // Eat '=' token.
2632 Tok = Parser.getTok();
2634 if (!parseFpABIValue(FpAbiVal, ".set"))
2637 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2638 reportParseError("unexpected token in statement");
2641 getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2642 Parser.Lex(); // Consume the EndOfStatement.
2646 bool MipsAsmParser::parseSetAssignment() {
2648 const MCExpr *Value;
2650 if (Parser.parseIdentifier(Name))
2651 reportParseError("expected identifier after .set");
2653 if (getLexer().isNot(AsmToken::Comma))
2654 return reportParseError("unexpected token in .set directive");
2657 if (Parser.parseExpression(Value))
2658 return reportParseError("expected valid expression after comma");
2660 // Check if the Name already exists as a symbol.
2661 MCSymbol *Sym = getContext().LookupSymbol(Name);
2663 return reportParseError("symbol already defined");
2664 Sym = getContext().GetOrCreateSymbol(Name);
2665 Sym->setVariableValue(Value);
2670 bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2672 if (getLexer().isNot(AsmToken::EndOfStatement))
2673 return reportParseError("unexpected token in .set directive");
2677 llvm_unreachable("Unimplemented feature");
2678 case Mips::FeatureDSP:
2679 setFeatureBits(Mips::FeatureDSP, "dsp");
2680 getTargetStreamer().emitDirectiveSetDsp();
2682 case Mips::FeatureMicroMips:
2683 getTargetStreamer().emitDirectiveSetMicroMips();
2685 case Mips::FeatureMips16:
2686 getTargetStreamer().emitDirectiveSetMips16();
2688 case Mips::FeatureMips1:
2689 selectArch("mips1");
2690 getTargetStreamer().emitDirectiveSetMips1();
2692 case Mips::FeatureMips2:
2693 selectArch("mips2");
2694 getTargetStreamer().emitDirectiveSetMips2();
2696 case Mips::FeatureMips3:
2697 selectArch("mips3");
2698 getTargetStreamer().emitDirectiveSetMips3();
2700 case Mips::FeatureMips4:
2701 selectArch("mips4");
2702 getTargetStreamer().emitDirectiveSetMips4();
2704 case Mips::FeatureMips5:
2705 selectArch("mips5");
2706 getTargetStreamer().emitDirectiveSetMips5();
2708 case Mips::FeatureMips32:
2709 selectArch("mips32");
2710 getTargetStreamer().emitDirectiveSetMips32();
2712 case Mips::FeatureMips32r2:
2713 selectArch("mips32r2");
2714 getTargetStreamer().emitDirectiveSetMips32R2();
2716 case Mips::FeatureMips32r6:
2717 selectArch("mips32r6");
2718 getTargetStreamer().emitDirectiveSetMips32R6();
2720 case Mips::FeatureMips64:
2721 selectArch("mips64");
2722 getTargetStreamer().emitDirectiveSetMips64();
2724 case Mips::FeatureMips64r2:
2725 selectArch("mips64r2");
2726 getTargetStreamer().emitDirectiveSetMips64R2();
2728 case Mips::FeatureMips64r6:
2729 selectArch("mips64r6");
2730 getTargetStreamer().emitDirectiveSetMips64R6();
2736 bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2737 if (getLexer().isNot(AsmToken::Comma)) {
2738 SMLoc Loc = getLexer().getLoc();
2739 Parser.eatToEndOfStatement();
2740 return Error(Loc, ErrorStr);
2743 Parser.Lex(); // Eat the comma.
2747 bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2748 if (Options.isReorder())
2749 Warning(Loc, ".cpload in reorder section");
2751 // FIXME: Warn if cpload is used in Mips16 mode.
2753 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2754 OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2755 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2756 reportParseError("expected register containing function address");
2760 MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2761 if (!RegOpnd.isGPRAsmReg()) {
2762 reportParseError(RegOpnd.getStartLoc(), "invalid register");
2766 getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2770 bool MipsAsmParser::parseDirectiveCPSetup() {
2773 bool SaveIsReg = true;
2775 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2776 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2777 if (ResTy == MatchOperand_NoMatch) {
2778 reportParseError("expected register containing function address");
2779 Parser.eatToEndOfStatement();
2783 MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2784 if (!FuncRegOpnd.isGPRAsmReg()) {
2785 reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2786 Parser.eatToEndOfStatement();
2790 FuncReg = FuncRegOpnd.getGPR32Reg();
2793 if (!eatComma("expected comma parsing directive"))
2796 ResTy = ParseAnyRegister(TmpReg);
2797 if (ResTy == MatchOperand_NoMatch) {
2798 const AsmToken &Tok = Parser.getTok();
2799 if (Tok.is(AsmToken::Integer)) {
2800 Save = Tok.getIntVal();
2804 reportParseError("expected save register or stack offset");
2805 Parser.eatToEndOfStatement();
2809 MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2810 if (!SaveOpnd.isGPRAsmReg()) {
2811 reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2812 Parser.eatToEndOfStatement();
2815 Save = SaveOpnd.getGPR32Reg();
2818 if (!eatComma("expected comma parsing directive"))
2822 if (Parser.parseIdentifier(Name))
2823 reportParseError("expected identifier");
2824 MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2826 getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2830 bool MipsAsmParser::parseDirectiveNaN() {
2831 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2832 const AsmToken &Tok = Parser.getTok();
2834 if (Tok.getString() == "2008") {
2836 getTargetStreamer().emitDirectiveNaN2008();
2838 } else if (Tok.getString() == "legacy") {
2840 getTargetStreamer().emitDirectiveNaNLegacy();
2844 // If we don't recognize the option passed to the .nan
2845 // directive (e.g. no option or unknown option), emit an error.
2846 reportParseError("invalid option in .nan directive");
2850 bool MipsAsmParser::parseDirectiveSet() {
2852 // Get the next token.
2853 const AsmToken &Tok = Parser.getTok();
2855 if (Tok.getString() == "noat") {
2856 return parseSetNoAtDirective();
2857 } else if (Tok.getString() == "at") {
2858 return parseSetAtDirective();
2859 } else if (Tok.getString() == "fp") {
2860 return parseSetFpDirective();
2861 } else if (Tok.getString() == "reorder") {
2862 return parseSetReorderDirective();
2863 } else if (Tok.getString() == "noreorder") {
2864 return parseSetNoReorderDirective();
2865 } else if (Tok.getString() == "macro") {
2866 return parseSetMacroDirective();
2867 } else if (Tok.getString() == "nomacro") {
2868 return parseSetNoMacroDirective();
2869 } else if (Tok.getString() == "mips16") {
2870 return parseSetFeature(Mips::FeatureMips16);
2871 } else if (Tok.getString() == "nomips16") {
2872 return parseSetNoMips16Directive();
2873 } else if (Tok.getString() == "nomicromips") {
2874 getTargetStreamer().emitDirectiveSetNoMicroMips();
2875 Parser.eatToEndOfStatement();
2877 } else if (Tok.getString() == "micromips") {
2878 return parseSetFeature(Mips::FeatureMicroMips);
2879 } else if (Tok.getString() == "mips1") {
2880 return parseSetFeature(Mips::FeatureMips1);
2881 } else if (Tok.getString() == "mips2") {
2882 return parseSetFeature(Mips::FeatureMips2);
2883 } else if (Tok.getString() == "mips3") {
2884 return parseSetFeature(Mips::FeatureMips3);
2885 } else if (Tok.getString() == "mips4") {
2886 return parseSetFeature(Mips::FeatureMips4);
2887 } else if (Tok.getString() == "mips5") {
2888 return parseSetFeature(Mips::FeatureMips5);
2889 } else if (Tok.getString() == "mips32") {
2890 return parseSetFeature(Mips::FeatureMips32);
2891 } else if (Tok.getString() == "mips32r2") {
2892 return parseSetFeature(Mips::FeatureMips32r2);
2893 } else if (Tok.getString() == "mips32r6") {
2894 return parseSetFeature(Mips::FeatureMips32r6);
2895 } else if (Tok.getString() == "mips64") {
2896 return parseSetFeature(Mips::FeatureMips64);
2897 } else if (Tok.getString() == "mips64r2") {
2898 return parseSetFeature(Mips::FeatureMips64r2);
2899 } else if (Tok.getString() == "mips64r6") {
2900 return parseSetFeature(Mips::FeatureMips64r6);
2901 } else if (Tok.getString() == "dsp") {
2902 return parseSetFeature(Mips::FeatureDSP);
2903 } else if (Tok.getString() == "msa") {
2904 return parseSetMsaDirective();
2905 } else if (Tok.getString() == "nomsa") {
2906 return parseSetNoMsaDirective();
2908 // It is just an identifier, look for an assignment.
2909 parseSetAssignment();
2916 /// parseDataDirective
2917 /// ::= .word [ expression (, expression)* ]
2918 bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2919 if (getLexer().isNot(AsmToken::EndOfStatement)) {
2921 const MCExpr *Value;
2922 if (getParser().parseExpression(Value))
2925 getParser().getStreamer().EmitValue(Value, Size);
2927 if (getLexer().is(AsmToken::EndOfStatement))
2930 // FIXME: Improve diagnostic.
2931 if (getLexer().isNot(AsmToken::Comma))
2932 return Error(L, "unexpected token in directive");
2941 /// parseDirectiveGpWord
2942 /// ::= .gpword local_sym
2943 bool MipsAsmParser::parseDirectiveGpWord() {
2944 const MCExpr *Value;
2945 // EmitGPRel32Value requires an expression, so we are using base class
2946 // method to evaluate the expression.
2947 if (getParser().parseExpression(Value))
2949 getParser().getStreamer().EmitGPRel32Value(Value);
2951 if (getLexer().isNot(AsmToken::EndOfStatement))
2952 return Error(getLexer().getLoc(), "unexpected token in directive");
2953 Parser.Lex(); // Eat EndOfStatement token.
2957 /// parseDirectiveGpDWord
2958 /// ::= .gpdword local_sym
2959 bool MipsAsmParser::parseDirectiveGpDWord() {
2960 const MCExpr *Value;
2961 // EmitGPRel64Value requires an expression, so we are using base class
2962 // method to evaluate the expression.
2963 if (getParser().parseExpression(Value))
2965 getParser().getStreamer().EmitGPRel64Value(Value);
2967 if (getLexer().isNot(AsmToken::EndOfStatement))
2968 return Error(getLexer().getLoc(), "unexpected token in directive");
2969 Parser.Lex(); // Eat EndOfStatement token.
2973 bool MipsAsmParser::parseDirectiveOption() {
2974 // Get the option token.
2975 AsmToken Tok = Parser.getTok();
2976 // At the moment only identifiers are supported.
2977 if (Tok.isNot(AsmToken::Identifier)) {
2978 Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2979 Parser.eatToEndOfStatement();
2983 StringRef Option = Tok.getIdentifier();
2985 if (Option == "pic0") {
2986 getTargetStreamer().emitDirectiveOptionPic0();
2988 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2989 Error(Parser.getTok().getLoc(),
2990 "unexpected token in .option pic0 directive");
2991 Parser.eatToEndOfStatement();
2996 if (Option == "pic2") {
2997 getTargetStreamer().emitDirectiveOptionPic2();
2999 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3000 Error(Parser.getTok().getLoc(),
3001 "unexpected token in .option pic2 directive");
3002 Parser.eatToEndOfStatement();
3008 Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
3009 Parser.eatToEndOfStatement();
3013 /// parseDirectiveModule
3014 /// ::= .module oddspreg
3015 /// ::= .module nooddspreg
3016 /// ::= .module fp=value
3017 bool MipsAsmParser::parseDirectiveModule() {
3018 MCAsmLexer &Lexer = getLexer();
3019 SMLoc L = Lexer.getLoc();
3021 if (!getTargetStreamer().isModuleDirectiveAllowed()) {
3022 // TODO : get a better message.
3023 reportParseError(".module directive must appear before any code");
3027 if (Lexer.is(AsmToken::Identifier)) {
3028 StringRef Option = Parser.getTok().getString();
3031 if (Option == "oddspreg") {
3032 getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
3033 clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3035 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3036 reportParseError("Expected end of statement");
3041 } else if (Option == "nooddspreg") {
3043 Error(L, "'.module nooddspreg' requires the O32 ABI");
3047 getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
3048 setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
3050 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3051 reportParseError("Expected end of statement");
3056 } else if (Option == "fp") {
3057 return parseDirectiveModuleFP();
3060 return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
3066 /// parseDirectiveModuleFP
3070 bool MipsAsmParser::parseDirectiveModuleFP() {
3071 MCAsmLexer &Lexer = getLexer();
3073 if (Lexer.isNot(AsmToken::Equal)) {
3074 reportParseError("unexpected token in statement");
3077 Parser.Lex(); // Eat '=' token.
3079 MipsABIFlagsSection::FpABIKind FpABI;
3080 if (!parseFpABIValue(FpABI, ".module"))
3083 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3084 reportParseError("unexpected token in statement");
3088 // Emit appropriate flags.
3089 getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
3090 Parser.Lex(); // Consume the EndOfStatement.
3094 bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
3095 StringRef Directive) {
3096 MCAsmLexer &Lexer = getLexer();
3098 if (Lexer.is(AsmToken::Identifier)) {
3099 StringRef Value = Parser.getTok().getString();
3102 if (Value != "xx") {
3103 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3108 reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
3112 FpABI = MipsABIFlagsSection::FpABIKind::XX;
3116 if (Lexer.is(AsmToken::Integer)) {
3117 unsigned Value = Parser.getTok().getIntVal();
3120 if (Value != 32 && Value != 64) {
3121 reportParseError("unsupported value, expected 'xx', '32' or '64'");
3127 reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
3131 FpABI = MipsABIFlagsSection::FpABIKind::S32;
3133 FpABI = MipsABIFlagsSection::FpABIKind::S64;
3141 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
3142 StringRef IDVal = DirectiveID.getString();
3144 if (IDVal == ".cpload")
3145 return parseDirectiveCPLoad(DirectiveID.getLoc());
3146 if (IDVal == ".dword") {
3147 parseDataDirective(8, DirectiveID.getLoc());
3150 if (IDVal == ".ent") {
3151 StringRef SymbolName;
3153 if (Parser.parseIdentifier(SymbolName)) {
3154 reportParseError("expected identifier after .ent");
3158 // There's an undocumented extension that allows an integer to
3159 // follow the name of the procedure which AFAICS is ignored by GAS.
3160 // Example: .ent foo,2
3161 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3162 if (getLexer().isNot(AsmToken::Comma)) {
3163 // Even though we accept this undocumented extension for compatibility
3164 // reasons, the additional integer argument does not actually change
3165 // the behaviour of the '.ent' directive, so we would like to discourage
3166 // its use. We do this by not referring to the extended version in
3167 // error messages which are not directly related to its use.
3168 reportParseError("unexpected token, expected end of statement");
3171 Parser.Lex(); // Eat the comma.
3172 const MCExpr *DummyNumber;
3173 int64_t DummyNumberVal;
3174 // If the user was explicitly trying to use the extended version,
3175 // we still give helpful extension-related error messages.
3176 if (Parser.parseExpression(DummyNumber)) {
3177 reportParseError("expected number after comma");
3180 if (!DummyNumber->EvaluateAsAbsolute(DummyNumberVal)) {
3181 reportParseError("expected an absolute expression after comma");
3186 // If this is not the end of the statement, report an error.
3187 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3188 reportParseError("unexpected token, expected end of statement");
3192 MCSymbol *Sym = getContext().GetOrCreateSymbol(SymbolName);
3194 getTargetStreamer().emitDirectiveEnt(*Sym);
3199 if (IDVal == ".end") {
3200 StringRef SymbolName;
3202 if (Parser.parseIdentifier(SymbolName)) {
3203 reportParseError("expected identifier after .end");
3207 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3208 reportParseError("unexpected token, expected end of statement");
3212 if (CurrentFn == nullptr) {
3213 reportParseError(".end used without .ent");
3217 if ((SymbolName != CurrentFn->getName())) {
3218 reportParseError(".end symbol does not match .ent symbol");
3222 getTargetStreamer().emitDirectiveEnd(SymbolName);
3223 CurrentFn = nullptr;
3227 if (IDVal == ".frame") {
3228 // .frame $stack_reg, frame_size_in_bytes, $return_reg
3229 SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
3230 OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
3231 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3232 reportParseError("expected stack register");
3236 MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3237 if (!StackRegOpnd.isGPRAsmReg()) {
3238 reportParseError(StackRegOpnd.getStartLoc(),
3239 "expected general purpose register");
3242 unsigned StackReg = StackRegOpnd.getGPR32Reg();
3244 if (Parser.getTok().is(AsmToken::Comma))
3247 reportParseError("unexpected token, expected comma");
3251 // Parse the frame size.
3252 const MCExpr *FrameSize;
3253 int64_t FrameSizeVal;
3255 if (Parser.parseExpression(FrameSize)) {
3256 reportParseError("expected frame size value");
3260 if (!FrameSize->EvaluateAsAbsolute(FrameSizeVal)) {
3261 reportParseError("frame size not an absolute expression");
3265 if (Parser.getTok().is(AsmToken::Comma))
3268 reportParseError("unexpected token, expected comma");
3272 // Parse the return register.
3274 ResTy = ParseAnyRegister(TmpReg);
3275 if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
3276 reportParseError("expected return register");
3280 MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
3281 if (!ReturnRegOpnd.isGPRAsmReg()) {
3282 reportParseError(ReturnRegOpnd.getStartLoc(),
3283 "expected general purpose register");
3287 // If this is not the end of the statement, report an error.
3288 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3289 reportParseError("unexpected token, expected end of statement");
3293 getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
3294 ReturnRegOpnd.getGPR32Reg());
3298 if (IDVal == ".set") {
3299 return parseDirectiveSet();
3302 if (IDVal == ".mask" || IDVal == ".fmask") {
3303 // .mask bitmask, frame_offset
3304 // bitmask: One bit for each register used.
3305 // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
3306 // first register is expected to be saved.
3308 // .mask 0x80000000, -4
3309 // .fmask 0x80000000, -4
3312 // Parse the bitmask
3313 const MCExpr *BitMask;
3316 if (Parser.parseExpression(BitMask)) {
3317 reportParseError("expected bitmask value");
3321 if (!BitMask->EvaluateAsAbsolute(BitMaskVal)) {
3322 reportParseError("bitmask not an absolute expression");
3326 if (Parser.getTok().is(AsmToken::Comma))
3329 reportParseError("unexpected token, expected comma");
3333 // Parse the frame_offset
3334 const MCExpr *FrameOffset;
3335 int64_t FrameOffsetVal;
3337 if (Parser.parseExpression(FrameOffset)) {
3338 reportParseError("expected frame offset value");
3342 if (!FrameOffset->EvaluateAsAbsolute(FrameOffsetVal)) {
3343 reportParseError("frame offset not an absolute expression");
3347 // If this is not the end of the statement, report an error.
3348 if (getLexer().isNot(AsmToken::EndOfStatement)) {
3349 reportParseError("unexpected token, expected end of statement");
3353 if (IDVal == ".mask")
3354 getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
3356 getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
3360 if (IDVal == ".nan")
3361 return parseDirectiveNaN();
3363 if (IDVal == ".gpword") {
3364 parseDirectiveGpWord();
3368 if (IDVal == ".gpdword") {
3369 parseDirectiveGpDWord();
3373 if (IDVal == ".word") {
3374 parseDataDirective(4, DirectiveID.getLoc());
3378 if (IDVal == ".option")
3379 return parseDirectiveOption();
3381 if (IDVal == ".abicalls") {
3382 getTargetStreamer().emitDirectiveAbiCalls();
3383 if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
3384 Error(Parser.getTok().getLoc(), "unexpected token in directive");
3386 Parser.eatToEndOfStatement();
3391 if (IDVal == ".cpsetup")
3392 return parseDirectiveCPSetup();
3394 if (IDVal == ".module")
3395 return parseDirectiveModule();
3400 extern "C" void LLVMInitializeMipsAsmParser() {
3401 RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3402 RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3403 RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3404 RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3407 #define GET_REGISTER_MATCHER
3408 #define GET_MATCHER_IMPLEMENTATION
3409 #include "MipsGenAsmMatcher.inc"