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