MipsAsmParser.cpp revision 764f6f51257a0669acc58c8e5b4b802a29069302
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  unsigned RegNum;
1453  // If the first token is not '$' we have an error.
1454  if (Parser.getTok().isNot(AsmToken::Dollar))
1455    return MatchOperand_NoMatch;
1456  SMLoc S = Parser.getTok().getLoc();
1457  Parser.Lex(); // Eat the '$'
1458
1459  const AsmToken &Tok = Parser.getTok(); // Get next token.
1460  if (Tok.is(AsmToken::Integer)) {
1461    RegNum = Tok.getIntVal();
1462    // At the moment only fcc0 is supported.
1463    if (RegNum != 0)
1464      return MatchOperand_ParseFail;
1465  } else if (Tok.is(AsmToken::Identifier)) {
1466    // At the moment only fcc0 is supported.
1467    if (Tok.getIdentifier() != "fcc0")
1468      return MatchOperand_ParseFail;
1469  } else
1470    return MatchOperand_NoMatch;
1471
1472  MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1473                                           Parser.getTok().getLoc());
1474  op->setRegKind(MipsOperand::Kind_CCRRegs);
1475  Operands.push_back(op);
1476
1477  Parser.Lex(); // Eat the register number.
1478  return MatchOperand_Success;
1479}
1480
1481MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1482
1483  MCSymbolRefExpr::VariantKind VK
1484                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1485    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1486    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1487    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1488    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1489    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1490    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1491    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1492    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1493    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1494    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1495    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1496    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1497    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1498    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1499    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1500    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1501    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1502    .Default(MCSymbolRefExpr::VK_None);
1503
1504  return VK;
1505}
1506
1507bool MipsAsmParser::
1508ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1509                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1510  // Check if we have valid mnemonic
1511  if (!mnemonicIsValid(Name)) {
1512    Parser.eatToEndOfStatement();
1513    return Error(NameLoc, "Unknown instruction");
1514  }
1515  // First operand in MCInst is instruction mnemonic.
1516  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1517
1518  // Read the remaining operands.
1519  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1520    // Read the first operand.
1521    if (ParseOperand(Operands, Name)) {
1522      SMLoc Loc = getLexer().getLoc();
1523      Parser.eatToEndOfStatement();
1524      return Error(Loc, "unexpected token in argument list");
1525    }
1526
1527    while (getLexer().is(AsmToken::Comma)) {
1528      Parser.Lex(); // Eat the comma.
1529      // Parse and remember the operand.
1530      if (ParseOperand(Operands, Name)) {
1531        SMLoc Loc = getLexer().getLoc();
1532        Parser.eatToEndOfStatement();
1533        return Error(Loc, "unexpected token in argument list");
1534      }
1535    }
1536  }
1537  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1538    SMLoc Loc = getLexer().getLoc();
1539    Parser.eatToEndOfStatement();
1540    return Error(Loc, "unexpected token in argument list");
1541  }
1542  Parser.Lex(); // Consume the EndOfStatement.
1543  return false;
1544}
1545
1546bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1547  SMLoc Loc = getLexer().getLoc();
1548  Parser.eatToEndOfStatement();
1549  return Error(Loc, ErrorMsg);
1550}
1551
1552bool MipsAsmParser::parseSetNoAtDirective() {
1553  // Line should look like: ".set noat".
1554  // set at reg to 0.
1555  Options.setATReg(0);
1556  // eat noat
1557  Parser.Lex();
1558  // If this is not the end of the statement, report an error.
1559  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1560    reportParseError("unexpected token in statement");
1561    return false;
1562  }
1563  Parser.Lex(); // Consume the EndOfStatement.
1564  return false;
1565}
1566
1567bool MipsAsmParser::parseSetAtDirective() {
1568  // Line can be .set at - defaults to $1
1569  // or .set at=$reg
1570  int AtRegNo;
1571  getParser().Lex();
1572  if (getLexer().is(AsmToken::EndOfStatement)) {
1573    Options.setATReg(1);
1574    Parser.Lex(); // Consume the EndOfStatement.
1575    return false;
1576  } else if (getLexer().is(AsmToken::Equal)) {
1577    getParser().Lex(); // Eat the '='.
1578    if (getLexer().isNot(AsmToken::Dollar)) {
1579      reportParseError("unexpected token in statement");
1580      return false;
1581    }
1582    Parser.Lex(); // Eat the '$'.
1583    const AsmToken &Reg = Parser.getTok();
1584    if (Reg.is(AsmToken::Identifier)) {
1585      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1586    } else if (Reg.is(AsmToken::Integer)) {
1587      AtRegNo = Reg.getIntVal();
1588    } else {
1589      reportParseError("unexpected token in statement");
1590      return false;
1591    }
1592
1593    if (AtRegNo < 1 || AtRegNo > 31) {
1594      reportParseError("unexpected token in statement");
1595      return false;
1596    }
1597
1598    if (!Options.setATReg(AtRegNo)) {
1599      reportParseError("unexpected token in statement");
1600      return false;
1601    }
1602    getParser().Lex(); // Eat the register.
1603
1604    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1605      reportParseError("unexpected token in statement");
1606      return false;
1607    }
1608    Parser.Lex(); // Consume the EndOfStatement.
1609    return false;
1610  } else {
1611    reportParseError("unexpected token in statement");
1612    return false;
1613  }
1614}
1615
1616bool MipsAsmParser::parseSetReorderDirective() {
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.setReorder();
1624  Parser.Lex(); // Consume the EndOfStatement.
1625  return false;
1626}
1627
1628bool MipsAsmParser::parseSetNoReorderDirective() {
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.setNoreorder();
1636  Parser.Lex(); // Consume the EndOfStatement.
1637  return false;
1638}
1639
1640bool MipsAsmParser::parseSetMacroDirective() {
1641  Parser.Lex();
1642  // If this is not the end of the statement, report an error.
1643  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1644    reportParseError("unexpected token in statement");
1645    return false;
1646  }
1647  Options.setMacro();
1648  Parser.Lex(); // Consume the EndOfStatement.
1649  return false;
1650}
1651
1652bool MipsAsmParser::parseSetNoMacroDirective() {
1653  Parser.Lex();
1654  // If this is not the end of the statement, report an error.
1655  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1656    reportParseError("`noreorder' must be set before `nomacro'");
1657    return false;
1658  }
1659  if (Options.isReorder()) {
1660    reportParseError("`noreorder' must be set before `nomacro'");
1661    return false;
1662  }
1663  Options.setNomacro();
1664  Parser.Lex(); // Consume the EndOfStatement.
1665  return false;
1666}
1667
1668bool MipsAsmParser::parseSetAssignment() {
1669  StringRef Name;
1670  const MCExpr *Value;
1671
1672  if (Parser.parseIdentifier(Name))
1673    reportParseError("expected identifier after .set");
1674
1675  if (getLexer().isNot(AsmToken::Comma))
1676    return reportParseError("unexpected token in .set directive");
1677  Lex(); // Eat comma
1678
1679  if (getLexer().is(AsmToken::Dollar)) {
1680    MCSymbol *Symbol;
1681    SMLoc DollarLoc = getLexer().getLoc();
1682    // Consume the dollar sign, and check for a following identifier.
1683    Parser.Lex();
1684    // We have a '$' followed by something, make sure they are adjacent.
1685    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1686      return true;
1687    StringRef Res = StringRef(DollarLoc.getPointer(),
1688        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1689    Symbol = getContext().GetOrCreateSymbol(Res);
1690    Parser.Lex();
1691    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1692                                    getContext());
1693  } else if (Parser.parseExpression(Value))
1694    return reportParseError("expected valid expression after comma");
1695
1696  // Check if the Name already exists as a symbol.
1697  MCSymbol *Sym = getContext().LookupSymbol(Name);
1698  if (Sym)
1699    return reportParseError("symbol already defined");
1700  Sym = getContext().GetOrCreateSymbol(Name);
1701  Sym->setVariableValue(Value);
1702
1703  return false;
1704}
1705
1706bool MipsAsmParser::parseDirectiveSet() {
1707
1708  // Get the next token.
1709  const AsmToken &Tok = Parser.getTok();
1710
1711  if (Tok.getString() == "noat") {
1712    return parseSetNoAtDirective();
1713  } else if (Tok.getString() == "at") {
1714    return parseSetAtDirective();
1715  } else if (Tok.getString() == "reorder") {
1716    return parseSetReorderDirective();
1717  } else if (Tok.getString() == "noreorder") {
1718    return parseSetNoReorderDirective();
1719  } else if (Tok.getString() == "macro") {
1720    return parseSetMacroDirective();
1721  } else if (Tok.getString() == "nomacro") {
1722    return parseSetNoMacroDirective();
1723  } else if (Tok.getString() == "nomips16") {
1724    // Ignore this directive for now.
1725    Parser.eatToEndOfStatement();
1726    return false;
1727  } else if (Tok.getString() == "nomicromips") {
1728    // Ignore this directive for now.
1729    Parser.eatToEndOfStatement();
1730    return false;
1731  } else {
1732    // It is just an identifier, look for an assignment.
1733    parseSetAssignment();
1734    return false;
1735  }
1736
1737  return true;
1738}
1739
1740/// parseDirectiveWord
1741///  ::= .word [ expression (, expression)* ]
1742bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1743  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1744    for (;;) {
1745      const MCExpr *Value;
1746      if (getParser().parseExpression(Value))
1747        return true;
1748
1749      getParser().getStreamer().EmitValue(Value, Size);
1750
1751      if (getLexer().is(AsmToken::EndOfStatement))
1752        break;
1753
1754      // FIXME: Improve diagnostic.
1755      if (getLexer().isNot(AsmToken::Comma))
1756        return Error(L, "unexpected token in directive");
1757      Parser.Lex();
1758    }
1759  }
1760
1761  Parser.Lex();
1762  return false;
1763}
1764
1765bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1766
1767  StringRef IDVal = DirectiveID.getString();
1768
1769  if (IDVal == ".ent") {
1770    // Ignore this directive for now.
1771    Parser.Lex();
1772    return false;
1773  }
1774
1775  if (IDVal == ".end") {
1776    // Ignore this directive for now.
1777    Parser.Lex();
1778    return false;
1779  }
1780
1781  if (IDVal == ".frame") {
1782    // Ignore this directive for now.
1783    Parser.eatToEndOfStatement();
1784    return false;
1785  }
1786
1787  if (IDVal == ".set") {
1788    return parseDirectiveSet();
1789  }
1790
1791  if (IDVal == ".fmask") {
1792    // Ignore this directive for now.
1793    Parser.eatToEndOfStatement();
1794    return false;
1795  }
1796
1797  if (IDVal == ".mask") {
1798    // Ignore this directive for now.
1799    Parser.eatToEndOfStatement();
1800    return false;
1801  }
1802
1803  if (IDVal == ".gpword") {
1804    // Ignore this directive for now.
1805    Parser.eatToEndOfStatement();
1806    return false;
1807  }
1808
1809  if (IDVal == ".word") {
1810    parseDirectiveWord(4, DirectiveID.getLoc());
1811    return false;
1812  }
1813
1814  return true;
1815}
1816
1817extern "C" void LLVMInitializeMipsAsmParser() {
1818  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1819  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1820  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1821  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1822}
1823
1824#define GET_REGISTER_MATCHER
1825#define GET_MATCHER_IMPLEMENTATION
1826#include "MipsGenAsmMatcher.inc"
1827