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