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