MipsAsmParser.cpp revision c6a4f5e819217e1e12c458aed8e7b122e23a3a58
1//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
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"
29
30using namespace llvm;
31
32#define DEBUG_TYPE "mips-asm-parser"
33
34namespace llvm {
35class MCInstrInfo;
36}
37
38namespace {
39class MipsAssemblerOptions {
40public:
41  MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
42
43  unsigned getATRegNum() { return aTReg; }
44  bool setATReg(unsigned Reg);
45
46  bool isReorder() { return reorder; }
47  void setReorder() { reorder = true; }
48  void setNoreorder() { reorder = false; }
49
50  bool isMacro() { return macro; }
51  void setMacro() { macro = true; }
52  void setNomacro() { macro = false; }
53
54private:
55  unsigned aTReg;
56  bool reorder;
57  bool macro;
58};
59}
60
61namespace {
62class MipsAsmParser : public MCTargetAsmParser {
63  MipsTargetStreamer &getTargetStreamer() {
64    MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
65    return static_cast<MipsTargetStreamer &>(TS);
66  }
67
68  MCSubtargetInfo &STI;
69  MCAsmParser &Parser;
70  MipsAssemblerOptions Options;
71
72#define GET_ASSEMBLER_HEADER
73#include "MipsGenAsmMatcher.inc"
74
75  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
76
77  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
78                               OperandVector &Operands, MCStreamer &Out,
79                               unsigned &ErrorInfo,
80                               bool MatchingInlineAsm) override;
81
82  /// Parse a register as used in CFI directives
83  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
84
85  bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
86
87  bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
88
89  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
90                        SMLoc NameLoc, OperandVector &Operands) override;
91
92  bool ParseDirective(AsmToken DirectiveID) override;
93
94  MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
95
96  MipsAsmParser::OperandMatchResultTy
97  MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
98                                    StringRef Identifier, SMLoc S);
99
100  MipsAsmParser::OperandMatchResultTy
101  MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
102
103  MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
104
105  MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
106
107  MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
108
109  MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
110
111  MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
112
113  bool searchSymbolAlias(OperandVector &Operands);
114
115  bool ParseOperand(OperandVector &, StringRef Mnemonic);
116
117  bool needsExpansion(MCInst &Inst);
118
119  // Expands assembly pseudo instructions.
120  // Returns false on success, true otherwise.
121  bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
122                         SmallVectorImpl<MCInst> &Instructions);
123
124  bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
125                     SmallVectorImpl<MCInst> &Instructions);
126
127  bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
128                            SmallVectorImpl<MCInst> &Instructions);
129
130  bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
131                            SmallVectorImpl<MCInst> &Instructions);
132
133  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
134                     SmallVectorImpl<MCInst> &Instructions, bool isLoad,
135                     bool isImmOpnd);
136  bool reportParseError(Twine ErrorMsg);
137  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
138
139  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
140  bool parseRelocOperand(const MCExpr *&Res);
141
142  const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
143
144  bool isEvaluated(const MCExpr *Expr);
145  bool parseSetFeature(uint64_t Feature);
146  bool parseDirectiveCPLoad(SMLoc Loc);
147  bool parseDirectiveCPSetup();
148  bool parseDirectiveNaN();
149  bool parseDirectiveSet();
150  bool parseDirectiveOption();
151
152  bool parseSetAtDirective();
153  bool parseSetNoAtDirective();
154  bool parseSetMacroDirective();
155  bool parseSetNoMacroDirective();
156  bool parseSetReorderDirective();
157  bool parseSetNoReorderDirective();
158  bool parseSetNoMips16Directive();
159  bool parseSetFpDirective();
160
161  bool parseSetAssignment();
162
163  bool parseDataDirective(unsigned Size, SMLoc L);
164  bool parseDirectiveGpWord();
165  bool parseDirectiveGpDWord();
166  bool parseDirectiveModule();
167  bool parseDirectiveModuleFP();
168  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
169                       StringRef Directive);
170
171  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
172
173  bool eatComma(StringRef ErrorStr);
174
175  int matchCPURegisterName(StringRef Symbol);
176
177  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
178
179  int matchFPURegisterName(StringRef Name);
180
181  int matchFCCRegisterName(StringRef Name);
182
183  int matchACRegisterName(StringRef Name);
184
185  int matchMSA128RegisterName(StringRef Name);
186
187  int matchMSA128CtrlRegisterName(StringRef Name);
188
189  unsigned getReg(int RC, int RegNo);
190
191  unsigned getGPR(int RegNo);
192
193  int getATReg(SMLoc Loc);
194
195  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
196                          SmallVectorImpl<MCInst> &Instructions);
197
198  // Helper function that checks if the value of a vector index is within the
199  // boundaries of accepted values for each RegisterKind
200  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
201  bool validateMSAIndex(int Val, int RegKind);
202
203  void setFeatureBits(unsigned Feature, StringRef FeatureString) {
204    if (!(STI.getFeatureBits() & Feature)) {
205      setAvailableFeatures(
206          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
207    }
208  }
209
210  void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
211    if (STI.getFeatureBits() & Feature) {
212      setAvailableFeatures(
213          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
214    }
215  }
216
217public:
218  enum MipsMatchResultTy {
219    Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
220#define GET_OPERAND_DIAGNOSTIC_TYPES
221#include "MipsGenAsmMatcher.inc"
222#undef GET_OPERAND_DIAGNOSTIC_TYPES
223
224  };
225
226  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
227                const MCInstrInfo &MII, const MCTargetOptions &Options)
228      : MCTargetAsmParser(), STI(sti), Parser(parser) {
229    // Initialize the set of available features.
230    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
231
232    getTargetStreamer().updateABIInfo(*this);
233
234    // Assert exactly one ABI was chosen.
235    assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
236            ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
237            ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
238            ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
239
240    if (!isABI_O32() && !allowOddSPReg() != 0)
241      report_fatal_error("-mno-odd-spreg requires the O32 ABI");
242  }
243
244  MCAsmParser &getParser() const { return Parser; }
245  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
246
247  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
248  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
249
250  bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
251  bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
252  bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
253  bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
254  bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
255  bool isABI_FPXX() const { return false; } // TODO: add check for FeatureXX
256
257  bool allowOddSPReg() const {
258    return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
259  }
260
261  bool inMicroMipsMode() const {
262    return STI.getFeatureBits() & Mips::FeatureMicroMips;
263  }
264  bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
265  bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
266  bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
267  bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
268  bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
269  bool hasMips32() const {
270    return (STI.getFeatureBits() & Mips::FeatureMips32);
271  }
272  bool hasMips64() const {
273    return (STI.getFeatureBits() & Mips::FeatureMips64);
274  }
275  bool hasMips32r2() const {
276    return (STI.getFeatureBits() & Mips::FeatureMips32r2);
277  }
278  bool hasMips64r2() const {
279    return (STI.getFeatureBits() & Mips::FeatureMips64r2);
280  }
281  bool hasMips32r6() const {
282    return (STI.getFeatureBits() & Mips::FeatureMips32r6);
283  }
284  bool hasMips64r6() const {
285    return (STI.getFeatureBits() & Mips::FeatureMips64r6);
286  }
287  bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
288  bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
289  bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
290
291  bool inMips16Mode() const {
292    return STI.getFeatureBits() & Mips::FeatureMips16;
293  }
294  // TODO: see how can we get this info.
295  bool mipsSEUsesSoftFloat() const { return false; }
296
297  /// Warn if RegNo is the current assembler temporary.
298  void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
299};
300}
301
302namespace {
303
304/// MipsOperand - Instances of this class represent a parsed Mips machine
305/// instruction.
306class MipsOperand : public MCParsedAsmOperand {
307public:
308  /// Broad categories of register classes
309  /// The exact class is finalized by the render method.
310  enum RegKind {
311    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
312    RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
313                          /// isFP64bit())
314    RegKind_FCC = 4,      /// FCC
315    RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
316    RegKind_MSACtrl = 16, /// MSA control registers
317    RegKind_COP2 = 32,    /// COP2
318    RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
319                          /// context).
320    RegKind_CCR = 128,    /// CCR
321    RegKind_HWRegs = 256, /// HWRegs
322    RegKind_COP3 = 512,   /// COP3
323
324    /// Potentially any (e.g. $1)
325    RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
326                      RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
327                      RegKind_CCR | RegKind_HWRegs | RegKind_COP3
328  };
329
330private:
331  enum KindTy {
332    k_Immediate,     /// An immediate (possibly involving symbol references)
333    k_Memory,        /// Base + Offset Memory Address
334    k_PhysRegister,  /// A physical register from the Mips namespace
335    k_RegisterIndex, /// A register index in one or more RegKind.
336    k_Token          /// A simple token
337  } Kind;
338
339public:
340  MipsOperand(KindTy K, MipsAsmParser &Parser)
341      : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
342
343private:
344  /// For diagnostics, and checking the assembler temporary
345  MipsAsmParser &AsmParser;
346
347  struct Token {
348    const char *Data;
349    unsigned Length;
350  };
351
352  struct PhysRegOp {
353    unsigned Num; /// Register Number
354  };
355
356  struct RegIdxOp {
357    unsigned Index; /// Index into the register class
358    RegKind Kind;   /// Bitfield of the kinds it could possibly be
359    const MCRegisterInfo *RegInfo;
360  };
361
362  struct ImmOp {
363    const MCExpr *Val;
364  };
365
366  struct MemOp {
367    MipsOperand *Base;
368    const MCExpr *Off;
369  };
370
371  union {
372    struct Token Tok;
373    struct PhysRegOp PhysReg;
374    struct RegIdxOp RegIdx;
375    struct ImmOp Imm;
376    struct MemOp Mem;
377  };
378
379  SMLoc StartLoc, EndLoc;
380
381  /// Internal constructor for register kinds
382  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
383                                                const MCRegisterInfo *RegInfo,
384                                                SMLoc S, SMLoc E,
385                                                MipsAsmParser &Parser) {
386    auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
387    Op->RegIdx.Index = Index;
388    Op->RegIdx.RegInfo = RegInfo;
389    Op->RegIdx.Kind = RegKind;
390    Op->StartLoc = S;
391    Op->EndLoc = E;
392    return Op;
393  }
394
395public:
396  /// Coerce the register to GPR32 and return the real register for the current
397  /// target.
398  unsigned getGPR32Reg() const {
399    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
400    AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
401    unsigned ClassID = Mips::GPR32RegClassID;
402    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
403  }
404
405  /// Coerce the register to GPR64 and return the real register for the current
406  /// target.
407  unsigned getGPR64Reg() const {
408    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
409    unsigned ClassID = Mips::GPR64RegClassID;
410    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
411  }
412
413private:
414  /// Coerce the register to AFGR64 and return the real register for the current
415  /// target.
416  unsigned getAFGR64Reg() const {
417    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
418    if (RegIdx.Index % 2 != 0)
419      AsmParser.Warning(StartLoc, "Float register should be even.");
420    return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
421        .getRegister(RegIdx.Index / 2);
422  }
423
424  /// Coerce the register to FGR64 and return the real register for the current
425  /// target.
426  unsigned getFGR64Reg() const {
427    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
428    return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
429        .getRegister(RegIdx.Index);
430  }
431
432  /// Coerce the register to FGR32 and return the real register for the current
433  /// target.
434  unsigned getFGR32Reg() const {
435    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
436    return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
437        .getRegister(RegIdx.Index);
438  }
439
440  /// Coerce the register to FGRH32 and return the real register for the current
441  /// target.
442  unsigned getFGRH32Reg() const {
443    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
444    return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
445        .getRegister(RegIdx.Index);
446  }
447
448  /// Coerce the register to FCC and return the real register for the current
449  /// target.
450  unsigned getFCCReg() const {
451    assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
452    return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
453        .getRegister(RegIdx.Index);
454  }
455
456  /// Coerce the register to MSA128 and return the real register for the current
457  /// target.
458  unsigned getMSA128Reg() const {
459    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
460    // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
461    // identical
462    unsigned ClassID = Mips::MSA128BRegClassID;
463    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
464  }
465
466  /// Coerce the register to MSACtrl and return the real register for the
467  /// current target.
468  unsigned getMSACtrlReg() const {
469    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
470    unsigned ClassID = Mips::MSACtrlRegClassID;
471    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
472  }
473
474  /// Coerce the register to COP2 and return the real register for the
475  /// current target.
476  unsigned getCOP2Reg() const {
477    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
478    unsigned ClassID = Mips::COP2RegClassID;
479    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
480  }
481
482  /// Coerce the register to COP3 and return the real register for the
483  /// current target.
484  unsigned getCOP3Reg() const {
485    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
486    unsigned ClassID = Mips::COP3RegClassID;
487    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
488  }
489
490  /// Coerce the register to ACC64DSP and return the real register for the
491  /// current target.
492  unsigned getACC64DSPReg() const {
493    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
494    unsigned ClassID = Mips::ACC64DSPRegClassID;
495    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
496  }
497
498  /// Coerce the register to HI32DSP and return the real register for the
499  /// current target.
500  unsigned getHI32DSPReg() const {
501    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
502    unsigned ClassID = Mips::HI32DSPRegClassID;
503    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
504  }
505
506  /// Coerce the register to LO32DSP and return the real register for the
507  /// current target.
508  unsigned getLO32DSPReg() const {
509    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
510    unsigned ClassID = Mips::LO32DSPRegClassID;
511    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
512  }
513
514  /// Coerce the register to CCR and return the real register for the
515  /// current target.
516  unsigned getCCRReg() const {
517    assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
518    unsigned ClassID = Mips::CCRRegClassID;
519    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
520  }
521
522  /// Coerce the register to HWRegs and return the real register for the
523  /// current target.
524  unsigned getHWRegsReg() const {
525    assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
526    unsigned ClassID = Mips::HWRegsRegClassID;
527    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
528  }
529
530public:
531  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
532    // Add as immediate when possible.  Null MCExpr = 0.
533    if (!Expr)
534      Inst.addOperand(MCOperand::CreateImm(0));
535    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
536      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
537    else
538      Inst.addOperand(MCOperand::CreateExpr(Expr));
539  }
540
541  void addRegOperands(MCInst &Inst, unsigned N) const {
542    llvm_unreachable("Use a custom parser instead");
543  }
544
545  /// Render the operand to an MCInst as a GPR32
546  /// Asserts if the wrong number of operands are requested, or the operand
547  /// is not a k_RegisterIndex compatible with RegKind_GPR
548  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
549    assert(N == 1 && "Invalid number of operands!");
550    Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
551  }
552
553  /// Render the operand to an MCInst as a GPR64
554  /// Asserts if the wrong number of operands are requested, or the operand
555  /// is not a k_RegisterIndex compatible with RegKind_GPR
556  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
557    assert(N == 1 && "Invalid number of operands!");
558    Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
559  }
560
561  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
562    assert(N == 1 && "Invalid number of operands!");
563    Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
564  }
565
566  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
567    assert(N == 1 && "Invalid number of operands!");
568    Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
569  }
570
571  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
572    assert(N == 1 && "Invalid number of operands!");
573    Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
574    // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
575    if (!AsmParser.allowOddSPReg() && RegIdx.Index & 1)
576      AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
577                                "registers");
578  }
579
580  void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
581    assert(N == 1 && "Invalid number of operands!");
582    Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
583  }
584
585  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
586    assert(N == 1 && "Invalid number of operands!");
587    Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
588  }
589
590  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
591    assert(N == 1 && "Invalid number of operands!");
592    Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
593  }
594
595  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
596    assert(N == 1 && "Invalid number of operands!");
597    Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
598  }
599
600  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
601    assert(N == 1 && "Invalid number of operands!");
602    Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
603  }
604
605  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
606    assert(N == 1 && "Invalid number of operands!");
607    Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
608  }
609
610  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
611    assert(N == 1 && "Invalid number of operands!");
612    Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
613  }
614
615  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
616    assert(N == 1 && "Invalid number of operands!");
617    Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
618  }
619
620  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
621    assert(N == 1 && "Invalid number of operands!");
622    Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
623  }
624
625  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
626    assert(N == 1 && "Invalid number of operands!");
627    Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
628  }
629
630  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
631    assert(N == 1 && "Invalid number of operands!");
632    Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
633  }
634
635  void addImmOperands(MCInst &Inst, unsigned N) const {
636    assert(N == 1 && "Invalid number of operands!");
637    const MCExpr *Expr = getImm();
638    addExpr(Inst, Expr);
639  }
640
641  void addMemOperands(MCInst &Inst, unsigned N) const {
642    assert(N == 2 && "Invalid number of operands!");
643
644    Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
645
646    const MCExpr *Expr = getMemOff();
647    addExpr(Inst, Expr);
648  }
649
650  bool isReg() const override {
651    // As a special case until we sort out the definition of div/divu, pretend
652    // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
653    if (isGPRAsmReg() && RegIdx.Index == 0)
654      return true;
655
656    return Kind == k_PhysRegister;
657  }
658  bool isRegIdx() const { return Kind == k_RegisterIndex; }
659  bool isImm() const override { return Kind == k_Immediate; }
660  bool isConstantImm() const {
661    return isImm() && dyn_cast<MCConstantExpr>(getImm());
662  }
663  bool isToken() const override {
664    // Note: It's not possible to pretend that other operand kinds are tokens.
665    // The matcher emitter checks tokens first.
666    return Kind == k_Token;
667  }
668  bool isMem() const override { return Kind == k_Memory; }
669  bool isConstantMemOff() const {
670    return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
671  }
672  template <unsigned Bits> bool isMemWithSimmOffset() const {
673    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
674  }
675  bool isInvNum() const { return Kind == k_Immediate; }
676  bool isLSAImm() const {
677    if (!isConstantImm())
678      return false;
679    int64_t Val = getConstantImm();
680    return 1 <= Val && Val <= 4;
681  }
682
683  StringRef getToken() const {
684    assert(Kind == k_Token && "Invalid access!");
685    return StringRef(Tok.Data, Tok.Length);
686  }
687
688  unsigned getReg() const override {
689    // As a special case until we sort out the definition of div/divu, pretend
690    // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
691    if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
692        RegIdx.Kind & RegKind_GPR)
693      return getGPR32Reg(); // FIXME: GPR64 too
694
695    assert(Kind == k_PhysRegister && "Invalid access!");
696    return PhysReg.Num;
697  }
698
699  const MCExpr *getImm() const {
700    assert((Kind == k_Immediate) && "Invalid access!");
701    return Imm.Val;
702  }
703
704  int64_t getConstantImm() const {
705    const MCExpr *Val = getImm();
706    return static_cast<const MCConstantExpr *>(Val)->getValue();
707  }
708
709  MipsOperand *getMemBase() const {
710    assert((Kind == k_Memory) && "Invalid access!");
711    return Mem.Base;
712  }
713
714  const MCExpr *getMemOff() const {
715    assert((Kind == k_Memory) && "Invalid access!");
716    return Mem.Off;
717  }
718
719  int64_t getConstantMemOff() const {
720    return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
721  }
722
723  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
724                                                  MipsAsmParser &Parser) {
725    auto Op = make_unique<MipsOperand>(k_Token, Parser);
726    Op->Tok.Data = Str.data();
727    Op->Tok.Length = Str.size();
728    Op->StartLoc = S;
729    Op->EndLoc = S;
730    return Op;
731  }
732
733  /// Create a numeric register (e.g. $1). The exact register remains
734  /// unresolved until an instruction successfully matches
735  static std::unique_ptr<MipsOperand>
736  CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
737                   SMLoc E, MipsAsmParser &Parser) {
738    DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
739    return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
740  }
741
742  /// Create a register that is definitely a GPR.
743  /// This is typically only used for named registers such as $gp.
744  static std::unique_ptr<MipsOperand>
745  CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
746               MipsAsmParser &Parser) {
747    return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
748  }
749
750  /// Create a register that is definitely a FGR.
751  /// This is typically only used for named registers such as $f0.
752  static std::unique_ptr<MipsOperand>
753  CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
754               MipsAsmParser &Parser) {
755    return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
756  }
757
758  /// Create a register that is definitely an FCC.
759  /// This is typically only used for named registers such as $fcc0.
760  static std::unique_ptr<MipsOperand>
761  CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
762               MipsAsmParser &Parser) {
763    return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
764  }
765
766  /// Create a register that is definitely an ACC.
767  /// This is typically only used for named registers such as $ac0.
768  static std::unique_ptr<MipsOperand>
769  CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
770               MipsAsmParser &Parser) {
771    return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
772  }
773
774  /// Create a register that is definitely an MSA128.
775  /// This is typically only used for named registers such as $w0.
776  static std::unique_ptr<MipsOperand>
777  CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
778                  SMLoc E, MipsAsmParser &Parser) {
779    return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
780  }
781
782  /// Create a register that is definitely an MSACtrl.
783  /// This is typically only used for named registers such as $msaaccess.
784  static std::unique_ptr<MipsOperand>
785  CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
786                   SMLoc E, MipsAsmParser &Parser) {
787    return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
788  }
789
790  static std::unique_ptr<MipsOperand>
791  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
792    auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
793    Op->Imm.Val = Val;
794    Op->StartLoc = S;
795    Op->EndLoc = E;
796    return Op;
797  }
798
799  static std::unique_ptr<MipsOperand>
800  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
801            SMLoc E, MipsAsmParser &Parser) {
802    auto Op = make_unique<MipsOperand>(k_Memory, Parser);
803    Op->Mem.Base = Base.release();
804    Op->Mem.Off = Off;
805    Op->StartLoc = S;
806    Op->EndLoc = E;
807    return Op;
808  }
809
810  bool isGPRAsmReg() const {
811    return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
812  }
813  bool isFGRAsmReg() const {
814    // AFGR64 is $0-$15 but we handle this in getAFGR64()
815    return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
816  }
817  bool isHWRegsAsmReg() const {
818    return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
819  }
820  bool isCCRAsmReg() const {
821    return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
822  }
823  bool isFCCAsmReg() const {
824    if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
825      return false;
826    if (!AsmParser.hasEightFccRegisters())
827      return RegIdx.Index == 0;
828    return RegIdx.Index <= 7;
829  }
830  bool isACCAsmReg() const {
831    return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
832  }
833  bool isCOP2AsmReg() const {
834    return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
835  }
836  bool isCOP3AsmReg() const {
837    return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
838  }
839  bool isMSA128AsmReg() const {
840    return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
841  }
842  bool isMSACtrlAsmReg() const {
843    return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
844  }
845
846  /// getStartLoc - Get the location of the first token of this operand.
847  SMLoc getStartLoc() const override { return StartLoc; }
848  /// getEndLoc - Get the location of the last token of this operand.
849  SMLoc getEndLoc() const override { return EndLoc; }
850
851  virtual ~MipsOperand() {
852    switch (Kind) {
853    case k_Immediate:
854      break;
855    case k_Memory:
856      delete Mem.Base;
857      break;
858    case k_PhysRegister:
859    case k_RegisterIndex:
860    case k_Token:
861      break;
862    }
863  }
864
865  void print(raw_ostream &OS) const override {
866    switch (Kind) {
867    case k_Immediate:
868      OS << "Imm<";
869      Imm.Val->print(OS);
870      OS << ">";
871      break;
872    case k_Memory:
873      OS << "Mem<";
874      Mem.Base->print(OS);
875      OS << ", ";
876      Mem.Off->print(OS);
877      OS << ">";
878      break;
879    case k_PhysRegister:
880      OS << "PhysReg<" << PhysReg.Num << ">";
881      break;
882    case k_RegisterIndex:
883      OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
884      break;
885    case k_Token:
886      OS << Tok.Data;
887      break;
888    }
889  }
890}; // class MipsOperand
891} // namespace
892
893namespace llvm {
894extern const MCInstrDesc MipsInsts[];
895}
896static const MCInstrDesc &getInstDesc(unsigned Opcode) {
897  return MipsInsts[Opcode];
898}
899
900bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
901                                       SmallVectorImpl<MCInst> &Instructions) {
902  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
903
904  Inst.setLoc(IDLoc);
905
906  if (MCID.isBranch() || MCID.isCall()) {
907    const unsigned Opcode = Inst.getOpcode();
908    MCOperand Offset;
909
910    switch (Opcode) {
911    default:
912      break;
913    case Mips::BEQ:
914    case Mips::BNE:
915    case Mips::BEQ_MM:
916    case Mips::BNE_MM:
917      assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
918      Offset = Inst.getOperand(2);
919      if (!Offset.isImm())
920        break; // We'll deal with this situation later on when applying fixups.
921      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
922        return Error(IDLoc, "branch target out of range");
923      if (OffsetToAlignment(Offset.getImm(),
924                            1LL << (inMicroMipsMode() ? 1 : 2)))
925        return Error(IDLoc, "branch to misaligned address");
926      break;
927    case Mips::BGEZ:
928    case Mips::BGTZ:
929    case Mips::BLEZ:
930    case Mips::BLTZ:
931    case Mips::BGEZAL:
932    case Mips::BLTZAL:
933    case Mips::BC1F:
934    case Mips::BC1T:
935    case Mips::BGEZ_MM:
936    case Mips::BGTZ_MM:
937    case Mips::BLEZ_MM:
938    case Mips::BLTZ_MM:
939    case Mips::BGEZAL_MM:
940    case Mips::BLTZAL_MM:
941    case Mips::BC1F_MM:
942    case Mips::BC1T_MM:
943      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
944      Offset = Inst.getOperand(1);
945      if (!Offset.isImm())
946        break; // We'll deal with this situation later on when applying fixups.
947      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
948        return Error(IDLoc, "branch target out of range");
949      if (OffsetToAlignment(Offset.getImm(),
950                            1LL << (inMicroMipsMode() ? 1 : 2)))
951        return Error(IDLoc, "branch to misaligned address");
952      break;
953    }
954  }
955
956  // SSNOP is deprecated on MIPS32r6/MIPS64r6
957  // We still accept it but it is a normal nop.
958  if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
959    std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
960    Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
961                                                      "nop instruction");
962  }
963
964  if (MCID.hasDelaySlot() && Options.isReorder()) {
965    // If this instruction has a delay slot and .set reorder is active,
966    // emit a NOP after it.
967    Instructions.push_back(Inst);
968    MCInst NopInst;
969    NopInst.setOpcode(Mips::SLL);
970    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
971    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
972    NopInst.addOperand(MCOperand::CreateImm(0));
973    Instructions.push_back(NopInst);
974    return false;
975  }
976
977  if (MCID.mayLoad() || MCID.mayStore()) {
978    // Check the offset of memory operand, if it is a symbol
979    // reference or immediate we may have to expand instructions.
980    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
981      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
982      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
983          (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
984        MCOperand &Op = Inst.getOperand(i);
985        if (Op.isImm()) {
986          int MemOffset = Op.getImm();
987          if (MemOffset < -32768 || MemOffset > 32767) {
988            // Offset can't exceed 16bit value.
989            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
990            return false;
991          }
992        } else if (Op.isExpr()) {
993          const MCExpr *Expr = Op.getExpr();
994          if (Expr->getKind() == MCExpr::SymbolRef) {
995            const MCSymbolRefExpr *SR =
996                static_cast<const MCSymbolRefExpr *>(Expr);
997            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
998              // Expand symbol.
999              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1000              return false;
1001            }
1002          } else if (!isEvaluated(Expr)) {
1003            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
1004            return false;
1005          }
1006        }
1007      }
1008    } // for
1009  }   // if load/store
1010
1011  if (needsExpansion(Inst))
1012    return expandInstruction(Inst, IDLoc, Instructions);
1013  else
1014    Instructions.push_back(Inst);
1015
1016  return false;
1017}
1018
1019bool MipsAsmParser::needsExpansion(MCInst &Inst) {
1020
1021  switch (Inst.getOpcode()) {
1022  case Mips::LoadImm32Reg:
1023  case Mips::LoadAddr32Imm:
1024  case Mips::LoadAddr32Reg:
1025  case Mips::LoadImm64Reg:
1026    return true;
1027  default:
1028    return false;
1029  }
1030}
1031
1032bool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
1033                                      SmallVectorImpl<MCInst> &Instructions) {
1034  switch (Inst.getOpcode()) {
1035  default:
1036    assert(0 && "unimplemented expansion");
1037    return true;
1038  case Mips::LoadImm32Reg:
1039    return expandLoadImm(Inst, IDLoc, Instructions);
1040  case Mips::LoadImm64Reg:
1041    if (!isGP64bit()) {
1042      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1043      return true;
1044    }
1045    return expandLoadImm(Inst, IDLoc, Instructions);
1046  case Mips::LoadAddr32Imm:
1047    return expandLoadAddressImm(Inst, IDLoc, Instructions);
1048  case Mips::LoadAddr32Reg:
1049    return expandLoadAddressReg(Inst, IDLoc, Instructions);
1050  }
1051}
1052
1053namespace {
1054template <int Shift, bool PerformShift>
1055void createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1056                   SmallVectorImpl<MCInst> &Instructions) {
1057  MCInst tmpInst;
1058  if (PerformShift) {
1059    tmpInst.setOpcode(Mips::DSLL);
1060    tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1061    tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1062    tmpInst.addOperand(MCOperand::CreateImm(16));
1063    tmpInst.setLoc(IDLoc);
1064    Instructions.push_back(tmpInst);
1065    tmpInst.clear();
1066  }
1067  tmpInst.setOpcode(Mips::ORi);
1068  tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1069  tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1070  tmpInst.addOperand(
1071      MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)));
1072  tmpInst.setLoc(IDLoc);
1073  Instructions.push_back(tmpInst);
1074}
1075}
1076
1077bool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1078                                  SmallVectorImpl<MCInst> &Instructions) {
1079  MCInst tmpInst;
1080  const MCOperand &ImmOp = Inst.getOperand(1);
1081  assert(ImmOp.isImm() && "expected immediate operand kind");
1082  const MCOperand &RegOp = Inst.getOperand(0);
1083  assert(RegOp.isReg() && "expected register operand kind");
1084
1085  int64_t ImmValue = ImmOp.getImm();
1086  tmpInst.setLoc(IDLoc);
1087  // FIXME: gas has a special case for values that are 000...1111, which
1088  // becomes a li -1 and then a dsrl
1089  if (0 <= ImmValue && ImmValue <= 65535) {
1090    // For 0 <= j <= 65535.
1091    // li d,j => ori d,$zero,j
1092    tmpInst.setOpcode(Mips::ORi);
1093    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1094    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1095    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1096    Instructions.push_back(tmpInst);
1097  } else if (ImmValue < 0 && ImmValue >= -32768) {
1098    // For -32768 <= j < 0.
1099    // li d,j => addiu d,$zero,j
1100    tmpInst.setOpcode(Mips::ADDiu);
1101    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1102    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1103    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1104    Instructions.push_back(tmpInst);
1105  } else if ((ImmValue & 0xffffffff) == ImmValue) {
1106    // For any value of j that is representable as a 32-bit integer, create
1107    // a sequence of:
1108    // li d,j => lui d,hi16(j)
1109    //           ori d,d,lo16(j)
1110    tmpInst.setOpcode(Mips::LUi);
1111    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1112    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1113    Instructions.push_back(tmpInst);
1114    createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1115  } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1116    if (!isGP64bit()) {
1117      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1118      return true;
1119    }
1120
1121    //            <-------  lo32 ------>
1122    // <-------  hi32 ------>
1123    // <- hi16 ->             <- lo16 ->
1124    //  _________________________________
1125    // |          |          |          |
1126    // | 16-bytes | 16-bytes | 16-bytes |
1127    // |__________|__________|__________|
1128    //
1129    // For any value of j that is representable as a 48-bit integer, create
1130    // a sequence of:
1131    // li d,j => lui d,hi16(j)
1132    //           ori d,d,hi16(lo32(j))
1133    //           dsll d,d,16
1134    //           ori d,d,lo16(lo32(j))
1135    tmpInst.setOpcode(Mips::LUi);
1136    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1137    tmpInst.addOperand(
1138        MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1139    Instructions.push_back(tmpInst);
1140    createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1141    createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1142  } else {
1143    if (!isGP64bit()) {
1144      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1145      return true;
1146    }
1147
1148    // <-------  hi32 ------> <-------  lo32 ------>
1149    // <- hi16 ->                        <- lo16 ->
1150    //  ___________________________________________
1151    // |          |          |          |          |
1152    // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1153    // |__________|__________|__________|__________|
1154    //
1155    // For any value of j that isn't representable as a 48-bit integer.
1156    // li d,j => lui d,hi16(j)
1157    //           ori d,d,lo16(hi32(j))
1158    //           dsll d,d,16
1159    //           ori d,d,hi16(lo32(j))
1160    //           dsll d,d,16
1161    //           ori d,d,lo16(lo32(j))
1162    tmpInst.setOpcode(Mips::LUi);
1163    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1164    tmpInst.addOperand(
1165        MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
1166    Instructions.push_back(tmpInst);
1167    createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1168    createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1169    createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1170  }
1171  return false;
1172}
1173
1174bool
1175MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1176                                    SmallVectorImpl<MCInst> &Instructions) {
1177  MCInst tmpInst;
1178  const MCOperand &ImmOp = Inst.getOperand(2);
1179  assert(ImmOp.isImm() && "expected immediate operand kind");
1180  const MCOperand &SrcRegOp = Inst.getOperand(1);
1181  assert(SrcRegOp.isReg() && "expected register operand kind");
1182  const MCOperand &DstRegOp = Inst.getOperand(0);
1183  assert(DstRegOp.isReg() && "expected register operand kind");
1184  int ImmValue = ImmOp.getImm();
1185  if (-32768 <= ImmValue && ImmValue <= 65535) {
1186    // For -32768 <= j <= 65535.
1187    // la d,j(s) => addiu d,s,j
1188    tmpInst.setOpcode(Mips::ADDiu);
1189    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1190    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1191    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1192    Instructions.push_back(tmpInst);
1193  } else {
1194    // For any other value of j that is representable as a 32-bit integer.
1195    // la d,j(s) => lui d,hi16(j)
1196    //              ori d,d,lo16(j)
1197    //              addu d,d,s
1198    tmpInst.setOpcode(Mips::LUi);
1199    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1200    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1201    Instructions.push_back(tmpInst);
1202    tmpInst.clear();
1203    tmpInst.setOpcode(Mips::ORi);
1204    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1205    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1206    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1207    Instructions.push_back(tmpInst);
1208    tmpInst.clear();
1209    tmpInst.setOpcode(Mips::ADDu);
1210    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1211    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
1212    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
1213    Instructions.push_back(tmpInst);
1214  }
1215  return false;
1216}
1217
1218bool
1219MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1220                                    SmallVectorImpl<MCInst> &Instructions) {
1221  MCInst tmpInst;
1222  const MCOperand &ImmOp = Inst.getOperand(1);
1223  assert(ImmOp.isImm() && "expected immediate operand kind");
1224  const MCOperand &RegOp = Inst.getOperand(0);
1225  assert(RegOp.isReg() && "expected register operand kind");
1226  int ImmValue = ImmOp.getImm();
1227  if (-32768 <= ImmValue && ImmValue <= 65535) {
1228    // For -32768 <= j <= 65535.
1229    // la d,j => addiu d,$zero,j
1230    tmpInst.setOpcode(Mips::ADDiu);
1231    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1232    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
1233    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
1234    Instructions.push_back(tmpInst);
1235  } else {
1236    // For any other value of j that is representable as a 32-bit integer.
1237    // la d,j => lui d,hi16(j)
1238    //           ori d,d,lo16(j)
1239    tmpInst.setOpcode(Mips::LUi);
1240    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1241    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
1242    Instructions.push_back(tmpInst);
1243    tmpInst.clear();
1244    tmpInst.setOpcode(Mips::ORi);
1245    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1246    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1247    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
1248    Instructions.push_back(tmpInst);
1249  }
1250  return false;
1251}
1252
1253void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
1254                                  SmallVectorImpl<MCInst> &Instructions,
1255                                  bool isLoad, bool isImmOpnd) {
1256  const MCSymbolRefExpr *SR;
1257  MCInst TempInst;
1258  unsigned ImmOffset, HiOffset, LoOffset;
1259  const MCExpr *ExprOffset;
1260  unsigned TmpRegNum;
1261  // 1st operand is either the source or destination register.
1262  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1263  unsigned RegOpNum = Inst.getOperand(0).getReg();
1264  // 2nd operand is the base register.
1265  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1266  unsigned BaseRegNum = Inst.getOperand(1).getReg();
1267  // 3rd operand is either an immediate or expression.
1268  if (isImmOpnd) {
1269    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
1270    ImmOffset = Inst.getOperand(2).getImm();
1271    LoOffset = ImmOffset & 0x0000ffff;
1272    HiOffset = (ImmOffset & 0xffff0000) >> 16;
1273    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
1274    if (LoOffset & 0x8000)
1275      HiOffset++;
1276  } else
1277    ExprOffset = Inst.getOperand(2).getExpr();
1278  // All instructions will have the same location.
1279  TempInst.setLoc(IDLoc);
1280  // These are some of the types of expansions we perform here:
1281  // 1) lw $8, sym        => lui $8, %hi(sym)
1282  //                         lw $8, %lo(sym)($8)
1283  // 2) lw $8, offset($9) => lui $8, %hi(offset)
1284  //                         add $8, $8, $9
1285  //                         lw $8, %lo(offset)($9)
1286  // 3) lw $8, offset($8) => lui $at, %hi(offset)
1287  //                         add $at, $at, $8
1288  //                         lw $8, %lo(offset)($at)
1289  // 4) sw $8, sym        => lui $at, %hi(sym)
1290  //                         sw $8, %lo(sym)($at)
1291  // 5) sw $8, offset($8) => lui $at, %hi(offset)
1292  //                         add $at, $at, $8
1293  //                         sw $8, %lo(offset)($at)
1294  // 6) ldc1 $f0, sym     => lui $at, %hi(sym)
1295  //                         ldc1 $f0, %lo(sym)($at)
1296  //
1297  // For load instructions we can use the destination register as a temporary
1298  // if base and dst are different (examples 1 and 2) and if the base register
1299  // is general purpose otherwise we must use $at (example 6) and error if it's
1300  // not available. For stores we must use $at (examples 4 and 5) because we
1301  // must not clobber the source register setting up the offset.
1302  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1303  int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1304  unsigned RegClassIDOp0 =
1305      getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1306  bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1307               (RegClassIDOp0 == Mips::GPR64RegClassID);
1308  if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1309    TmpRegNum = RegOpNum;
1310  else {
1311    int AT = getATReg(IDLoc);
1312    // At this point we need AT to perform the expansions and we exit if it is
1313    // not available.
1314    if (!AT)
1315      return;
1316    TmpRegNum = getReg(
1317        (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1318  }
1319
1320  TempInst.setOpcode(Mips::LUi);
1321  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1322  if (isImmOpnd)
1323    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
1324  else {
1325    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1326      SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
1327      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
1328          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
1329          getContext());
1330      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1331    } else {
1332      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
1333      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
1334    }
1335  }
1336  // Add the instruction to the list.
1337  Instructions.push_back(TempInst);
1338  // Prepare TempInst for next instruction.
1339  TempInst.clear();
1340  // Add temp register to base.
1341  TempInst.setOpcode(Mips::ADDu);
1342  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1343  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1344  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
1345  Instructions.push_back(TempInst);
1346  TempInst.clear();
1347  // And finally, create original instruction with low part
1348  // of offset and new base.
1349  TempInst.setOpcode(Inst.getOpcode());
1350  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
1351  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
1352  if (isImmOpnd)
1353    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
1354  else {
1355    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
1356      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
1357          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
1358          getContext());
1359      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1360    } else {
1361      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
1362      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
1363    }
1364  }
1365  Instructions.push_back(TempInst);
1366  TempInst.clear();
1367}
1368
1369unsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1370  // As described by the Mips32r2 spec, the registers Rd and Rs for
1371  // jalr.hb must be different.
1372  unsigned Opcode = Inst.getOpcode();
1373
1374  if (Opcode == Mips::JALR_HB &&
1375      (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1376    return Match_RequiresDifferentSrcAndDst;
1377
1378  return Match_Success;
1379}
1380
1381bool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1382                                            OperandVector &Operands,
1383                                            MCStreamer &Out,
1384                                            unsigned &ErrorInfo,
1385                                            bool MatchingInlineAsm) {
1386
1387  MCInst Inst;
1388  SmallVector<MCInst, 8> Instructions;
1389  unsigned MatchResult =
1390      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1391
1392  switch (MatchResult) {
1393  default:
1394    break;
1395  case Match_Success: {
1396    if (processInstruction(Inst, IDLoc, Instructions))
1397      return true;
1398    for (unsigned i = 0; i < Instructions.size(); i++)
1399      Out.EmitInstruction(Instructions[i], STI);
1400    return false;
1401  }
1402  case Match_MissingFeature:
1403    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1404    return true;
1405  case Match_InvalidOperand: {
1406    SMLoc ErrorLoc = IDLoc;
1407    if (ErrorInfo != ~0U) {
1408      if (ErrorInfo >= Operands.size())
1409        return Error(IDLoc, "too few operands for instruction");
1410
1411      ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
1412      if (ErrorLoc == SMLoc())
1413        ErrorLoc = IDLoc;
1414    }
1415
1416    return Error(ErrorLoc, "invalid operand for instruction");
1417  }
1418  case Match_MnemonicFail:
1419    return Error(IDLoc, "invalid instruction");
1420  case Match_RequiresDifferentSrcAndDst:
1421    return Error(IDLoc, "source and destination must be different");
1422  }
1423  return true;
1424}
1425
1426void MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
1427  if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
1428    if (RegIndex == 1)
1429      Warning(Loc, "Used $at without \".set noat\"");
1430    else
1431      Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
1432                       Twine(RegIndex) + "\"");
1433  }
1434}
1435
1436int MipsAsmParser::matchCPURegisterName(StringRef Name) {
1437  int CC;
1438
1439  CC = StringSwitch<unsigned>(Name)
1440           .Case("zero", 0)
1441           .Case("at", 1)
1442           .Case("a0", 4)
1443           .Case("a1", 5)
1444           .Case("a2", 6)
1445           .Case("a3", 7)
1446           .Case("v0", 2)
1447           .Case("v1", 3)
1448           .Case("s0", 16)
1449           .Case("s1", 17)
1450           .Case("s2", 18)
1451           .Case("s3", 19)
1452           .Case("s4", 20)
1453           .Case("s5", 21)
1454           .Case("s6", 22)
1455           .Case("s7", 23)
1456           .Case("k0", 26)
1457           .Case("k1", 27)
1458           .Case("gp", 28)
1459           .Case("sp", 29)
1460           .Case("fp", 30)
1461           .Case("s8", 30)
1462           .Case("ra", 31)
1463           .Case("t0", 8)
1464           .Case("t1", 9)
1465           .Case("t2", 10)
1466           .Case("t3", 11)
1467           .Case("t4", 12)
1468           .Case("t5", 13)
1469           .Case("t6", 14)
1470           .Case("t7", 15)
1471           .Case("t8", 24)
1472           .Case("t9", 25)
1473           .Default(-1);
1474
1475  if (isABI_N32() || isABI_N64()) {
1476    // Although SGI documentation just cuts out t0-t3 for n32/n64,
1477    // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
1478    // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
1479    if (8 <= CC && CC <= 11)
1480      CC += 4;
1481
1482    if (CC == -1)
1483      CC = StringSwitch<unsigned>(Name)
1484               .Case("a4", 8)
1485               .Case("a5", 9)
1486               .Case("a6", 10)
1487               .Case("a7", 11)
1488               .Case("kt0", 26)
1489               .Case("kt1", 27)
1490               .Default(-1);
1491  }
1492
1493  return CC;
1494}
1495
1496int MipsAsmParser::matchFPURegisterName(StringRef Name) {
1497
1498  if (Name[0] == 'f') {
1499    StringRef NumString = Name.substr(1);
1500    unsigned IntVal;
1501    if (NumString.getAsInteger(10, IntVal))
1502      return -1;     // This is not an integer.
1503    if (IntVal > 31) // Maximum index for fpu register.
1504      return -1;
1505    return IntVal;
1506  }
1507  return -1;
1508}
1509
1510int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1511
1512  if (Name.startswith("fcc")) {
1513    StringRef NumString = Name.substr(3);
1514    unsigned IntVal;
1515    if (NumString.getAsInteger(10, IntVal))
1516      return -1;    // This is not an integer.
1517    if (IntVal > 7) // There are only 8 fcc registers.
1518      return -1;
1519    return IntVal;
1520  }
1521  return -1;
1522}
1523
1524int MipsAsmParser::matchACRegisterName(StringRef Name) {
1525
1526  if (Name.startswith("ac")) {
1527    StringRef NumString = Name.substr(2);
1528    unsigned IntVal;
1529    if (NumString.getAsInteger(10, IntVal))
1530      return -1;    // This is not an integer.
1531    if (IntVal > 3) // There are only 3 acc registers.
1532      return -1;
1533    return IntVal;
1534  }
1535  return -1;
1536}
1537
1538int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
1539  unsigned IntVal;
1540
1541  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
1542    return -1;
1543
1544  if (IntVal > 31)
1545    return -1;
1546
1547  return IntVal;
1548}
1549
1550int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1551  int CC;
1552
1553  CC = StringSwitch<unsigned>(Name)
1554           .Case("msair", 0)
1555           .Case("msacsr", 1)
1556           .Case("msaaccess", 2)
1557           .Case("msasave", 3)
1558           .Case("msamodify", 4)
1559           .Case("msarequest", 5)
1560           .Case("msamap", 6)
1561           .Case("msaunmap", 7)
1562           .Default(-1);
1563
1564  return CC;
1565}
1566
1567bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1568  if (Reg > 31)
1569    return false;
1570
1571  aTReg = Reg;
1572  return true;
1573}
1574
1575int MipsAsmParser::getATReg(SMLoc Loc) {
1576  int AT = Options.getATRegNum();
1577  if (AT == 0)
1578    reportParseError(Loc,
1579                     "Pseudo instruction requires $at, which is not available");
1580  return AT;
1581}
1582
1583unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1584  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1585}
1586
1587unsigned MipsAsmParser::getGPR(int RegNo) {
1588  return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
1589                RegNo);
1590}
1591
1592int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1593  if (RegNum >
1594      getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1595    return -1;
1596
1597  return getReg(RegClass, RegNum);
1598}
1599
1600bool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
1601  DEBUG(dbgs() << "ParseOperand\n");
1602
1603  // Check if the current operand has a custom associated parser, if so, try to
1604  // custom parse the operand, or fallback to the general approach.
1605  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1606  if (ResTy == MatchOperand_Success)
1607    return false;
1608  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1609  // there was a match, but an error occurred, in which case, just return that
1610  // the operand parsing failed.
1611  if (ResTy == MatchOperand_ParseFail)
1612    return true;
1613
1614  DEBUG(dbgs() << ".. Generic Parser\n");
1615
1616  switch (getLexer().getKind()) {
1617  default:
1618    Error(Parser.getTok().getLoc(), "unexpected token in operand");
1619    return true;
1620  case AsmToken::Dollar: {
1621    // Parse the register.
1622    SMLoc S = Parser.getTok().getLoc();
1623
1624    // Almost all registers have been parsed by custom parsers. There is only
1625    // one exception to this. $zero (and it's alias $0) will reach this point
1626    // for div, divu, and similar instructions because it is not an operand
1627    // to the instruction definition but an explicit register. Special case
1628    // this situation for now.
1629    if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1630      return false;
1631
1632    // Maybe it is a symbol reference.
1633    StringRef Identifier;
1634    if (Parser.parseIdentifier(Identifier))
1635      return true;
1636
1637    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1638    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1639    // Otherwise create a symbol reference.
1640    const MCExpr *Res =
1641        MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1642
1643    Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1644    return false;
1645  }
1646  // Else drop to expression parsing.
1647  case AsmToken::LParen:
1648  case AsmToken::Minus:
1649  case AsmToken::Plus:
1650  case AsmToken::Integer:
1651  case AsmToken::Tilde:
1652  case AsmToken::String: {
1653    DEBUG(dbgs() << ".. generic integer\n");
1654    OperandMatchResultTy ResTy = ParseImm(Operands);
1655    return ResTy != MatchOperand_Success;
1656  }
1657  case AsmToken::Percent: {
1658    // It is a symbol reference or constant expression.
1659    const MCExpr *IdVal;
1660    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1661    if (parseRelocOperand(IdVal))
1662      return true;
1663
1664    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1665
1666    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1667    return false;
1668  } // case AsmToken::Percent
1669  } // switch(getLexer().getKind())
1670  return true;
1671}
1672
1673const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1674                                               StringRef RelocStr) {
1675  const MCExpr *Res;
1676  // Check the type of the expression.
1677  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1678    // It's a constant, evaluate reloc value.
1679    int16_t Val;
1680    switch (getVariantKind(RelocStr)) {
1681    case MCSymbolRefExpr::VK_Mips_ABS_LO:
1682      // Get the 1st 16-bits.
1683      Val = MCE->getValue() & 0xffff;
1684      break;
1685    case MCSymbolRefExpr::VK_Mips_ABS_HI:
1686      // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
1687      // 16 bits being negative.
1688      Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
1689      break;
1690    case MCSymbolRefExpr::VK_Mips_HIGHER:
1691      // Get the 3rd 16-bits.
1692      Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
1693      break;
1694    case MCSymbolRefExpr::VK_Mips_HIGHEST:
1695      // Get the 4th 16-bits.
1696      Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
1697      break;
1698    default:
1699      report_fatal_error("Unsupported reloc value!");
1700    }
1701    return MCConstantExpr::Create(Val, getContext());
1702  }
1703
1704  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1705    // It's a symbol, create a symbolic expression from the symbol.
1706    StringRef Symbol = MSRE->getSymbol().getName();
1707    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1708    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1709    return Res;
1710  }
1711
1712  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1713    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1714
1715    // Try to create target expression.
1716    if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
1717      return MipsMCExpr::Create(VK, Expr, getContext());
1718
1719    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1720    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1721    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1722    return Res;
1723  }
1724
1725  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1726    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1727    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1728    return Res;
1729  }
1730  // Just return the original expression.
1731  return Expr;
1732}
1733
1734bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1735
1736  switch (Expr->getKind()) {
1737  case MCExpr::Constant:
1738    return true;
1739  case MCExpr::SymbolRef:
1740    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1741  case MCExpr::Binary:
1742    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1743      if (!isEvaluated(BE->getLHS()))
1744        return false;
1745      return isEvaluated(BE->getRHS());
1746    }
1747  case MCExpr::Unary:
1748    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1749  case MCExpr::Target:
1750    return true;
1751  }
1752  return false;
1753}
1754
1755bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1756  Parser.Lex();                          // Eat the % token.
1757  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1758  if (Tok.isNot(AsmToken::Identifier))
1759    return true;
1760
1761  std::string Str = Tok.getIdentifier().str();
1762
1763  Parser.Lex(); // Eat the identifier.
1764  // Now make an expression from the rest of the operand.
1765  const MCExpr *IdVal;
1766  SMLoc EndLoc;
1767
1768  if (getLexer().getKind() == AsmToken::LParen) {
1769    while (1) {
1770      Parser.Lex(); // Eat the '(' token.
1771      if (getLexer().getKind() == AsmToken::Percent) {
1772        Parser.Lex(); // Eat the % token.
1773        const AsmToken &nextTok = Parser.getTok();
1774        if (nextTok.isNot(AsmToken::Identifier))
1775          return true;
1776        Str += "(%";
1777        Str += nextTok.getIdentifier();
1778        Parser.Lex(); // Eat the identifier.
1779        if (getLexer().getKind() != AsmToken::LParen)
1780          return true;
1781      } else
1782        break;
1783    }
1784    if (getParser().parseParenExpression(IdVal, EndLoc))
1785      return true;
1786
1787    while (getLexer().getKind() == AsmToken::RParen)
1788      Parser.Lex(); // Eat the ')' token.
1789
1790  } else
1791    return true; // Parenthesis must follow the relocation operand.
1792
1793  Res = evaluateRelocExpr(IdVal, Str);
1794  return false;
1795}
1796
1797bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1798                                  SMLoc &EndLoc) {
1799  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
1800  OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
1801  if (ResTy == MatchOperand_Success) {
1802    assert(Operands.size() == 1);
1803    MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
1804    StartLoc = Operand.getStartLoc();
1805    EndLoc = Operand.getEndLoc();
1806
1807    // AFAIK, we only support numeric registers and named GPR's in CFI
1808    // directives.
1809    // Don't worry about eating tokens before failing. Using an unrecognised
1810    // register is a parse error.
1811    if (Operand.isGPRAsmReg()) {
1812      // Resolve to GPR32 or GPR64 appropriately.
1813      RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
1814    }
1815
1816    return (RegNo == (unsigned)-1);
1817  }
1818
1819  assert(Operands.size() == 0);
1820  return (RegNo == (unsigned)-1);
1821}
1822
1823bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1824  SMLoc S;
1825  bool Result = true;
1826
1827  while (getLexer().getKind() == AsmToken::LParen)
1828    Parser.Lex();
1829
1830  switch (getLexer().getKind()) {
1831  default:
1832    return true;
1833  case AsmToken::Identifier:
1834  case AsmToken::LParen:
1835  case AsmToken::Integer:
1836  case AsmToken::Minus:
1837  case AsmToken::Plus:
1838    if (isParenExpr)
1839      Result = getParser().parseParenExpression(Res, S);
1840    else
1841      Result = (getParser().parseExpression(Res));
1842    while (getLexer().getKind() == AsmToken::RParen)
1843      Parser.Lex();
1844    break;
1845  case AsmToken::Percent:
1846    Result = parseRelocOperand(Res);
1847  }
1848  return Result;
1849}
1850
1851MipsAsmParser::OperandMatchResultTy
1852MipsAsmParser::parseMemOperand(OperandVector &Operands) {
1853  DEBUG(dbgs() << "parseMemOperand\n");
1854  const MCExpr *IdVal = nullptr;
1855  SMLoc S;
1856  bool isParenExpr = false;
1857  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1858  // First operand is the offset.
1859  S = Parser.getTok().getLoc();
1860
1861  if (getLexer().getKind() == AsmToken::LParen) {
1862    Parser.Lex();
1863    isParenExpr = true;
1864  }
1865
1866  if (getLexer().getKind() != AsmToken::Dollar) {
1867    if (parseMemOffset(IdVal, isParenExpr))
1868      return MatchOperand_ParseFail;
1869
1870    const AsmToken &Tok = Parser.getTok(); // Get the next token.
1871    if (Tok.isNot(AsmToken::LParen)) {
1872      MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1873      if (Mnemonic.getToken() == "la") {
1874        SMLoc E =
1875            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1876        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
1877        return MatchOperand_Success;
1878      }
1879      if (Tok.is(AsmToken::EndOfStatement)) {
1880        SMLoc E =
1881            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1882
1883        // Zero register assumed, add a memory operand with ZERO as its base.
1884        // "Base" will be managed by k_Memory.
1885        auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1886                                              S, E, *this);
1887        Operands.push_back(
1888            MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
1889        return MatchOperand_Success;
1890      }
1891      Error(Parser.getTok().getLoc(), "'(' expected");
1892      return MatchOperand_ParseFail;
1893    }
1894
1895    Parser.Lex(); // Eat the '(' token.
1896  }
1897
1898  Res = ParseAnyRegister(Operands);
1899  if (Res != MatchOperand_Success)
1900    return Res;
1901
1902  if (Parser.getTok().isNot(AsmToken::RParen)) {
1903    Error(Parser.getTok().getLoc(), "')' expected");
1904    return MatchOperand_ParseFail;
1905  }
1906
1907  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1908
1909  Parser.Lex(); // Eat the ')' token.
1910
1911  if (!IdVal)
1912    IdVal = MCConstantExpr::Create(0, getContext());
1913
1914  // Replace the register operand with the memory operand.
1915  std::unique_ptr<MipsOperand> op(
1916      static_cast<MipsOperand *>(Operands.back().release()));
1917  // Remove the register from the operands.
1918  // "op" will be managed by k_Memory.
1919  Operands.pop_back();
1920  // Add the memory operand.
1921  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1922    int64_t Imm;
1923    if (IdVal->EvaluateAsAbsolute(Imm))
1924      IdVal = MCConstantExpr::Create(Imm, getContext());
1925    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1926      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1927                                   getContext());
1928  }
1929
1930  Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1931  return MatchOperand_Success;
1932}
1933
1934bool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1935
1936  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1937  if (Sym) {
1938    SMLoc S = Parser.getTok().getLoc();
1939    const MCExpr *Expr;
1940    if (Sym->isVariable())
1941      Expr = Sym->getVariableValue();
1942    else
1943      return false;
1944    if (Expr->getKind() == MCExpr::SymbolRef) {
1945      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1946      const StringRef DefSymbol = Ref->getSymbol().getName();
1947      if (DefSymbol.startswith("$")) {
1948        OperandMatchResultTy ResTy =
1949            MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
1950        if (ResTy == MatchOperand_Success) {
1951          Parser.Lex();
1952          return true;
1953        } else if (ResTy == MatchOperand_ParseFail)
1954          llvm_unreachable("Should never ParseFail");
1955        return false;
1956      }
1957    } else if (Expr->getKind() == MCExpr::Constant) {
1958      Parser.Lex();
1959      const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1960      Operands.push_back(
1961          MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
1962      return true;
1963    }
1964  }
1965  return false;
1966}
1967
1968MipsAsmParser::OperandMatchResultTy
1969MipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
1970                                                 StringRef Identifier,
1971                                                 SMLoc S) {
1972  int Index = matchCPURegisterName(Identifier);
1973  if (Index != -1) {
1974    Operands.push_back(MipsOperand::CreateGPRReg(
1975        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1976    return MatchOperand_Success;
1977  }
1978
1979  Index = matchFPURegisterName(Identifier);
1980  if (Index != -1) {
1981    Operands.push_back(MipsOperand::CreateFGRReg(
1982        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1983    return MatchOperand_Success;
1984  }
1985
1986  Index = matchFCCRegisterName(Identifier);
1987  if (Index != -1) {
1988    Operands.push_back(MipsOperand::CreateFCCReg(
1989        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1990    return MatchOperand_Success;
1991  }
1992
1993  Index = matchACRegisterName(Identifier);
1994  if (Index != -1) {
1995    Operands.push_back(MipsOperand::CreateACCReg(
1996        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1997    return MatchOperand_Success;
1998  }
1999
2000  Index = matchMSA128RegisterName(Identifier);
2001  if (Index != -1) {
2002    Operands.push_back(MipsOperand::CreateMSA128Reg(
2003        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2004    return MatchOperand_Success;
2005  }
2006
2007  Index = matchMSA128CtrlRegisterName(Identifier);
2008  if (Index != -1) {
2009    Operands.push_back(MipsOperand::CreateMSACtrlReg(
2010        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
2011    return MatchOperand_Success;
2012  }
2013
2014  return MatchOperand_NoMatch;
2015}
2016
2017MipsAsmParser::OperandMatchResultTy
2018MipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
2019  auto Token = Parser.getLexer().peekTok(false);
2020
2021  if (Token.is(AsmToken::Identifier)) {
2022    DEBUG(dbgs() << ".. identifier\n");
2023    StringRef Identifier = Token.getIdentifier();
2024    OperandMatchResultTy ResTy =
2025        MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
2026    return ResTy;
2027  } else if (Token.is(AsmToken::Integer)) {
2028    DEBUG(dbgs() << ".. integer\n");
2029    Operands.push_back(MipsOperand::CreateNumericReg(
2030        Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
2031        *this));
2032    return MatchOperand_Success;
2033  }
2034
2035  DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
2036
2037  return MatchOperand_NoMatch;
2038}
2039
2040MipsAsmParser::OperandMatchResultTy
2041MipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
2042  DEBUG(dbgs() << "ParseAnyRegister\n");
2043
2044  auto Token = Parser.getTok();
2045
2046  SMLoc S = Token.getLoc();
2047
2048  if (Token.isNot(AsmToken::Dollar)) {
2049    DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
2050    if (Token.is(AsmToken::Identifier)) {
2051      if (searchSymbolAlias(Operands))
2052        return MatchOperand_Success;
2053    }
2054    DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
2055    return MatchOperand_NoMatch;
2056  }
2057  DEBUG(dbgs() << ".. $\n");
2058
2059  OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
2060  if (ResTy == MatchOperand_Success) {
2061    Parser.Lex(); // $
2062    Parser.Lex(); // identifier
2063  }
2064  return ResTy;
2065}
2066
2067MipsAsmParser::OperandMatchResultTy
2068MipsAsmParser::ParseImm(OperandVector &Operands) {
2069  switch (getLexer().getKind()) {
2070  default:
2071    return MatchOperand_NoMatch;
2072  case AsmToken::LParen:
2073  case AsmToken::Minus:
2074  case AsmToken::Plus:
2075  case AsmToken::Integer:
2076  case AsmToken::Tilde:
2077  case AsmToken::String:
2078    break;
2079  }
2080
2081  const MCExpr *IdVal;
2082  SMLoc S = Parser.getTok().getLoc();
2083  if (getParser().parseExpression(IdVal))
2084    return MatchOperand_ParseFail;
2085
2086  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2087  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2088  return MatchOperand_Success;
2089}
2090
2091MipsAsmParser::OperandMatchResultTy
2092MipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
2093  DEBUG(dbgs() << "ParseJumpTarget\n");
2094
2095  SMLoc S = getLexer().getLoc();
2096
2097  // Integers and expressions are acceptable
2098  OperandMatchResultTy ResTy = ParseImm(Operands);
2099  if (ResTy != MatchOperand_NoMatch)
2100    return ResTy;
2101
2102  // Registers are a valid target and have priority over symbols.
2103  ResTy = ParseAnyRegister(Operands);
2104  if (ResTy != MatchOperand_NoMatch)
2105    return ResTy;
2106
2107  const MCExpr *Expr = nullptr;
2108  if (Parser.parseExpression(Expr)) {
2109    // We have no way of knowing if a symbol was consumed so we must ParseFail
2110    return MatchOperand_ParseFail;
2111  }
2112  Operands.push_back(
2113      MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
2114  return MatchOperand_Success;
2115}
2116
2117MipsAsmParser::OperandMatchResultTy
2118MipsAsmParser::parseInvNum(OperandVector &Operands) {
2119  const MCExpr *IdVal;
2120  // If the first token is '$' we may have register operand.
2121  if (Parser.getTok().is(AsmToken::Dollar))
2122    return MatchOperand_NoMatch;
2123  SMLoc S = Parser.getTok().getLoc();
2124  if (getParser().parseExpression(IdVal))
2125    return MatchOperand_ParseFail;
2126  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2127  assert(MCE && "Unexpected MCExpr type.");
2128  int64_t Val = MCE->getValue();
2129  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2130  Operands.push_back(MipsOperand::CreateImm(
2131      MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2132  return MatchOperand_Success;
2133}
2134
2135MipsAsmParser::OperandMatchResultTy
2136MipsAsmParser::ParseLSAImm(OperandVector &Operands) {
2137  switch (getLexer().getKind()) {
2138  default:
2139    return MatchOperand_NoMatch;
2140  case AsmToken::LParen:
2141  case AsmToken::Plus:
2142  case AsmToken::Minus:
2143  case AsmToken::Integer:
2144    break;
2145  }
2146
2147  const MCExpr *Expr;
2148  SMLoc S = Parser.getTok().getLoc();
2149
2150  if (getParser().parseExpression(Expr))
2151    return MatchOperand_ParseFail;
2152
2153  int64_t Val;
2154  if (!Expr->EvaluateAsAbsolute(Val)) {
2155    Error(S, "expected immediate value");
2156    return MatchOperand_ParseFail;
2157  }
2158
2159  // The LSA instruction allows a 2-bit unsigned immediate. For this reason
2160  // and because the CPU always adds one to the immediate field, the allowed
2161  // range becomes 1..4. We'll only check the range here and will deal
2162  // with the addition/subtraction when actually decoding/encoding
2163  // the instruction.
2164  if (Val < 1 || Val > 4) {
2165    Error(S, "immediate not in range (1..4)");
2166    return MatchOperand_ParseFail;
2167  }
2168
2169  Operands.push_back(
2170      MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
2171  return MatchOperand_Success;
2172}
2173
2174MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2175
2176  MCSymbolRefExpr::VariantKind VK =
2177      StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2178          .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2179          .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2180          .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2181          .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2182          .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2183          .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2184          .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2185          .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2186          .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2187          .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2188          .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2189          .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2190          .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2191          .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2192          .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2193          .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2194          .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2195          .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
2196          .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
2197          .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
2198          .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
2199          .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
2200          .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2201          .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2202          .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
2203          .Default(MCSymbolRefExpr::VK_None);
2204
2205  assert(VK != MCSymbolRefExpr::VK_None);
2206
2207  return VK;
2208}
2209
2210/// Sometimes (i.e. load/stores) the operand may be followed immediately by
2211/// either this.
2212/// ::= '(', register, ')'
2213/// handle it before we iterate so we don't get tripped up by the lack of
2214/// a comma.
2215bool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
2216  if (getLexer().is(AsmToken::LParen)) {
2217    Operands.push_back(
2218        MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
2219    Parser.Lex();
2220    if (ParseOperand(Operands, Name)) {
2221      SMLoc Loc = getLexer().getLoc();
2222      Parser.eatToEndOfStatement();
2223      return Error(Loc, "unexpected token in argument list");
2224    }
2225    if (Parser.getTok().isNot(AsmToken::RParen)) {
2226      SMLoc Loc = getLexer().getLoc();
2227      Parser.eatToEndOfStatement();
2228      return Error(Loc, "unexpected token, expected ')'");
2229    }
2230    Operands.push_back(
2231        MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
2232    Parser.Lex();
2233  }
2234  return false;
2235}
2236
2237/// Sometimes (i.e. in MSA) the operand may be followed immediately by
2238/// either one of these.
2239/// ::= '[', register, ']'
2240/// ::= '[', integer, ']'
2241/// handle it before we iterate so we don't get tripped up by the lack of
2242/// a comma.
2243bool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2244                                       OperandVector &Operands) {
2245  if (getLexer().is(AsmToken::LBrac)) {
2246    Operands.push_back(
2247        MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
2248    Parser.Lex();
2249    if (ParseOperand(Operands, Name)) {
2250      SMLoc Loc = getLexer().getLoc();
2251      Parser.eatToEndOfStatement();
2252      return Error(Loc, "unexpected token in argument list");
2253    }
2254    if (Parser.getTok().isNot(AsmToken::RBrac)) {
2255      SMLoc Loc = getLexer().getLoc();
2256      Parser.eatToEndOfStatement();
2257      return Error(Loc, "unexpected token, expected ']'");
2258    }
2259    Operands.push_back(
2260        MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
2261    Parser.Lex();
2262  }
2263  return false;
2264}
2265
2266bool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2267                                     SMLoc NameLoc, OperandVector &Operands) {
2268  DEBUG(dbgs() << "ParseInstruction\n");
2269  // We have reached first instruction, module directive after
2270  // this is forbidden.
2271  getTargetStreamer().setCanHaveModuleDir(false);
2272  // Check if we have valid mnemonic
2273  if (!mnemonicIsValid(Name, 0)) {
2274    Parser.eatToEndOfStatement();
2275    return Error(NameLoc, "Unknown instruction");
2276  }
2277  // First operand in MCInst is instruction mnemonic.
2278  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2279
2280  // Read the remaining operands.
2281  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2282    // Read the first operand.
2283    if (ParseOperand(Operands, Name)) {
2284      SMLoc Loc = getLexer().getLoc();
2285      Parser.eatToEndOfStatement();
2286      return Error(Loc, "unexpected token in argument list");
2287    }
2288    if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
2289      return true;
2290    // AFAIK, parenthesis suffixes are never on the first operand
2291
2292    while (getLexer().is(AsmToken::Comma)) {
2293      Parser.Lex(); // Eat the comma.
2294      // Parse and remember the operand.
2295      if (ParseOperand(Operands, Name)) {
2296        SMLoc Loc = getLexer().getLoc();
2297        Parser.eatToEndOfStatement();
2298        return Error(Loc, "unexpected token in argument list");
2299      }
2300      // Parse bracket and parenthesis suffixes before we iterate
2301      if (getLexer().is(AsmToken::LBrac)) {
2302        if (ParseBracketSuffix(Name, Operands))
2303          return true;
2304      } else if (getLexer().is(AsmToken::LParen) &&
2305                 ParseParenSuffix(Name, Operands))
2306        return true;
2307    }
2308  }
2309  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2310    SMLoc Loc = getLexer().getLoc();
2311    Parser.eatToEndOfStatement();
2312    return Error(Loc, "unexpected token in argument list");
2313  }
2314  Parser.Lex(); // Consume the EndOfStatement.
2315  return false;
2316}
2317
2318bool MipsAsmParser::reportParseError(Twine ErrorMsg) {
2319  SMLoc Loc = getLexer().getLoc();
2320  Parser.eatToEndOfStatement();
2321  return Error(Loc, ErrorMsg);
2322}
2323
2324bool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2325  return Error(Loc, ErrorMsg);
2326}
2327
2328bool MipsAsmParser::parseSetNoAtDirective() {
2329  // Line should look like: ".set noat".
2330  // set at reg to 0.
2331  Options.setATReg(0);
2332  // eat noat
2333  Parser.Lex();
2334  // If this is not the end of the statement, report an error.
2335  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2336    reportParseError("unexpected token in statement");
2337    return false;
2338  }
2339  Parser.Lex(); // Consume the EndOfStatement.
2340  return false;
2341}
2342
2343bool MipsAsmParser::parseSetAtDirective() {
2344  // Line can be .set at - defaults to $1
2345  // or .set at=$reg
2346  int AtRegNo;
2347  getParser().Lex();
2348  if (getLexer().is(AsmToken::EndOfStatement)) {
2349    Options.setATReg(1);
2350    Parser.Lex(); // Consume the EndOfStatement.
2351    return false;
2352  } else if (getLexer().is(AsmToken::Equal)) {
2353    getParser().Lex(); // Eat the '='.
2354    if (getLexer().isNot(AsmToken::Dollar)) {
2355      reportParseError("unexpected token in statement");
2356      return false;
2357    }
2358    Parser.Lex(); // Eat the '$'.
2359    const AsmToken &Reg = Parser.getTok();
2360    if (Reg.is(AsmToken::Identifier)) {
2361      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2362    } else if (Reg.is(AsmToken::Integer)) {
2363      AtRegNo = Reg.getIntVal();
2364    } else {
2365      reportParseError("unexpected token in statement");
2366      return false;
2367    }
2368
2369    if (AtRegNo < 0 || AtRegNo > 31) {
2370      reportParseError("unexpected token in statement");
2371      return false;
2372    }
2373
2374    if (!Options.setATReg(AtRegNo)) {
2375      reportParseError("unexpected token in statement");
2376      return false;
2377    }
2378    getParser().Lex(); // Eat the register.
2379
2380    if (getLexer().isNot(AsmToken::EndOfStatement)) {
2381      reportParseError("unexpected token in statement");
2382      return false;
2383    }
2384    Parser.Lex(); // Consume the EndOfStatement.
2385    return false;
2386  } else {
2387    reportParseError("unexpected token in statement");
2388    return false;
2389  }
2390}
2391
2392bool MipsAsmParser::parseSetReorderDirective() {
2393  Parser.Lex();
2394  // If this is not the end of the statement, report an error.
2395  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2396    reportParseError("unexpected token in statement");
2397    return false;
2398  }
2399  Options.setReorder();
2400  getTargetStreamer().emitDirectiveSetReorder();
2401  Parser.Lex(); // Consume the EndOfStatement.
2402  return false;
2403}
2404
2405bool MipsAsmParser::parseSetNoReorderDirective() {
2406  Parser.Lex();
2407  // If this is not the end of the statement, report an error.
2408  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2409    reportParseError("unexpected token in statement");
2410    return false;
2411  }
2412  Options.setNoreorder();
2413  getTargetStreamer().emitDirectiveSetNoReorder();
2414  Parser.Lex(); // Consume the EndOfStatement.
2415  return false;
2416}
2417
2418bool MipsAsmParser::parseSetMacroDirective() {
2419  Parser.Lex();
2420  // If this is not the end of the statement, report an error.
2421  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2422    reportParseError("unexpected token in statement");
2423    return false;
2424  }
2425  Options.setMacro();
2426  Parser.Lex(); // Consume the EndOfStatement.
2427  return false;
2428}
2429
2430bool MipsAsmParser::parseSetNoMacroDirective() {
2431  Parser.Lex();
2432  // If this is not the end of the statement, report an error.
2433  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2434    reportParseError("`noreorder' must be set before `nomacro'");
2435    return false;
2436  }
2437  if (Options.isReorder()) {
2438    reportParseError("`noreorder' must be set before `nomacro'");
2439    return false;
2440  }
2441  Options.setNomacro();
2442  Parser.Lex(); // Consume the EndOfStatement.
2443  return false;
2444}
2445
2446bool MipsAsmParser::parseSetNoMips16Directive() {
2447  Parser.Lex();
2448  // If this is not the end of the statement, report an error.
2449  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2450    reportParseError("unexpected token in statement");
2451    return false;
2452  }
2453  // For now do nothing.
2454  Parser.Lex(); // Consume the EndOfStatement.
2455  return false;
2456}
2457
2458bool MipsAsmParser::parseSetFpDirective() {
2459  MipsABIFlagsSection::FpABIKind FpAbiVal;
2460  // Line can be: .set fp=32
2461  //              .set fp=xx
2462  //              .set fp=64
2463  Parser.Lex(); // Eat fp token
2464  AsmToken Tok = Parser.getTok();
2465  if (Tok.isNot(AsmToken::Equal)) {
2466    reportParseError("unexpected token in statement");
2467    return false;
2468  }
2469  Parser.Lex(); // Eat '=' token.
2470  Tok = Parser.getTok();
2471
2472  if (!parseFpABIValue(FpAbiVal, ".set"))
2473    return false;
2474
2475  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2476    reportParseError("unexpected token in statement");
2477    return false;
2478  }
2479  getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2480  Parser.Lex(); // Consume the EndOfStatement.
2481  return false;
2482}
2483
2484bool MipsAsmParser::parseSetAssignment() {
2485  StringRef Name;
2486  const MCExpr *Value;
2487
2488  if (Parser.parseIdentifier(Name))
2489    reportParseError("expected identifier after .set");
2490
2491  if (getLexer().isNot(AsmToken::Comma))
2492    return reportParseError("unexpected token in .set directive");
2493  Lex(); // Eat comma
2494
2495  if (Parser.parseExpression(Value))
2496    return reportParseError("expected valid expression after comma");
2497
2498  // Check if the Name already exists as a symbol.
2499  MCSymbol *Sym = getContext().LookupSymbol(Name);
2500  if (Sym)
2501    return reportParseError("symbol already defined");
2502  Sym = getContext().GetOrCreateSymbol(Name);
2503  Sym->setVariableValue(Value);
2504
2505  return false;
2506}
2507
2508bool MipsAsmParser::parseSetFeature(uint64_t Feature) {
2509  Parser.Lex();
2510  if (getLexer().isNot(AsmToken::EndOfStatement))
2511    return reportParseError("unexpected token in .set directive");
2512
2513  switch (Feature) {
2514  default:
2515    llvm_unreachable("Unimplemented feature");
2516  case Mips::FeatureDSP:
2517    setFeatureBits(Mips::FeatureDSP, "dsp");
2518    getTargetStreamer().emitDirectiveSetDsp();
2519    break;
2520  case Mips::FeatureMicroMips:
2521    getTargetStreamer().emitDirectiveSetMicroMips();
2522    break;
2523  case Mips::FeatureMips16:
2524    getTargetStreamer().emitDirectiveSetMips16();
2525    break;
2526  case Mips::FeatureMips32r2:
2527    setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2528    getTargetStreamer().emitDirectiveSetMips32R2();
2529    break;
2530  case Mips::FeatureMips64:
2531    setFeatureBits(Mips::FeatureMips64, "mips64");
2532    getTargetStreamer().emitDirectiveSetMips64();
2533    break;
2534  case Mips::FeatureMips64r2:
2535    setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2536    getTargetStreamer().emitDirectiveSetMips64R2();
2537    break;
2538  }
2539  return false;
2540}
2541
2542bool MipsAsmParser::eatComma(StringRef ErrorStr) {
2543  if (getLexer().isNot(AsmToken::Comma)) {
2544    SMLoc Loc = getLexer().getLoc();
2545    Parser.eatToEndOfStatement();
2546    return Error(Loc, ErrorStr);
2547  }
2548
2549  Parser.Lex(); // Eat the comma.
2550  return true;
2551}
2552
2553bool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2554  if (Options.isReorder())
2555    Warning(Loc, ".cpload in reorder section");
2556
2557  // FIXME: Warn if cpload is used in Mips16 mode.
2558
2559  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2560  OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2561  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2562    reportParseError("expected register containing function address");
2563    return false;
2564  }
2565
2566  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2567  if (!RegOpnd.isGPRAsmReg()) {
2568    reportParseError(RegOpnd.getStartLoc(), "invalid register");
2569    return false;
2570  }
2571
2572  getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2573  return false;
2574}
2575
2576bool MipsAsmParser::parseDirectiveCPSetup() {
2577  unsigned FuncReg;
2578  unsigned Save;
2579  bool SaveIsReg = true;
2580
2581  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2582  OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2583  if (ResTy == MatchOperand_NoMatch) {
2584    reportParseError("expected register containing function address");
2585    Parser.eatToEndOfStatement();
2586    return false;
2587  }
2588
2589  MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2590  if (!FuncRegOpnd.isGPRAsmReg()) {
2591    reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2592    Parser.eatToEndOfStatement();
2593    return false;
2594  }
2595
2596  FuncReg = FuncRegOpnd.getGPR32Reg();
2597  TmpReg.clear();
2598
2599  if (!eatComma("expected comma parsing directive"))
2600    return true;
2601
2602  ResTy = ParseAnyRegister(TmpReg);
2603  if (ResTy == MatchOperand_NoMatch) {
2604    const AsmToken &Tok = Parser.getTok();
2605    if (Tok.is(AsmToken::Integer)) {
2606      Save = Tok.getIntVal();
2607      SaveIsReg = false;
2608      Parser.Lex();
2609    } else {
2610      reportParseError("expected save register or stack offset");
2611      Parser.eatToEndOfStatement();
2612      return false;
2613    }
2614  } else {
2615    MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2616    if (!SaveOpnd.isGPRAsmReg()) {
2617      reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2618      Parser.eatToEndOfStatement();
2619      return false;
2620    }
2621    Save = SaveOpnd.getGPR32Reg();
2622  }
2623
2624  if (!eatComma("expected comma parsing directive"))
2625    return true;
2626
2627  StringRef Name;
2628  if (Parser.parseIdentifier(Name))
2629    reportParseError("expected identifier");
2630  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2631
2632  getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2633  return false;
2634}
2635
2636bool MipsAsmParser::parseDirectiveNaN() {
2637  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2638    const AsmToken &Tok = Parser.getTok();
2639
2640    if (Tok.getString() == "2008") {
2641      Parser.Lex();
2642      getTargetStreamer().emitDirectiveNaN2008();
2643      return false;
2644    } else if (Tok.getString() == "legacy") {
2645      Parser.Lex();
2646      getTargetStreamer().emitDirectiveNaNLegacy();
2647      return false;
2648    }
2649  }
2650  // If we don't recognize the option passed to the .nan
2651  // directive (e.g. no option or unknown option), emit an error.
2652  reportParseError("invalid option in .nan directive");
2653  return false;
2654}
2655
2656bool MipsAsmParser::parseDirectiveSet() {
2657
2658  // Get the next token.
2659  const AsmToken &Tok = Parser.getTok();
2660
2661  if (Tok.getString() == "noat") {
2662    return parseSetNoAtDirective();
2663  } else if (Tok.getString() == "at") {
2664    return parseSetAtDirective();
2665  } else if (Tok.getString() == "fp") {
2666    return parseSetFpDirective();
2667  } else if (Tok.getString() == "reorder") {
2668    return parseSetReorderDirective();
2669  } else if (Tok.getString() == "noreorder") {
2670    return parseSetNoReorderDirective();
2671  } else if (Tok.getString() == "macro") {
2672    return parseSetMacroDirective();
2673  } else if (Tok.getString() == "nomacro") {
2674    return parseSetNoMacroDirective();
2675  } else if (Tok.getString() == "mips16") {
2676    return parseSetFeature(Mips::FeatureMips16);
2677  } else if (Tok.getString() == "nomips16") {
2678    return parseSetNoMips16Directive();
2679  } else if (Tok.getString() == "nomicromips") {
2680    getTargetStreamer().emitDirectiveSetNoMicroMips();
2681    Parser.eatToEndOfStatement();
2682    return false;
2683  } else if (Tok.getString() == "micromips") {
2684    return parseSetFeature(Mips::FeatureMicroMips);
2685  } else if (Tok.getString() == "mips32r2") {
2686    return parseSetFeature(Mips::FeatureMips32r2);
2687  } else if (Tok.getString() == "mips64") {
2688    return parseSetFeature(Mips::FeatureMips64);
2689  } else if (Tok.getString() == "mips64r2") {
2690    return parseSetFeature(Mips::FeatureMips64r2);
2691  } else if (Tok.getString() == "dsp") {
2692    return parseSetFeature(Mips::FeatureDSP);
2693  } else {
2694    // It is just an identifier, look for an assignment.
2695    parseSetAssignment();
2696    return false;
2697  }
2698
2699  return true;
2700}
2701
2702/// parseDataDirective
2703///  ::= .word [ expression (, expression)* ]
2704bool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2705  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2706    for (;;) {
2707      const MCExpr *Value;
2708      if (getParser().parseExpression(Value))
2709        return true;
2710
2711      getParser().getStreamer().EmitValue(Value, Size);
2712
2713      if (getLexer().is(AsmToken::EndOfStatement))
2714        break;
2715
2716      // FIXME: Improve diagnostic.
2717      if (getLexer().isNot(AsmToken::Comma))
2718        return Error(L, "unexpected token in directive");
2719      Parser.Lex();
2720    }
2721  }
2722
2723  Parser.Lex();
2724  return false;
2725}
2726
2727/// parseDirectiveGpWord
2728///  ::= .gpword local_sym
2729bool MipsAsmParser::parseDirectiveGpWord() {
2730  const MCExpr *Value;
2731  // EmitGPRel32Value requires an expression, so we are using base class
2732  // method to evaluate the expression.
2733  if (getParser().parseExpression(Value))
2734    return true;
2735  getParser().getStreamer().EmitGPRel32Value(Value);
2736
2737  if (getLexer().isNot(AsmToken::EndOfStatement))
2738    return Error(getLexer().getLoc(), "unexpected token in directive");
2739  Parser.Lex(); // Eat EndOfStatement token.
2740  return false;
2741}
2742
2743/// parseDirectiveGpDWord
2744///  ::= .gpdword local_sym
2745bool MipsAsmParser::parseDirectiveGpDWord() {
2746  const MCExpr *Value;
2747  // EmitGPRel64Value requires an expression, so we are using base class
2748  // method to evaluate the expression.
2749  if (getParser().parseExpression(Value))
2750    return true;
2751  getParser().getStreamer().EmitGPRel64Value(Value);
2752
2753  if (getLexer().isNot(AsmToken::EndOfStatement))
2754    return Error(getLexer().getLoc(), "unexpected token in directive");
2755  Parser.Lex(); // Eat EndOfStatement token.
2756  return false;
2757}
2758
2759bool MipsAsmParser::parseDirectiveOption() {
2760  // Get the option token.
2761  AsmToken Tok = Parser.getTok();
2762  // At the moment only identifiers are supported.
2763  if (Tok.isNot(AsmToken::Identifier)) {
2764    Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
2765    Parser.eatToEndOfStatement();
2766    return false;
2767  }
2768
2769  StringRef Option = Tok.getIdentifier();
2770
2771  if (Option == "pic0") {
2772    getTargetStreamer().emitDirectiveOptionPic0();
2773    Parser.Lex();
2774    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2775      Error(Parser.getTok().getLoc(),
2776            "unexpected token in .option pic0 directive");
2777      Parser.eatToEndOfStatement();
2778    }
2779    return false;
2780  }
2781
2782  if (Option == "pic2") {
2783    getTargetStreamer().emitDirectiveOptionPic2();
2784    Parser.Lex();
2785    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2786      Error(Parser.getTok().getLoc(),
2787            "unexpected token in .option pic2 directive");
2788      Parser.eatToEndOfStatement();
2789    }
2790    return false;
2791  }
2792
2793  // Unknown option.
2794  Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
2795  Parser.eatToEndOfStatement();
2796  return false;
2797}
2798
2799/// parseDirectiveModule
2800///  ::= .module oddspreg
2801///  ::= .module nooddspreg
2802///  ::= .module fp=value
2803bool MipsAsmParser::parseDirectiveModule() {
2804  MCAsmLexer &Lexer = getLexer();
2805  SMLoc L = Lexer.getLoc();
2806
2807  if (!getTargetStreamer().getCanHaveModuleDir()) {
2808    // TODO : get a better message.
2809    reportParseError(".module directive must appear before any code");
2810    return false;
2811  }
2812
2813  if (Lexer.is(AsmToken::Identifier)) {
2814    StringRef Option = Parser.getTok().getString();
2815    Parser.Lex();
2816
2817    if (Option == "oddspreg") {
2818      getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
2819      clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2820
2821      if (getLexer().isNot(AsmToken::EndOfStatement)) {
2822        reportParseError("Expected end of statement");
2823        return false;
2824      }
2825
2826      return false;
2827    } else if (Option == "nooddspreg") {
2828      if (!isABI_O32()) {
2829        Error(L, "'.module nooddspreg' requires the O32 ABI");
2830        return false;
2831      }
2832
2833      getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
2834      setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2835
2836      if (getLexer().isNot(AsmToken::EndOfStatement)) {
2837        reportParseError("Expected end of statement");
2838        return false;
2839      }
2840
2841      return false;
2842    } else if (Option == "fp") {
2843      return parseDirectiveModuleFP();
2844    }
2845
2846    return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
2847  }
2848
2849  return false;
2850}
2851
2852/// parseDirectiveModuleFP
2853///  ::= =32
2854///  ::= =xx
2855///  ::= =64
2856bool MipsAsmParser::parseDirectiveModuleFP() {
2857  MCAsmLexer &Lexer = getLexer();
2858
2859  if (Lexer.isNot(AsmToken::Equal)) {
2860    reportParseError("unexpected token in statement");
2861    return false;
2862  }
2863  Parser.Lex(); // Eat '=' token.
2864
2865  MipsABIFlagsSection::FpABIKind FpABI;
2866  if (!parseFpABIValue(FpABI, ".module"))
2867    return false;
2868
2869  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2870    reportParseError("unexpected token in statement");
2871    return false;
2872  }
2873
2874  // Emit appropriate flags.
2875  getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
2876  Parser.Lex(); // Consume the EndOfStatement.
2877  return false;
2878}
2879
2880bool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
2881                                    StringRef Directive) {
2882  MCAsmLexer &Lexer = getLexer();
2883
2884  if (Lexer.is(AsmToken::Identifier)) {
2885    StringRef Value = Parser.getTok().getString();
2886    Parser.Lex();
2887
2888    if (Value != "xx") {
2889      reportParseError("unsupported value, expected 'xx', '32' or '64'");
2890      return false;
2891    }
2892
2893    if (!isABI_O32()) {
2894      reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
2895      return false;
2896    }
2897
2898    FpABI = MipsABIFlagsSection::FpABIKind::XX;
2899    return true;
2900  }
2901
2902  if (Lexer.is(AsmToken::Integer)) {
2903    unsigned Value = Parser.getTok().getIntVal();
2904    Parser.Lex();
2905
2906    if (Value != 32 && Value != 64) {
2907      reportParseError("unsupported value, expected 'xx', '32' or '64'");
2908      return false;
2909    }
2910
2911    if (Value == 32) {
2912      if (!isABI_O32()) {
2913        reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
2914        return false;
2915      }
2916
2917      FpABI = MipsABIFlagsSection::FpABIKind::S32;
2918    } else
2919      FpABI = MipsABIFlagsSection::FpABIKind::S64;
2920
2921    return true;
2922  }
2923
2924  return false;
2925}
2926
2927bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2928  StringRef IDVal = DirectiveID.getString();
2929
2930  if (IDVal == ".cpload")
2931    return parseDirectiveCPLoad(DirectiveID.getLoc());
2932  if (IDVal == ".dword") {
2933    parseDataDirective(8, DirectiveID.getLoc());
2934    return false;
2935  }
2936
2937  if (IDVal == ".ent") {
2938    // Ignore this directive for now.
2939    Parser.Lex();
2940    return false;
2941  }
2942
2943  if (IDVal == ".end") {
2944    // Ignore this directive for now.
2945    Parser.Lex();
2946    return false;
2947  }
2948
2949  if (IDVal == ".frame") {
2950    // Ignore this directive for now.
2951    Parser.eatToEndOfStatement();
2952    return false;
2953  }
2954
2955  if (IDVal == ".set") {
2956    return parseDirectiveSet();
2957  }
2958
2959  if (IDVal == ".fmask") {
2960    // Ignore this directive for now.
2961    Parser.eatToEndOfStatement();
2962    return false;
2963  }
2964
2965  if (IDVal == ".mask") {
2966    // Ignore this directive for now.
2967    Parser.eatToEndOfStatement();
2968    return false;
2969  }
2970
2971  if (IDVal == ".nan")
2972    return parseDirectiveNaN();
2973
2974  if (IDVal == ".gpword") {
2975    parseDirectiveGpWord();
2976    return false;
2977  }
2978
2979  if (IDVal == ".gpdword") {
2980    parseDirectiveGpDWord();
2981    return false;
2982  }
2983
2984  if (IDVal == ".word") {
2985    parseDataDirective(4, DirectiveID.getLoc());
2986    return false;
2987  }
2988
2989  if (IDVal == ".option")
2990    return parseDirectiveOption();
2991
2992  if (IDVal == ".abicalls") {
2993    getTargetStreamer().emitDirectiveAbiCalls();
2994    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
2995      Error(Parser.getTok().getLoc(), "unexpected token in directive");
2996      // Clear line
2997      Parser.eatToEndOfStatement();
2998    }
2999    return false;
3000  }
3001
3002  if (IDVal == ".cpsetup")
3003    return parseDirectiveCPSetup();
3004
3005  if (IDVal == ".module")
3006    return parseDirectiveModule();
3007
3008  return true;
3009}
3010
3011extern "C" void LLVMInitializeMipsAsmParser() {
3012  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3013  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3014  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3015  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3016}
3017
3018#define GET_REGISTER_MATCHER
3019#define GET_MATCHER_IMPLEMENTATION
3020#include "MipsGenAsmMatcher.inc"
3021