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