MipsAsmParser.cpp revision 2263a2ca72e21206d45a69532004a0b17881e733
1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//                     The LLVM Compiler Infrastructure
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This file is distributed under the University of Illinois Open Source
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// License. See LICENSE.TXT for details.
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)//
88bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)//===----------------------------------------------------------------------===//
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "MCTargetDesc/MipsMCTargetDesc.h"
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "MipsRegisterInfo.h"
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "MipsTargetStreamer.h"
13d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "llvm/ADT/StringSwitch.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCContext.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCExpr.h"
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCInst.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCParser/MCAsmLexer.h"
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "llvm/MC/MCStreamer.h"
208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/MC/MCSubtargetInfo.h"
218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/MC/MCSymbol.h"
228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/MC/MCTargetAsmParser.h"
238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/Support/TargetRegistry.h"
248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)#include "llvm/ADT/APInt.h"
258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using namespace llvm;
27
28namespace llvm {
29class MCInstrInfo;
30}
31
32namespace {
33class MipsAssemblerOptions {
34public:
35  MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
36
37  unsigned getATRegNum() { return aTReg; }
38  bool setATReg(unsigned Reg);
39
40  bool isReorder() { return reorder; }
41  void setReorder() { reorder = true; }
42  void setNoreorder() { reorder = false; }
43
44  bool isMacro() { return macro; }
45  void setMacro() { macro = true; }
46  void setNomacro() { macro = false; }
47
48private:
49  unsigned aTReg;
50  bool reorder;
51  bool macro;
52};
53}
54
55namespace {
56class MipsAsmParser : public MCTargetAsmParser {
57
58  MipsTargetStreamer &getTargetStreamer() {
59    MCTargetStreamer &TS = Parser.getStreamer().getTargetStreamer();
60    return static_cast<MipsTargetStreamer &>(TS);
61  }
62
63  MCSubtargetInfo &STI;
64  MCAsmParser &Parser;
65  MipsAssemblerOptions Options;
66  bool hasConsumedDollar;
67
68#define GET_ASSEMBLER_HEADER
69#include "MipsGenAsmMatcher.inc"
70
71  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
72                               SmallVectorImpl<MCParsedAsmOperand *> &Operands,
73                               MCStreamer &Out, unsigned &ErrorInfo,
74                               bool MatchingInlineAsm);
75
76  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
77
78  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
79                        SMLoc NameLoc,
80                        SmallVectorImpl<MCParsedAsmOperand *> &Operands);
81
82  bool ParseDirective(AsmToken DirectiveID);
83
84  MipsAsmParser::OperandMatchResultTy
85  parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
86
87  MipsAsmParser::OperandMatchResultTy
88  parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands, int RegKind);
89
90  MipsAsmParser::OperandMatchResultTy
91  parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
92                   int RegKind);
93
94  MipsAsmParser::OperandMatchResultTy
95  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
96
97  bool parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
98                   int RegKind);
99
100  MipsAsmParser::OperandMatchResultTy
101  parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
102
103  MipsAsmParser::OperandMatchResultTy
104  parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
105
106  MipsAsmParser::OperandMatchResultTy
107  parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
108
109  MipsAsmParser::OperandMatchResultTy
110  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
111
112  MipsAsmParser::OperandMatchResultTy
113  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
114
115  MipsAsmParser::OperandMatchResultTy
116  parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
117
118  MipsAsmParser::OperandMatchResultTy
119  parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
120
121  MipsAsmParser::OperandMatchResultTy
122  parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
123
124  MipsAsmParser::OperandMatchResultTy
125  parseFGRH32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
126
127  MipsAsmParser::OperandMatchResultTy
128  parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
129
130  MipsAsmParser::OperandMatchResultTy
131  parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
132
133  MipsAsmParser::OperandMatchResultTy
134  parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
135
136  MipsAsmParser::OperandMatchResultTy
137  parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
138
139  MipsAsmParser::OperandMatchResultTy
140  parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
141
142  MipsAsmParser::OperandMatchResultTy
143  parseMSA128BRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
144
145  MipsAsmParser::OperandMatchResultTy
146  parseMSA128HRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
147
148  MipsAsmParser::OperandMatchResultTy
149  parseMSA128WRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
150
151  MipsAsmParser::OperandMatchResultTy
152  parseMSA128DRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
153
154  MipsAsmParser::OperandMatchResultTy
155  parseMSA128CtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
156
157  MipsAsmParser::OperandMatchResultTy
158  parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands);
159
160  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
161                         unsigned RegKind);
162
163  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &,
164                    StringRef Mnemonic);
165
166  int tryParseRegister(bool is64BitReg);
167
168  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
169                               bool is64BitReg);
170
171  bool needsExpansion(MCInst &Inst);
172
173  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
174                         SmallVectorImpl<MCInst> &Instructions);
175  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
176                     SmallVectorImpl<MCInst> &Instructions);
177  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
178                            SmallVectorImpl<MCInst> &Instructions);
179  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
180                            SmallVectorImpl<MCInst> &Instructions);
181  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
182                     SmallVectorImpl<MCInst> &Instructions, bool isLoad,
183                     bool isImmOpnd);
184  bool reportParseError(StringRef ErrorMsg);
185
186  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
187  bool parseRelocOperand(const MCExpr *&Res);
188
189  const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
190
191  bool isEvaluated(const MCExpr *Expr);
192  bool parseDirectiveSet();
193  bool parseDirectiveMipsHackStocg();
194  bool parseDirectiveMipsHackELFFlags();
195
196  bool parseSetAtDirective();
197  bool parseSetNoAtDirective();
198  bool parseSetMacroDirective();
199  bool parseSetNoMacroDirective();
200  bool parseSetReorderDirective();
201  bool parseSetNoReorderDirective();
202
203  bool parseSetAssignment();
204
205  bool parseDirectiveWord(unsigned Size, SMLoc L);
206  bool parseDirectiveGpWord();
207
208  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
209
210  bool isMips64() const {
211    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
212  }
213
214  bool isFP64() const {
215    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
216  }
217
218  bool isN64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
219
220  int matchRegisterName(StringRef Symbol, bool is64BitReg);
221
222  int matchCPURegisterName(StringRef Symbol);
223
224  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
225
226  int matchFPURegisterName(StringRef Name);
227
228  int matchFCCRegisterName(StringRef Name);
229
230  int matchACRegisterName(StringRef Name);
231
232  int matchMSA128RegisterName(StringRef Name);
233
234  int matchMSA128CtrlRegisterName(StringRef Name);
235
236  int regKindToRegClass(int RegKind);
237
238  unsigned getReg(int RC, int RegNo);
239
240  int getATReg();
241
242  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
243                          SmallVectorImpl<MCInst> &Instructions);
244
245  // Helper function that checks if the value of a vector index is within the
246  // boundaries of accepted values for each RegisterKind
247  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
248  bool validateMSAIndex(int Val, int RegKind);
249
250public:
251  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
252                const MCInstrInfo &MII)
253      : MCTargetAsmParser(), STI(sti), Parser(parser),
254        hasConsumedDollar(false) {
255    // Initialize the set of available features.
256    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
257  }
258
259  MCAsmParser &getParser() const { return Parser; }
260  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
261};
262}
263
264namespace {
265
266/// MipsOperand - Instances of this class represent a parsed Mips machine
267/// instruction.
268class MipsOperand : public MCParsedAsmOperand {
269
270public:
271  enum RegisterKind {
272    Kind_None,
273    Kind_GPR32,
274    Kind_GPR64,
275    Kind_HWRegs,
276    Kind_FGR32Regs,
277    Kind_FGRH32Regs,
278    Kind_FGR64Regs,
279    Kind_AFGR64Regs,
280    Kind_CCRRegs,
281    Kind_FCCRegs,
282    Kind_ACC64DSP,
283    Kind_LO32DSP,
284    Kind_HI32DSP,
285    Kind_COP2,
286    Kind_MSA128BRegs,
287    Kind_MSA128HRegs,
288    Kind_MSA128WRegs,
289    Kind_MSA128DRegs,
290    Kind_MSA128CtrlRegs
291  };
292
293private:
294  enum KindTy {
295    k_CondCode,
296    k_CoprocNum,
297    k_Immediate,
298    k_Memory,
299    k_PostIndexRegister,
300    k_Register,
301    k_PtrReg,
302    k_Token
303  } Kind;
304
305  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
306
307  struct Token {
308    const char *Data;
309    unsigned Length;
310  };
311
312  struct RegOp {
313    unsigned RegNum;
314    RegisterKind Kind;
315  };
316
317  struct ImmOp {
318    const MCExpr *Val;
319  };
320
321  struct MemOp {
322    unsigned Base;
323    const MCExpr *Off;
324  };
325
326  union {
327    struct Token Tok;
328    struct RegOp Reg;
329    struct ImmOp Imm;
330    struct MemOp Mem;
331  };
332
333  SMLoc StartLoc, EndLoc;
334
335public:
336  void addRegOperands(MCInst &Inst, unsigned N) const {
337    assert(N == 1 && "Invalid number of operands!");
338    Inst.addOperand(MCOperand::CreateReg(getReg()));
339  }
340
341  void addPtrRegOperands(MCInst &Inst, unsigned N) const {
342    assert(N == 1 && "Invalid number of operands!");
343    Inst.addOperand(MCOperand::CreateReg(getPtrReg()));
344  }
345
346  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
347    // Add as immediate when possible.  Null MCExpr = 0.
348    if (Expr == 0)
349      Inst.addOperand(MCOperand::CreateImm(0));
350    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
351      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
352    else
353      Inst.addOperand(MCOperand::CreateExpr(Expr));
354  }
355
356  void addImmOperands(MCInst &Inst, unsigned N) const {
357    assert(N == 1 && "Invalid number of operands!");
358    const MCExpr *Expr = getImm();
359    addExpr(Inst, Expr);
360  }
361
362  void addMemOperands(MCInst &Inst, unsigned N) const {
363    assert(N == 2 && "Invalid number of operands!");
364
365    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
366
367    const MCExpr *Expr = getMemOff();
368    addExpr(Inst, Expr);
369  }
370
371  bool isReg() const { return Kind == k_Register; }
372  bool isImm() const { return Kind == k_Immediate; }
373  bool isToken() const { return Kind == k_Token; }
374  bool isMem() const { return Kind == k_Memory; }
375  bool isPtrReg() const { return Kind == k_PtrReg; }
376  bool isInvNum() const { return Kind == k_Immediate; }
377
378  StringRef getToken() const {
379    assert(Kind == k_Token && "Invalid access!");
380    return StringRef(Tok.Data, Tok.Length);
381  }
382
383  unsigned getReg() const {
384    assert((Kind == k_Register) && "Invalid access!");
385    return Reg.RegNum;
386  }
387
388  unsigned getPtrReg() const {
389    assert((Kind == k_PtrReg) && "Invalid access!");
390    return Reg.RegNum;
391  }
392
393  void setRegKind(RegisterKind RegKind) {
394    assert((Kind == k_Register || Kind == k_PtrReg) && "Invalid access!");
395    Reg.Kind = RegKind;
396  }
397
398  const MCExpr *getImm() const {
399    assert((Kind == k_Immediate) && "Invalid access!");
400    return Imm.Val;
401  }
402
403  unsigned getMemBase() const {
404    assert((Kind == k_Memory) && "Invalid access!");
405    return Mem.Base;
406  }
407
408  const MCExpr *getMemOff() const {
409    assert((Kind == k_Memory) && "Invalid access!");
410    return Mem.Off;
411  }
412
413  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
414    MipsOperand *Op = new MipsOperand(k_Token);
415    Op->Tok.Data = Str.data();
416    Op->Tok.Length = Str.size();
417    Op->StartLoc = S;
418    Op->EndLoc = S;
419    return Op;
420  }
421
422  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
423    MipsOperand *Op = new MipsOperand(k_Register);
424    Op->Reg.RegNum = RegNum;
425    Op->StartLoc = S;
426    Op->EndLoc = E;
427    return Op;
428  }
429
430  static MipsOperand *CreatePtrReg(unsigned RegNum, SMLoc S, SMLoc E) {
431    MipsOperand *Op = new MipsOperand(k_PtrReg);
432    Op->Reg.RegNum = RegNum;
433    Op->StartLoc = S;
434    Op->EndLoc = E;
435    return Op;
436  }
437
438  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
439    MipsOperand *Op = new MipsOperand(k_Immediate);
440    Op->Imm.Val = Val;
441    Op->StartLoc = S;
442    Op->EndLoc = E;
443    return Op;
444  }
445
446  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off, SMLoc S,
447                                SMLoc E) {
448    MipsOperand *Op = new MipsOperand(k_Memory);
449    Op->Mem.Base = Base;
450    Op->Mem.Off = Off;
451    Op->StartLoc = S;
452    Op->EndLoc = E;
453    return Op;
454  }
455
456  bool isGPR32Asm() const {
457    return Kind == k_Register && Reg.Kind == Kind_GPR32;
458  }
459  void addRegAsmOperands(MCInst &Inst, unsigned N) const {
460    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
461  }
462
463  bool isGPR64Asm() const {
464    return Kind == k_Register && Reg.Kind == Kind_GPR64;
465  }
466
467  bool isHWRegsAsm() const {
468    assert((Kind == k_Register) && "Invalid access!");
469    return Reg.Kind == Kind_HWRegs;
470  }
471
472  bool isCCRAsm() const {
473    assert((Kind == k_Register) && "Invalid access!");
474    return Reg.Kind == Kind_CCRRegs;
475  }
476
477  bool isAFGR64Asm() const {
478    return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
479  }
480
481  bool isFGR64Asm() const {
482    return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
483  }
484
485  bool isFGR32Asm() const {
486    return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
487  }
488
489  bool isFGRH32Asm() const {
490    return (Kind == k_Register) && Reg.Kind == Kind_FGRH32Regs;
491  }
492
493  bool isFCCRegsAsm() const {
494    return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
495  }
496
497  bool isACC64DSPAsm() const {
498    return Kind == k_Register && Reg.Kind == Kind_ACC64DSP;
499  }
500
501  bool isLO32DSPAsm() const {
502    return Kind == k_Register && Reg.Kind == Kind_LO32DSP;
503  }
504
505  bool isHI32DSPAsm() const {
506    return Kind == k_Register && Reg.Kind == Kind_HI32DSP;
507  }
508
509  bool isCOP2Asm() const { return Kind == k_Register && Reg.Kind == Kind_COP2; }
510
511  bool isMSA128BAsm() const {
512    return Kind == k_Register && Reg.Kind == Kind_MSA128BRegs;
513  }
514
515  bool isMSA128HAsm() const {
516    return Kind == k_Register && Reg.Kind == Kind_MSA128HRegs;
517  }
518
519  bool isMSA128WAsm() const {
520    return Kind == k_Register && Reg.Kind == Kind_MSA128WRegs;
521  }
522
523  bool isMSA128DAsm() const {
524    return Kind == k_Register && Reg.Kind == Kind_MSA128DRegs;
525  }
526
527  bool isMSA128CRAsm() const {
528    return Kind == k_Register && Reg.Kind == Kind_MSA128CtrlRegs;
529  }
530
531  /// getStartLoc - Get the location of the first token of this operand.
532  SMLoc getStartLoc() const { return StartLoc; }
533  /// getEndLoc - Get the location of the last token of this operand.
534  SMLoc getEndLoc() const { return EndLoc; }
535
536  virtual void print(raw_ostream &OS) const {
537    llvm_unreachable("unimplemented!");
538  }
539}; // class MipsOperand
540} // namespace
541
542namespace llvm {
543extern const MCInstrDesc MipsInsts[];
544}
545static const MCInstrDesc &getInstDesc(unsigned Opcode) {
546  return MipsInsts[Opcode];
547}
548
549bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
550                                       SmallVectorImpl<MCInst> &Instructions) {
551  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
552  Inst.setLoc(IDLoc);
553  if (MCID.hasDelaySlot() && Options.isReorder()) {
554    // If this instruction has a delay slot and .set reorder is active,
555    // emit a NOP after it.
556    Instructions.push_back(Inst);
557    MCInst NopInst;
558    NopInst.setOpcode(Mips::SLL);
559    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
560    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
561    NopInst.addOperand(MCOperand::CreateImm(0));
562    Instructions.push_back(NopInst);
563    return false;
564  }
565
566  if (MCID.mayLoad() || MCID.mayStore()) {
567    // Check the offset of memory operand, if it is a symbol
568    // reference or immediate we may have to expand instructions.
569    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
570      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
571      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
572          (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
573        MCOperand &Op = Inst.getOperand(i);
574        if (Op.isImm()) {
575          int MemOffset = Op.getImm();
576          if (MemOffset < -32768 || MemOffset > 32767) {
577            // Offset can't exceed 16bit value.
578            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
579            return false;
580          }
581        } else if (Op.isExpr()) {
582          const MCExpr *Expr = Op.getExpr();
583          if (Expr->getKind() == MCExpr::SymbolRef) {
584            const MCSymbolRefExpr *SR =
585                static_cast<const MCSymbolRefExpr *>(Expr);
586            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
587              // Expand symbol.
588              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
589              return false;
590            }
591          } else if (!isEvaluated(Expr)) {
592            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
593            return false;
594          }
595        }
596      }
597    } // for
598  }   // if load/store
599
600  if (needsExpansion(Inst))
601    expandInstruction(Inst, IDLoc, Instructions);
602  else
603    Instructions.push_back(Inst);
604
605  return false;
606}
607
608bool MipsAsmParser::needsExpansion(MCInst &Inst) {
609
610  switch (Inst.getOpcode()) {
611  case Mips::LoadImm32Reg:
612  case Mips::LoadAddr32Imm:
613  case Mips::LoadAddr32Reg:
614    return true;
615  default:
616    return false;
617  }
618}
619
620void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
621                                      SmallVectorImpl<MCInst> &Instructions) {
622  switch (Inst.getOpcode()) {
623  case Mips::LoadImm32Reg:
624    return expandLoadImm(Inst, IDLoc, Instructions);
625  case Mips::LoadAddr32Imm:
626    return expandLoadAddressImm(Inst, IDLoc, Instructions);
627  case Mips::LoadAddr32Reg:
628    return expandLoadAddressReg(Inst, IDLoc, Instructions);
629  }
630}
631
632void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
633                                  SmallVectorImpl<MCInst> &Instructions) {
634  MCInst tmpInst;
635  const MCOperand &ImmOp = Inst.getOperand(1);
636  assert(ImmOp.isImm() && "expected immediate operand kind");
637  const MCOperand &RegOp = Inst.getOperand(0);
638  assert(RegOp.isReg() && "expected register operand kind");
639
640  int ImmValue = ImmOp.getImm();
641  tmpInst.setLoc(IDLoc);
642  if (0 <= ImmValue && ImmValue <= 65535) {
643    // For 0 <= j <= 65535.
644    // li d,j => ori d,$zero,j
645    tmpInst.setOpcode(Mips::ORi);
646    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
647    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
648    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
649    Instructions.push_back(tmpInst);
650  } else if (ImmValue < 0 && ImmValue >= -32768) {
651    // For -32768 <= j < 0.
652    // li d,j => addiu d,$zero,j
653    tmpInst.setOpcode(Mips::ADDiu);
654    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
655    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
656    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
657    Instructions.push_back(tmpInst);
658  } else {
659    // For any other value of j that is representable as a 32-bit integer.
660    // li d,j => lui d,hi16(j)
661    //           ori d,d,lo16(j)
662    tmpInst.setOpcode(Mips::LUi);
663    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
664    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
665    Instructions.push_back(tmpInst);
666    tmpInst.clear();
667    tmpInst.setOpcode(Mips::ORi);
668    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
669    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
670    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
671    tmpInst.setLoc(IDLoc);
672    Instructions.push_back(tmpInst);
673  }
674}
675
676void
677MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
678                                    SmallVectorImpl<MCInst> &Instructions) {
679  MCInst tmpInst;
680  const MCOperand &ImmOp = Inst.getOperand(2);
681  assert(ImmOp.isImm() && "expected immediate operand kind");
682  const MCOperand &SrcRegOp = Inst.getOperand(1);
683  assert(SrcRegOp.isReg() && "expected register operand kind");
684  const MCOperand &DstRegOp = Inst.getOperand(0);
685  assert(DstRegOp.isReg() && "expected register operand kind");
686  int ImmValue = ImmOp.getImm();
687  if (-32768 <= ImmValue && ImmValue <= 65535) {
688    // For -32768 <= j <= 65535.
689    // la d,j(s) => addiu d,s,j
690    tmpInst.setOpcode(Mips::ADDiu);
691    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
692    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
693    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
694    Instructions.push_back(tmpInst);
695  } else {
696    // For any other value of j that is representable as a 32-bit integer.
697    // la d,j(s) => lui d,hi16(j)
698    //              ori d,d,lo16(j)
699    //              addu d,d,s
700    tmpInst.setOpcode(Mips::LUi);
701    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
702    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
703    Instructions.push_back(tmpInst);
704    tmpInst.clear();
705    tmpInst.setOpcode(Mips::ORi);
706    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
707    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
708    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
709    Instructions.push_back(tmpInst);
710    tmpInst.clear();
711    tmpInst.setOpcode(Mips::ADDu);
712    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
713    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
714    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
715    Instructions.push_back(tmpInst);
716  }
717}
718
719void
720MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
721                                    SmallVectorImpl<MCInst> &Instructions) {
722  MCInst tmpInst;
723  const MCOperand &ImmOp = Inst.getOperand(1);
724  assert(ImmOp.isImm() && "expected immediate operand kind");
725  const MCOperand &RegOp = Inst.getOperand(0);
726  assert(RegOp.isReg() && "expected register operand kind");
727  int ImmValue = ImmOp.getImm();
728  if (-32768 <= ImmValue && ImmValue <= 65535) {
729    // For -32768 <= j <= 65535.
730    // la d,j => addiu d,$zero,j
731    tmpInst.setOpcode(Mips::ADDiu);
732    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
733    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
734    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
735    Instructions.push_back(tmpInst);
736  } else {
737    // For any other value of j that is representable as a 32-bit integer.
738    // la d,j => lui d,hi16(j)
739    //           ori d,d,lo16(j)
740    tmpInst.setOpcode(Mips::LUi);
741    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
742    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
743    Instructions.push_back(tmpInst);
744    tmpInst.clear();
745    tmpInst.setOpcode(Mips::ORi);
746    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
747    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
748    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
749    Instructions.push_back(tmpInst);
750  }
751}
752
753void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
754                                  SmallVectorImpl<MCInst> &Instructions,
755                                  bool isLoad, bool isImmOpnd) {
756  const MCSymbolRefExpr *SR;
757  MCInst TempInst;
758  unsigned ImmOffset, HiOffset, LoOffset;
759  const MCExpr *ExprOffset;
760  unsigned TmpRegNum;
761  unsigned AtRegNum = getReg(
762      (isMips64()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, getATReg());
763  // 1st operand is either the source or destination register.
764  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
765  unsigned RegOpNum = Inst.getOperand(0).getReg();
766  // 2nd operand is the base register.
767  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
768  unsigned BaseRegNum = Inst.getOperand(1).getReg();
769  // 3rd operand is either an immediate or expression.
770  if (isImmOpnd) {
771    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
772    ImmOffset = Inst.getOperand(2).getImm();
773    LoOffset = ImmOffset & 0x0000ffff;
774    HiOffset = (ImmOffset & 0xffff0000) >> 16;
775    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
776    if (LoOffset & 0x8000)
777      HiOffset++;
778  } else
779    ExprOffset = Inst.getOperand(2).getExpr();
780  // All instructions will have the same location.
781  TempInst.setLoc(IDLoc);
782  // 1st instruction in expansion is LUi. For load instruction we can use
783  // the dst register as a temporary if base and dst are different,
784  // but for stores we must use $at.
785  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
786  TempInst.setOpcode(Mips::LUi);
787  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
788  if (isImmOpnd)
789    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
790  else {
791    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
792      SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
793      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
794          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
795          getContext());
796      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
797    } else {
798      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
799      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
800    }
801  }
802  // Add the instruction to the list.
803  Instructions.push_back(TempInst);
804  // Prepare TempInst for next instruction.
805  TempInst.clear();
806  // Add temp register to base.
807  TempInst.setOpcode(Mips::ADDu);
808  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
809  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
810  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
811  Instructions.push_back(TempInst);
812  TempInst.clear();
813  // And finaly, create original instruction with low part
814  // of offset and new base.
815  TempInst.setOpcode(Inst.getOpcode());
816  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
817  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
818  if (isImmOpnd)
819    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
820  else {
821    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
822      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
823          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
824          getContext());
825      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
826    } else {
827      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
828      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
829    }
830  }
831  Instructions.push_back(TempInst);
832  TempInst.clear();
833}
834
835bool MipsAsmParser::MatchAndEmitInstruction(
836    SMLoc IDLoc, unsigned &Opcode,
837    SmallVectorImpl<MCParsedAsmOperand *> &Operands, MCStreamer &Out,
838    unsigned &ErrorInfo, bool MatchingInlineAsm) {
839  MCInst Inst;
840  SmallVector<MCInst, 8> Instructions;
841  unsigned MatchResult =
842      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
843
844  switch (MatchResult) {
845  default:
846    break;
847  case Match_Success: {
848    if (processInstruction(Inst, IDLoc, Instructions))
849      return true;
850    for (unsigned i = 0; i < Instructions.size(); i++)
851      Out.EmitInstruction(Instructions[i]);
852    return false;
853  }
854  case Match_MissingFeature:
855    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
856    return true;
857  case Match_InvalidOperand: {
858    SMLoc ErrorLoc = IDLoc;
859    if (ErrorInfo != ~0U) {
860      if (ErrorInfo >= Operands.size())
861        return Error(IDLoc, "too few operands for instruction");
862
863      ErrorLoc = ((MipsOperand *)Operands[ErrorInfo])->getStartLoc();
864      if (ErrorLoc == SMLoc())
865        ErrorLoc = IDLoc;
866    }
867
868    return Error(ErrorLoc, "invalid operand for instruction");
869  }
870  case Match_MnemonicFail:
871    return Error(IDLoc, "invalid instruction");
872  }
873  return true;
874}
875
876int MipsAsmParser::matchCPURegisterName(StringRef Name) {
877  int CC;
878
879  if (Name == "at")
880    return getATReg();
881
882  CC = StringSwitch<unsigned>(Name)
883           .Case("zero", 0)
884           .Case("a0", 4)
885           .Case("a1", 5)
886           .Case("a2", 6)
887           .Case("a3", 7)
888           .Case("v0", 2)
889           .Case("v1", 3)
890           .Case("s0", 16)
891           .Case("s1", 17)
892           .Case("s2", 18)
893           .Case("s3", 19)
894           .Case("s4", 20)
895           .Case("s5", 21)
896           .Case("s6", 22)
897           .Case("s7", 23)
898           .Case("k0", 26)
899           .Case("k1", 27)
900           .Case("sp", 29)
901           .Case("fp", 30)
902           .Case("gp", 28)
903           .Case("ra", 31)
904           .Case("t0", 8)
905           .Case("t1", 9)
906           .Case("t2", 10)
907           .Case("t3", 11)
908           .Case("t4", 12)
909           .Case("t5", 13)
910           .Case("t6", 14)
911           .Case("t7", 15)
912           .Case("t8", 24)
913           .Case("t9", 25)
914           .Default(-1);
915
916  // Although SGI documentation just cuts out t0-t3 for n32/n64,
917  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
918  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
919  if (isMips64() && 8 <= CC && CC <= 11)
920    CC += 4;
921
922  if (CC == -1 && isMips64())
923    CC = StringSwitch<unsigned>(Name)
924             .Case("a4", 8)
925             .Case("a5", 9)
926             .Case("a6", 10)
927             .Case("a7", 11)
928             .Case("kt0", 26)
929             .Case("kt1", 27)
930             .Case("s8", 30)
931             .Default(-1);
932
933  return CC;
934}
935
936int MipsAsmParser::matchFPURegisterName(StringRef Name) {
937
938  if (Name[0] == 'f') {
939    StringRef NumString = Name.substr(1);
940    unsigned IntVal;
941    if (NumString.getAsInteger(10, IntVal))
942      return -1;     // This is not an integer.
943    if (IntVal > 31) // Maximum index for fpu register.
944      return -1;
945    return IntVal;
946  }
947  return -1;
948}
949
950int MipsAsmParser::matchFCCRegisterName(StringRef Name) {
951
952  if (Name.startswith("fcc")) {
953    StringRef NumString = Name.substr(3);
954    unsigned IntVal;
955    if (NumString.getAsInteger(10, IntVal))
956      return -1;    // This is not an integer.
957    if (IntVal > 7) // There are only 8 fcc registers.
958      return -1;
959    return IntVal;
960  }
961  return -1;
962}
963
964int MipsAsmParser::matchACRegisterName(StringRef Name) {
965
966  if (Name.startswith("ac")) {
967    StringRef NumString = Name.substr(2);
968    unsigned IntVal;
969    if (NumString.getAsInteger(10, IntVal))
970      return -1;    // This is not an integer.
971    if (IntVal > 3) // There are only 3 acc registers.
972      return -1;
973    return IntVal;
974  }
975  return -1;
976}
977
978int MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
979  unsigned IntVal;
980
981  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
982    return -1;
983
984  if (IntVal > 31)
985    return -1;
986
987  return IntVal;
988}
989
990int MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
991  int CC;
992
993  CC = StringSwitch<unsigned>(Name)
994           .Case("msair", 0)
995           .Case("msacsr", 1)
996           .Case("msaaccess", 2)
997           .Case("msasave", 3)
998           .Case("msamodify", 4)
999           .Case("msarequest", 5)
1000           .Case("msamap", 6)
1001           .Case("msaunmap", 7)
1002           .Default(-1);
1003
1004  return CC;
1005}
1006
1007int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
1008
1009  int CC;
1010  CC = matchCPURegisterName(Name);
1011  if (CC != -1)
1012    return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
1013                                                : Mips::GPR32RegClassID);
1014  CC = matchFPURegisterName(Name);
1015  // TODO: decide about fpu register class
1016  if (CC != -1)
1017    return matchRegisterByNumber(CC, isFP64() ? Mips::FGR64RegClassID
1018                                              : Mips::FGR32RegClassID);
1019  return matchMSA128RegisterName(Name);
1020}
1021
1022int MipsAsmParser::regKindToRegClass(int RegKind) {
1023
1024  switch (RegKind) {
1025  case MipsOperand::Kind_GPR32:
1026    return Mips::GPR32RegClassID;
1027  case MipsOperand::Kind_GPR64:
1028    return Mips::GPR64RegClassID;
1029  case MipsOperand::Kind_HWRegs:
1030    return Mips::HWRegsRegClassID;
1031  case MipsOperand::Kind_FGR32Regs:
1032    return Mips::FGR32RegClassID;
1033  case MipsOperand::Kind_FGRH32Regs:
1034    return Mips::FGRH32RegClassID;
1035  case MipsOperand::Kind_FGR64Regs:
1036    return Mips::FGR64RegClassID;
1037  case MipsOperand::Kind_AFGR64Regs:
1038    return Mips::AFGR64RegClassID;
1039  case MipsOperand::Kind_CCRRegs:
1040    return Mips::CCRRegClassID;
1041  case MipsOperand::Kind_ACC64DSP:
1042    return Mips::ACC64DSPRegClassID;
1043  case MipsOperand::Kind_FCCRegs:
1044    return Mips::FCCRegClassID;
1045  case MipsOperand::Kind_MSA128BRegs:
1046    return Mips::MSA128BRegClassID;
1047  case MipsOperand::Kind_MSA128HRegs:
1048    return Mips::MSA128HRegClassID;
1049  case MipsOperand::Kind_MSA128WRegs:
1050    return Mips::MSA128WRegClassID;
1051  case MipsOperand::Kind_MSA128DRegs:
1052    return Mips::MSA128DRegClassID;
1053  case MipsOperand::Kind_MSA128CtrlRegs:
1054    return Mips::MSACtrlRegClassID;
1055  default:
1056    return -1;
1057  }
1058}
1059
1060bool MipsAssemblerOptions::setATReg(unsigned Reg) {
1061  if (Reg > 31)
1062    return false;
1063
1064  aTReg = Reg;
1065  return true;
1066}
1067
1068int MipsAsmParser::getATReg() { return Options.getATRegNum(); }
1069
1070unsigned MipsAsmParser::getReg(int RC, int RegNo) {
1071  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1072}
1073
1074int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1075  if (RegNum >
1076      getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs())
1077    return -1;
1078
1079  return getReg(RegClass, RegNum);
1080}
1081
1082int MipsAsmParser::tryParseRegister(bool is64BitReg) {
1083  const AsmToken &Tok = Parser.getTok();
1084  int RegNum = -1;
1085
1086  if (Tok.is(AsmToken::Identifier)) {
1087    std::string lowerCase = Tok.getString().lower();
1088    RegNum = matchRegisterName(lowerCase, is64BitReg);
1089  } else if (Tok.is(AsmToken::Integer))
1090    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
1091                                   is64BitReg ? Mips::GPR64RegClassID
1092                                              : Mips::GPR32RegClassID);
1093  return RegNum;
1094}
1095
1096bool MipsAsmParser::tryParseRegisterOperand(
1097    SmallVectorImpl<MCParsedAsmOperand *> &Operands, bool is64BitReg) {
1098
1099  SMLoc S = Parser.getTok().getLoc();
1100  int RegNo = -1;
1101
1102  RegNo = tryParseRegister(is64BitReg);
1103  if (RegNo == -1)
1104    return true;
1105
1106  Operands.push_back(
1107      MipsOperand::CreateReg(RegNo, S, Parser.getTok().getLoc()));
1108  Parser.Lex(); // Eat register token.
1109  return false;
1110}
1111
1112bool
1113MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1114                            StringRef Mnemonic) {
1115  // Check if the current operand has a custom associated parser, if so, try to
1116  // custom parse the operand, or fallback to the general approach.
1117  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1118  if (ResTy == MatchOperand_Success)
1119    return false;
1120  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1121  // there was a match, but an error occurred, in which case, just return that
1122  // the operand parsing failed.
1123  if (ResTy == MatchOperand_ParseFail)
1124    return true;
1125
1126  switch (getLexer().getKind()) {
1127  default:
1128    Error(Parser.getTok().getLoc(), "unexpected token in operand");
1129    return true;
1130  case AsmToken::Dollar: {
1131    // Parse the register.
1132    SMLoc S = Parser.getTok().getLoc();
1133    Parser.Lex(); // Eat dollar token.
1134    // Parse the register operand.
1135    if (!tryParseRegisterOperand(Operands, isMips64())) {
1136      if (getLexer().is(AsmToken::LParen)) {
1137        // Check if it is indexed addressing operand.
1138        Operands.push_back(MipsOperand::CreateToken("(", S));
1139        Parser.Lex(); // Eat the parenthesis.
1140        if (getLexer().isNot(AsmToken::Dollar))
1141          return true;
1142
1143        Parser.Lex(); // Eat the dollar
1144        if (tryParseRegisterOperand(Operands, isMips64()))
1145          return true;
1146
1147        if (!getLexer().is(AsmToken::RParen))
1148          return true;
1149
1150        S = Parser.getTok().getLoc();
1151        Operands.push_back(MipsOperand::CreateToken(")", S));
1152        Parser.Lex();
1153      }
1154      return false;
1155    }
1156    // Maybe it is a symbol reference.
1157    StringRef Identifier;
1158    if (Parser.parseIdentifier(Identifier))
1159      return true;
1160
1161    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1162
1163    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1164
1165    // Otherwise create a symbol reference.
1166    const MCExpr *Res =
1167        MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1168
1169    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1170    return false;
1171  }
1172  case AsmToken::Identifier:
1173    // Look for the existing symbol, we should check if
1174    // we need to assigne the propper RegisterKind.
1175    if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1176      return false;
1177  // Else drop to expression parsing.
1178  case AsmToken::LParen:
1179  case AsmToken::Minus:
1180  case AsmToken::Plus:
1181  case AsmToken::Integer:
1182  case AsmToken::String: {
1183    // Quoted label names.
1184    const MCExpr *IdVal;
1185    SMLoc S = Parser.getTok().getLoc();
1186    if (getParser().parseExpression(IdVal))
1187      return true;
1188    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1189    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1190    return false;
1191  }
1192  case AsmToken::Percent: {
1193    // It is a symbol reference or constant expression.
1194    const MCExpr *IdVal;
1195    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1196    if (parseRelocOperand(IdVal))
1197      return true;
1198
1199    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1200
1201    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1202    return false;
1203  } // case AsmToken::Percent
1204  } // switch(getLexer().getKind())
1205  return true;
1206}
1207
1208const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1209                                               StringRef RelocStr) {
1210  const MCExpr *Res;
1211  // Check the type of the expression.
1212  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1213    // It's a constant, evaluate lo or hi value.
1214    if (RelocStr == "lo") {
1215      short Val = MCE->getValue();
1216      Res = MCConstantExpr::Create(Val, getContext());
1217    } else if (RelocStr == "hi") {
1218      int Val = MCE->getValue();
1219      int LoSign = Val & 0x8000;
1220      Val = (Val & 0xffff0000) >> 16;
1221      // Lower part is treated as a signed int, so if it is negative
1222      // we must add 1 to the hi part to compensate.
1223      if (LoSign)
1224        Val++;
1225      Res = MCConstantExpr::Create(Val, getContext());
1226    } else {
1227      llvm_unreachable("Invalid RelocStr value");
1228    }
1229    return Res;
1230  }
1231
1232  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1233    // It's a symbol, create a symbolic expression from the symbol.
1234    StringRef Symbol = MSRE->getSymbol().getName();
1235    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1236    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1237    return Res;
1238  }
1239
1240  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1241    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1242    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1243    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1244    return Res;
1245  }
1246
1247  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1248    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1249    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1250    return Res;
1251  }
1252  // Just return the original expression.
1253  return Expr;
1254}
1255
1256bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1257
1258  switch (Expr->getKind()) {
1259  case MCExpr::Constant:
1260    return true;
1261  case MCExpr::SymbolRef:
1262    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1263  case MCExpr::Binary:
1264    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1265      if (!isEvaluated(BE->getLHS()))
1266        return false;
1267      return isEvaluated(BE->getRHS());
1268    }
1269  case MCExpr::Unary:
1270    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1271  default:
1272    return false;
1273  }
1274  return false;
1275}
1276
1277bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1278  Parser.Lex();                          // Eat the % token.
1279  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1280  if (Tok.isNot(AsmToken::Identifier))
1281    return true;
1282
1283  std::string Str = Tok.getIdentifier().str();
1284
1285  Parser.Lex(); // Eat the identifier.
1286  // Now make an expression from the rest of the operand.
1287  const MCExpr *IdVal;
1288  SMLoc EndLoc;
1289
1290  if (getLexer().getKind() == AsmToken::LParen) {
1291    while (1) {
1292      Parser.Lex(); // Eat the '(' token.
1293      if (getLexer().getKind() == AsmToken::Percent) {
1294        Parser.Lex(); // Eat the % token.
1295        const AsmToken &nextTok = Parser.getTok();
1296        if (nextTok.isNot(AsmToken::Identifier))
1297          return true;
1298        Str += "(%";
1299        Str += nextTok.getIdentifier();
1300        Parser.Lex(); // Eat the identifier.
1301        if (getLexer().getKind() != AsmToken::LParen)
1302          return true;
1303      } else
1304        break;
1305    }
1306    if (getParser().parseParenExpression(IdVal, EndLoc))
1307      return true;
1308
1309    while (getLexer().getKind() == AsmToken::RParen)
1310      Parser.Lex(); // Eat the ')' token.
1311
1312  } else
1313    return true; // Parenthesis must follow the relocation operand.
1314
1315  Res = evaluateRelocExpr(IdVal, Str);
1316  return false;
1317}
1318
1319bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1320                                  SMLoc &EndLoc) {
1321  StartLoc = Parser.getTok().getLoc();
1322  RegNo = tryParseRegister(isMips64());
1323  EndLoc = Parser.getTok().getLoc();
1324  return (RegNo == (unsigned)-1);
1325}
1326
1327bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1328  SMLoc S;
1329  bool Result = true;
1330
1331  while (getLexer().getKind() == AsmToken::LParen)
1332    Parser.Lex();
1333
1334  switch (getLexer().getKind()) {
1335  default:
1336    return true;
1337  case AsmToken::Identifier:
1338  case AsmToken::LParen:
1339  case AsmToken::Integer:
1340  case AsmToken::Minus:
1341  case AsmToken::Plus:
1342    if (isParenExpr)
1343      Result = getParser().parseParenExpression(Res, S);
1344    else
1345      Result = (getParser().parseExpression(Res));
1346    while (getLexer().getKind() == AsmToken::RParen)
1347      Parser.Lex();
1348    break;
1349  case AsmToken::Percent:
1350    Result = parseRelocOperand(Res);
1351  }
1352  return Result;
1353}
1354
1355MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1356    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1357
1358  const MCExpr *IdVal = 0;
1359  SMLoc S;
1360  bool isParenExpr = false;
1361  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1362  // First operand is the offset.
1363  S = Parser.getTok().getLoc();
1364
1365  if (getLexer().getKind() == AsmToken::LParen) {
1366    Parser.Lex();
1367    isParenExpr = true;
1368  }
1369
1370  if (getLexer().getKind() != AsmToken::Dollar) {
1371    if (parseMemOffset(IdVal, isParenExpr))
1372      return MatchOperand_ParseFail;
1373
1374    const AsmToken &Tok = Parser.getTok(); // Get the next token.
1375    if (Tok.isNot(AsmToken::LParen)) {
1376      MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1377      if (Mnemonic->getToken() == "la") {
1378        SMLoc E =
1379            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1380        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1381        return MatchOperand_Success;
1382      }
1383      if (Tok.is(AsmToken::EndOfStatement)) {
1384        SMLoc E =
1385            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1386
1387        // Zero register assumed, add a memory operand with ZERO as its base.
1388        Operands.push_back(MipsOperand::CreateMem(
1389            isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
1390        return MatchOperand_Success;
1391      }
1392      Error(Parser.getTok().getLoc(), "'(' expected");
1393      return MatchOperand_ParseFail;
1394    }
1395
1396    Parser.Lex(); // Eat the '(' token.
1397  }
1398
1399  Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1400                                       : (int)MipsOperand::Kind_GPR32);
1401  if (Res != MatchOperand_Success)
1402    return Res;
1403
1404  if (Parser.getTok().isNot(AsmToken::RParen)) {
1405    Error(Parser.getTok().getLoc(), "')' expected");
1406    return MatchOperand_ParseFail;
1407  }
1408
1409  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1410
1411  Parser.Lex(); // Eat the ')' token.
1412
1413  if (IdVal == 0)
1414    IdVal = MCConstantExpr::Create(0, getContext());
1415
1416  // Replace the register operand with the memory operand.
1417  MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
1418  int RegNo = op->getReg();
1419  // Remove the register from the operands.
1420  Operands.pop_back();
1421  // Add the memory operand.
1422  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1423    int64_t Imm;
1424    if (IdVal->EvaluateAsAbsolute(Imm))
1425      IdVal = MCConstantExpr::Create(Imm, getContext());
1426    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1427      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1428                                   getContext());
1429  }
1430
1431  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1432  delete op;
1433  return MatchOperand_Success;
1434}
1435
1436bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1437                                int RegKind) {
1438  // If the first token is not '$' we have an error.
1439  if (Parser.getTok().isNot(AsmToken::Dollar))
1440    return false;
1441
1442  SMLoc S = Parser.getTok().getLoc();
1443  Parser.Lex();
1444  AsmToken::TokenKind TkKind = getLexer().getKind();
1445  int Reg;
1446
1447  if (TkKind == AsmToken::Integer) {
1448    Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1449                                regKindToRegClass(RegKind));
1450    if (Reg == -1)
1451      return false;
1452  } else if (TkKind == AsmToken::Identifier) {
1453    if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1454      return false;
1455    Reg = getReg(regKindToRegClass(RegKind), Reg);
1456  } else {
1457    return false;
1458  }
1459
1460  MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1461  Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1462  Operands.push_back(Op);
1463  Parser.Lex();
1464  return true;
1465}
1466
1467MipsAsmParser::OperandMatchResultTy
1468MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1469  MipsOperand::RegisterKind RegKind =
1470      isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
1471
1472  // Parse index register.
1473  if (!parsePtrReg(Operands, RegKind))
1474    return MatchOperand_NoMatch;
1475
1476  // Parse '('.
1477  if (Parser.getTok().isNot(AsmToken::LParen))
1478    return MatchOperand_NoMatch;
1479
1480  Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1481  Parser.Lex();
1482
1483  // Parse base register.
1484  if (!parsePtrReg(Operands, RegKind))
1485    return MatchOperand_NoMatch;
1486
1487  // Parse ')'.
1488  if (Parser.getTok().isNot(AsmToken::RParen))
1489    return MatchOperand_NoMatch;
1490
1491  Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1492  Parser.Lex();
1493
1494  return MatchOperand_Success;
1495}
1496
1497MipsAsmParser::OperandMatchResultTy
1498MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1499                         int RegKind) {
1500  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1501  if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
1502    if (searchSymbolAlias(Operands, Kind))
1503      return MatchOperand_Success;
1504    return MatchOperand_NoMatch;
1505  }
1506  SMLoc S = Parser.getTok().getLoc();
1507  // If the first token is not '$', we have an error.
1508  if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1509    return MatchOperand_NoMatch;
1510  if (!hasConsumedDollar) {
1511    Parser.Lex(); // Eat the '$'
1512    hasConsumedDollar = true;
1513  }
1514  if (getLexer().getKind() == AsmToken::Identifier) {
1515    int RegNum = -1;
1516    std::string RegName = Parser.getTok().getString().lower();
1517    // Match register by name
1518    switch (RegKind) {
1519    case MipsOperand::Kind_GPR32:
1520    case MipsOperand::Kind_GPR64:
1521      RegNum = matchCPURegisterName(RegName);
1522      break;
1523    case MipsOperand::Kind_AFGR64Regs:
1524    case MipsOperand::Kind_FGR64Regs:
1525    case MipsOperand::Kind_FGR32Regs:
1526    case MipsOperand::Kind_FGRH32Regs:
1527      RegNum = matchFPURegisterName(RegName);
1528      if (RegKind == MipsOperand::Kind_AFGR64Regs)
1529        RegNum /= 2;
1530      else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1531        if (RegNum != -1 && RegNum % 2 != 0)
1532          Warning(S, "Float register should be even.");
1533      break;
1534    case MipsOperand::Kind_FCCRegs:
1535      RegNum = matchFCCRegisterName(RegName);
1536      break;
1537    case MipsOperand::Kind_ACC64DSP:
1538      RegNum = matchACRegisterName(RegName);
1539      break;
1540    default:
1541      break; // No match, value is set to -1.
1542    }
1543    // No match found, return _NoMatch to give a chance to other round.
1544    if (RegNum < 0)
1545      return MatchOperand_NoMatch;
1546
1547    int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1548    if (RegVal == -1)
1549      return MatchOperand_NoMatch;
1550
1551    MipsOperand *Op =
1552        MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1553    Op->setRegKind(Kind);
1554    Operands.push_back(Op);
1555    hasConsumedDollar = false;
1556    Parser.Lex(); // Eat the register name.
1557    return MatchOperand_Success;
1558  } else if (getLexer().getKind() == AsmToken::Integer) {
1559    unsigned RegNum = Parser.getTok().getIntVal();
1560    if (Kind == MipsOperand::Kind_HWRegs) {
1561      if (RegNum != 29)
1562        return MatchOperand_NoMatch;
1563      // Only hwreg 29 is supported, found at index 0.
1564      RegNum = 0;
1565    }
1566    int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1567    if (Reg == -1)
1568      return MatchOperand_NoMatch;
1569    MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1570    Op->setRegKind(Kind);
1571    Operands.push_back(Op);
1572    hasConsumedDollar = false;
1573    Parser.Lex(); // Eat the register number.
1574    if ((RegKind == MipsOperand::Kind_GPR32) &&
1575        (getLexer().is(AsmToken::LParen))) {
1576      // Check if it is indexed addressing operand.
1577      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1578      Parser.Lex(); // Eat the parenthesis.
1579      if (parseRegs(Operands, RegKind) != MatchOperand_Success)
1580        return MatchOperand_NoMatch;
1581      if (getLexer().isNot(AsmToken::RParen))
1582        return MatchOperand_NoMatch;
1583      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1584      Parser.Lex();
1585    }
1586    return MatchOperand_Success;
1587  }
1588  return MatchOperand_NoMatch;
1589}
1590
1591bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1592  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1593
1594  if (Val < 0)
1595    return false;
1596
1597  switch (Kind) {
1598  default:
1599    return false;
1600  case MipsOperand::Kind_MSA128BRegs:
1601    return Val < 16;
1602  case MipsOperand::Kind_MSA128HRegs:
1603    return Val < 8;
1604  case MipsOperand::Kind_MSA128WRegs:
1605    return Val < 4;
1606  case MipsOperand::Kind_MSA128DRegs:
1607    return Val < 2;
1608  }
1609}
1610
1611MipsAsmParser::OperandMatchResultTy
1612MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1613                            int RegKind) {
1614  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1615  SMLoc S = Parser.getTok().getLoc();
1616  std::string RegName;
1617
1618  if (Parser.getTok().isNot(AsmToken::Dollar))
1619    return MatchOperand_NoMatch;
1620
1621  switch (RegKind) {
1622  default:
1623    return MatchOperand_ParseFail;
1624  case MipsOperand::Kind_MSA128BRegs:
1625  case MipsOperand::Kind_MSA128HRegs:
1626  case MipsOperand::Kind_MSA128WRegs:
1627  case MipsOperand::Kind_MSA128DRegs:
1628    break;
1629  }
1630
1631  Parser.Lex(); // Eat the '$'.
1632  if (getLexer().getKind() == AsmToken::Identifier)
1633    RegName = Parser.getTok().getString().lower();
1634  else
1635    return MatchOperand_ParseFail;
1636
1637  int RegNum = matchMSA128RegisterName(RegName);
1638
1639  if (RegNum < 0 || RegNum > 31)
1640    return MatchOperand_ParseFail;
1641
1642  int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1643  if (RegVal == -1)
1644    return MatchOperand_ParseFail;
1645
1646  MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1647  Op->setRegKind(Kind);
1648  Operands.push_back(Op);
1649
1650  Parser.Lex(); // Eat the register identifier.
1651
1652  // MSA registers may be suffixed with an index in the form of:
1653  // 1) Immediate expression.
1654  // 2) General Purpose Register.
1655  // Examples:
1656  //   1) copy_s.b $29,$w0[0]
1657  //   2) sld.b $w0,$w1[$1]
1658
1659  if (Parser.getTok().isNot(AsmToken::LBrac))
1660    return MatchOperand_Success;
1661
1662  MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1663
1664  Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1665  Parser.Lex(); // Parse the '[' token.
1666
1667  if (Parser.getTok().is(AsmToken::Dollar)) {
1668    // This must be a GPR.
1669    MipsOperand *RegOp;
1670    SMLoc VIdx = Parser.getTok().getLoc();
1671    Parser.Lex(); // Parse the '$' token.
1672
1673    // GPR have aliases and we must account for that. Example: $30 == $fp
1674    if (getLexer().getKind() == AsmToken::Integer) {
1675      unsigned RegNum = Parser.getTok().getIntVal();
1676      int Reg = matchRegisterByNumber(
1677          RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1678      if (Reg == -1) {
1679        Error(VIdx, "invalid general purpose register");
1680        return MatchOperand_ParseFail;
1681      }
1682
1683      RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1684    } else if (getLexer().getKind() == AsmToken::Identifier) {
1685      int RegNum = -1;
1686      std::string RegName = Parser.getTok().getString().lower();
1687
1688      RegNum = matchCPURegisterName(RegName);
1689      if (RegNum == -1) {
1690        Error(VIdx, "general purpose register expected");
1691        return MatchOperand_ParseFail;
1692      }
1693      RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1694      RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1695    } else
1696      return MatchOperand_ParseFail;
1697
1698    RegOp->setRegKind(MipsOperand::Kind_GPR32);
1699    Operands.push_back(RegOp);
1700    Parser.Lex(); // Eat the register identifier.
1701
1702    if (Parser.getTok().isNot(AsmToken::RBrac))
1703      return MatchOperand_ParseFail;
1704
1705    Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1706    Parser.Lex(); // Parse the ']' token.
1707
1708    return MatchOperand_Success;
1709  }
1710
1711  // The index must be a constant expression then.
1712  SMLoc VIdx = Parser.getTok().getLoc();
1713  const MCExpr *ImmVal;
1714
1715  if (getParser().parseExpression(ImmVal))
1716    return MatchOperand_ParseFail;
1717
1718  const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1719  if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1720    Error(VIdx, "invalid immediate value");
1721    return MatchOperand_ParseFail;
1722  }
1723
1724  SMLoc E = Parser.getTok().getEndLoc();
1725
1726  if (Parser.getTok().isNot(AsmToken::RBrac))
1727    return MatchOperand_ParseFail;
1728
1729  bool insve =
1730      Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1731      Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
1732
1733  // The second vector index of insve instructions is always 0.
1734  if (insve && Operands.size() > 6) {
1735    if (expr->getValue() != 0) {
1736      Error(VIdx, "immediate value must be 0");
1737      return MatchOperand_ParseFail;
1738    }
1739    Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1740  } else
1741    Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1742
1743  Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1744
1745  Parser.Lex(); // Parse the ']' token.
1746
1747  return MatchOperand_Success;
1748}
1749
1750MipsAsmParser::OperandMatchResultTy
1751MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1752                                int RegKind) {
1753  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1754
1755  if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1756    return MatchOperand_NoMatch;
1757
1758  if (Parser.getTok().isNot(AsmToken::Dollar))
1759    return MatchOperand_ParseFail;
1760
1761  SMLoc S = Parser.getTok().getLoc();
1762
1763  Parser.Lex(); // Eat the '$' symbol.
1764
1765  int RegNum = -1;
1766  if (getLexer().getKind() == AsmToken::Identifier)
1767    RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1768  else if (getLexer().getKind() == AsmToken::Integer)
1769    RegNum = Parser.getTok().getIntVal();
1770  else
1771    return MatchOperand_ParseFail;
1772
1773  if (RegNum < 0 || RegNum > 7)
1774    return MatchOperand_ParseFail;
1775
1776  int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1777  if (RegVal == -1)
1778    return MatchOperand_ParseFail;
1779
1780  MipsOperand *RegOp =
1781      MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1782  RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1783  Operands.push_back(RegOp);
1784  Parser.Lex(); // Eat the register identifier.
1785
1786  return MatchOperand_Success;
1787}
1788
1789MipsAsmParser::OperandMatchResultTy
1790MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1791
1792  if (!isMips64())
1793    return MatchOperand_NoMatch;
1794  return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
1795}
1796
1797MipsAsmParser::OperandMatchResultTy
1798MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1799  return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
1800}
1801
1802MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1803    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1804
1805  if (isFP64())
1806    return MatchOperand_NoMatch;
1807  return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
1808}
1809
1810MipsAsmParser::OperandMatchResultTy
1811MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1812  if (!isFP64())
1813    return MatchOperand_NoMatch;
1814  return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
1815}
1816
1817MipsAsmParser::OperandMatchResultTy
1818MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1819  return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1820}
1821
1822MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1823    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1824  return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
1825}
1826
1827MipsAsmParser::OperandMatchResultTy
1828MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1829  return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
1830}
1831
1832MipsAsmParser::OperandMatchResultTy
1833MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1834  return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
1835}
1836
1837MipsAsmParser::OperandMatchResultTy
1838MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1839  // If the first token is not '$' we have an error.
1840  if (Parser.getTok().isNot(AsmToken::Dollar))
1841    return MatchOperand_NoMatch;
1842
1843  SMLoc S = Parser.getTok().getLoc();
1844  Parser.Lex(); // Eat the '$'
1845
1846  const AsmToken &Tok = Parser.getTok(); // Get next token.
1847
1848  if (Tok.isNot(AsmToken::Identifier))
1849    return MatchOperand_NoMatch;
1850
1851  if (!Tok.getIdentifier().startswith("ac"))
1852    return MatchOperand_NoMatch;
1853
1854  StringRef NumString = Tok.getIdentifier().substr(2);
1855
1856  unsigned IntVal;
1857  if (NumString.getAsInteger(10, IntVal))
1858    return MatchOperand_NoMatch;
1859
1860  unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1861
1862  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1863  Op->setRegKind(MipsOperand::Kind_LO32DSP);
1864  Operands.push_back(Op);
1865
1866  Parser.Lex(); // Eat the register number.
1867  return MatchOperand_Success;
1868}
1869
1870MipsAsmParser::OperandMatchResultTy
1871MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1872  // If the first token is not '$' we have an error.
1873  if (Parser.getTok().isNot(AsmToken::Dollar))
1874    return MatchOperand_NoMatch;
1875
1876  SMLoc S = Parser.getTok().getLoc();
1877  Parser.Lex(); // Eat the '$'
1878
1879  const AsmToken &Tok = Parser.getTok(); // Get next token.
1880
1881  if (Tok.isNot(AsmToken::Identifier))
1882    return MatchOperand_NoMatch;
1883
1884  if (!Tok.getIdentifier().startswith("ac"))
1885    return MatchOperand_NoMatch;
1886
1887  StringRef NumString = Tok.getIdentifier().substr(2);
1888
1889  unsigned IntVal;
1890  if (NumString.getAsInteger(10, IntVal))
1891    return MatchOperand_NoMatch;
1892
1893  unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1894
1895  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1896  Op->setRegKind(MipsOperand::Kind_HI32DSP);
1897  Operands.push_back(Op);
1898
1899  Parser.Lex(); // Eat the register number.
1900  return MatchOperand_Success;
1901}
1902
1903MipsAsmParser::OperandMatchResultTy
1904MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1905  // If the first token is not '$' we have an error.
1906  if (Parser.getTok().isNot(AsmToken::Dollar))
1907    return MatchOperand_NoMatch;
1908
1909  SMLoc S = Parser.getTok().getLoc();
1910  Parser.Lex(); // Eat the '$'
1911
1912  const AsmToken &Tok = Parser.getTok(); // Get next token.
1913
1914  if (Tok.isNot(AsmToken::Integer))
1915    return MatchOperand_NoMatch;
1916
1917  unsigned IntVal = Tok.getIntVal();
1918
1919  unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1920
1921  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1922  Op->setRegKind(MipsOperand::Kind_COP2);
1923  Operands.push_back(Op);
1924
1925  Parser.Lex(); // Eat the register number.
1926  return MatchOperand_Success;
1927}
1928
1929MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
1930    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1931  return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
1932}
1933
1934MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
1935    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1936  return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
1937}
1938
1939MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
1940    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1941  return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
1942}
1943
1944MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
1945    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1946  return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
1947}
1948
1949MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
1950    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1951  return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
1952}
1953
1954bool MipsAsmParser::searchSymbolAlias(
1955    SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
1956
1957  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1958  if (Sym) {
1959    SMLoc S = Parser.getTok().getLoc();
1960    const MCExpr *Expr;
1961    if (Sym->isVariable())
1962      Expr = Sym->getVariableValue();
1963    else
1964      return false;
1965    if (Expr->getKind() == MCExpr::SymbolRef) {
1966      MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1967      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1968      const StringRef DefSymbol = Ref->getSymbol().getName();
1969      if (DefSymbol.startswith("$")) {
1970        int RegNum = -1;
1971        APInt IntVal(32, -1);
1972        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1973          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1974                                         isMips64() ? Mips::GPR64RegClassID
1975                                                    : Mips::GPR32RegClassID);
1976        else {
1977          // Lookup for the register with the corresponding name.
1978          switch (Kind) {
1979          case MipsOperand::Kind_AFGR64Regs:
1980          case MipsOperand::Kind_FGR64Regs:
1981            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1982            break;
1983          case MipsOperand::Kind_FGR32Regs:
1984            RegNum = matchFPURegisterName(DefSymbol.substr(1));
1985            break;
1986          case MipsOperand::Kind_GPR64:
1987          case MipsOperand::Kind_GPR32:
1988          default:
1989            RegNum = matchCPURegisterName(DefSymbol.substr(1));
1990            break;
1991          }
1992          if (RegNum > -1)
1993            RegNum = getReg(regKindToRegClass(Kind), RegNum);
1994        }
1995        if (RegNum > -1) {
1996          Parser.Lex();
1997          MipsOperand *op =
1998              MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
1999          op->setRegKind(Kind);
2000          Operands.push_back(op);
2001          return true;
2002        }
2003      }
2004    } else if (Expr->getKind() == MCExpr::Constant) {
2005      Parser.Lex();
2006      const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2007      MipsOperand *op =
2008          MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
2009      Operands.push_back(op);
2010      return true;
2011    }
2012  }
2013  return false;
2014}
2015
2016MipsAsmParser::OperandMatchResultTy
2017MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2018  return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
2019}
2020
2021MipsAsmParser::OperandMatchResultTy
2022MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2023  return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
2024}
2025
2026MipsAsmParser::OperandMatchResultTy
2027MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2028  const MCExpr *IdVal;
2029  // If the first token is '$' we may have register operand.
2030  if (Parser.getTok().is(AsmToken::Dollar))
2031    return MatchOperand_NoMatch;
2032  SMLoc S = Parser.getTok().getLoc();
2033  if (getParser().parseExpression(IdVal))
2034    return MatchOperand_ParseFail;
2035  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2036  assert(MCE && "Unexpected MCExpr type.");
2037  int64_t Val = MCE->getValue();
2038  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2039  Operands.push_back(MipsOperand::CreateImm(
2040      MCConstantExpr::Create(0 - Val, getContext()), S, E));
2041  return MatchOperand_Success;
2042}
2043
2044MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2045
2046  MCSymbolRefExpr::VariantKind VK =
2047      StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2048          .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2049          .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2050          .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2051          .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2052          .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2053          .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2054          .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2055          .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2056          .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2057          .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2058          .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2059          .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2060          .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2061          .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2062          .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2063          .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2064          .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2065          .Default(MCSymbolRefExpr::VK_None);
2066
2067  return VK;
2068}
2069
2070bool MipsAsmParser::ParseInstruction(
2071    ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2072    SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2073  // Check if we have valid mnemonic
2074  if (!mnemonicIsValid(Name, 0)) {
2075    Parser.eatToEndOfStatement();
2076    return Error(NameLoc, "Unknown instruction");
2077  }
2078  // First operand in MCInst is instruction mnemonic.
2079  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
2080
2081  // Read the remaining operands.
2082  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2083    // Read the first operand.
2084    if (ParseOperand(Operands, Name)) {
2085      SMLoc Loc = getLexer().getLoc();
2086      Parser.eatToEndOfStatement();
2087      return Error(Loc, "unexpected token in argument list");
2088    }
2089
2090    while (getLexer().is(AsmToken::Comma)) {
2091      Parser.Lex(); // Eat the comma.
2092      // Parse and remember the operand.
2093      if (ParseOperand(Operands, Name)) {
2094        SMLoc Loc = getLexer().getLoc();
2095        Parser.eatToEndOfStatement();
2096        return Error(Loc, "unexpected token in argument list");
2097      }
2098    }
2099  }
2100  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2101    SMLoc Loc = getLexer().getLoc();
2102    Parser.eatToEndOfStatement();
2103    return Error(Loc, "unexpected token in argument list");
2104  }
2105  Parser.Lex(); // Consume the EndOfStatement.
2106  return false;
2107}
2108
2109bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2110  SMLoc Loc = getLexer().getLoc();
2111  Parser.eatToEndOfStatement();
2112  return Error(Loc, ErrorMsg);
2113}
2114
2115bool MipsAsmParser::parseSetNoAtDirective() {
2116  // Line should look like: ".set noat".
2117  // set at reg to 0.
2118  Options.setATReg(0);
2119  // eat noat
2120  Parser.Lex();
2121  // If this is not the end of the statement, report an error.
2122  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2123    reportParseError("unexpected token in statement");
2124    return false;
2125  }
2126  Parser.Lex(); // Consume the EndOfStatement.
2127  return false;
2128}
2129
2130bool MipsAsmParser::parseSetAtDirective() {
2131  // Line can be .set at - defaults to $1
2132  // or .set at=$reg
2133  int AtRegNo;
2134  getParser().Lex();
2135  if (getLexer().is(AsmToken::EndOfStatement)) {
2136    Options.setATReg(1);
2137    Parser.Lex(); // Consume the EndOfStatement.
2138    return false;
2139  } else if (getLexer().is(AsmToken::Equal)) {
2140    getParser().Lex(); // Eat the '='.
2141    if (getLexer().isNot(AsmToken::Dollar)) {
2142      reportParseError("unexpected token in statement");
2143      return false;
2144    }
2145    Parser.Lex(); // Eat the '$'.
2146    const AsmToken &Reg = Parser.getTok();
2147    if (Reg.is(AsmToken::Identifier)) {
2148      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2149    } else if (Reg.is(AsmToken::Integer)) {
2150      AtRegNo = Reg.getIntVal();
2151    } else {
2152      reportParseError("unexpected token in statement");
2153      return false;
2154    }
2155
2156    if (AtRegNo < 1 || AtRegNo > 31) {
2157      reportParseError("unexpected token in statement");
2158      return false;
2159    }
2160
2161    if (!Options.setATReg(AtRegNo)) {
2162      reportParseError("unexpected token in statement");
2163      return false;
2164    }
2165    getParser().Lex(); // Eat the register.
2166
2167    if (getLexer().isNot(AsmToken::EndOfStatement)) {
2168      reportParseError("unexpected token in statement");
2169      return false;
2170    }
2171    Parser.Lex(); // Consume the EndOfStatement.
2172    return false;
2173  } else {
2174    reportParseError("unexpected token in statement");
2175    return false;
2176  }
2177}
2178
2179bool MipsAsmParser::parseSetReorderDirective() {
2180  Parser.Lex();
2181  // If this is not the end of the statement, report an error.
2182  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2183    reportParseError("unexpected token in statement");
2184    return false;
2185  }
2186  Options.setReorder();
2187  Parser.Lex(); // Consume the EndOfStatement.
2188  return false;
2189}
2190
2191bool MipsAsmParser::parseSetNoReorderDirective() {
2192  Parser.Lex();
2193  // If this is not the end of the statement, report an error.
2194  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2195    reportParseError("unexpected token in statement");
2196    return false;
2197  }
2198  Options.setNoreorder();
2199  Parser.Lex(); // Consume the EndOfStatement.
2200  return false;
2201}
2202
2203bool MipsAsmParser::parseSetMacroDirective() {
2204  Parser.Lex();
2205  // If this is not the end of the statement, report an error.
2206  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2207    reportParseError("unexpected token in statement");
2208    return false;
2209  }
2210  Options.setMacro();
2211  Parser.Lex(); // Consume the EndOfStatement.
2212  return false;
2213}
2214
2215bool MipsAsmParser::parseSetNoMacroDirective() {
2216  Parser.Lex();
2217  // If this is not the end of the statement, report an error.
2218  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2219    reportParseError("`noreorder' must be set before `nomacro'");
2220    return false;
2221  }
2222  if (Options.isReorder()) {
2223    reportParseError("`noreorder' must be set before `nomacro'");
2224    return false;
2225  }
2226  Options.setNomacro();
2227  Parser.Lex(); // Consume the EndOfStatement.
2228  return false;
2229}
2230
2231bool MipsAsmParser::parseSetAssignment() {
2232  StringRef Name;
2233  const MCExpr *Value;
2234
2235  if (Parser.parseIdentifier(Name))
2236    reportParseError("expected identifier after .set");
2237
2238  if (getLexer().isNot(AsmToken::Comma))
2239    return reportParseError("unexpected token in .set directive");
2240  Lex(); // Eat comma
2241
2242  if (getLexer().is(AsmToken::Dollar)) {
2243    MCSymbol *Symbol;
2244    SMLoc DollarLoc = getLexer().getLoc();
2245    // Consume the dollar sign, and check for a following identifier.
2246    Parser.Lex();
2247    // We have a '$' followed by something, make sure they are adjacent.
2248    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2249      return true;
2250    StringRef Res =
2251        StringRef(DollarLoc.getPointer(),
2252                  getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2253    Symbol = getContext().GetOrCreateSymbol(Res);
2254    Parser.Lex();
2255    Value =
2256        MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, getContext());
2257  } else if (Parser.parseExpression(Value))
2258    return reportParseError("expected valid expression after comma");
2259
2260  // Check if the Name already exists as a symbol.
2261  MCSymbol *Sym = getContext().LookupSymbol(Name);
2262  if (Sym)
2263    return reportParseError("symbol already defined");
2264  Sym = getContext().GetOrCreateSymbol(Name);
2265  Sym->setVariableValue(Value);
2266
2267  return false;
2268}
2269
2270bool MipsAsmParser::parseDirectiveSet() {
2271
2272  // Get the next token.
2273  const AsmToken &Tok = Parser.getTok();
2274
2275  if (Tok.getString() == "noat") {
2276    return parseSetNoAtDirective();
2277  } else if (Tok.getString() == "at") {
2278    return parseSetAtDirective();
2279  } else if (Tok.getString() == "reorder") {
2280    return parseSetReorderDirective();
2281  } else if (Tok.getString() == "noreorder") {
2282    return parseSetNoReorderDirective();
2283  } else if (Tok.getString() == "macro") {
2284    return parseSetMacroDirective();
2285  } else if (Tok.getString() == "nomacro") {
2286    return parseSetNoMacroDirective();
2287  } else if (Tok.getString() == "nomips16") {
2288    // Ignore this directive for now.
2289    Parser.eatToEndOfStatement();
2290    return false;
2291  } else if (Tok.getString() == "nomicromips") {
2292    // Ignore this directive for now.
2293    Parser.eatToEndOfStatement();
2294    return false;
2295  } else {
2296    // It is just an identifier, look for an assignment.
2297    parseSetAssignment();
2298    return false;
2299  }
2300
2301  return true;
2302}
2303
2304bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2305  MCAsmParser &Parser = getParser();
2306  StringRef Name;
2307  if (Parser.parseIdentifier(Name))
2308    reportParseError("expected identifier");
2309
2310  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2311  if (getLexer().isNot(AsmToken::Comma))
2312    return TokError("unexpected token");
2313  Lex();
2314
2315  int64_t Flags = 0;
2316  if (Parser.parseAbsoluteExpression(Flags))
2317    return TokError("unexpected token");
2318
2319  getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
2320  return false;
2321}
2322
2323bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2324  int64_t Flags = 0;
2325  if (Parser.parseAbsoluteExpression(Flags))
2326    return TokError("unexpected token");
2327
2328  getTargetStreamer().emitMipsHackELFFlags(Flags);
2329  return false;
2330}
2331
2332/// parseDirectiveWord
2333///  ::= .word [ expression (, expression)* ]
2334bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2335  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2336    for (;;) {
2337      const MCExpr *Value;
2338      if (getParser().parseExpression(Value))
2339        return true;
2340
2341      getParser().getStreamer().EmitValue(Value, Size);
2342
2343      if (getLexer().is(AsmToken::EndOfStatement))
2344        break;
2345
2346      // FIXME: Improve diagnostic.
2347      if (getLexer().isNot(AsmToken::Comma))
2348        return Error(L, "unexpected token in directive");
2349      Parser.Lex();
2350    }
2351  }
2352
2353  Parser.Lex();
2354  return false;
2355}
2356
2357/// parseDirectiveGpWord
2358///  ::= .gpword local_sym
2359bool MipsAsmParser::parseDirectiveGpWord() {
2360  const MCExpr *Value;
2361  // EmitGPRel32Value requires an expression, so we are using base class
2362  // method to evaluate the expression.
2363  if (getParser().parseExpression(Value))
2364    return true;
2365
2366  getParser().getStreamer().EmitGPRel32Value(Value);
2367  Parser.Lex(); // Eat last token.
2368
2369  if (getLexer().is(AsmToken::EndOfStatement))
2370    return Error(getLexer().getLoc(), "unexpected token in directive");
2371
2372  return false;
2373}
2374
2375bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2376
2377  StringRef IDVal = DirectiveID.getString();
2378
2379  if (IDVal == ".ent") {
2380    // Ignore this directive for now.
2381    Parser.Lex();
2382    return false;
2383  }
2384
2385  if (IDVal == ".end") {
2386    // Ignore this directive for now.
2387    Parser.Lex();
2388    return false;
2389  }
2390
2391  if (IDVal == ".frame") {
2392    // Ignore this directive for now.
2393    Parser.eatToEndOfStatement();
2394    return false;
2395  }
2396
2397  if (IDVal == ".set") {
2398    return parseDirectiveSet();
2399  }
2400
2401  if (IDVal == ".fmask") {
2402    // Ignore this directive for now.
2403    Parser.eatToEndOfStatement();
2404    return false;
2405  }
2406
2407  if (IDVal == ".mask") {
2408    // Ignore this directive for now.
2409    Parser.eatToEndOfStatement();
2410    return false;
2411  }
2412
2413  if (IDVal == ".gpword") {
2414    // Ignore this directive for now.
2415    parseDirectiveGpWord();
2416    return false;
2417  }
2418
2419  if (IDVal == ".word") {
2420    parseDirectiveWord(4, DirectiveID.getLoc());
2421    return false;
2422  }
2423
2424  if (IDVal == ".mips_hack_stocg")
2425    return parseDirectiveMipsHackStocg();
2426
2427  if (IDVal == ".mips_hack_elf_flags")
2428    return parseDirectiveMipsHackELFFlags();
2429
2430  return true;
2431}
2432
2433extern "C" void LLVMInitializeMipsAsmParser() {
2434  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2435  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2436  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2437  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2438}
2439
2440#define GET_REGISTER_MATCHER
2441#define GET_MATCHER_IMPLEMENTATION
2442#include "MipsGenAsmMatcher.inc"
2443