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