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