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