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