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