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