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