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