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