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