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