This patch that enables the Mips assembler to use symbols for offset for instructions
[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   int CC;
782   CC = matchCPURegisterName(Name);
783   if (CC != -1)
784     return matchRegisterByNumber(CC,is64BitReg?Mips::CPU64RegsRegClassID:
785                                Mips::CPURegsRegClassID);
786
787   if (Name[0] == 'f') {
788     StringRef NumString = Name.substr(1);
789     unsigned IntVal;
790     if( NumString.getAsInteger(10, IntVal))
791       return -1; // not integer
792     if (IntVal > 31)
793       return -1;
794
795     FpFormatTy Format = getFpFormat();
796
797     if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
798       return getReg(Mips::FGR32RegClassID, IntVal);
799     if (Format == FP_FORMAT_D) {
800       if(isFP64()) {
801         return getReg(Mips::FGR64RegClassID, IntVal);
802       }
803       // only even numbers available as register pairs
804       if (( IntVal > 31) || (IntVal%2 !=  0))
805         return -1;
806       return getReg(Mips::AFGR64RegClassID, IntVal/2);
807     }
808   }
809
810   return -1;
811 }
812 void MipsAsmParser::setDefaultFpFormat() {
813
814   if (isMips64() || isFP64())
815     FpFormat = FP_FORMAT_D;
816   else
817     FpFormat = FP_FORMAT_S;
818 }
819
820 bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
821
822   bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
823     .Case("ldxc1", true)
824     .Case("ldc1",  true)
825     .Case("sdxc1", true)
826     .Case("sdc1",  true)
827     .Default(false);
828
829   return IsDouble;
830 }
831 void MipsAsmParser::setFpFormat(StringRef Format) {
832
833   FpFormat = StringSwitch<FpFormatTy>(Format.lower())
834     .Case(".s",  FP_FORMAT_S)
835     .Case(".d",  FP_FORMAT_D)
836     .Case(".l",  FP_FORMAT_L)
837     .Case(".w",  FP_FORMAT_W)
838     .Default(FP_FORMAT_NONE);
839 }
840
841 bool MipsAssemblerOptions::setATReg(unsigned Reg) {
842   if (Reg > 31)
843     return false;
844
845   aTReg = Reg;
846   return true;
847 }
848
849 int MipsAsmParser::getATReg() {
850   return Options.getATRegNum();
851 }
852
853 unsigned MipsAsmParser::getReg(int RC,int RegNo) {
854   return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
855 }
856
857 int MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
858
859   if (RegNum > 31)
860     return -1;
861
862   return getReg(RegClass, RegNum);
863 }
864
865 int MipsAsmParser::tryParseRegister(bool is64BitReg) {
866   const AsmToken &Tok = Parser.getTok();
867   int RegNum = -1;
868
869   if (Tok.is(AsmToken::Identifier)) {
870     std::string lowerCase = Tok.getString().lower();
871     RegNum = matchRegisterName(lowerCase, is64BitReg);
872   } else if (Tok.is(AsmToken::Integer))
873     RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
874                                    is64BitReg ? Mips::CPU64RegsRegClassID
875                                               : Mips::CPURegsRegClassID);
876   return RegNum;
877 }
878
879 bool MipsAsmParser::
880   tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
881                           bool is64BitReg){
882
883   SMLoc S = Parser.getTok().getLoc();
884   int RegNo = -1;
885
886   RegNo = tryParseRegister(is64BitReg);
887   if (RegNo == -1)
888     return true;
889
890   Operands.push_back(MipsOperand::CreateReg(RegNo, S,
891       Parser.getTok().getLoc()));
892   Parser.Lex(); // Eat register token.
893   return false;
894 }
895
896 bool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
897                                  StringRef Mnemonic) {
898   // Check if the current operand has a custom associated parser, if so, try to
899   // custom parse the operand, or fallback to the general approach.
900   OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
901   if (ResTy == MatchOperand_Success)
902     return false;
903   // If there wasn't a custom match, try the generic matcher below. Otherwise,
904   // there was a match, but an error occurred, in which case, just return that
905   // the operand parsing failed.
906   if (ResTy == MatchOperand_ParseFail)
907     return true;
908
909   switch (getLexer().getKind()) {
910   default:
911     Error(Parser.getTok().getLoc(), "unexpected token in operand");
912     return true;
913   case AsmToken::Dollar: {
914     // parse register
915     SMLoc S = Parser.getTok().getLoc();
916     Parser.Lex(); // Eat dollar token.
917     // parse register operand
918     if (!tryParseRegisterOperand(Operands, isMips64())) {
919       if (getLexer().is(AsmToken::LParen)) {
920         // check if it is indexed addressing operand
921         Operands.push_back(MipsOperand::CreateToken("(", S));
922         Parser.Lex(); // eat parenthesis
923         if (getLexer().isNot(AsmToken::Dollar))
924           return true;
925
926         Parser.Lex(); // eat dollar
927         if (tryParseRegisterOperand(Operands, isMips64()))
928           return true;
929
930         if (!getLexer().is(AsmToken::RParen))
931           return true;
932
933         S = Parser.getTok().getLoc();
934         Operands.push_back(MipsOperand::CreateToken(")", S));
935         Parser.Lex();
936       }
937       return false;
938     }
939     // maybe it is a symbol reference
940     StringRef Identifier;
941     if (Parser.parseIdentifier(Identifier))
942       return true;
943
944     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
945
946     MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
947
948     // Otherwise create a symbol ref.
949     const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
950                                                 getContext());
951
952     Operands.push_back(MipsOperand::CreateImm(Res, S, E));
953     return false;
954   }
955   case AsmToken::Identifier:
956     // Look for the existing symbol, we should check if
957     // we need to assigne the propper RegisterKind
958    if (searchSymbolAlias(Operands,MipsOperand::Kind_None))
959      return false;
960     //else drop to expression parsing
961   case AsmToken::LParen:
962   case AsmToken::Minus:
963   case AsmToken::Plus:
964   case AsmToken::Integer:
965   case AsmToken::String: {
966      // quoted label names
967     const MCExpr *IdVal;
968     SMLoc S = Parser.getTok().getLoc();
969     if (getParser().parseExpression(IdVal))
970       return true;
971     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
972     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
973     return false;
974   }
975   case AsmToken::Percent: {
976     // it is a symbol reference or constant expression
977     const MCExpr *IdVal;
978     SMLoc S = Parser.getTok().getLoc(); // start location of the operand
979     if (parseRelocOperand(IdVal))
980       return true;
981
982     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
983
984     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
985     return false;
986   } // case AsmToken::Percent
987   } // switch(getLexer().getKind())
988   return true;
989 }
990
991 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
992
993   Parser.Lex(); // eat % token
994   const AsmToken &Tok = Parser.getTok(); // get next token, operation
995   if (Tok.isNot(AsmToken::Identifier))
996     return true;
997
998   std::string Str = Tok.getIdentifier().str();
999
1000   Parser.Lex(); // eat identifier
1001   // now make expression from the rest of the operand
1002   const MCExpr *IdVal;
1003   SMLoc EndLoc;
1004
1005   if (getLexer().getKind() == AsmToken::LParen) {
1006     while (1) {
1007       Parser.Lex(); // eat '(' token
1008       if (getLexer().getKind() == AsmToken::Percent) {
1009         Parser.Lex(); // eat % token
1010         const AsmToken &nextTok = Parser.getTok();
1011         if (nextTok.isNot(AsmToken::Identifier))
1012           return true;
1013         Str += "(%";
1014         Str += nextTok.getIdentifier();
1015         Parser.Lex(); // eat identifier
1016         if (getLexer().getKind() != AsmToken::LParen)
1017           return true;
1018       } else
1019         break;
1020     }
1021     if (getParser().parseParenExpression(IdVal,EndLoc))
1022       return true;
1023
1024     while (getLexer().getKind() == AsmToken::RParen)
1025       Parser.Lex(); // eat ')' token
1026
1027   } else
1028     return true; // parenthesis must follow reloc operand
1029
1030   // Check the type of the expression
1031   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
1032     // It's a constant, evaluate lo or hi value
1033     if (Str == "lo") {
1034       short Val = MCE->getValue();
1035       Res = MCConstantExpr::Create(Val, getContext());
1036     } else if (Str == "hi") {
1037       int Val = MCE->getValue();
1038       int LoSign = Val & 0x8000;
1039       Val = (Val & 0xffff0000) >> 16;
1040       // Lower part is treated as a signed int, so if it is negative
1041       // we must add 1 to the hi part to compensate
1042       if (LoSign)
1043         Val++;
1044       Res = MCConstantExpr::Create(Val, getContext());
1045     }
1046     return false;
1047   }
1048
1049   if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
1050     // It's a symbol, create symbolic expression from symbol
1051     StringRef Symbol = MSRE->getSymbol().getName();
1052     MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
1053     Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
1054     return false;
1055   }
1056   return true;
1057 }
1058
1059 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1060                                   SMLoc &EndLoc) {
1061
1062   StartLoc = Parser.getTok().getLoc();
1063   RegNo = tryParseRegister(isMips64());
1064   EndLoc = Parser.getTok().getLoc();
1065   return (RegNo == (unsigned)-1);
1066 }
1067
1068 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
1069
1070   SMLoc S;
1071
1072   switch(getLexer().getKind()) {
1073   default:
1074     return true;
1075   case AsmToken::Identifier:
1076   case AsmToken::Integer:
1077   case AsmToken::Minus:
1078   case AsmToken::Plus:
1079     return (getParser().parseExpression(Res));
1080   case AsmToken::Percent:
1081     return parseRelocOperand(Res);
1082   case AsmToken::LParen:
1083     return false;  // it's probably assuming 0
1084   }
1085   return true;
1086 }
1087
1088 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1089                SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
1090
1091   const MCExpr *IdVal = 0;
1092   SMLoc S;
1093   // first operand is the offset
1094   S = Parser.getTok().getLoc();
1095
1096   if (parseMemOffset(IdVal))
1097     return MatchOperand_ParseFail;
1098
1099   const AsmToken &Tok = Parser.getTok(); // get next token
1100   if (Tok.isNot(AsmToken::LParen)) {
1101     MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
1102     if (Mnemonic->getToken() == "la") {
1103       SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1);
1104       Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1105       return MatchOperand_Success;
1106     }
1107     Error(Parser.getTok().getLoc(), "'(' expected");
1108     return MatchOperand_ParseFail;
1109   }
1110
1111   Parser.Lex(); // Eat '(' token.
1112
1113   const AsmToken &Tok1 = Parser.getTok(); // get next token
1114   if (Tok1.is(AsmToken::Dollar)) {
1115     Parser.Lex(); // Eat '$' token.
1116     if (tryParseRegisterOperand(Operands, isMips64())) {
1117       Error(Parser.getTok().getLoc(), "unexpected token in operand");
1118       return MatchOperand_ParseFail;
1119     }
1120
1121   } else {
1122     Error(Parser.getTok().getLoc(), "unexpected token in operand");
1123     return MatchOperand_ParseFail;
1124   }
1125
1126   const AsmToken &Tok2 = Parser.getTok(); // get next token
1127   if (Tok2.isNot(AsmToken::RParen)) {
1128     Error(Parser.getTok().getLoc(), "')' expected");
1129     return MatchOperand_ParseFail;
1130   }
1131
1132   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1133
1134   Parser.Lex(); // Eat ')' token.
1135
1136   if (IdVal == 0)
1137     IdVal = MCConstantExpr::Create(0, getContext());
1138
1139   // now replace register operand with the mem operand
1140   MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1141   int RegNo = op->getReg();
1142   // remove register from operands
1143   Operands.pop_back();
1144   // and add memory operand
1145   Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1146   delete op;
1147   return MatchOperand_Success;
1148 }
1149
1150 MipsAsmParser::OperandMatchResultTy
1151 MipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1152
1153   if (!isMips64())
1154     return MatchOperand_NoMatch;
1155   if (getLexer().getKind() == AsmToken::Identifier) {
1156     if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs))
1157       return MatchOperand_Success;
1158     return MatchOperand_NoMatch;
1159   }
1160   // if the first token is not '$' we have an error
1161   if (Parser.getTok().isNot(AsmToken::Dollar))
1162     return MatchOperand_NoMatch;
1163
1164   Parser.Lex(); // Eat $
1165   if(!tryParseRegisterOperand(Operands, true)) {
1166     // set the proper register kind
1167     MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1168     op->setRegKind(MipsOperand::Kind_CPU64Regs);
1169     return MatchOperand_Success;
1170   }
1171   return MatchOperand_NoMatch;
1172 }
1173
1174 bool MipsAsmParser::
1175 searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1176                   unsigned RegisterKind) {
1177
1178   MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1179   if (Sym) {
1180     SMLoc S = Parser.getTok().getLoc();
1181     const MCExpr *Expr;
1182     if (Sym->isVariable())
1183       Expr = Sym->getVariableValue();
1184     else
1185       return false;
1186     if (Expr->getKind() == MCExpr::SymbolRef) {
1187       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1188       const StringRef DefSymbol = Ref->getSymbol().getName();
1189       if (DefSymbol.startswith("$")) {
1190         // Lookup for the register with corresponding name
1191         int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64());
1192         if (RegNum > -1) {
1193           Parser.Lex();
1194           MipsOperand *op = MipsOperand::CreateReg(RegNum,S,
1195                                          Parser.getTok().getLoc());
1196           op->setRegKind((MipsOperand::RegisterKind)RegisterKind);
1197           Operands.push_back(op);
1198           return true;
1199         }
1200       }
1201     } else if (Expr->getKind() == MCExpr::Constant) {
1202       Parser.Lex();
1203       const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1204       MipsOperand *op = MipsOperand::CreateImm(Const,S,
1205                                      Parser.getTok().getLoc());
1206       Operands.push_back(op);
1207       return true;
1208     }
1209   }
1210   return false;
1211 }
1212 MipsAsmParser::OperandMatchResultTy
1213 MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1214
1215   if (getLexer().getKind() == AsmToken::Identifier) {
1216     if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs))
1217       return MatchOperand_Success;
1218     return MatchOperand_NoMatch;
1219   }
1220   // if the first token is not '$' we have an error
1221   if (Parser.getTok().isNot(AsmToken::Dollar))
1222     return MatchOperand_NoMatch;
1223
1224   Parser.Lex(); // Eat $
1225   if(!tryParseRegisterOperand(Operands, false)) {
1226     // set the propper register kind
1227     MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1228     op->setRegKind(MipsOperand::Kind_CPURegs);
1229     return MatchOperand_Success;
1230   }
1231   return MatchOperand_NoMatch;
1232 }
1233
1234 MipsAsmParser::OperandMatchResultTy
1235 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1236
1237   if (isMips64())
1238     return MatchOperand_NoMatch;
1239
1240   // if the first token is not '$' we have error
1241   if (Parser.getTok().isNot(AsmToken::Dollar))
1242     return MatchOperand_NoMatch;
1243   SMLoc S = Parser.getTok().getLoc();
1244   Parser.Lex(); // Eat $
1245
1246   const AsmToken &Tok = Parser.getTok(); // get next token
1247   if (Tok.isNot(AsmToken::Integer))
1248     return MatchOperand_NoMatch;
1249
1250   unsigned RegNum = Tok.getIntVal();
1251   // at the moment only hwreg29 is supported
1252   if (RegNum != 29)
1253     return MatchOperand_ParseFail;
1254
1255   MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1256         Parser.getTok().getLoc());
1257   op->setRegKind(MipsOperand::Kind_HWRegs);
1258   Operands.push_back(op);
1259
1260   Parser.Lex(); // Eat reg number
1261   return MatchOperand_Success;
1262 }
1263
1264 MipsAsmParser::OperandMatchResultTy
1265 MipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1266
1267   if (!isMips64())
1268     return MatchOperand_NoMatch;
1269     //if the first token is not '$' we have error
1270   if (Parser.getTok().isNot(AsmToken::Dollar))
1271     return MatchOperand_NoMatch;
1272   SMLoc S = Parser.getTok().getLoc();
1273   Parser.Lex(); // Eat $
1274
1275   const AsmToken &Tok = Parser.getTok(); // get next token
1276   if (Tok.isNot(AsmToken::Integer))
1277     return MatchOperand_NoMatch;
1278
1279   unsigned RegNum = Tok.getIntVal();
1280   // at the moment only hwreg29 is supported
1281   if (RegNum != 29)
1282     return MatchOperand_ParseFail;
1283
1284   MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1285         Parser.getTok().getLoc());
1286   op->setRegKind(MipsOperand::Kind_HW64Regs);
1287   Operands.push_back(op);
1288
1289   Parser.Lex(); // Eat reg number
1290   return MatchOperand_Success;
1291 }
1292
1293 MipsAsmParser::OperandMatchResultTy
1294 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1295   unsigned RegNum;
1296   //if the first token is not '$' we have error
1297   if (Parser.getTok().isNot(AsmToken::Dollar))
1298     return MatchOperand_NoMatch;
1299   SMLoc S = Parser.getTok().getLoc();
1300   Parser.Lex(); // Eat $
1301
1302   const AsmToken &Tok = Parser.getTok(); // get next token
1303   if (Tok.is(AsmToken::Integer)) {
1304     RegNum = Tok.getIntVal();
1305     // at the moment only fcc0 is supported
1306     if (RegNum != 0)
1307       return MatchOperand_ParseFail;
1308   } else if (Tok.is(AsmToken::Identifier)) {
1309     // at the moment only fcc0 is supported
1310     if (Tok.getIdentifier() != "fcc0")
1311       return MatchOperand_ParseFail;
1312   } else
1313     return MatchOperand_NoMatch;
1314
1315   MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1316         Parser.getTok().getLoc());
1317   op->setRegKind(MipsOperand::Kind_CCRRegs);
1318   Operands.push_back(op);
1319
1320   Parser.Lex(); // Eat reg number
1321   return MatchOperand_Success;
1322 }
1323
1324 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1325
1326   MCSymbolRefExpr::VariantKind VK
1327                    = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1328     .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1329     .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1330     .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1331     .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1332     .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1333     .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1334     .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1335     .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1336     .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1337     .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1338     .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1339     .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1340     .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1341     .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1342     .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1343     .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1344     .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1345     .Default(MCSymbolRefExpr::VK_None);
1346
1347   return VK;
1348 }
1349
1350 static int ConvertCcString(StringRef CondString) {
1351   int CC = StringSwitch<unsigned>(CondString)
1352       .Case(".f",    0)
1353       .Case(".un",   1)
1354       .Case(".eq",   2)
1355       .Case(".ueq",  3)
1356       .Case(".olt",  4)
1357       .Case(".ult",  5)
1358       .Case(".ole",  6)
1359       .Case(".ule",  7)
1360       .Case(".sf",   8)
1361       .Case(".ngle", 9)
1362       .Case(".seq",  10)
1363       .Case(".ngl",  11)
1364       .Case(".lt",   12)
1365       .Case(".nge",  13)
1366       .Case(".le",   14)
1367       .Case(".ngt",  15)
1368       .Default(-1);
1369
1370   return CC;
1371 }
1372
1373 bool MipsAsmParser::
1374 parseMathOperation(StringRef Name, SMLoc NameLoc,
1375                    SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1376   // split the format
1377   size_t Start = Name.find('.'), Next = Name.rfind('.');
1378   StringRef Format1 = Name.slice(Start, Next);
1379   // and add the first format to the operands
1380   Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
1381   // now for the second format
1382   StringRef Format2 = Name.slice(Next, StringRef::npos);
1383   Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
1384
1385   // set the format for the first register
1386   setFpFormat(Format1);
1387
1388   // Read the remaining operands.
1389   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1390     // Read the first operand.
1391     if (ParseOperand(Operands, Name)) {
1392       SMLoc Loc = getLexer().getLoc();
1393       Parser.eatToEndOfStatement();
1394       return Error(Loc, "unexpected token in argument list");
1395     }
1396
1397     if (getLexer().isNot(AsmToken::Comma)) {
1398       SMLoc Loc = getLexer().getLoc();
1399       Parser.eatToEndOfStatement();
1400       return Error(Loc, "unexpected token in argument list");
1401
1402     }
1403     Parser.Lex();  // Eat the comma.
1404
1405     //set the format for the first register
1406     setFpFormat(Format2);
1407
1408     // Parse and remember the operand.
1409     if (ParseOperand(Operands, Name)) {
1410       SMLoc Loc = getLexer().getLoc();
1411       Parser.eatToEndOfStatement();
1412       return Error(Loc, "unexpected token in argument list");
1413     }
1414   }
1415
1416   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1417     SMLoc Loc = getLexer().getLoc();
1418     Parser.eatToEndOfStatement();
1419     return Error(Loc, "unexpected token in argument list");
1420   }
1421
1422   Parser.Lex(); // Consume the EndOfStatement
1423   return false;
1424 }
1425
1426 bool MipsAsmParser::
1427 ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1428                  SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1429   StringRef Mnemonic;
1430   // floating point instructions: should register be treated as double?
1431   if (requestsDoubleOperand(Name)) {
1432     setFpFormat(FP_FORMAT_D);
1433   Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1434   Mnemonic = Name;
1435   }
1436   else {
1437     setDefaultFpFormat();
1438     // Create the leading tokens for the mnemonic, split by '.' characters.
1439     size_t Start = 0, Next = Name.find('.');
1440     Mnemonic = Name.slice(Start, Next);
1441
1442     Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
1443
1444     if (Next != StringRef::npos) {
1445       // there is a format token in mnemonic
1446       // StringRef Rest = Name.slice(Next, StringRef::npos);
1447       size_t Dot = Name.find('.', Next+1);
1448       StringRef Format = Name.slice(Next, Dot);
1449       if (Dot == StringRef::npos) //only one '.' in a string, it's a format
1450         Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1451       else {
1452         if (Name.startswith("c.")){
1453           // floating point compare, add '.' and immediate represent for cc
1454           Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
1455           int Cc = ConvertCcString(Format);
1456           if (Cc == -1) {
1457             return Error(NameLoc, "Invalid conditional code");
1458           }
1459           SMLoc E = SMLoc::getFromPointer(
1460               Parser.getTok().getLoc().getPointer() -1 );
1461           Operands.push_back(MipsOperand::CreateImm(
1462               MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
1463         } else {
1464           // trunc, ceil, floor ...
1465           return parseMathOperation(Name, NameLoc, Operands);
1466         }
1467
1468         // the rest is a format
1469         Format = Name.slice(Dot, StringRef::npos);
1470         Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1471       }
1472
1473       setFpFormat(Format);
1474     }
1475   }
1476
1477   // Read the remaining operands.
1478   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1479     // Read the first operand.
1480     if (ParseOperand(Operands, Mnemonic)) {
1481       SMLoc Loc = getLexer().getLoc();
1482       Parser.eatToEndOfStatement();
1483       return Error(Loc, "unexpected token in argument list");
1484     }
1485
1486     while (getLexer().is(AsmToken::Comma) ) {
1487       Parser.Lex();  // Eat the comma.
1488
1489       // Parse and remember the operand.
1490       if (ParseOperand(Operands, Name)) {
1491         SMLoc Loc = getLexer().getLoc();
1492         Parser.eatToEndOfStatement();
1493         return Error(Loc, "unexpected token in argument list");
1494       }
1495     }
1496   }
1497
1498   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1499     SMLoc Loc = getLexer().getLoc();
1500     Parser.eatToEndOfStatement();
1501     return Error(Loc, "unexpected token in argument list");
1502   }
1503
1504   Parser.Lex(); // Consume the EndOfStatement
1505   return false;
1506 }
1507
1508 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1509    SMLoc Loc = getLexer().getLoc();
1510    Parser.eatToEndOfStatement();
1511    return Error(Loc, ErrorMsg);
1512 }
1513
1514 bool MipsAsmParser::parseSetNoAtDirective() {
1515   // Line should look like:
1516   //  .set noat
1517   // set at reg to 0
1518   Options.setATReg(0);
1519   // eat noat
1520   Parser.Lex();
1521   // If this is not the end of the statement, report error
1522   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1523     reportParseError("unexpected token in statement");
1524     return false;
1525   }
1526   Parser.Lex(); // Consume the EndOfStatement
1527   return false;
1528 }
1529 bool MipsAsmParser::parseSetAtDirective() {
1530   // line can be
1531   //  .set at - defaults to $1
1532   // or .set at=$reg
1533   int AtRegNo;
1534   getParser().Lex();
1535   if (getLexer().is(AsmToken::EndOfStatement)) {
1536     Options.setATReg(1);
1537     Parser.Lex(); // Consume the EndOfStatement
1538     return false;
1539   } else if (getLexer().is(AsmToken::Equal)) {
1540     getParser().Lex(); // eat '='
1541     if (getLexer().isNot(AsmToken::Dollar)) {
1542       reportParseError("unexpected token in statement");
1543       return false;
1544     }
1545     Parser.Lex(); // Eat '$'
1546     const AsmToken &Reg = Parser.getTok();
1547     if (Reg.is(AsmToken::Identifier)) {
1548       AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1549     } else if (Reg.is(AsmToken::Integer)) {
1550       AtRegNo = Reg.getIntVal();
1551     } else {
1552       reportParseError("unexpected token in statement");
1553       return false;
1554     }
1555
1556     if ( AtRegNo < 1 || AtRegNo > 31) {
1557       reportParseError("unexpected token in statement");
1558       return false;
1559     }
1560
1561     if (!Options.setATReg(AtRegNo)) {
1562       reportParseError("unexpected token in statement");
1563       return false;
1564     }
1565     getParser().Lex(); // Eat reg
1566
1567     if (getLexer().isNot(AsmToken::EndOfStatement)) {
1568       reportParseError("unexpected token in statement");
1569       return false;
1570      }
1571     Parser.Lex(); // Consume the EndOfStatement
1572     return false;
1573   } else {
1574     reportParseError("unexpected token in statement");
1575     return false;
1576   }
1577 }
1578
1579 bool MipsAsmParser::parseSetReorderDirective() {
1580   Parser.Lex();
1581   // If this is not the end of the statement, report error
1582   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1583     reportParseError("unexpected token in statement");
1584     return false;
1585   }
1586   Options.setReorder();
1587   Parser.Lex(); // Consume the EndOfStatement
1588   return false;
1589 }
1590
1591 bool MipsAsmParser::parseSetNoReorderDirective() {
1592     Parser.Lex();
1593     // if this is not the end of the statement, report error
1594     if (getLexer().isNot(AsmToken::EndOfStatement)) {
1595       reportParseError("unexpected token in statement");
1596       return false;
1597     }
1598     Options.setNoreorder();
1599     Parser.Lex(); // Consume the EndOfStatement
1600     return false;
1601 }
1602
1603 bool MipsAsmParser::parseSetMacroDirective() {
1604   Parser.Lex();
1605   // if this is not the end of the statement, report error
1606   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1607     reportParseError("unexpected token in statement");
1608     return false;
1609   }
1610   Options.setMacro();
1611   Parser.Lex(); // Consume the EndOfStatement
1612   return false;
1613 }
1614
1615 bool MipsAsmParser::parseSetNoMacroDirective() {
1616   Parser.Lex();
1617   // if this is not the end of the statement, report error
1618   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1619     reportParseError("`noreorder' must be set before `nomacro'");
1620     return false;
1621   }
1622   if (Options.isReorder()) {
1623     reportParseError("`noreorder' must be set before `nomacro'");
1624     return false;
1625   }
1626   Options.setNomacro();
1627   Parser.Lex(); // Consume the EndOfStatement
1628   return false;
1629 }
1630
1631 bool MipsAsmParser::parseSetAssignment() {
1632   StringRef Name;
1633   const MCExpr *Value;
1634
1635   if (Parser.parseIdentifier(Name))
1636     reportParseError("expected identifier after .set");
1637
1638   if (getLexer().isNot(AsmToken::Comma))
1639     return reportParseError("unexpected token in .set directive");
1640   Lex(); //eat comma
1641
1642   if (Parser.parseExpression(Value))
1643     reportParseError("expected valid expression after comma");
1644
1645   // check if the Name already exists as a symbol
1646   MCSymbol *Sym = getContext().LookupSymbol(Name);
1647   if (Sym) {
1648     return reportParseError("symbol already defined");
1649   }
1650   Sym = getContext().GetOrCreateSymbol(Name);
1651   Sym->setVariableValue(Value);
1652
1653   return false;
1654 }
1655 bool MipsAsmParser::parseDirectiveSet() {
1656
1657   // get next token
1658   const AsmToken &Tok = Parser.getTok();
1659
1660   if (Tok.getString() == "noat") {
1661     return parseSetNoAtDirective();
1662   } else if (Tok.getString() == "at") {
1663     return parseSetAtDirective();
1664   } else if (Tok.getString() == "reorder") {
1665     return parseSetReorderDirective();
1666   } else if (Tok.getString() == "noreorder") {
1667     return parseSetNoReorderDirective();
1668   } else if (Tok.getString() == "macro") {
1669     return parseSetMacroDirective();
1670   } else if (Tok.getString() == "nomacro") {
1671     return parseSetNoMacroDirective();
1672   } else if (Tok.getString() == "nomips16") {
1673     // ignore this directive for now
1674     Parser.eatToEndOfStatement();
1675     return false;
1676   } else if (Tok.getString() == "nomicromips") {
1677     // ignore this directive for now
1678     Parser.eatToEndOfStatement();
1679     return false;
1680   } else {
1681     // it is just an identifier, look for assignment
1682     parseSetAssignment();
1683     return false;
1684   }
1685
1686   return true;
1687 }
1688
1689 /// parseDirectiveWord
1690 ///  ::= .word [ expression (, expression)* ]
1691 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1692   if (getLexer().isNot(AsmToken::EndOfStatement)) {
1693     for (;;) {
1694       const MCExpr *Value;
1695       if (getParser().parseExpression(Value))
1696         return true;
1697
1698       getParser().getStreamer().EmitValue(Value, Size);
1699
1700       if (getLexer().is(AsmToken::EndOfStatement))
1701         break;
1702
1703       // FIXME: Improve diagnostic.
1704       if (getLexer().isNot(AsmToken::Comma))
1705         return Error(L, "unexpected token in directive");
1706       Parser.Lex();
1707     }
1708   }
1709
1710   Parser.Lex();
1711   return false;
1712 }
1713
1714 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1715
1716   StringRef IDVal = DirectiveID.getString();
1717
1718   if ( IDVal == ".ent") {
1719     // ignore this directive for now
1720     Parser.Lex();
1721     return false;
1722   }
1723
1724   if (IDVal == ".end") {
1725     // ignore this directive for now
1726     Parser.Lex();
1727     return false;
1728   }
1729
1730   if (IDVal == ".frame") {
1731     // ignore this directive for now
1732     Parser.eatToEndOfStatement();
1733     return false;
1734   }
1735
1736   if (IDVal == ".set") {
1737     return parseDirectiveSet();
1738   }
1739
1740   if (IDVal == ".fmask") {
1741     // ignore this directive for now
1742     Parser.eatToEndOfStatement();
1743     return false;
1744   }
1745
1746   if (IDVal == ".mask") {
1747     // ignore this directive for now
1748     Parser.eatToEndOfStatement();
1749     return false;
1750   }
1751
1752   if (IDVal == ".gpword") {
1753     // ignore this directive for now
1754     Parser.eatToEndOfStatement();
1755     return false;
1756   }
1757
1758   if (IDVal == ".word") {
1759     parseDirectiveWord(4, DirectiveID.getLoc());
1760     return false;
1761   }
1762
1763   return true;
1764 }
1765
1766 extern "C" void LLVMInitializeMipsAsmParser() {
1767   RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1768   RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1769   RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1770   RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1771 }
1772
1773 #define GET_REGISTER_MATCHER
1774 #define GET_MATCHER_IMPLEMENTATION
1775 #include "MipsGenAsmMatcher.inc"