Implement gpword directive for mips, test case added. Stype changes using clang-forma...
[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
1163     MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
1164
1165     // Otherwise create a symbol reference.
1166     const MCExpr *Res =
1167         MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1168
1169     Operands.push_back(MipsOperand::CreateImm(Res, S, E));
1170     return false;
1171   }
1172   case AsmToken::Identifier:
1173     // Look for the existing symbol, we should check if
1174     // we need to assigne the propper RegisterKind.
1175     if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
1176       return false;
1177   // Else drop to expression parsing.
1178   case AsmToken::LParen:
1179   case AsmToken::Minus:
1180   case AsmToken::Plus:
1181   case AsmToken::Integer:
1182   case AsmToken::String: {
1183     // Quoted label names.
1184     const MCExpr *IdVal;
1185     SMLoc S = Parser.getTok().getLoc();
1186     if (getParser().parseExpression(IdVal))
1187       return true;
1188     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1189     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1190     return false;
1191   }
1192   case AsmToken::Percent: {
1193     // It is a symbol reference or constant expression.
1194     const MCExpr *IdVal;
1195     SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1196     if (parseRelocOperand(IdVal))
1197       return true;
1198
1199     SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1200
1201     Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1202     return false;
1203   } // case AsmToken::Percent
1204   } // switch(getLexer().getKind())
1205   return true;
1206 }
1207
1208 const MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
1209                                                StringRef RelocStr) {
1210   const MCExpr *Res;
1211   // Check the type of the expression.
1212   if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
1213     // It's a constant, evaluate lo or hi value.
1214     if (RelocStr == "lo") {
1215       short Val = MCE->getValue();
1216       Res = MCConstantExpr::Create(Val, getContext());
1217     } else if (RelocStr == "hi") {
1218       int Val = MCE->getValue();
1219       int LoSign = Val & 0x8000;
1220       Val = (Val & 0xffff0000) >> 16;
1221       // Lower part is treated as a signed int, so if it is negative
1222       // we must add 1 to the hi part to compensate.
1223       if (LoSign)
1224         Val++;
1225       Res = MCConstantExpr::Create(Val, getContext());
1226     } else {
1227       llvm_unreachable("Invalid RelocStr value");
1228     }
1229     return Res;
1230   }
1231
1232   if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
1233     // It's a symbol, create a symbolic expression from the symbol.
1234     StringRef Symbol = MSRE->getSymbol().getName();
1235     MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
1236     Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
1237     return Res;
1238   }
1239
1240   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1241     const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
1242     const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
1243     Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
1244     return Res;
1245   }
1246
1247   if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
1248     const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
1249     Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
1250     return Res;
1251   }
1252   // Just return the original expression.
1253   return Expr;
1254 }
1255
1256 bool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
1257
1258   switch (Expr->getKind()) {
1259   case MCExpr::Constant:
1260     return true;
1261   case MCExpr::SymbolRef:
1262     return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
1263   case MCExpr::Binary:
1264     if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
1265       if (!isEvaluated(BE->getLHS()))
1266         return false;
1267       return isEvaluated(BE->getRHS());
1268     }
1269   case MCExpr::Unary:
1270     return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
1271   default:
1272     return false;
1273   }
1274   return false;
1275 }
1276
1277 bool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
1278   Parser.Lex();                          // Eat the % token.
1279   const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
1280   if (Tok.isNot(AsmToken::Identifier))
1281     return true;
1282
1283   std::string Str = Tok.getIdentifier().str();
1284
1285   Parser.Lex(); // Eat the identifier.
1286   // Now make an expression from the rest of the operand.
1287   const MCExpr *IdVal;
1288   SMLoc EndLoc;
1289
1290   if (getLexer().getKind() == AsmToken::LParen) {
1291     while (1) {
1292       Parser.Lex(); // Eat the '(' token.
1293       if (getLexer().getKind() == AsmToken::Percent) {
1294         Parser.Lex(); // Eat the % token.
1295         const AsmToken &nextTok = Parser.getTok();
1296         if (nextTok.isNot(AsmToken::Identifier))
1297           return true;
1298         Str += "(%";
1299         Str += nextTok.getIdentifier();
1300         Parser.Lex(); // Eat the identifier.
1301         if (getLexer().getKind() != AsmToken::LParen)
1302           return true;
1303       } else
1304         break;
1305     }
1306     if (getParser().parseParenExpression(IdVal, EndLoc))
1307       return true;
1308
1309     while (getLexer().getKind() == AsmToken::RParen)
1310       Parser.Lex(); // Eat the ')' token.
1311
1312   } else
1313     return true; // Parenthesis must follow the relocation operand.
1314
1315   Res = evaluateRelocExpr(IdVal, Str);
1316   return false;
1317 }
1318
1319 bool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1320                                   SMLoc &EndLoc) {
1321   StartLoc = Parser.getTok().getLoc();
1322   RegNo = tryParseRegister(isMips64());
1323   EndLoc = Parser.getTok().getLoc();
1324   return (RegNo == (unsigned)-1);
1325 }
1326
1327 bool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1328   SMLoc S;
1329   bool Result = true;
1330
1331   while (getLexer().getKind() == AsmToken::LParen)
1332     Parser.Lex();
1333
1334   switch (getLexer().getKind()) {
1335   default:
1336     return true;
1337   case AsmToken::Identifier:
1338   case AsmToken::LParen:
1339   case AsmToken::Integer:
1340   case AsmToken::Minus:
1341   case AsmToken::Plus:
1342     if (isParenExpr)
1343       Result = getParser().parseParenExpression(Res, S);
1344     else
1345       Result = (getParser().parseExpression(Res));
1346     while (getLexer().getKind() == AsmToken::RParen)
1347       Parser.Lex();
1348     break;
1349   case AsmToken::Percent:
1350     Result = parseRelocOperand(Res);
1351   }
1352   return Result;
1353 }
1354
1355 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1356     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1357
1358   const MCExpr *IdVal = 0;
1359   SMLoc S;
1360   bool isParenExpr = false;
1361   MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
1362   // First operand is the offset.
1363   S = Parser.getTok().getLoc();
1364
1365   if (getLexer().getKind() == AsmToken::LParen) {
1366     Parser.Lex();
1367     isParenExpr = true;
1368   }
1369
1370   if (getLexer().getKind() != AsmToken::Dollar) {
1371     if (parseMemOffset(IdVal, isParenExpr))
1372       return MatchOperand_ParseFail;
1373
1374     const AsmToken &Tok = Parser.getTok(); // Get the next token.
1375     if (Tok.isNot(AsmToken::LParen)) {
1376       MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1377       if (Mnemonic->getToken() == "la") {
1378         SMLoc E =
1379             SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1380         Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1381         return MatchOperand_Success;
1382       }
1383       if (Tok.is(AsmToken::EndOfStatement)) {
1384         SMLoc E =
1385             SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1386
1387         // Zero register assumed, add a memory operand with ZERO as its base.
1388         Operands.push_back(MipsOperand::CreateMem(
1389             isMips64() ? Mips::ZERO_64 : Mips::ZERO, IdVal, S, E));
1390         return MatchOperand_Success;
1391       }
1392       Error(Parser.getTok().getLoc(), "'(' expected");
1393       return MatchOperand_ParseFail;
1394     }
1395
1396     Parser.Lex(); // Eat the '(' token.
1397   }
1398
1399   Res = parseRegs(Operands, isMips64() ? (int)MipsOperand::Kind_GPR64
1400                                        : (int)MipsOperand::Kind_GPR32);
1401   if (Res != MatchOperand_Success)
1402     return Res;
1403
1404   if (Parser.getTok().isNot(AsmToken::RParen)) {
1405     Error(Parser.getTok().getLoc(), "')' expected");
1406     return MatchOperand_ParseFail;
1407   }
1408
1409   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1410
1411   Parser.Lex(); // Eat the ')' token.
1412
1413   if (IdVal == 0)
1414     IdVal = MCConstantExpr::Create(0, getContext());
1415
1416   // Replace the register operand with the memory operand.
1417   MipsOperand *op = static_cast<MipsOperand *>(Operands.back());
1418   int RegNo = op->getReg();
1419   // Remove the register from the operands.
1420   Operands.pop_back();
1421   // Add the memory operand.
1422   if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
1423     int64_t Imm;
1424     if (IdVal->EvaluateAsAbsolute(Imm))
1425       IdVal = MCConstantExpr::Create(Imm, getContext());
1426     else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
1427       IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
1428                                    getContext());
1429   }
1430
1431   Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
1432   delete op;
1433   return MatchOperand_Success;
1434 }
1435
1436 bool MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1437                                 int RegKind) {
1438   // If the first token is not '$' we have an error.
1439   if (Parser.getTok().isNot(AsmToken::Dollar))
1440     return false;
1441
1442   SMLoc S = Parser.getTok().getLoc();
1443   Parser.Lex();
1444   AsmToken::TokenKind TkKind = getLexer().getKind();
1445   int Reg;
1446
1447   if (TkKind == AsmToken::Integer) {
1448     Reg = matchRegisterByNumber(Parser.getTok().getIntVal(),
1449                                 regKindToRegClass(RegKind));
1450     if (Reg == -1)
1451       return false;
1452   } else if (TkKind == AsmToken::Identifier) {
1453     if ((Reg = matchCPURegisterName(Parser.getTok().getString().lower())) == -1)
1454       return false;
1455     Reg = getReg(regKindToRegClass(RegKind), Reg);
1456   } else {
1457     return false;
1458   }
1459
1460   MipsOperand *Op = MipsOperand::CreatePtrReg(Reg, S, Parser.getTok().getLoc());
1461   Op->setRegKind((MipsOperand::RegisterKind)RegKind);
1462   Operands.push_back(Op);
1463   Parser.Lex();
1464   return true;
1465 }
1466
1467 MipsAsmParser::OperandMatchResultTy
1468 MipsAsmParser::parsePtrReg(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1469   MipsOperand::RegisterKind RegKind =
1470       isN64() ? MipsOperand::Kind_GPR64 : MipsOperand::Kind_GPR32;
1471
1472   // Parse index register.
1473   if (!parsePtrReg(Operands, RegKind))
1474     return MatchOperand_NoMatch;
1475
1476   // Parse '('.
1477   if (Parser.getTok().isNot(AsmToken::LParen))
1478     return MatchOperand_NoMatch;
1479
1480   Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1481   Parser.Lex();
1482
1483   // Parse base register.
1484   if (!parsePtrReg(Operands, RegKind))
1485     return MatchOperand_NoMatch;
1486
1487   // Parse ')'.
1488   if (Parser.getTok().isNot(AsmToken::RParen))
1489     return MatchOperand_NoMatch;
1490
1491   Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1492   Parser.Lex();
1493
1494   return MatchOperand_Success;
1495 }
1496
1497 MipsAsmParser::OperandMatchResultTy
1498 MipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1499                          int RegKind) {
1500   MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1501   if (getLexer().getKind() == AsmToken::Identifier && !hasConsumedDollar) {
1502     if (searchSymbolAlias(Operands, Kind))
1503       return MatchOperand_Success;
1504     return MatchOperand_NoMatch;
1505   }
1506   SMLoc S = Parser.getTok().getLoc();
1507   // If the first token is not '$', we have an error.
1508   if (Parser.getTok().isNot(AsmToken::Dollar) && !hasConsumedDollar)
1509     return MatchOperand_NoMatch;
1510   if (!hasConsumedDollar) {
1511     Parser.Lex(); // Eat the '$'
1512     hasConsumedDollar = true;
1513   }
1514   if (getLexer().getKind() == AsmToken::Identifier) {
1515     int RegNum = -1;
1516     std::string RegName = Parser.getTok().getString().lower();
1517     // Match register by name
1518     switch (RegKind) {
1519     case MipsOperand::Kind_GPR32:
1520     case MipsOperand::Kind_GPR64:
1521       RegNum = matchCPURegisterName(RegName);
1522       break;
1523     case MipsOperand::Kind_AFGR64Regs:
1524     case MipsOperand::Kind_FGR64Regs:
1525     case MipsOperand::Kind_FGR32Regs:
1526     case MipsOperand::Kind_FGRH32Regs:
1527       RegNum = matchFPURegisterName(RegName);
1528       if (RegKind == MipsOperand::Kind_AFGR64Regs)
1529         RegNum /= 2;
1530       else if (RegKind == MipsOperand::Kind_FGRH32Regs && !isFP64())
1531         if (RegNum != -1 && RegNum % 2 != 0)
1532           Warning(S, "Float register should be even.");
1533       break;
1534     case MipsOperand::Kind_FCCRegs:
1535       RegNum = matchFCCRegisterName(RegName);
1536       break;
1537     case MipsOperand::Kind_ACC64DSP:
1538       RegNum = matchACRegisterName(RegName);
1539       break;
1540     default:
1541       break; // No match, value is set to -1.
1542     }
1543     // No match found, return _NoMatch to give a chance to other round.
1544     if (RegNum < 0)
1545       return MatchOperand_NoMatch;
1546
1547     int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1548     if (RegVal == -1)
1549       return MatchOperand_NoMatch;
1550
1551     MipsOperand *Op =
1552         MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1553     Op->setRegKind(Kind);
1554     Operands.push_back(Op);
1555     hasConsumedDollar = false;
1556     Parser.Lex(); // Eat the register name.
1557     return MatchOperand_Success;
1558   } else if (getLexer().getKind() == AsmToken::Integer) {
1559     unsigned RegNum = Parser.getTok().getIntVal();
1560     if (Kind == MipsOperand::Kind_HWRegs) {
1561       if (RegNum != 29)
1562         return MatchOperand_NoMatch;
1563       // Only hwreg 29 is supported, found at index 0.
1564       RegNum = 0;
1565     }
1566     int Reg = matchRegisterByNumber(RegNum, regKindToRegClass(Kind));
1567     if (Reg == -1)
1568       return MatchOperand_NoMatch;
1569     MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1570     Op->setRegKind(Kind);
1571     Operands.push_back(Op);
1572     hasConsumedDollar = false;
1573     Parser.Lex(); // Eat the register number.
1574     if ((RegKind == MipsOperand::Kind_GPR32) &&
1575         (getLexer().is(AsmToken::LParen))) {
1576       // Check if it is indexed addressing operand.
1577       Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1578       Parser.Lex(); // Eat the parenthesis.
1579       if (parseRegs(Operands, RegKind) != MatchOperand_Success)
1580         return MatchOperand_NoMatch;
1581       if (getLexer().isNot(AsmToken::RParen))
1582         return MatchOperand_NoMatch;
1583       Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1584       Parser.Lex();
1585     }
1586     return MatchOperand_Success;
1587   }
1588   return MatchOperand_NoMatch;
1589 }
1590
1591 bool MipsAsmParser::validateMSAIndex(int Val, int RegKind) {
1592   MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1593
1594   if (Val < 0)
1595     return false;
1596
1597   switch (Kind) {
1598   default:
1599     return false;
1600   case MipsOperand::Kind_MSA128BRegs:
1601     return Val < 16;
1602   case MipsOperand::Kind_MSA128HRegs:
1603     return Val < 8;
1604   case MipsOperand::Kind_MSA128WRegs:
1605     return Val < 4;
1606   case MipsOperand::Kind_MSA128DRegs:
1607     return Val < 2;
1608   }
1609 }
1610
1611 MipsAsmParser::OperandMatchResultTy
1612 MipsAsmParser::parseMSARegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1613                             int RegKind) {
1614   MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1615   SMLoc S = Parser.getTok().getLoc();
1616   std::string RegName;
1617
1618   if (Parser.getTok().isNot(AsmToken::Dollar))
1619     return MatchOperand_NoMatch;
1620
1621   switch (RegKind) {
1622   default:
1623     return MatchOperand_ParseFail;
1624   case MipsOperand::Kind_MSA128BRegs:
1625   case MipsOperand::Kind_MSA128HRegs:
1626   case MipsOperand::Kind_MSA128WRegs:
1627   case MipsOperand::Kind_MSA128DRegs:
1628     break;
1629   }
1630
1631   Parser.Lex(); // Eat the '$'.
1632   if (getLexer().getKind() == AsmToken::Identifier)
1633     RegName = Parser.getTok().getString().lower();
1634   else
1635     return MatchOperand_ParseFail;
1636
1637   int RegNum = matchMSA128RegisterName(RegName);
1638
1639   if (RegNum < 0 || RegNum > 31)
1640     return MatchOperand_ParseFail;
1641
1642   int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1643   if (RegVal == -1)
1644     return MatchOperand_ParseFail;
1645
1646   MipsOperand *Op = MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1647   Op->setRegKind(Kind);
1648   Operands.push_back(Op);
1649
1650   Parser.Lex(); // Eat the register identifier.
1651
1652   // MSA registers may be suffixed with an index in the form of:
1653   // 1) Immediate expression.
1654   // 2) General Purpose Register.
1655   // Examples:
1656   //   1) copy_s.b $29,$w0[0]
1657   //   2) sld.b $w0,$w1[$1]
1658
1659   if (Parser.getTok().isNot(AsmToken::LBrac))
1660     return MatchOperand_Success;
1661
1662   MipsOperand *Mnemonic = static_cast<MipsOperand *>(Operands[0]);
1663
1664   Operands.push_back(MipsOperand::CreateToken("[", Parser.getTok().getLoc()));
1665   Parser.Lex(); // Parse the '[' token.
1666
1667   if (Parser.getTok().is(AsmToken::Dollar)) {
1668     // This must be a GPR.
1669     MipsOperand *RegOp;
1670     SMLoc VIdx = Parser.getTok().getLoc();
1671     Parser.Lex(); // Parse the '$' token.
1672
1673     // GPR have aliases and we must account for that. Example: $30 == $fp
1674     if (getLexer().getKind() == AsmToken::Integer) {
1675       unsigned RegNum = Parser.getTok().getIntVal();
1676       int Reg = matchRegisterByNumber(
1677           RegNum, regKindToRegClass(MipsOperand::Kind_GPR32));
1678       if (Reg == -1) {
1679         Error(VIdx, "invalid general purpose register");
1680         return MatchOperand_ParseFail;
1681       }
1682
1683       RegOp = MipsOperand::CreateReg(Reg, VIdx, Parser.getTok().getLoc());
1684     } else if (getLexer().getKind() == AsmToken::Identifier) {
1685       int RegNum = -1;
1686       std::string RegName = Parser.getTok().getString().lower();
1687
1688       RegNum = matchCPURegisterName(RegName);
1689       if (RegNum == -1) {
1690         Error(VIdx, "general purpose register expected");
1691         return MatchOperand_ParseFail;
1692       }
1693       RegNum = getReg(regKindToRegClass(MipsOperand::Kind_GPR32), RegNum);
1694       RegOp = MipsOperand::CreateReg(RegNum, VIdx, Parser.getTok().getLoc());
1695     } else
1696       return MatchOperand_ParseFail;
1697
1698     RegOp->setRegKind(MipsOperand::Kind_GPR32);
1699     Operands.push_back(RegOp);
1700     Parser.Lex(); // Eat the register identifier.
1701
1702     if (Parser.getTok().isNot(AsmToken::RBrac))
1703       return MatchOperand_ParseFail;
1704
1705     Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1706     Parser.Lex(); // Parse the ']' token.
1707
1708     return MatchOperand_Success;
1709   }
1710
1711   // The index must be a constant expression then.
1712   SMLoc VIdx = Parser.getTok().getLoc();
1713   const MCExpr *ImmVal;
1714
1715   if (getParser().parseExpression(ImmVal))
1716     return MatchOperand_ParseFail;
1717
1718   const MCConstantExpr *expr = dyn_cast<MCConstantExpr>(ImmVal);
1719   if (!expr || !validateMSAIndex((int)expr->getValue(), Kind)) {
1720     Error(VIdx, "invalid immediate value");
1721     return MatchOperand_ParseFail;
1722   }
1723
1724   SMLoc E = Parser.getTok().getEndLoc();
1725
1726   if (Parser.getTok().isNot(AsmToken::RBrac))
1727     return MatchOperand_ParseFail;
1728
1729   bool insve =
1730       Mnemonic->getToken() == "insve.b" || Mnemonic->getToken() == "insve.h" ||
1731       Mnemonic->getToken() == "insve.w" || Mnemonic->getToken() == "insve.d";
1732
1733   // The second vector index of insve instructions is always 0.
1734   if (insve && Operands.size() > 6) {
1735     if (expr->getValue() != 0) {
1736       Error(VIdx, "immediate value must be 0");
1737       return MatchOperand_ParseFail;
1738     }
1739     Operands.push_back(MipsOperand::CreateToken("0", VIdx));
1740   } else
1741     Operands.push_back(MipsOperand::CreateImm(expr, VIdx, E));
1742
1743   Operands.push_back(MipsOperand::CreateToken("]", Parser.getTok().getLoc()));
1744
1745   Parser.Lex(); // Parse the ']' token.
1746
1747   return MatchOperand_Success;
1748 }
1749
1750 MipsAsmParser::OperandMatchResultTy
1751 MipsAsmParser::parseMSACtrlRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands,
1752                                 int RegKind) {
1753   MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1754
1755   if (Kind != MipsOperand::Kind_MSA128CtrlRegs)
1756     return MatchOperand_NoMatch;
1757
1758   if (Parser.getTok().isNot(AsmToken::Dollar))
1759     return MatchOperand_ParseFail;
1760
1761   SMLoc S = Parser.getTok().getLoc();
1762
1763   Parser.Lex(); // Eat the '$' symbol.
1764
1765   int RegNum = -1;
1766   if (getLexer().getKind() == AsmToken::Identifier)
1767     RegNum = matchMSA128CtrlRegisterName(Parser.getTok().getString().lower());
1768   else if (getLexer().getKind() == AsmToken::Integer)
1769     RegNum = Parser.getTok().getIntVal();
1770   else
1771     return MatchOperand_ParseFail;
1772
1773   if (RegNum < 0 || RegNum > 7)
1774     return MatchOperand_ParseFail;
1775
1776   int RegVal = getReg(regKindToRegClass(Kind), RegNum);
1777   if (RegVal == -1)
1778     return MatchOperand_ParseFail;
1779
1780   MipsOperand *RegOp =
1781       MipsOperand::CreateReg(RegVal, S, Parser.getTok().getLoc());
1782   RegOp->setRegKind(MipsOperand::Kind_MSA128CtrlRegs);
1783   Operands.push_back(RegOp);
1784   Parser.Lex(); // Eat the register identifier.
1785
1786   return MatchOperand_Success;
1787 }
1788
1789 MipsAsmParser::OperandMatchResultTy
1790 MipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1791
1792   if (!isMips64())
1793     return MatchOperand_NoMatch;
1794   return parseRegs(Operands, (int)MipsOperand::Kind_GPR64);
1795 }
1796
1797 MipsAsmParser::OperandMatchResultTy
1798 MipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1799   return parseRegs(Operands, (int)MipsOperand::Kind_GPR32);
1800 }
1801
1802 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseAFGR64Regs(
1803     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1804
1805   if (isFP64())
1806     return MatchOperand_NoMatch;
1807   return parseRegs(Operands, (int)MipsOperand::Kind_AFGR64Regs);
1808 }
1809
1810 MipsAsmParser::OperandMatchResultTy
1811 MipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1812   if (!isFP64())
1813     return MatchOperand_NoMatch;
1814   return parseRegs(Operands, (int)MipsOperand::Kind_FGR64Regs);
1815 }
1816
1817 MipsAsmParser::OperandMatchResultTy
1818 MipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1819   return parseRegs(Operands, (int)MipsOperand::Kind_FGR32Regs);
1820 }
1821
1822 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseFGRH32Regs(
1823     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1824   return parseRegs(Operands, (int)MipsOperand::Kind_FGRH32Regs);
1825 }
1826
1827 MipsAsmParser::OperandMatchResultTy
1828 MipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1829   return parseRegs(Operands, (int)MipsOperand::Kind_FCCRegs);
1830 }
1831
1832 MipsAsmParser::OperandMatchResultTy
1833 MipsAsmParser::parseACC64DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1834   return parseRegs(Operands, (int)MipsOperand::Kind_ACC64DSP);
1835 }
1836
1837 MipsAsmParser::OperandMatchResultTy
1838 MipsAsmParser::parseLO32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1839   // If the first token is not '$' we have an error.
1840   if (Parser.getTok().isNot(AsmToken::Dollar))
1841     return MatchOperand_NoMatch;
1842
1843   SMLoc S = Parser.getTok().getLoc();
1844   Parser.Lex(); // Eat the '$'
1845
1846   const AsmToken &Tok = Parser.getTok(); // Get next token.
1847
1848   if (Tok.isNot(AsmToken::Identifier))
1849     return MatchOperand_NoMatch;
1850
1851   if (!Tok.getIdentifier().startswith("ac"))
1852     return MatchOperand_NoMatch;
1853
1854   StringRef NumString = Tok.getIdentifier().substr(2);
1855
1856   unsigned IntVal;
1857   if (NumString.getAsInteger(10, IntVal))
1858     return MatchOperand_NoMatch;
1859
1860   unsigned Reg = matchRegisterByNumber(IntVal, Mips::LO32DSPRegClassID);
1861
1862   MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1863   Op->setRegKind(MipsOperand::Kind_LO32DSP);
1864   Operands.push_back(Op);
1865
1866   Parser.Lex(); // Eat the register number.
1867   return MatchOperand_Success;
1868 }
1869
1870 MipsAsmParser::OperandMatchResultTy
1871 MipsAsmParser::parseHI32DSP(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1872   // If the first token is not '$' we have an error.
1873   if (Parser.getTok().isNot(AsmToken::Dollar))
1874     return MatchOperand_NoMatch;
1875
1876   SMLoc S = Parser.getTok().getLoc();
1877   Parser.Lex(); // Eat the '$'
1878
1879   const AsmToken &Tok = Parser.getTok(); // Get next token.
1880
1881   if (Tok.isNot(AsmToken::Identifier))
1882     return MatchOperand_NoMatch;
1883
1884   if (!Tok.getIdentifier().startswith("ac"))
1885     return MatchOperand_NoMatch;
1886
1887   StringRef NumString = Tok.getIdentifier().substr(2);
1888
1889   unsigned IntVal;
1890   if (NumString.getAsInteger(10, IntVal))
1891     return MatchOperand_NoMatch;
1892
1893   unsigned Reg = matchRegisterByNumber(IntVal, Mips::HI32DSPRegClassID);
1894
1895   MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1896   Op->setRegKind(MipsOperand::Kind_HI32DSP);
1897   Operands.push_back(Op);
1898
1899   Parser.Lex(); // Eat the register number.
1900   return MatchOperand_Success;
1901 }
1902
1903 MipsAsmParser::OperandMatchResultTy
1904 MipsAsmParser::parseCOP2(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1905   // If the first token is not '$' we have an error.
1906   if (Parser.getTok().isNot(AsmToken::Dollar))
1907     return MatchOperand_NoMatch;
1908
1909   SMLoc S = Parser.getTok().getLoc();
1910   Parser.Lex(); // Eat the '$'
1911
1912   const AsmToken &Tok = Parser.getTok(); // Get next token.
1913
1914   if (Tok.isNot(AsmToken::Integer))
1915     return MatchOperand_NoMatch;
1916
1917   unsigned IntVal = Tok.getIntVal();
1918
1919   unsigned Reg = matchRegisterByNumber(IntVal, Mips::COP2RegClassID);
1920
1921   MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1922   Op->setRegKind(MipsOperand::Kind_COP2);
1923   Operands.push_back(Op);
1924
1925   Parser.Lex(); // Eat the register number.
1926   return MatchOperand_Success;
1927 }
1928
1929 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128BRegs(
1930     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1931   return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128BRegs);
1932 }
1933
1934 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128HRegs(
1935     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1936   return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128HRegs);
1937 }
1938
1939 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128WRegs(
1940     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1941   return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128WRegs);
1942 }
1943
1944 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128DRegs(
1945     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1946   return parseMSARegs(Operands, (int)MipsOperand::Kind_MSA128DRegs);
1947 }
1948
1949 MipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMSA128CtrlRegs(
1950     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
1951   return parseMSACtrlRegs(Operands, (int)MipsOperand::Kind_MSA128CtrlRegs);
1952 }
1953
1954 bool MipsAsmParser::searchSymbolAlias(
1955     SmallVectorImpl<MCParsedAsmOperand *> &Operands, unsigned RegKind) {
1956
1957   MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1958   if (Sym) {
1959     SMLoc S = Parser.getTok().getLoc();
1960     const MCExpr *Expr;
1961     if (Sym->isVariable())
1962       Expr = Sym->getVariableValue();
1963     else
1964       return false;
1965     if (Expr->getKind() == MCExpr::SymbolRef) {
1966       MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1967       const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
1968       const StringRef DefSymbol = Ref->getSymbol().getName();
1969       if (DefSymbol.startswith("$")) {
1970         int RegNum = -1;
1971         APInt IntVal(32, -1);
1972         if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1973           RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1974                                          isMips64() ? Mips::GPR64RegClassID
1975                                                     : Mips::GPR32RegClassID);
1976         else {
1977           // Lookup for the register with the corresponding name.
1978           switch (Kind) {
1979           case MipsOperand::Kind_AFGR64Regs:
1980           case MipsOperand::Kind_FGR64Regs:
1981             RegNum = matchFPURegisterName(DefSymbol.substr(1));
1982             break;
1983           case MipsOperand::Kind_FGR32Regs:
1984             RegNum = matchFPURegisterName(DefSymbol.substr(1));
1985             break;
1986           case MipsOperand::Kind_GPR64:
1987           case MipsOperand::Kind_GPR32:
1988           default:
1989             RegNum = matchCPURegisterName(DefSymbol.substr(1));
1990             break;
1991           }
1992           if (RegNum > -1)
1993             RegNum = getReg(regKindToRegClass(Kind), RegNum);
1994         }
1995         if (RegNum > -1) {
1996           Parser.Lex();
1997           MipsOperand *op =
1998               MipsOperand::CreateReg(RegNum, S, Parser.getTok().getLoc());
1999           op->setRegKind(Kind);
2000           Operands.push_back(op);
2001           return true;
2002         }
2003       }
2004     } else if (Expr->getKind() == MCExpr::Constant) {
2005       Parser.Lex();
2006       const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
2007       MipsOperand *op =
2008           MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc());
2009       Operands.push_back(op);
2010       return true;
2011     }
2012   }
2013   return false;
2014 }
2015
2016 MipsAsmParser::OperandMatchResultTy
2017 MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2018   return parseRegs(Operands, (int)MipsOperand::Kind_HWRegs);
2019 }
2020
2021 MipsAsmParser::OperandMatchResultTy
2022 MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2023   return parseRegs(Operands, (int)MipsOperand::Kind_CCRRegs);
2024 }
2025
2026 MipsAsmParser::OperandMatchResultTy
2027 MipsAsmParser::parseInvNum(SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2028   const MCExpr *IdVal;
2029   // If the first token is '$' we may have register operand.
2030   if (Parser.getTok().is(AsmToken::Dollar))
2031     return MatchOperand_NoMatch;
2032   SMLoc S = Parser.getTok().getLoc();
2033   if (getParser().parseExpression(IdVal))
2034     return MatchOperand_ParseFail;
2035   const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
2036   assert(MCE && "Unexpected MCExpr type.");
2037   int64_t Val = MCE->getValue();
2038   SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2039   Operands.push_back(MipsOperand::CreateImm(
2040       MCConstantExpr::Create(0 - Val, getContext()), S, E));
2041   return MatchOperand_Success;
2042 }
2043
2044 MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
2045
2046   MCSymbolRefExpr::VariantKind VK =
2047       StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
2048           .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
2049           .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
2050           .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
2051           .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
2052           .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
2053           .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
2054           .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
2055           .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
2056           .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
2057           .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
2058           .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
2059           .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
2060           .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
2061           .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
2062           .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
2063           .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
2064           .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
2065           .Default(MCSymbolRefExpr::VK_None);
2066
2067   return VK;
2068 }
2069
2070 bool MipsAsmParser::ParseInstruction(
2071     ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
2072     SmallVectorImpl<MCParsedAsmOperand *> &Operands) {
2073   // Check if we have valid mnemonic
2074   if (!mnemonicIsValid(Name, 0)) {
2075     Parser.eatToEndOfStatement();
2076     return Error(NameLoc, "Unknown instruction");
2077   }
2078   // First operand in MCInst is instruction mnemonic.
2079   Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
2080
2081   // Read the remaining operands.
2082   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2083     // Read the first operand.
2084     if (ParseOperand(Operands, Name)) {
2085       SMLoc Loc = getLexer().getLoc();
2086       Parser.eatToEndOfStatement();
2087       return Error(Loc, "unexpected token in argument list");
2088     }
2089
2090     while (getLexer().is(AsmToken::Comma)) {
2091       Parser.Lex(); // Eat the comma.
2092       // Parse and remember the operand.
2093       if (ParseOperand(Operands, Name)) {
2094         SMLoc Loc = getLexer().getLoc();
2095         Parser.eatToEndOfStatement();
2096         return Error(Loc, "unexpected token in argument list");
2097       }
2098     }
2099   }
2100   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2101     SMLoc Loc = getLexer().getLoc();
2102     Parser.eatToEndOfStatement();
2103     return Error(Loc, "unexpected token in argument list");
2104   }
2105   Parser.Lex(); // Consume the EndOfStatement.
2106   return false;
2107 }
2108
2109 bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
2110   SMLoc Loc = getLexer().getLoc();
2111   Parser.eatToEndOfStatement();
2112   return Error(Loc, ErrorMsg);
2113 }
2114
2115 bool MipsAsmParser::parseSetNoAtDirective() {
2116   // Line should look like: ".set noat".
2117   // set at reg to 0.
2118   Options.setATReg(0);
2119   // eat noat
2120   Parser.Lex();
2121   // If this is not the end of the statement, report an error.
2122   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2123     reportParseError("unexpected token in statement");
2124     return false;
2125   }
2126   Parser.Lex(); // Consume the EndOfStatement.
2127   return false;
2128 }
2129
2130 bool MipsAsmParser::parseSetAtDirective() {
2131   // Line can be .set at - defaults to $1
2132   // or .set at=$reg
2133   int AtRegNo;
2134   getParser().Lex();
2135   if (getLexer().is(AsmToken::EndOfStatement)) {
2136     Options.setATReg(1);
2137     Parser.Lex(); // Consume the EndOfStatement.
2138     return false;
2139   } else if (getLexer().is(AsmToken::Equal)) {
2140     getParser().Lex(); // Eat the '='.
2141     if (getLexer().isNot(AsmToken::Dollar)) {
2142       reportParseError("unexpected token in statement");
2143       return false;
2144     }
2145     Parser.Lex(); // Eat the '$'.
2146     const AsmToken &Reg = Parser.getTok();
2147     if (Reg.is(AsmToken::Identifier)) {
2148       AtRegNo = matchCPURegisterName(Reg.getIdentifier());
2149     } else if (Reg.is(AsmToken::Integer)) {
2150       AtRegNo = Reg.getIntVal();
2151     } else {
2152       reportParseError("unexpected token in statement");
2153       return false;
2154     }
2155
2156     if (AtRegNo < 1 || AtRegNo > 31) {
2157       reportParseError("unexpected token in statement");
2158       return false;
2159     }
2160
2161     if (!Options.setATReg(AtRegNo)) {
2162       reportParseError("unexpected token in statement");
2163       return false;
2164     }
2165     getParser().Lex(); // Eat the register.
2166
2167     if (getLexer().isNot(AsmToken::EndOfStatement)) {
2168       reportParseError("unexpected token in statement");
2169       return false;
2170     }
2171     Parser.Lex(); // Consume the EndOfStatement.
2172     return false;
2173   } else {
2174     reportParseError("unexpected token in statement");
2175     return false;
2176   }
2177 }
2178
2179 bool MipsAsmParser::parseSetReorderDirective() {
2180   Parser.Lex();
2181   // If this is not the end of the statement, report an error.
2182   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2183     reportParseError("unexpected token in statement");
2184     return false;
2185   }
2186   Options.setReorder();
2187   Parser.Lex(); // Consume the EndOfStatement.
2188   return false;
2189 }
2190
2191 bool MipsAsmParser::parseSetNoReorderDirective() {
2192   Parser.Lex();
2193   // If this is not the end of the statement, report an error.
2194   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2195     reportParseError("unexpected token in statement");
2196     return false;
2197   }
2198   Options.setNoreorder();
2199   Parser.Lex(); // Consume the EndOfStatement.
2200   return false;
2201 }
2202
2203 bool MipsAsmParser::parseSetMacroDirective() {
2204   Parser.Lex();
2205   // If this is not the end of the statement, report an error.
2206   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2207     reportParseError("unexpected token in statement");
2208     return false;
2209   }
2210   Options.setMacro();
2211   Parser.Lex(); // Consume the EndOfStatement.
2212   return false;
2213 }
2214
2215 bool MipsAsmParser::parseSetNoMacroDirective() {
2216   Parser.Lex();
2217   // If this is not the end of the statement, report an error.
2218   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2219     reportParseError("`noreorder' must be set before `nomacro'");
2220     return false;
2221   }
2222   if (Options.isReorder()) {
2223     reportParseError("`noreorder' must be set before `nomacro'");
2224     return false;
2225   }
2226   Options.setNomacro();
2227   Parser.Lex(); // Consume the EndOfStatement.
2228   return false;
2229 }
2230
2231 bool MipsAsmParser::parseSetAssignment() {
2232   StringRef Name;
2233   const MCExpr *Value;
2234
2235   if (Parser.parseIdentifier(Name))
2236     reportParseError("expected identifier after .set");
2237
2238   if (getLexer().isNot(AsmToken::Comma))
2239     return reportParseError("unexpected token in .set directive");
2240   Lex(); // Eat comma
2241
2242   if (getLexer().is(AsmToken::Dollar)) {
2243     MCSymbol *Symbol;
2244     SMLoc DollarLoc = getLexer().getLoc();
2245     // Consume the dollar sign, and check for a following identifier.
2246     Parser.Lex();
2247     // We have a '$' followed by something, make sure they are adjacent.
2248     if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
2249       return true;
2250     StringRef Res =
2251         StringRef(DollarLoc.getPointer(),
2252                   getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
2253     Symbol = getContext().GetOrCreateSymbol(Res);
2254     Parser.Lex();
2255     Value =
2256         MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None, getContext());
2257   } else if (Parser.parseExpression(Value))
2258     return reportParseError("expected valid expression after comma");
2259
2260   // Check if the Name already exists as a symbol.
2261   MCSymbol *Sym = getContext().LookupSymbol(Name);
2262   if (Sym)
2263     return reportParseError("symbol already defined");
2264   Sym = getContext().GetOrCreateSymbol(Name);
2265   Sym->setVariableValue(Value);
2266
2267   return false;
2268 }
2269
2270 bool MipsAsmParser::parseDirectiveSet() {
2271
2272   // Get the next token.
2273   const AsmToken &Tok = Parser.getTok();
2274
2275   if (Tok.getString() == "noat") {
2276     return parseSetNoAtDirective();
2277   } else if (Tok.getString() == "at") {
2278     return parseSetAtDirective();
2279   } else if (Tok.getString() == "reorder") {
2280     return parseSetReorderDirective();
2281   } else if (Tok.getString() == "noreorder") {
2282     return parseSetNoReorderDirective();
2283   } else if (Tok.getString() == "macro") {
2284     return parseSetMacroDirective();
2285   } else if (Tok.getString() == "nomacro") {
2286     return parseSetNoMacroDirective();
2287   } else if (Tok.getString() == "nomips16") {
2288     // Ignore this directive for now.
2289     Parser.eatToEndOfStatement();
2290     return false;
2291   } else if (Tok.getString() == "nomicromips") {
2292     // Ignore this directive for now.
2293     Parser.eatToEndOfStatement();
2294     return false;
2295   } else {
2296     // It is just an identifier, look for an assignment.
2297     parseSetAssignment();
2298     return false;
2299   }
2300
2301   return true;
2302 }
2303
2304 bool MipsAsmParser::parseDirectiveMipsHackStocg() {
2305   MCAsmParser &Parser = getParser();
2306   StringRef Name;
2307   if (Parser.parseIdentifier(Name))
2308     reportParseError("expected identifier");
2309
2310   MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
2311   if (getLexer().isNot(AsmToken::Comma))
2312     return TokError("unexpected token");
2313   Lex();
2314
2315   int64_t Flags = 0;
2316   if (Parser.parseAbsoluteExpression(Flags))
2317     return TokError("unexpected token");
2318
2319   getTargetStreamer().emitMipsHackSTOCG(Sym, Flags);
2320   return false;
2321 }
2322
2323 bool MipsAsmParser::parseDirectiveMipsHackELFFlags() {
2324   int64_t Flags = 0;
2325   if (Parser.parseAbsoluteExpression(Flags))
2326     return TokError("unexpected token");
2327
2328   getTargetStreamer().emitMipsHackELFFlags(Flags);
2329   return false;
2330 }
2331
2332 /// parseDirectiveWord
2333 ///  ::= .word [ expression (, expression)* ]
2334 bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
2335   if (getLexer().isNot(AsmToken::EndOfStatement)) {
2336     for (;;) {
2337       const MCExpr *Value;
2338       if (getParser().parseExpression(Value))
2339         return true;
2340
2341       getParser().getStreamer().EmitValue(Value, Size);
2342
2343       if (getLexer().is(AsmToken::EndOfStatement))
2344         break;
2345
2346       // FIXME: Improve diagnostic.
2347       if (getLexer().isNot(AsmToken::Comma))
2348         return Error(L, "unexpected token in directive");
2349       Parser.Lex();
2350     }
2351   }
2352
2353   Parser.Lex();
2354   return false;
2355 }
2356
2357 /// parseDirectiveGpWord
2358 ///  ::= .gpword local_sym
2359 bool MipsAsmParser::parseDirectiveGpWord() {
2360   const MCExpr *Value;
2361   // EmitGPRel32Value requires an expression, so we are using base class
2362   // method to evaluate the expression.
2363   if (getParser().parseExpression(Value))
2364     return true;
2365
2366   getParser().getStreamer().EmitGPRel32Value(Value);
2367   Parser.Lex(); // Eat last token.
2368
2369   if (getLexer().is(AsmToken::EndOfStatement))
2370     return Error(getLexer().getLoc(), "unexpected token in directive");
2371
2372   return false;
2373 }
2374
2375 bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2376
2377   StringRef IDVal = DirectiveID.getString();
2378
2379   if (IDVal == ".ent") {
2380     // Ignore this directive for now.
2381     Parser.Lex();
2382     return false;
2383   }
2384
2385   if (IDVal == ".end") {
2386     // Ignore this directive for now.
2387     Parser.Lex();
2388     return false;
2389   }
2390
2391   if (IDVal == ".frame") {
2392     // Ignore this directive for now.
2393     Parser.eatToEndOfStatement();
2394     return false;
2395   }
2396
2397   if (IDVal == ".set") {
2398     return parseDirectiveSet();
2399   }
2400
2401   if (IDVal == ".fmask") {
2402     // Ignore this directive for now.
2403     Parser.eatToEndOfStatement();
2404     return false;
2405   }
2406
2407   if (IDVal == ".mask") {
2408     // Ignore this directive for now.
2409     Parser.eatToEndOfStatement();
2410     return false;
2411   }
2412
2413   if (IDVal == ".gpword") {
2414     // Ignore this directive for now.
2415     parseDirectiveGpWord();
2416     return false;
2417   }
2418
2419   if (IDVal == ".word") {
2420     parseDirectiveWord(4, DirectiveID.getLoc());
2421     return false;
2422   }
2423
2424   if (IDVal == ".mips_hack_stocg")
2425     return parseDirectiveMipsHackStocg();
2426
2427   if (IDVal == ".mips_hack_elf_flags")
2428     return parseDirectiveMipsHackELFFlags();
2429
2430   return true;
2431 }
2432
2433 extern "C" void LLVMInitializeMipsAsmParser() {
2434   RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
2435   RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
2436   RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
2437   RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
2438 }
2439
2440 #define GET_REGISTER_MATCHER
2441 #define GET_MATCHER_IMPLEMENTATION
2442 #include "MipsGenAsmMatcher.inc"