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