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