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