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