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