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