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