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