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