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