MipsAsmParser.cpp revision c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8
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  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
88
89  MipsAsmParser::OperandMatchResultTy
90  parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
91
92  MipsAsmParser::OperandMatchResultTy
93  parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
94
95  MipsAsmParser::OperandMatchResultTy
96  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
97
98  MipsAsmParser::OperandMatchResultTy
99  parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
100
101  MipsAsmParser::OperandMatchResultTy
102  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
103
104  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
105                         unsigned RegisterClass);
106
107  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
108                    StringRef Mnemonic);
109
110  int tryParseRegister(bool is64BitReg);
111
112  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
113                               bool is64BitReg);
114
115  bool needsExpansion(MCInst &Inst);
116
117  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
118                         SmallVectorImpl<MCInst> &Instructions);
119  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
120                     SmallVectorImpl<MCInst> &Instructions);
121  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
122                            SmallVectorImpl<MCInst> &Instructions);
123  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
124                            SmallVectorImpl<MCInst> &Instructions);
125  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
126                     SmallVectorImpl<MCInst> &Instructions,
127                     bool isLoad,bool isImmOpnd);
128  bool reportParseError(StringRef ErrorMsg);
129
130  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
131  bool parseRelocOperand(const MCExpr *&Res);
132
133  const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
134
135  bool isEvaluated(const MCExpr *Expr);
136  bool parseDirectiveSet();
137
138  bool parseSetAtDirective();
139  bool parseSetNoAtDirective();
140  bool parseSetMacroDirective();
141  bool parseSetNoMacroDirective();
142  bool parseSetReorderDirective();
143  bool parseSetNoReorderDirective();
144
145  bool parseSetAssignment();
146
147  bool parseDirectiveWord(unsigned Size, SMLoc L);
148
149  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
150
151  bool isMips64() const {
152    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
153  }
154
155  bool isFP64() const {
156    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
157  }
158
159  int matchRegisterName(StringRef Symbol, bool is64BitReg);
160
161  int matchCPURegisterName(StringRef Symbol);
162
163  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
164
165  void setFpFormat(FpFormatTy Format) {
166    FpFormat = Format;
167  }
168
169  void setDefaultFpFormat();
170
171  void setFpFormat(StringRef Format);
172
173  FpFormatTy getFpFormat() {return FpFormat;}
174
175  bool requestsDoubleOperand(StringRef Mnemonic);
176
177  unsigned getReg(int RC, int RegNo);
178
179  int getATReg();
180
181  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
182                        SmallVectorImpl<MCInst> &Instructions);
183public:
184  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
185    : MCTargetAsmParser(), STI(sti), Parser(parser) {
186    // Initialize the set of available features.
187    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
188  }
189
190  MCAsmParser &getParser() const { return Parser; }
191  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
192
193};
194}
195
196namespace {
197
198/// MipsOperand - Instances of this class represent a parsed Mips machine
199/// instruction.
200class MipsOperand : public MCParsedAsmOperand {
201
202public:
203  enum RegisterKind {
204    Kind_None,
205    Kind_CPURegs,
206    Kind_CPU64Regs,
207    Kind_HWRegs,
208    Kind_HW64Regs,
209    Kind_FGR32Regs,
210    Kind_FGR64Regs,
211    Kind_AFGR64Regs,
212    Kind_CCRRegs
213  };
214
215private:
216  enum KindTy {
217    k_CondCode,
218    k_CoprocNum,
219    k_Immediate,
220    k_Memory,
221    k_PostIndexRegister,
222    k_Register,
223    k_Token
224  } Kind;
225
226  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
227
228  struct Token {
229    const char *Data;
230    unsigned Length;
231  };
232
233  struct RegOp {
234    unsigned RegNum;
235    RegisterKind Kind;
236  };
237
238  struct ImmOp {
239    const MCExpr *Val;
240  };
241
242  struct MemOp {
243    unsigned Base;
244    const MCExpr *Off;
245  };
246
247  union {
248    struct Token Tok;
249    struct RegOp Reg;
250    struct ImmOp Imm;
251    struct MemOp Mem;
252  };
253
254  SMLoc StartLoc, EndLoc;
255
256public:
257  void addRegOperands(MCInst &Inst, unsigned N) const {
258    assert(N == 1 && "Invalid number of operands!");
259    Inst.addOperand(MCOperand::CreateReg(getReg()));
260  }
261
262  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
263    // Add as immediate when possible.  Null MCExpr = 0.
264    if (Expr == 0)
265      Inst.addOperand(MCOperand::CreateImm(0));
266    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
267      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
268    else
269      Inst.addOperand(MCOperand::CreateExpr(Expr));
270  }
271
272  void addImmOperands(MCInst &Inst, unsigned N) const {
273    assert(N == 1 && "Invalid number of operands!");
274    const MCExpr *Expr = getImm();
275    addExpr(Inst, Expr);
276  }
277
278  void addMemOperands(MCInst &Inst, unsigned N) const {
279    assert(N == 2 && "Invalid number of operands!");
280
281    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
282
283    const MCExpr *Expr = getMemOff();
284    addExpr(Inst, Expr);
285  }
286
287  bool isReg() const { return Kind == k_Register; }
288  bool isImm() const { return Kind == k_Immediate; }
289  bool isToken() const { return Kind == k_Token; }
290  bool isMem() const { return Kind == k_Memory; }
291
292  StringRef getToken() const {
293    assert(Kind == k_Token && "Invalid access!");
294    return StringRef(Tok.Data, Tok.Length);
295  }
296
297  unsigned getReg() const {
298    assert((Kind == k_Register) && "Invalid access!");
299    return Reg.RegNum;
300  }
301
302  void setRegKind(RegisterKind RegKind) {
303    assert((Kind == k_Register) && "Invalid access!");
304    Reg.Kind = RegKind;
305  }
306
307  const MCExpr *getImm() const {
308    assert((Kind == k_Immediate) && "Invalid access!");
309    return Imm.Val;
310  }
311
312  unsigned getMemBase() const {
313    assert((Kind == k_Memory) && "Invalid access!");
314    return Mem.Base;
315  }
316
317  const MCExpr *getMemOff() const {
318    assert((Kind == k_Memory) && "Invalid access!");
319    return Mem.Off;
320  }
321
322  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
323    MipsOperand *Op = new MipsOperand(k_Token);
324    Op->Tok.Data = Str.data();
325    Op->Tok.Length = Str.size();
326    Op->StartLoc = S;
327    Op->EndLoc = S;
328    return Op;
329  }
330
331  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
332    MipsOperand *Op = new MipsOperand(k_Register);
333    Op->Reg.RegNum = RegNum;
334    Op->StartLoc = S;
335    Op->EndLoc = E;
336    return Op;
337  }
338
339  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
340    MipsOperand *Op = new MipsOperand(k_Immediate);
341    Op->Imm.Val = Val;
342    Op->StartLoc = S;
343    Op->EndLoc = E;
344    return Op;
345  }
346
347  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
348                                 SMLoc S, SMLoc E) {
349    MipsOperand *Op = new MipsOperand(k_Memory);
350    Op->Mem.Base = Base;
351    Op->Mem.Off = Off;
352    Op->StartLoc = S;
353    Op->EndLoc = E;
354    return Op;
355  }
356
357  bool isCPURegsAsm() const {
358    return Kind == k_Register && Reg.Kind == Kind_CPURegs;
359  }
360  void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const {
361    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
362  }
363
364  bool isCPU64RegsAsm() const {
365    return Kind == k_Register && Reg.Kind == Kind_CPU64Regs;
366  }
367  void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const {
368    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
369  }
370
371  bool isHWRegsAsm() const {
372    assert((Kind == k_Register) && "Invalid access!");
373    return Reg.Kind == Kind_HWRegs;
374  }
375  void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const {
376    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
377  }
378
379  bool isHW64RegsAsm() const {
380    assert((Kind == k_Register) && "Invalid access!");
381    return Reg.Kind == Kind_HW64Regs;
382  }
383  void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const {
384    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
385  }
386
387  void addCCRAsmOperands(MCInst &Inst, unsigned N) const {
388    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
389  }
390
391  bool isCCRAsm() const {
392    assert((Kind == k_Register) && "Invalid access!");
393    return Reg.Kind == Kind_CCRRegs;
394  }
395
396  /// getStartLoc - Get the location of the first token of this operand.
397  SMLoc getStartLoc() const {
398    return StartLoc;
399  }
400  /// getEndLoc - Get the location of the last token of this operand.
401  SMLoc getEndLoc() const {
402    return EndLoc;
403  }
404
405  virtual void print(raw_ostream &OS) const {
406    llvm_unreachable("unimplemented!");
407  }
408}; // class MipsOperand
409}  // namespace
410
411namespace llvm {
412extern const MCInstrDesc MipsInsts[];
413}
414static const MCInstrDesc &getInstDesc(unsigned Opcode) {
415  return MipsInsts[Opcode];
416}
417
418bool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
419                                       SmallVectorImpl<MCInst> &Instructions) {
420  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
421  Inst.setLoc(IDLoc);
422  if (MCID.hasDelaySlot() && Options.isReorder()) {
423    // If this instruction has a delay slot and .set reorder is active,
424    // emit a NOP after it.
425    Instructions.push_back(Inst);
426    MCInst NopInst;
427    NopInst.setOpcode(Mips::SLL);
428    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
429    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
430    NopInst.addOperand(MCOperand::CreateImm(0));
431    Instructions.push_back(NopInst);
432    return false;
433  }
434
435  if (MCID.mayLoad() || MCID.mayStore()) {
436    // Check the offset of memory operand, if it is a symbol
437    // reference or immediate we may have to expand instructions.
438    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
439      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
440      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
441          || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
442        MCOperand &Op = Inst.getOperand(i);
443        if (Op.isImm()) {
444          int MemOffset = Op.getImm();
445          if (MemOffset < -32768 || MemOffset > 32767) {
446            // Offset can't exceed 16bit value.
447            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
448            return false;
449          }
450        } else if (Op.isExpr()) {
451          const MCExpr *Expr = Op.getExpr();
452          if (Expr->getKind() == MCExpr::SymbolRef) {
453            const MCSymbolRefExpr *SR =
454                static_cast<const MCSymbolRefExpr*>(Expr);
455            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
456              // Expand symbol.
457              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
458              return false;
459            }
460          } else if (!isEvaluated(Expr)) {
461            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
462            return false;
463          }
464        }
465      }
466    } // for
467  } // if load/store
468
469  if (needsExpansion(Inst))
470    expandInstruction(Inst, IDLoc, Instructions);
471  else
472    Instructions.push_back(Inst);
473
474  return false;
475}
476
477bool MipsAsmParser::needsExpansion(MCInst &Inst) {
478
479  switch (Inst.getOpcode()) {
480  case Mips::LoadImm32Reg:
481  case Mips::LoadAddr32Imm:
482  case Mips::LoadAddr32Reg:
483    return true;
484  default:
485    return false;
486  }
487}
488
489void MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
490                                       SmallVectorImpl<MCInst> &Instructions) {
491  switch (Inst.getOpcode()) {
492  case Mips::LoadImm32Reg:
493    return expandLoadImm(Inst, IDLoc, Instructions);
494  case Mips::LoadAddr32Imm:
495    return expandLoadAddressImm(Inst, IDLoc, Instructions);
496  case Mips::LoadAddr32Reg:
497    return expandLoadAddressReg(Inst, IDLoc, Instructions);
498  }
499}
500
501void MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
502                                  SmallVectorImpl<MCInst> &Instructions) {
503  MCInst tmpInst;
504  const MCOperand &ImmOp = Inst.getOperand(1);
505  assert(ImmOp.isImm() && "expected immediate operand kind");
506  const MCOperand &RegOp = Inst.getOperand(0);
507  assert(RegOp.isReg() && "expected register operand kind");
508
509  int ImmValue = ImmOp.getImm();
510  tmpInst.setLoc(IDLoc);
511  if (0 <= ImmValue && ImmValue <= 65535) {
512    // For 0 <= j <= 65535.
513    // li d,j => ori d,$zero,j
514    tmpInst.setOpcode(Mips::ORi);
515    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
516    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
517    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
518    Instructions.push_back(tmpInst);
519  } else if (ImmValue < 0 && ImmValue >= -32768) {
520    // For -32768 <= j < 0.
521    // li d,j => addiu d,$zero,j
522    tmpInst.setOpcode(Mips::ADDiu);
523    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
524    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
525    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
526    Instructions.push_back(tmpInst);
527  } else {
528    // For any other value of j that is representable as a 32-bit integer.
529    // li d,j => lui d,hi16(j)
530    //           ori d,d,lo16(j)
531    tmpInst.setOpcode(Mips::LUi);
532    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
533    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
534    Instructions.push_back(tmpInst);
535    tmpInst.clear();
536    tmpInst.setOpcode(Mips::ORi);
537    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
538    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
539    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
540    tmpInst.setLoc(IDLoc);
541    Instructions.push_back(tmpInst);
542  }
543}
544
545void MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
546                                       SmallVectorImpl<MCInst> &Instructions) {
547  MCInst tmpInst;
548  const MCOperand &ImmOp = Inst.getOperand(2);
549  assert(ImmOp.isImm() && "expected immediate operand kind");
550  const MCOperand &SrcRegOp = Inst.getOperand(1);
551  assert(SrcRegOp.isReg() && "expected register operand kind");
552  const MCOperand &DstRegOp = Inst.getOperand(0);
553  assert(DstRegOp.isReg() && "expected register operand kind");
554  int ImmValue = ImmOp.getImm();
555  if (-32768 <= ImmValue && ImmValue <= 65535) {
556    // For -32768 <= j <= 65535.
557    // la d,j(s) => addiu d,s,j
558    tmpInst.setOpcode(Mips::ADDiu);
559    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
560    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
561    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
562    Instructions.push_back(tmpInst);
563  } else {
564    // For any other value of j that is representable as a 32-bit integer.
565    // la d,j(s) => lui d,hi16(j)
566    //              ori d,d,lo16(j)
567    //              addu d,d,s
568    tmpInst.setOpcode(Mips::LUi);
569    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
570    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
571    Instructions.push_back(tmpInst);
572    tmpInst.clear();
573    tmpInst.setOpcode(Mips::ORi);
574    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
575    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
576    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
577    Instructions.push_back(tmpInst);
578    tmpInst.clear();
579    tmpInst.setOpcode(Mips::ADDu);
580    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
581    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
582    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
583    Instructions.push_back(tmpInst);
584  }
585}
586
587void MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
588                                       SmallVectorImpl<MCInst> &Instructions) {
589  MCInst tmpInst;
590  const MCOperand &ImmOp = Inst.getOperand(1);
591  assert(ImmOp.isImm() && "expected immediate operand kind");
592  const MCOperand &RegOp = Inst.getOperand(0);
593  assert(RegOp.isReg() && "expected register operand kind");
594  int ImmValue = ImmOp.getImm();
595  if (-32768 <= ImmValue && ImmValue <= 65535) {
596    // For -32768 <= j <= 65535.
597    // la d,j => addiu d,$zero,j
598    tmpInst.setOpcode(Mips::ADDiu);
599    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
600    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
601    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
602    Instructions.push_back(tmpInst);
603  } else {
604    // For any other value of j that is representable as a 32-bit integer.
605    // la d,j => lui d,hi16(j)
606    //           ori d,d,lo16(j)
607    tmpInst.setOpcode(Mips::LUi);
608    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
609    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
610    Instructions.push_back(tmpInst);
611    tmpInst.clear();
612    tmpInst.setOpcode(Mips::ORi);
613    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
614    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
615    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
616    Instructions.push_back(tmpInst);
617  }
618}
619
620void MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
621          SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
622  const MCSymbolRefExpr *SR;
623  MCInst TempInst;
624  unsigned ImmOffset, HiOffset, LoOffset;
625  const MCExpr *ExprOffset;
626  unsigned TmpRegNum;
627  unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID
628                             : Mips::CPURegsRegClassID, getATReg());
629  // 1st operand is either the source or destination register.
630  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
631  unsigned RegOpNum = Inst.getOperand(0).getReg();
632  // 2nd operand is the base register.
633  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
634  unsigned BaseRegNum = Inst.getOperand(1).getReg();
635  // 3rd operand is either an immediate or expression.
636  if (isImmOpnd) {
637    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
638    ImmOffset = Inst.getOperand(2).getImm();
639    LoOffset = ImmOffset & 0x0000ffff;
640    HiOffset = (ImmOffset & 0xffff0000) >> 16;
641    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
642    if (LoOffset & 0x8000)
643      HiOffset++;
644  } else
645    ExprOffset = Inst.getOperand(2).getExpr();
646  // All instructions will have the same location.
647  TempInst.setLoc(IDLoc);
648  // 1st instruction in expansion is LUi. For load instruction we can use
649  // the dst register as a temporary if base and dst are different,
650  // but for stores we must use $at.
651  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
652  TempInst.setOpcode(Mips::LUi);
653  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
654  if (isImmOpnd)
655    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
656  else {
657    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
658      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
659      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
660          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
661          getContext());
662      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
663    } else {
664      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
665      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
666    }
667  }
668  // Add the instruction to the list.
669  Instructions.push_back(TempInst);
670  // Prepare TempInst for next instruction.
671  TempInst.clear();
672  // Add temp register to base.
673  TempInst.setOpcode(Mips::ADDu);
674  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
675  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
676  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
677  Instructions.push_back(TempInst);
678  TempInst.clear();
679  // And finaly, create original instruction with low part
680  // of offset and new base.
681  TempInst.setOpcode(Inst.getOpcode());
682  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
683  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
684  if (isImmOpnd)
685    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
686  else {
687    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
688      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
689          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
690          getContext());
691      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
692    } else {
693      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
694      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
695    }
696  }
697  Instructions.push_back(TempInst);
698  TempInst.clear();
699}
700
701bool MipsAsmParser::
702MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
703                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
704                        MCStreamer &Out, unsigned &ErrorInfo,
705                        bool MatchingInlineAsm) {
706  MCInst Inst;
707  SmallVector<MCInst, 8> Instructions;
708  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
709                                              MatchingInlineAsm);
710
711  switch (MatchResult) {
712  default:
713    break;
714  case Match_Success: {
715    if (processInstruction(Inst, IDLoc, Instructions))
716      return true;
717    for (unsigned i = 0; i < Instructions.size(); i++)
718      Out.EmitInstruction(Instructions[i]);
719    return false;
720  }
721  case Match_MissingFeature:
722    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
723    return true;
724  case Match_InvalidOperand: {
725    SMLoc ErrorLoc = IDLoc;
726    if (ErrorInfo != ~0U) {
727      if (ErrorInfo >= Operands.size())
728        return Error(IDLoc, "too few operands for instruction");
729
730      ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
731      if (ErrorLoc == SMLoc())
732        ErrorLoc = IDLoc;
733    }
734
735    return Error(ErrorLoc, "invalid operand for instruction");
736  }
737  case Match_MnemonicFail:
738    return Error(IDLoc, "invalid instruction");
739  }
740  return true;
741}
742
743int MipsAsmParser::matchCPURegisterName(StringRef Name) {
744   int CC;
745
746  if (Name == "at")
747    return getATReg();
748
749    CC = StringSwitch<unsigned>(Name)
750    .Case("zero", 0)
751    .Case("a0",   4)
752    .Case("a1",   5)
753    .Case("a2",   6)
754    .Case("a3",   7)
755    .Case("v0",   2)
756    .Case("v1",   3)
757    .Case("s0",  16)
758    .Case("s1",  17)
759    .Case("s2",  18)
760    .Case("s3",  19)
761    .Case("s4",  20)
762    .Case("s5",  21)
763    .Case("s6",  22)
764    .Case("s7",  23)
765    .Case("k0",  26)
766    .Case("k1",  27)
767    .Case("sp",  29)
768    .Case("fp",  30)
769    .Case("gp",  28)
770    .Case("ra",  31)
771    .Case("t0",   8)
772    .Case("t1",   9)
773    .Case("t2",  10)
774    .Case("t3",  11)
775    .Case("t4",  12)
776    .Case("t5",  13)
777    .Case("t6",  14)
778    .Case("t7",  15)
779    .Case("t8",  24)
780    .Case("t9",  25)
781    .Default(-1);
782
783  // Although SGI documentation just cuts out t0-t3 for n32/n64,
784  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
785  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
786  if (isMips64() && 8 <= CC && CC <= 11)
787    CC += 4;
788
789  if (CC == -1 && isMips64())
790    CC = StringSwitch<unsigned>(Name)
791      .Case("a4",   8)
792      .Case("a5",   9)
793      .Case("a6",  10)
794      .Case("a7",  11)
795      .Case("kt0", 26)
796      .Case("kt1", 27)
797      .Case("s8",  30)
798      .Default(-1);
799
800  return CC;
801}
802
803int MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
804
805  if (Name.equals("fcc0"))
806    return Mips::FCC0;
807
808  int CC;
809  CC = matchCPURegisterName(Name);
810  if (CC != -1)
811    return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID
812                                                : Mips::CPURegsRegClassID);
813
814  if (Name[0] == 'f') {
815    StringRef NumString = Name.substr(1);
816    unsigned IntVal;
817    if (NumString.getAsInteger(10, IntVal))
818      return -1; // This is not an integer.
819    if (IntVal > 31)
820      return -1;
821
822    FpFormatTy Format = getFpFormat();
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
837  return -1;
838}
839
840void MipsAsmParser::setDefaultFpFormat() {
841
842  if (isMips64() || isFP64())
843    FpFormat = FP_FORMAT_D;
844  else
845    FpFormat = FP_FORMAT_S;
846}
847
848bool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
849
850  bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
851    .Case("ldxc1", true)
852    .Case("ldc1",  true)
853    .Case("sdxc1", true)
854    .Case("sdc1",  true)
855    .Default(false);
856
857  return IsDouble;
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::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1257
1258  if (!isMips64())
1259    return MatchOperand_NoMatch;
1260  if (getLexer().getKind() == AsmToken::Identifier) {
1261    if (searchSymbolAlias(Operands, MipsOperand::Kind_CPU64Regs))
1262      return MatchOperand_Success;
1263    return MatchOperand_NoMatch;
1264  }
1265  // If the first token is not '$', we have an error.
1266  if (Parser.getTok().isNot(AsmToken::Dollar))
1267    return MatchOperand_NoMatch;
1268
1269  Parser.Lex(); // Eat $
1270  if (!tryParseRegisterOperand(Operands, true)) {
1271    // Set the proper register kind.
1272    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1273    op->setRegKind(MipsOperand::Kind_CPU64Regs);
1274    return MatchOperand_Success;
1275  }
1276  return MatchOperand_NoMatch;
1277}
1278
1279bool MipsAsmParser::searchSymbolAlias(
1280    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegisterKind) {
1281
1282  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1283  if (Sym) {
1284    SMLoc S = Parser.getTok().getLoc();
1285    const MCExpr *Expr;
1286    if (Sym->isVariable())
1287      Expr = Sym->getVariableValue();
1288    else
1289      return false;
1290    if (Expr->getKind() == MCExpr::SymbolRef) {
1291      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1292      const StringRef DefSymbol = Ref->getSymbol().getName();
1293      if (DefSymbol.startswith("$")) {
1294        int RegNum = -1;
1295        APInt IntVal(32, -1);
1296        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1297          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1298                                         isMips64()
1299                                           ? Mips::CPU64RegsRegClassID
1300                                           : Mips::CPURegsRegClassID);
1301        else
1302          // Lookup for the register with corresponding name
1303          RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
1304        if (RegNum > -1) {
1305          Parser.Lex();
1306          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
1307                                                   Parser.getTok().getLoc());
1308          op->setRegKind((MipsOperand::RegisterKind) RegisterKind);
1309          Operands.push_back(op);
1310          return true;
1311        }
1312      }
1313    } else if (Expr->getKind() == MCExpr::Constant) {
1314      Parser.Lex();
1315      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1316      MipsOperand *op = MipsOperand::CreateImm(Const, S,
1317                                               Parser.getTok().getLoc());
1318      Operands.push_back(op);
1319      return true;
1320    }
1321  }
1322  return false;
1323}
1324
1325MipsAsmParser::OperandMatchResultTy
1326MipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1327
1328  if (getLexer().getKind() == AsmToken::Identifier) {
1329    if (searchSymbolAlias(Operands, MipsOperand::Kind_CPURegs))
1330      return MatchOperand_Success;
1331    return MatchOperand_NoMatch;
1332  }
1333  // If the first token is not '$' we have an error.
1334  if (Parser.getTok().isNot(AsmToken::Dollar))
1335    return MatchOperand_NoMatch;
1336
1337  Parser.Lex(); // Eat $
1338  if (!tryParseRegisterOperand(Operands, false)) {
1339    // Set the proper register kind.
1340    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1341    op->setRegKind(MipsOperand::Kind_CPURegs);
1342    return MatchOperand_Success;
1343  }
1344  return MatchOperand_NoMatch;
1345}
1346
1347MipsAsmParser::OperandMatchResultTy
1348MipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1349
1350  if (isMips64())
1351    return MatchOperand_NoMatch;
1352
1353  // If the first token is not '$' we have error.
1354  if (Parser.getTok().isNot(AsmToken::Dollar))
1355    return MatchOperand_NoMatch;
1356  SMLoc S = Parser.getTok().getLoc();
1357  Parser.Lex(); // Eat the '$'.
1358
1359  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1360  if (Tok.isNot(AsmToken::Integer))
1361    return MatchOperand_NoMatch;
1362
1363  unsigned RegNum = Tok.getIntVal();
1364  // At the moment only hwreg29 is supported.
1365  if (RegNum != 29)
1366    return MatchOperand_ParseFail;
1367
1368  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1369      Parser.getTok().getLoc());
1370  op->setRegKind(MipsOperand::Kind_HWRegs);
1371  Operands.push_back(op);
1372
1373  Parser.Lex(); // Eat the register number.
1374  return MatchOperand_Success;
1375}
1376
1377MipsAsmParser::OperandMatchResultTy
1378MipsAsmParser::parseHW64Regs(
1379    SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1380
1381  if (!isMips64())
1382    return MatchOperand_NoMatch;
1383  // If the first token is not '$' we have an error.
1384  if (Parser.getTok().isNot(AsmToken::Dollar))
1385    return MatchOperand_NoMatch;
1386  SMLoc S = Parser.getTok().getLoc();
1387  Parser.Lex(); // Eat $
1388
1389  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1390  if (Tok.isNot(AsmToken::Integer))
1391    return MatchOperand_NoMatch;
1392
1393  unsigned RegNum = Tok.getIntVal();
1394  // At the moment only hwreg29 is supported.
1395  if (RegNum != 29)
1396    return MatchOperand_ParseFail;
1397
1398  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1399                                           Parser.getTok().getLoc());
1400  op->setRegKind(MipsOperand::Kind_HW64Regs);
1401  Operands.push_back(op);
1402
1403  Parser.Lex(); // Eat the register number.
1404  return MatchOperand_Success;
1405}
1406
1407MipsAsmParser::OperandMatchResultTy
1408MipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1409  unsigned RegNum;
1410  // If the first token is not '$' we have an error.
1411  if (Parser.getTok().isNot(AsmToken::Dollar))
1412    return MatchOperand_NoMatch;
1413  SMLoc S = Parser.getTok().getLoc();
1414  Parser.Lex(); // Eat the '$'
1415
1416  const AsmToken &Tok = Parser.getTok(); // Get next token.
1417  if (Tok.is(AsmToken::Integer)) {
1418    RegNum = Tok.getIntVal();
1419    // At the moment only fcc0 is supported.
1420    if (RegNum != 0)
1421      return MatchOperand_ParseFail;
1422  } else if (Tok.is(AsmToken::Identifier)) {
1423    // At the moment only fcc0 is supported.
1424    if (Tok.getIdentifier() != "fcc0")
1425      return MatchOperand_ParseFail;
1426  } else
1427    return MatchOperand_NoMatch;
1428
1429  MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1430                                           Parser.getTok().getLoc());
1431  op->setRegKind(MipsOperand::Kind_CCRRegs);
1432  Operands.push_back(op);
1433
1434  Parser.Lex(); // Eat the register number.
1435  return MatchOperand_Success;
1436}
1437
1438MCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
1439
1440  MCSymbolRefExpr::VariantKind VK
1441                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
1442    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
1443    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
1444    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
1445    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
1446    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
1447    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
1448    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
1449    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
1450    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
1451    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
1452    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
1453    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
1454    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
1455    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
1456    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
1457    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
1458    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
1459    .Default(MCSymbolRefExpr::VK_None);
1460
1461  return VK;
1462}
1463
1464static int ConvertCcString(StringRef CondString) {
1465  int CC = StringSwitch<unsigned>(CondString)
1466    .Case(".f",    0)
1467    .Case(".un",   1)
1468    .Case(".eq",   2)
1469    .Case(".ueq",  3)
1470    .Case(".olt",  4)
1471    .Case(".ult",  5)
1472    .Case(".ole",  6)
1473    .Case(".ule",  7)
1474    .Case(".sf",   8)
1475    .Case(".ngle", 9)
1476    .Case(".seq",  10)
1477    .Case(".ngl",  11)
1478    .Case(".lt",   12)
1479    .Case(".nge",  13)
1480    .Case(".le",   14)
1481    .Case(".ngt",  15)
1482    .Default(-1);
1483
1484  return CC;
1485}
1486
1487bool MipsAsmParser::
1488parseMathOperation(StringRef Name, SMLoc NameLoc,
1489                   SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1490  // Split the format.
1491  size_t Start = Name.find('.'), Next = Name.rfind('.');
1492  StringRef Format1 = Name.slice(Start, Next);
1493  // Add the first format to the operands.
1494  Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
1495  // Now for the second format.
1496  StringRef Format2 = Name.slice(Next, StringRef::npos);
1497  Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
1498
1499  // Set the format for the first register.
1500  setFpFormat(Format1);
1501
1502  // Read the remaining operands.
1503  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1504    // Read the first operand.
1505    if (ParseOperand(Operands, Name)) {
1506      SMLoc Loc = getLexer().getLoc();
1507      Parser.eatToEndOfStatement();
1508      return Error(Loc, "unexpected token in argument list");
1509    }
1510
1511    if (getLexer().isNot(AsmToken::Comma)) {
1512      SMLoc Loc = getLexer().getLoc();
1513      Parser.eatToEndOfStatement();
1514      return Error(Loc, "unexpected token in argument list");
1515    }
1516    Parser.Lex(); // Eat the comma.
1517
1518    // Set the format for the first register
1519    setFpFormat(Format2);
1520
1521    // Parse and remember the operand.
1522    if (ParseOperand(Operands, Name)) {
1523      SMLoc Loc = getLexer().getLoc();
1524      Parser.eatToEndOfStatement();
1525      return Error(Loc, "unexpected token in argument list");
1526    }
1527  }
1528
1529  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1530    SMLoc Loc = getLexer().getLoc();
1531    Parser.eatToEndOfStatement();
1532    return Error(Loc, "unexpected token in argument list");
1533  }
1534
1535  Parser.Lex(); // Consume the EndOfStatement.
1536  return false;
1537}
1538
1539bool MipsAsmParser::
1540ParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1541                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1542  StringRef Mnemonic;
1543  // Floating point instructions: Should the register be treated as a double?
1544  if (requestsDoubleOperand(Name)) {
1545    setFpFormat(FP_FORMAT_D);
1546    Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1547    Mnemonic = Name;
1548  } else {
1549    setDefaultFpFormat();
1550    // Create the leading tokens for the mnemonic, split by '.' characters.
1551    size_t Start = 0, Next = Name.find('.');
1552    Mnemonic = Name.slice(Start, Next);
1553
1554    Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
1555
1556    if (Next != StringRef::npos) {
1557      // There is a format token in mnemonic.
1558      size_t Dot = Name.find('.', Next + 1);
1559      StringRef Format = Name.slice(Next, Dot);
1560      if (Dot == StringRef::npos) // Only one '.' in a string, it's a format.
1561        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1562      else {
1563        if (Name.startswith("c.")) {
1564          // Floating point compare, add '.' and immediate represent for cc.
1565          Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
1566          int Cc = ConvertCcString(Format);
1567          if (Cc == -1) {
1568            return Error(NameLoc, "Invalid conditional code");
1569          }
1570          SMLoc E = SMLoc::getFromPointer(
1571              Parser.getTok().getLoc().getPointer() - 1);
1572          Operands.push_back(
1573              MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()),
1574                                     NameLoc, E));
1575        } else {
1576          // trunc, ceil, floor ...
1577          return parseMathOperation(Name, NameLoc, Operands);
1578        }
1579
1580        // The rest is a format.
1581        Format = Name.slice(Dot, StringRef::npos);
1582        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1583      }
1584
1585      setFpFormat(Format);
1586    }
1587  }
1588
1589  // Read the remaining operands.
1590  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1591    // Read the first operand.
1592    if (ParseOperand(Operands, Mnemonic)) {
1593      SMLoc Loc = getLexer().getLoc();
1594      Parser.eatToEndOfStatement();
1595      return Error(Loc, "unexpected token in argument list");
1596    }
1597
1598    while (getLexer().is(AsmToken::Comma)) {
1599      Parser.Lex(); // Eat the comma.
1600
1601      // Parse and remember the operand.
1602      if (ParseOperand(Operands, Name)) {
1603        SMLoc Loc = getLexer().getLoc();
1604        Parser.eatToEndOfStatement();
1605        return Error(Loc, "unexpected token in argument list");
1606      }
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
1616  Parser.Lex(); // Consume the EndOfStatement.
1617  return false;
1618}
1619
1620bool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
1621  SMLoc Loc = getLexer().getLoc();
1622  Parser.eatToEndOfStatement();
1623  return Error(Loc, ErrorMsg);
1624}
1625
1626bool MipsAsmParser::parseSetNoAtDirective() {
1627  // Line should look like: ".set noat".
1628  // set at reg to 0.
1629  Options.setATReg(0);
1630  // eat noat
1631  Parser.Lex();
1632  // If this is not the end of the statement, report an error.
1633  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1634    reportParseError("unexpected token in statement");
1635    return false;
1636  }
1637  Parser.Lex(); // Consume the EndOfStatement.
1638  return false;
1639}
1640
1641bool MipsAsmParser::parseSetAtDirective() {
1642  // Line can be .set at - defaults to $1
1643  // or .set at=$reg
1644  int AtRegNo;
1645  getParser().Lex();
1646  if (getLexer().is(AsmToken::EndOfStatement)) {
1647    Options.setATReg(1);
1648    Parser.Lex(); // Consume the EndOfStatement.
1649    return false;
1650  } else if (getLexer().is(AsmToken::Equal)) {
1651    getParser().Lex(); // Eat the '='.
1652    if (getLexer().isNot(AsmToken::Dollar)) {
1653      reportParseError("unexpected token in statement");
1654      return false;
1655    }
1656    Parser.Lex(); // Eat the '$'.
1657    const AsmToken &Reg = Parser.getTok();
1658    if (Reg.is(AsmToken::Identifier)) {
1659      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
1660    } else if (Reg.is(AsmToken::Integer)) {
1661      AtRegNo = Reg.getIntVal();
1662    } else {
1663      reportParseError("unexpected token in statement");
1664      return false;
1665    }
1666
1667    if (AtRegNo < 1 || AtRegNo > 31) {
1668      reportParseError("unexpected token in statement");
1669      return false;
1670    }
1671
1672    if (!Options.setATReg(AtRegNo)) {
1673      reportParseError("unexpected token in statement");
1674      return false;
1675    }
1676    getParser().Lex(); // Eat the register.
1677
1678    if (getLexer().isNot(AsmToken::EndOfStatement)) {
1679      reportParseError("unexpected token in statement");
1680      return false;
1681    }
1682    Parser.Lex(); // Consume the EndOfStatement.
1683    return false;
1684  } else {
1685    reportParseError("unexpected token in statement");
1686    return false;
1687  }
1688}
1689
1690bool MipsAsmParser::parseSetReorderDirective() {
1691  Parser.Lex();
1692  // If this is not the end of the statement, report an error.
1693  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1694    reportParseError("unexpected token in statement");
1695    return false;
1696  }
1697  Options.setReorder();
1698  Parser.Lex(); // Consume the EndOfStatement.
1699  return false;
1700}
1701
1702bool MipsAsmParser::parseSetNoReorderDirective() {
1703  Parser.Lex();
1704  // If this is not the end of the statement, report an error.
1705  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1706    reportParseError("unexpected token in statement");
1707    return false;
1708  }
1709  Options.setNoreorder();
1710  Parser.Lex(); // Consume the EndOfStatement.
1711  return false;
1712}
1713
1714bool MipsAsmParser::parseSetMacroDirective() {
1715  Parser.Lex();
1716  // If this is not the end of the statement, report an error.
1717  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1718    reportParseError("unexpected token in statement");
1719    return false;
1720  }
1721  Options.setMacro();
1722  Parser.Lex(); // Consume the EndOfStatement.
1723  return false;
1724}
1725
1726bool MipsAsmParser::parseSetNoMacroDirective() {
1727  Parser.Lex();
1728  // If this is not the end of the statement, report an error.
1729  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1730    reportParseError("`noreorder' must be set before `nomacro'");
1731    return false;
1732  }
1733  if (Options.isReorder()) {
1734    reportParseError("`noreorder' must be set before `nomacro'");
1735    return false;
1736  }
1737  Options.setNomacro();
1738  Parser.Lex(); // Consume the EndOfStatement.
1739  return false;
1740}
1741
1742bool MipsAsmParser::parseSetAssignment() {
1743  StringRef Name;
1744  const MCExpr *Value;
1745
1746  if (Parser.parseIdentifier(Name))
1747    reportParseError("expected identifier after .set");
1748
1749  if (getLexer().isNot(AsmToken::Comma))
1750    return reportParseError("unexpected token in .set directive");
1751  Lex(); // Eat comma
1752
1753  if (getLexer().is(AsmToken::Dollar)) {
1754    MCSymbol *Symbol;
1755    SMLoc DollarLoc = getLexer().getLoc();
1756    // Consume the dollar sign, and check for a following identifier.
1757    Parser.Lex();
1758    // We have a '$' followed by something, make sure they are adjacent.
1759    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1760      return true;
1761    StringRef Res = StringRef(DollarLoc.getPointer(),
1762        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1763    Symbol = getContext().GetOrCreateSymbol(Res);
1764    Parser.Lex();
1765    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1766                                    getContext());
1767  } else if (Parser.parseExpression(Value))
1768    return reportParseError("expected valid expression after comma");
1769
1770  // Check if the Name already exists as a symbol.
1771  MCSymbol *Sym = getContext().LookupSymbol(Name);
1772  if (Sym)
1773    return reportParseError("symbol already defined");
1774  Sym = getContext().GetOrCreateSymbol(Name);
1775  Sym->setVariableValue(Value);
1776
1777  return false;
1778}
1779
1780bool MipsAsmParser::parseDirectiveSet() {
1781
1782  // Get the next token.
1783  const AsmToken &Tok = Parser.getTok();
1784
1785  if (Tok.getString() == "noat") {
1786    return parseSetNoAtDirective();
1787  } else if (Tok.getString() == "at") {
1788    return parseSetAtDirective();
1789  } else if (Tok.getString() == "reorder") {
1790    return parseSetReorderDirective();
1791  } else if (Tok.getString() == "noreorder") {
1792    return parseSetNoReorderDirective();
1793  } else if (Tok.getString() == "macro") {
1794    return parseSetMacroDirective();
1795  } else if (Tok.getString() == "nomacro") {
1796    return parseSetNoMacroDirective();
1797  } else if (Tok.getString() == "nomips16") {
1798    // Ignore this directive for now.
1799    Parser.eatToEndOfStatement();
1800    return false;
1801  } else if (Tok.getString() == "nomicromips") {
1802    // Ignore this directive for now.
1803    Parser.eatToEndOfStatement();
1804    return false;
1805  } else {
1806    // It is just an identifier, look for an assignment.
1807    parseSetAssignment();
1808    return false;
1809  }
1810
1811  return true;
1812}
1813
1814/// parseDirectiveWord
1815///  ::= .word [ expression (, expression)* ]
1816bool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1817  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1818    for (;;) {
1819      const MCExpr *Value;
1820      if (getParser().parseExpression(Value))
1821        return true;
1822
1823      getParser().getStreamer().EmitValue(Value, Size);
1824
1825      if (getLexer().is(AsmToken::EndOfStatement))
1826        break;
1827
1828      // FIXME: Improve diagnostic.
1829      if (getLexer().isNot(AsmToken::Comma))
1830        return Error(L, "unexpected token in directive");
1831      Parser.Lex();
1832    }
1833  }
1834
1835  Parser.Lex();
1836  return false;
1837}
1838
1839bool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1840
1841  StringRef IDVal = DirectiveID.getString();
1842
1843  if (IDVal == ".ent") {
1844    // Ignore this directive for now.
1845    Parser.Lex();
1846    return false;
1847  }
1848
1849  if (IDVal == ".end") {
1850    // Ignore this directive for now.
1851    Parser.Lex();
1852    return false;
1853  }
1854
1855  if (IDVal == ".frame") {
1856    // Ignore this directive for now.
1857    Parser.eatToEndOfStatement();
1858    return false;
1859  }
1860
1861  if (IDVal == ".set") {
1862    return parseDirectiveSet();
1863  }
1864
1865  if (IDVal == ".fmask") {
1866    // Ignore this directive for now.
1867    Parser.eatToEndOfStatement();
1868    return false;
1869  }
1870
1871  if (IDVal == ".mask") {
1872    // Ignore this directive for now.
1873    Parser.eatToEndOfStatement();
1874    return false;
1875  }
1876
1877  if (IDVal == ".gpword") {
1878    // Ignore this directive for now.
1879    Parser.eatToEndOfStatement();
1880    return false;
1881  }
1882
1883  if (IDVal == ".word") {
1884    parseDirectiveWord(4, DirectiveID.getLoc());
1885    return false;
1886  }
1887
1888  return true;
1889}
1890
1891extern "C" void LLVMInitializeMipsAsmParser() {
1892  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1893  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1894  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1895  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1896}
1897
1898#define GET_REGISTER_MATCHER
1899#define GET_MATCHER_IMPLEMENTATION
1900#include "MipsGenAsmMatcher.inc"
1901