MipsAsmParser.cpp revision 94ce6dadd131ca80adf2ba05391f689684540601
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    if ((Kind == MipsOperand::Kind_CPURegs)
1272      && (getLexer().is(AsmToken::LParen))) {
1273      // Check if it is indexed addressing operand.
1274      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1275      Parser.Lex(); // Eat the parenthesis.
1276      if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1277        return MatchOperand_NoMatch;
1278      if (getLexer().isNot(AsmToken::RParen))
1279        return MatchOperand_NoMatch;
1280      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1281      Parser.Lex();
1282    }
1283    return MatchOperand_Success;
1284  }
1285  return MatchOperand_NoMatch;
1286}
1287
1288MipsAsmParser::OperandMatchResultTy
1289MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1290
1291  if (!isMips64())
1292    return MatchOperand_NoMatch;
1293  return parseRegs(Operands, (int) MipsOperand::Kind_CPU64Regs);
1294}
1295
1296MipsAsmParser::OperandMatchResultTy
1297MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1298 return parseRegs(Operands, (int) MipsOperand::Kind_CPURegs);
1299}
1300
1301MipsAsmParser::OperandMatchResultTy
1302MipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1303
1304  if (isFP64())
1305    return MatchOperand_NoMatch;
1306  // Double operand is expected, set appropriate format
1307  setFpFormat(FP_FORMAT_D);
1308
1309  return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
1310}
1311
1312MipsAsmParser::OperandMatchResultTy
1313MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1314  if (!isFP64())
1315    return MatchOperand_NoMatch;
1316  // Double operand is expected, set appropriate format
1317  setFpFormat(FP_FORMAT_D);
1318
1319 return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
1320}
1321
1322MipsAsmParser::OperandMatchResultTy
1323MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1324 // Single operand is expected, set appropriate format
1325  setFpFormat(FP_FORMAT_S);
1326  return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
1327}
1328
1329bool MipsAsmParser::searchSymbolAlias(
1330    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1331
1332  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1333  if (Sym) {
1334    SMLoc S = Parser.getTok().getLoc();
1335    const MCExpr *Expr;
1336    if (Sym->isVariable())
1337      Expr = Sym->getVariableValue();
1338    else
1339      return false;
1340    if (Expr->getKind() == MCExpr::SymbolRef) {
1341      MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1342      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1343      const StringRef DefSymbol = Ref->getSymbol().getName();
1344      if (DefSymbol.startswith("$")) {
1345        int RegNum = -1;
1346        APInt IntVal(32, -1);
1347        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1348          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1349                                     isMips64()
1350                                       ? Mips::CPU64RegsRegClassID
1351                                       : Mips::CPURegsRegClassID);
1352        else {
1353          // Lookup for the register with the corresponding name.
1354          switch (Kind) {
1355          case MipsOperand::Kind_AFGR64Regs:
1356          case MipsOperand::Kind_FGR64Regs:
1357            RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D);
1358            break;
1359          case MipsOperand::Kind_FGR32Regs:
1360            RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S);
1361            break;
1362          case MipsOperand::Kind_CPU64Regs:
1363          case MipsOperand::Kind_CPURegs:
1364          default:
1365            RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
1366            break;
1367          }
1368        }
1369        if (RegNum > -1) {
1370          Parser.Lex();
1371          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1372                                                   Parser.getTok().getLoc());
1373          op->setRegKind(Kind);
1374          Operands.push_back(op);
1375          return true;
1376        }
1377      }
1378    } else if (Expr->getKind() == MCExpr::Constant) {
1379      Parser.Lex();
1380      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1381      MipsOperand *op = MipsOperand::CreateImm(Const, S,
1382          Parser.getTok().getLoc());
1383      Operands.push_back(op);
1384      return true;
1385    }
1386  }
1387  return false;
1388}
1389
1390MipsAsmParser::OperandMatchResultTy
1391MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1392
1393  if (isMips64())
1394    return MatchOperand_NoMatch;
1395
1396  // If the first token is not '$' we have error.
1397  if (Parser.getTok().isNot(AsmToken::Dollar))
1398    return MatchOperand_NoMatch;
1399  SMLoc S = Parser.getTok().getLoc();
1400  Parser.Lex(); // Eat the '$'.
1401
1402  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1403  if (Tok.isNot(AsmToken::Integer))
1404    return MatchOperand_NoMatch;
1405
1406  unsigned RegNum = Tok.getIntVal();
1407  // At the moment only hwreg29 is supported.
1408  if (RegNum != 29)
1409    return MatchOperand_ParseFail;
1410
1411  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1412      Parser.getTok().getLoc());
1413  op->setRegKind(MipsOperand::Kind_HWRegs);
1414  Operands.push_back(op);
1415
1416  Parser.Lex(); // Eat the register number.
1417  return MatchOperand_Success;
1418}
1419
1420MipsAsmParser::OperandMatchResultTy
1421MipsAsmParser::parseHW64Regs(
1422    SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1423
1424  if (!isMips64())
1425    return MatchOperand_NoMatch;
1426  // If the first token is not '$' we have an error.
1427  if (Parser.getTok().isNot(AsmToken::Dollar))
1428    return MatchOperand_NoMatch;
1429  SMLoc S = Parser.getTok().getLoc();
1430  Parser.Lex(); // Eat $
1431
1432  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1433  if (Tok.isNot(AsmToken::Integer))
1434    return MatchOperand_NoMatch;
1435
1436  unsigned RegNum = Tok.getIntVal();
1437  // At the moment only hwreg29 is supported.
1438  if (RegNum != 29)
1439    return MatchOperand_ParseFail;
1440
1441  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1442                                           Parser.getTok().getLoc());
1443  op->setRegKind(MipsOperand::Kind_HW64Regs);
1444  Operands.push_back(op);
1445
1446  Parser.Lex(); // Eat the register number.
1447  return MatchOperand_Success;
1448}
1449
1450MipsAsmParser::OperandMatchResultTy
1451MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1452  // If the first token is not '$' we have an error.
1453  if (Parser.getTok().isNot(AsmToken::Dollar))
1454    return MatchOperand_NoMatch;
1455
1456  SMLoc S = Parser.getTok().getLoc();
1457  Parser.Lex(); // Eat the '$'
1458
1459  const AsmToken &Tok = Parser.getTok(); // Get next token.
1460
1461  if (Tok.isNot(AsmToken::Integer))
1462    return MatchOperand_NoMatch;
1463
1464  unsigned Reg = matchRegisterByNumber(Tok.getIntVal(), Mips::CCRRegClassID);
1465
1466  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1467  Op->setRegKind(MipsOperand::Kind_CCRRegs);
1468  Operands.push_back(Op);
1469
1470  Parser.Lex(); // Eat the register number.
1471  return MatchOperand_Success;
1472}
1473
1474MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1475
1476  MCSymbolRefExpr::VariantKind VK
1477                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1478    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1479    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1480    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1481    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1482    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1483    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1484    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1485    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1486    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1487    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1488    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1489    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1490    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1491    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1492    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1493    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1494    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1495    .Default(MCSymbolRefExpr::VK_None);
1496
1497  return VK;
1498}
1499
1500bool MipsAsmParser::
1501ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1502                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1503  // Check if we have valid mnemonic
1504  if (!mnemonicIsValid(Name, 0)) {
1505    Parser.eatToEndOfStatement();
1506    return Error(NameLoc, "Unknown instruction");
1507  }
1508  // First operand in MCInst is instruction mnemonic.
1509  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1510
1511  // Read the remaining operands.
1512  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1513    // Read the first operand.
1514    if (ParseOperand(Operands, Name)) {
1515      SMLoc Loc = getLexer().getLoc();
1516      Parser.eatToEndOfStatement();
1517      return Error(Loc, "unexpected token in argument list");
1518    }
1519
1520    while (getLexer().is(AsmToken::Comma)) {
1521      Parser.Lex(); // Eat the comma.
1522      // Parse and remember the operand.
1523      if (ParseOperand(Operands, Name)) {
1524        SMLoc Loc = getLexer().getLoc();
1525        Parser.eatToEndOfStatement();
1526        return Error(Loc, "unexpected token in argument list");
1527      }
1528    }
1529  }
1530  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1531    SMLoc Loc = getLexer().getLoc();
1532    Parser.eatToEndOfStatement();
1533    return Error(Loc, "unexpected token in argument list");
1534  }
1535  Parser.Lex(); // Consume the EndOfStatement.
1536  return false;
1537}
1538
1539bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1540  SMLoc Loc = getLexer().getLoc();
1541  Parser.eatToEndOfStatement();
1542  return Error(Loc, ErrorMsg);
1543}
1544
1545bool MipsAsmParser::parseSetNoAtDirective() {
1546  // Line should look like: ".set noat".
1547  // set at reg to 0.
1548  Options.setATReg(0);
1549  // eat noat
1550  Parser.Lex();
1551  // If this is not the end of the statement, report an error.
1552  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1553    reportParseError("unexpected token in statement");
1554    return false;
1555  }
1556  Parser.Lex(); // Consume the EndOfStatement.
1557  return false;
1558}
1559
1560bool MipsAsmParser::parseSetAtDirective() {
1561  // Line can be .set at - defaults to $1
1562  // or .set at=$reg
1563  int AtRegNo;
1564  getParser().Lex();
1565  if (getLexer().is(AsmToken::EndOfStatement)) {
1566    Options.setATReg(1);
1567    Parser.Lex(); // Consume the EndOfStatement.
1568    return false;
1569  } else if (getLexer().is(AsmToken::Equal)) {
1570    getParser().Lex(); // Eat the '='.
1571    if (getLexer().isNot(AsmToken::Dollar)) {
1572      reportParseError("unexpected token in statement");
1573      return false;
1574    }
1575    Parser.Lex(); // Eat the '$'.
1576    const AsmToken &Reg = Parser.getTok();
1577    if (Reg.is(AsmToken::Identifier)) {
1578      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1579    } else if (Reg.is(AsmToken::Integer)) {
1580      AtRegNo = Reg.getIntVal();
1581    } else {
1582      reportParseError("unexpected token in statement");
1583      return false;
1584    }
1585
1586    if (AtRegNo < 1 || AtRegNo > 31) {
1587      reportParseError("unexpected token in statement");
1588      return false;
1589    }
1590
1591    if (!Options.setATReg(AtRegNo)) {
1592      reportParseError("unexpected token in statement");
1593      return false;
1594    }
1595    getParser().Lex(); // Eat the register.
1596
1597    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1598      reportParseError("unexpected token in statement");
1599      return false;
1600    }
1601    Parser.Lex(); // Consume the EndOfStatement.
1602    return false;
1603  } else {
1604    reportParseError("unexpected token in statement");
1605    return false;
1606  }
1607}
1608
1609bool MipsAsmParser::parseSetReorderDirective() {
1610  Parser.Lex();
1611  // If this is not the end of the statement, report an error.
1612  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1613    reportParseError("unexpected token in statement");
1614    return false;
1615  }
1616  Options.setReorder();
1617  Parser.Lex(); // Consume the EndOfStatement.
1618  return false;
1619}
1620
1621bool MipsAsmParser::parseSetNoReorderDirective() {
1622  Parser.Lex();
1623  // If this is not the end of the statement, report an error.
1624  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1625    reportParseError("unexpected token in statement");
1626    return false;
1627  }
1628  Options.setNoreorder();
1629  Parser.Lex(); // Consume the EndOfStatement.
1630  return false;
1631}
1632
1633bool MipsAsmParser::parseSetMacroDirective() {
1634  Parser.Lex();
1635  // If this is not the end of the statement, report an error.
1636  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1637    reportParseError("unexpected token in statement");
1638    return false;
1639  }
1640  Options.setMacro();
1641  Parser.Lex(); // Consume the EndOfStatement.
1642  return false;
1643}
1644
1645bool MipsAsmParser::parseSetNoMacroDirective() {
1646  Parser.Lex();
1647  // If this is not the end of the statement, report an error.
1648  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1649    reportParseError("`noreorder' must be set before `nomacro'");
1650    return false;
1651  }
1652  if (Options.isReorder()) {
1653    reportParseError("`noreorder' must be set before `nomacro'");
1654    return false;
1655  }
1656  Options.setNomacro();
1657  Parser.Lex(); // Consume the EndOfStatement.
1658  return false;
1659}
1660
1661bool MipsAsmParser::parseSetAssignment() {
1662  StringRef Name;
1663  const MCExpr *Value;
1664
1665  if (Parser.parseIdentifier(Name))
1666    reportParseError("expected identifier after .set");
1667
1668  if (getLexer().isNot(AsmToken::Comma))
1669    return reportParseError("unexpected token in .set directive");
1670  Lex(); // Eat comma
1671
1672  if (getLexer().is(AsmToken::Dollar)) {
1673    MCSymbol *Symbol;
1674    SMLoc DollarLoc = getLexer().getLoc();
1675    // Consume the dollar sign, and check for a following identifier.
1676    Parser.Lex();
1677    // We have a '$' followed by something, make sure they are adjacent.
1678    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1679      return true;
1680    StringRef Res = StringRef(DollarLoc.getPointer(),
1681        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1682    Symbol = getContext().GetOrCreateSymbol(Res);
1683    Parser.Lex();
1684    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1685                                    getContext());
1686  } else if (Parser.parseExpression(Value))
1687    return reportParseError("expected valid expression after comma");
1688
1689  // Check if the Name already exists as a symbol.
1690  MCSymbol *Sym = getContext().LookupSymbol(Name);
1691  if (Sym)
1692    return reportParseError("symbol already defined");
1693  Sym = getContext().GetOrCreateSymbol(Name);
1694  Sym->setVariableValue(Value);
1695
1696  return false;
1697}
1698
1699bool MipsAsmParser::parseDirectiveSet() {
1700
1701  // Get the next token.
1702  const AsmToken &Tok = Parser.getTok();
1703
1704  if (Tok.getString() == "noat") {
1705    return parseSetNoAtDirective();
1706  } else if (Tok.getString() == "at") {
1707    return parseSetAtDirective();
1708  } else if (Tok.getString() == "reorder") {
1709    return parseSetReorderDirective();
1710  } else if (Tok.getString() == "noreorder") {
1711    return parseSetNoReorderDirective();
1712  } else if (Tok.getString() == "macro") {
1713    return parseSetMacroDirective();
1714  } else if (Tok.getString() == "nomacro") {
1715    return parseSetNoMacroDirective();
1716  } else if (Tok.getString() == "nomips16") {
1717    // Ignore this directive for now.
1718    Parser.eatToEndOfStatement();
1719    return false;
1720  } else if (Tok.getString() == "nomicromips") {
1721    // Ignore this directive for now.
1722    Parser.eatToEndOfStatement();
1723    return false;
1724  } else {
1725    // It is just an identifier, look for an assignment.
1726    parseSetAssignment();
1727    return false;
1728  }
1729
1730  return true;
1731}
1732
1733/// parseDirectiveWord
1734///  ::= .word [ expression (, expression)* ]
1735bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1736  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1737    for (;;) {
1738      const MCExpr *Value;
1739      if (getParser().parseExpression(Value))
1740        return true;
1741
1742      getParser().getStreamer().EmitValue(Value, Size);
1743
1744      if (getLexer().is(AsmToken::EndOfStatement))
1745        break;
1746
1747      // FIXME: Improve diagnostic.
1748      if (getLexer().isNot(AsmToken::Comma))
1749        return Error(L, "unexpected token in directive");
1750      Parser.Lex();
1751    }
1752  }
1753
1754  Parser.Lex();
1755  return false;
1756}
1757
1758bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1759
1760  StringRef IDVal = DirectiveID.getString();
1761
1762  if (IDVal == ".ent") {
1763    // Ignore this directive for now.
1764    Parser.Lex();
1765    return false;
1766  }
1767
1768  if (IDVal == ".end") {
1769    // Ignore this directive for now.
1770    Parser.Lex();
1771    return false;
1772  }
1773
1774  if (IDVal == ".frame") {
1775    // Ignore this directive for now.
1776    Parser.eatToEndOfStatement();
1777    return false;
1778  }
1779
1780  if (IDVal == ".set") {
1781    return parseDirectiveSet();
1782  }
1783
1784  if (IDVal == ".fmask") {
1785    // Ignore this directive for now.
1786    Parser.eatToEndOfStatement();
1787    return false;
1788  }
1789
1790  if (IDVal == ".mask") {
1791    // Ignore this directive for now.
1792    Parser.eatToEndOfStatement();
1793    return false;
1794  }
1795
1796  if (IDVal == ".gpword") {
1797    // Ignore this directive for now.
1798    Parser.eatToEndOfStatement();
1799    return false;
1800  }
1801
1802  if (IDVal == ".word") {
1803    parseDirectiveWord(4, DirectiveID.getLoc());
1804    return false;
1805  }
1806
1807  return true;
1808}
1809
1810extern "C" void LLVMInitializeMipsAsmParser() {
1811  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1812  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1813  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1814  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1815}
1816
1817#define GET_REGISTER_MATCHER
1818#define GET_MATCHER_IMPLEMENTATION
1819#include "MipsGenAsmMatcher.inc"
1820