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