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