1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//
3fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//                     The LLVM Compiler Infrastructure
4fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//
5fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// This file is distributed under the University of Illinois Open Source
6fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// License. See LICENSE.TXT for details.
7fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//
8fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//===----------------------------------------------------------------------===//
9fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
10fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h"
11ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h"
12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h"
13ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h"
14ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h"
15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h"
16ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h"
17ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h"
18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h"
19fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "llvm/MC/MCParser/MCAsmLexer.h"
2072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
2172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h"
22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h"
23fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
24fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm;
25fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
26fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace {
27ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
28fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser {
2972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
30f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  enum FpFormatTy {
31f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_NONE = -1,
32f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_S,
33f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_D,
34f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_L,
35f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_W
36f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  } FpFormat;
37f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
38ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCSubtargetInfo &STI;
39ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &Parser;
40ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
4172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER
4272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc"
4372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
44fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool MatchAndEmitInstruction(SMLoc IDLoc,
45fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
46fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                               MCStreamer &Out);
47fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
48fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
49fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
50fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
5172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
52fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
53f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool parseMathOperation(StringRef Name, SMLoc NameLoc,
54f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
56fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseDirective(AsmToken DirectiveID);
57fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
58ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MipsAsmParser::OperandMatchResultTy
59ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
60038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
61ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned
62ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  getMCInstOperandNum(unsigned Kind, MCInst &Inst,
63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                      const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
64ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                      unsigned OperandNum, unsigned &NumMCOperands);
65ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
66ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
67ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                    StringRef Mnemonic);
68ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
69ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int tryParseRegister(StringRef Mnemonic);
70ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
71ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
72ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                               StringRef Mnemonic);
73ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  bool parseMemOffset(const MCExpr *&Res);
756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  bool parseRelocOperand(const MCExpr *&Res);
766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
77f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
78ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool isMips64() const {
79ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
80ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
81ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
82f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool isFP64() const {
83f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
84f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
85f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
86ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int matchRegisterName(StringRef Symbol);
87ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
88ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic);
89ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
90f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(FpFormatTy Format) {
91f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = Format;
92f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
93f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
94f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setDefaultFpFormat();
95f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
96f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(StringRef Format);
97f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
98f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormatTy getFpFormat() {return FpFormat;}
99f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
100f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool requestsDoubleOperand(StringRef Mnemonic);
101f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
102ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned getReg(int RC,int RegNo);
103038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
104fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
105fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
106ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    : MCTargetAsmParser(), STI(sti), Parser(parser) {
107ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
108ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
109fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  }
110fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &getParser() const { return Parser; }
112ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
113ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
114fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
115fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
116fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
11772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
11872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
11972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
12072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
12172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
122ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
12372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
12472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CondCode,
12572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CoprocNum,
12672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Immediate,
12772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Memory,
12872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_PostIndexRegister,
12972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Register,
13072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Token
13172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
13272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
13372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
134ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
135ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
136ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    struct {
137ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      const char *Data;
138ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      unsigned Length;
139ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    } Tok;
140ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
141ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    struct {
142ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      unsigned RegNum;
143ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    } Reg;
144ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
145ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    struct {
146ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      const MCExpr *Val;
147ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    } Imm;
1486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    struct {
1506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      unsigned Base;
1516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      const MCExpr *Off;
1526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    } Mem;
153ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
154ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
155ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
156ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
15772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
15872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addRegOperands(MCInst &Inst, unsigned N) const {
159ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
160ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.addOperand(MCOperand::CreateReg(getReg()));
16172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
162ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
16372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
164ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
165ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Expr == 0)
166ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(0));
167ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
168ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
169ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
170ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateExpr(Expr));
17172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
172ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
17372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
175ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
176ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    addExpr(Inst,Expr);
17772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
178ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
17972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
1806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
1816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
1836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
1856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    addExpr(Inst,Expr);
18672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
18772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
18872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isReg() const { return Kind == k_Register; }
18972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isImm() const { return Kind == k_Immediate; }
19072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isToken() const { return Kind == k_Token; }
19172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isMem() const { return Kind == k_Memory; }
19272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
19372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
19472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
195ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
19772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
19872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  unsigned getReg() const {
19972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert((Kind == k_Register) && "Invalid access!");
200ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Reg.RegNum;
201ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
202ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
203ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
204ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert((Kind == k_Immediate) && "Invalid access!");
205ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
206ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
207ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
2086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  unsigned getMemBase() const {
2096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
2106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
2116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
2126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
2146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
2156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
2166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
2176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
218ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
219ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Token);
220ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
221ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
222ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
223ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
224ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
225ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
226ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
227ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
228ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Register);
229ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Reg.RegNum = RegNum;
230ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
231ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
232ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
233ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
234ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
235ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
236ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Immediate);
237ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Imm.Val = Val;
238ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
239ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
240ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
24172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
24272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
2436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
2446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                 SMLoc S, SMLoc E) {
2456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MipsOperand *Op = new MipsOperand(k_Memory);
2466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Base = Base;
2476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
2486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
2496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
2506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
2516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
2526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
253ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
254ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc getStartLoc() const { return StartLoc; }
255ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
256ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc getEndLoc() const { return EndLoc; }
257ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
25872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  virtual void print(raw_ostream &OS) const {
25972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    llvm_unreachable("unimplemented!");
26072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
26172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka};
26272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka}
26372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
264038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosierunsigned MipsAsmParser::
2655d637d7e93c1f6058c16b41b8ac7dd36c61b4a5cChad RosiergetMCInstOperandNum(unsigned Kind, MCInst &Inst,
266038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier                    const SmallVectorImpl<MCParsedAsmOperand*> &Operands,
2672cc97def7434345e399e4f5f3f2001d6d7a93c6fChad Rosier                    unsigned OperandNum, unsigned &NumMCOperands) {
2685d637d7e93c1f6058c16b41b8ac7dd36c61b4a5cChad Rosier  assert (0 && "getMCInstOperandNum() not supported by the Mips target.");
269efeaae8578ce9173a47f9e3fa5c44b90ae60c5abChad Rosier  // The Mips backend doesn't currently include the matcher implementation, so
2705d637d7e93c1f6058c16b41b8ac7dd36c61b4a5cChad Rosier  // the getMCInstOperandNumImpl() is undefined.  This is a temporary
271efeaae8578ce9173a47f9e3fa5c44b90ae60c5abChad Rosier  // work around.
2722cc97def7434345e399e4f5f3f2001d6d7a93c6fChad Rosier  NumMCOperands = 0;
273038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier  return 0;
274038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier}
275038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
276fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
277fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaMatchAndEmitInstruction(SMLoc IDLoc,
278fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
279fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        MCStreamer &Out) {
280ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
281ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned ErrorInfo;
282ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned Kind;
283ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst, ErrorInfo);
284ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
285ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
286ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default: break;
287ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
288ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.setLoc(IDLoc);
289ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Out.EmitInstruction(Inst);
290ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
292ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
293ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
294ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
295ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
296ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
297ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ErrorInfo != ~0U) {
298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
299ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
300ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
301ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc();
302ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
303ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
304ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
305ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
306ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
309ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
310fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
311fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
312fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
313ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name) {
314ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
315ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter   int CC = StringSwitch<unsigned>(Name)
316ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("zero",  Mips::ZERO)
317ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a0",  Mips::A0)
318ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a1",  Mips::A1)
319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a2",  Mips::A2)
320ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a3",  Mips::A3)
321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("v0",  Mips::V0)
322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("v1",  Mips::V1)
323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s0",  Mips::S0)
324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s1",  Mips::S1)
325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s2",  Mips::S2)
326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s3",  Mips::S3)
327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s4",  Mips::S4)
328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s5",  Mips::S5)
329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s6",  Mips::S6)
330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s7",  Mips::S7)
331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("k0",  Mips::K0)
332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("k1",  Mips::K1)
333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("sp",  Mips::SP)
334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("fp",  Mips::FP)
335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("gp",  Mips::GP)
336ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("ra",  Mips::RA)
337ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t0",  Mips::T0)
338ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t1",  Mips::T1)
339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t2",  Mips::T2)
340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t3",  Mips::T3)
341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t4",  Mips::T4)
342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t5",  Mips::T5)
343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t6",  Mips::T6)
344ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t7",  Mips::T7)
345ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t8",  Mips::T8)
346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t9",  Mips::T9)
347ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("at",  Mips::AT)
348ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("fcc0",  Mips::FCC0)
349ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Default(-1);
350ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
351ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (CC != -1) {
352ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //64 bit register in Mips are following 32 bit definitions.
353ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (isMips64())
354ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      CC++;
355ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return CC;
356ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
357ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
358f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
359f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
360f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
361f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if( NumString.getAsInteger(10, IntVal))
362f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1; //not integer
363f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (IntVal > 31)
364f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
365f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
366f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormatTy Format = getFpFormat();
367f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
368f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
369f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::FGR32RegClassID, IntVal);
370f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_D) {
371f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if(isFP64()) {
372f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return getReg(Mips::FGR64RegClassID, IntVal);
373f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
374f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      //only even numbers available as register pairs
375f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if (( IntVal > 31) || (IntVal%2 !=  0))
376f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return -1;
377f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::AFGR64RegClassID, IntVal/2);
378f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
379f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
380f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
381ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
382ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
383f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() {
384f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
385f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() || isFP64())
386f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_D;
387f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else
388f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_S;
389f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
390f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
391f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
392f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
393f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
394f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldxc1", true)
395f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldc1",  true)
396f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdxc1", true)
397f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdc1",  true)
398f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(false);
399f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
400f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return IsDouble;
401f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
402f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) {
403f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
404f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormat = StringSwitch<FpFormatTy>(Format.lower())
405f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".s",  FP_FORMAT_S)
406f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".d",  FP_FORMAT_D)
407f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".l",  FP_FORMAT_L)
408f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".w",  FP_FORMAT_W)
409f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(FP_FORMAT_NONE);
410f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
411ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
412ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterunsigned MipsAsmParser::getReg(int RC,int RegNo){
413ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
414ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
415ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
416ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum,StringRef Mnemonic) {
417ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
418ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Mnemonic.lower() == "rdhwr") {
419ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //at the moment only hwreg29 is supported
420ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (RegNum != 29)
421ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return -1;
422ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Mips::HWR29;
423ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
424ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
425ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNum > 31)
426ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return -1;
427ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
428ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return getReg(Mips::CPURegsRegClassID,RegNum);
429ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
430ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
431ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::tryParseRegister(StringRef Mnemonic) {
432ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const AsmToken &Tok = Parser.getTok();
433ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNum = -1;
434ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
435ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Tok.is(AsmToken::Identifier)) {
436ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    std::string lowerCase = Tok.getString().lower();
437ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    RegNum = matchRegisterName(lowerCase);
438ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  } else if (Tok.is(AsmToken::Integer))
4396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    RegNum = matchRegisterByNumber(static_cast<unsigned> (Tok.getIntVal()),
4406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                   Mnemonic.lower());
441f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    else
442f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return RegNum;  //error
443f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64
444f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() && RegNum == Mips::ZERO_64) {
445f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Mnemonic.find("ddiv") != StringRef::npos)
446f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      RegNum = Mips::ZERO;
447f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
448ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return RegNum;
449ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
450ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
451fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
452ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
453ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                          StringRef Mnemonic){
454ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
455ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc S = Parser.getTok().getLoc();
456ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNo = -1;
457f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
458f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //FIXME: we should make a more generic method for CCR
459f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if ((Mnemonic == "cfc1" || Mnemonic == "ctc1")
460f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){
461f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    RegNo = Parser.getTok().getIntVal();  //get the int value
462f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    //at the moment only fcc0 is supported
463f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (RegNo ==  0)
464f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      RegNo = Mips::FCC0;
465f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  } else
466f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    RegNo = tryParseRegister(Mnemonic);
467ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNo == -1)
468ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
469ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
470ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
471f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.getTok().getLoc()));
472ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Eat register token.
473ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
474ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
475ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
476ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
477ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                 StringRef Mnemonic) {
478ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  //Check if the current operand has a custom associated parser, if so, try to
479ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  //custom parse the operand, or fallback to the general approach.
480ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
481ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
482ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
483ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
484ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
485ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
486ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
487ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
488ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
489ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
490ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
491ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
492ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
493ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
494ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //parse register
495ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
496ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.Lex(); // Eat dollar token.
497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //parse register operand
498ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (!tryParseRegisterOperand(Operands,Mnemonic)) {
499ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (getLexer().is(AsmToken::LParen)) {
500ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        //check if it is indexed addressing operand
501ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken("(", S));
502ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex(); //eat parenthesis
503ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (getLexer().isNot(AsmToken::Dollar))
504ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
505ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
506ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex(); //eat dollar
507ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (tryParseRegisterOperand(Operands,Mnemonic))
508ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
509ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
510ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (!getLexer().is(AsmToken::RParen))
511ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
512ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
513ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        S = Parser.getTok().getLoc();
514ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken(")", S));
515ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex();
516ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
517ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
518ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
519ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //maybe it is a symbol reference
520ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
521ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Parser.ParseIdentifier(Identifier))
522ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
523ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
5246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
525ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
52638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
527ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
528ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Otherwise create a symbol ref.
5296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
530ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                                getContext());
531ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
532ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
533ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
534ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
535ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Identifier:
536ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
537ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
538ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
539ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
540ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
541ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter     // quoted label names
542ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *IdVal;
543ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
544ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (getParser().ParseExpression(IdVal))
545ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
5466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
547ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
548ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
549ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
5506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
5516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    //it is a symbol reference or constant expression
5526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
5536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc S = Parser.getTok().getLoc(); //start location of the operand
5546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (parseRelocOperand(IdVal))
5556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
5566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
5586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
5606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
5616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }//case AsmToken::Percent
562ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }//switch(getLexer().getKind())
563fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
564fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
565fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
5666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
5676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); //eat % token
5696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const AsmToken &Tok = Parser.getTok(); //get next token, operation
5706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
5716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
5726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
57338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  std::string Str = Tok.getIdentifier().str();
5746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); //eat identifier
5766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  //now make expression from the rest of the operand
5776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
5786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc EndLoc;
5796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
5816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
5826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Parser.Lex(); //eat '(' token
5836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
5846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        Parser.Lex(); //eat % token
5856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
5866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
5876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
58838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
58938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
5906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        Parser.Lex(); //eat identifier
5916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
5926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
5936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
5946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
5956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
5966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (getParser().ParseParenExpression(IdVal,EndLoc))
5976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
5986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (getLexer().getKind() == AsmToken::RParen)
6006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Parser.Lex(); //eat ')' token
6016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
6036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true; //parenthesis must follow reloc operand
6046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  //Check the type of the expression
60638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
6076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    //it's a constant, evaluate lo or hi value
60838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    int Val = MCE->getValue();
6096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (Str == "lo") {
6106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Val = Val & 0xffff;
6116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    } else if (Str == "hi") {
6126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Val = (Val & 0xffff0000) >> 16;
6136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
6146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Res = MCConstantExpr::Create(Val, getContext());
6156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
6166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
61838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
6196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    //it's a symbol, create symbolic expression from symbol
62038539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    StringRef Symbol = MSRE->getSymbol().getName();
6216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
6226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
6236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
6246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return true;
6266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
6276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
628ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
629ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
630ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
631ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  StartLoc = Parser.getTok().getLoc();
632ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  RegNo = tryParseRegister("");
633ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  EndLoc = Parser.getTok().getLoc();
634ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return (RegNo == (unsigned)-1);
635ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
636ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
6376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
6386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc S;
6406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  switch(getLexer().getKind()) {
6426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
6436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
6446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
6456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
6466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
6476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return (getParser().ParseExpression(Res));
648f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  case AsmToken::Percent:
6496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return parseRelocOperand(Res);
6506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::LParen:
6516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;  //it's probably assuming 0
6526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return true;
6546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
6556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
656ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
657ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
6586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal = 0;
6606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc S;
6616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  //first operand is the offset
6626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  S = Parser.getTok().getLoc();
6636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (parseMemOffset(IdVal))
6656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
6666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const AsmToken &Tok = Parser.getTok(); //get next token
6686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::LParen)) {
6696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "'(' expected");
6706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
6716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); // Eat '(' token.
6746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const AsmToken &Tok1 = Parser.getTok(); //get next token
6766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok1.is(AsmToken::Dollar)) {
6776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Parser.Lex(); // Eat '$' token.
6786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (tryParseRegisterOperand(Operands,"")) {
6796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Error(Parser.getTok().getLoc(), "unexpected token in operand");
6806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return MatchOperand_ParseFail;
6816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
6826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else {
6846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(),"unexpected token in operand");
6856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
6866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const AsmToken &Tok2 = Parser.getTok(); //get next token
6896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok2.isNot(AsmToken::RParen)) {
6906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
6916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
6926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); // Eat ')' token.
6976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (IdVal == 0)
6996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    IdVal = MCConstantExpr::Create(0, getContext());
7006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  //now replace register operand with the mem operand
7026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
7036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  int RegNo = op->getReg();
7046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  //remove register from operands
7056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
7066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  //and add memory operand
7076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
7086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  delete op;
709ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
710ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
711ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
7126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
7136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind VK
7156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
7166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
7176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
7186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
7196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
7206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
7216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
7226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
7236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
7246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
7256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
7266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
7276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
7286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
7296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
7306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
7316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
7326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
7336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Default(MCSymbolRefExpr::VK_None);
7346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return VK;
7366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
7376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7381ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) {
739f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  int CC = StringSwitch<unsigned>(CondString)
740f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".f",    0)
741f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".un",   1)
742f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".eq",   2)
743f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ueq",  3)
744f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".olt",  4)
745f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ult",  5)
746f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ole",  6)
747f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ule",  7)
748f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".sf",   8)
749f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngle", 9)
750f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".seq",  10)
751f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngl",  11)
752f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".lt",   12)
753f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".nge",  13)
754f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".le",   14)
755f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngt",  15)
756f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Default(-1);
757f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
758f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return CC;
759f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
760f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
761f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::
762f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc,
763f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter                        SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
764f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //split the format
765f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  size_t Start = Name.find('.'), Next = Name.rfind('.');
766f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format1 = Name.slice(Start, Next);
767f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //and add the first format to the operands
768f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
769f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //now for the second format
770f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format2 = Name.slice(Next, StringRef::npos);
771f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
772f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
773f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //set the format for the first register
774f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  setFpFormat(Format1);
775f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
776f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  // Read the remaining operands.
777f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
778f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Read the first operand.
779f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
780f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
781f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.EatToEndOfStatement();
782f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
783f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
784f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
785f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (getLexer().isNot(AsmToken::Comma)) {
786f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
787f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.EatToEndOfStatement();
788f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
789f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
790f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
791f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Parser.Lex();  // Eat the comma.
792f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
793f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    //set the format for the first register
794f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(Format2);
795f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
796f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Parse and remember the operand.
797f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
798f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
799f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.EatToEndOfStatement();
800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
803f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
804f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
805f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    SMLoc Loc = getLexer().getLoc();
806f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Parser.EatToEndOfStatement();
807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return Error(Loc, "unexpected token in argument list");
808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
809f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
810f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Parser.Lex(); // Consume the EndOfStatement
811f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return false;
812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
813f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
814fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
815fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaParseInstruction(StringRef Name, SMLoc NameLoc,
816fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
817f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //floating point instructions: should register be treated as double?
818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (requestsDoubleOperand(Name)) {
819f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(FP_FORMAT_D);
820ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else {
823f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setDefaultFpFormat();
824f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Create the leading tokens for the mnemonic, split by '.' characters.
825f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    size_t Start = 0, Next = Name.find('.');
826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef Mnemonic = Name.slice(Start, Next);
827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Next != StringRef::npos) {
831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      //there is a format token in mnemonic
832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      //StringRef Rest = Name.slice(Next, StringRef::npos);
833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      size_t Dot = Name.find('.', Next+1);
834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      StringRef Format = Name.slice(Next, Dot);
835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if (Dot == StringRef::npos) //only one '.' in a string, it's a format
836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      else {
838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        if (Name.startswith("c.")){
839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          // floating point compare, add '.' and immediate represent for cc
840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
841f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          int Cc = ConvertCcString(Format);
842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          if (Cc == -1) {
843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter            return Error(NameLoc, "Invalid conditional code");
844f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          }
845f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          SMLoc E = SMLoc::getFromPointer(
846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter              Parser.getTok().getLoc().getPointer() -1 );
847f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateImm(
848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter              MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        } else {
850f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          //trunc, ceil, floor ...
851f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          return parseMathOperation(Name, NameLoc, Operands);
852f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        }
853f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
854f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        //the rest is a format
855f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Format = Name.slice(Dot, StringRef::npos);
856f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
857f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
858f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
859f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      setFpFormat(Format);
860f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
861f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
862ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
865ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
866ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ParseOperand(Operands, Name)) {
867ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
868ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Parser.EatToEndOfStatement();
869ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
870ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
871ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
872ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    while (getLexer().is(AsmToken::Comma) ) {
873ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Parser.Lex();  // Eat the comma.
874ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
875ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ParseOperand(Operands, Name)) {
877ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
878ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.EatToEndOfStatement();
879ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
880ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
881ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
882ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
885ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
886ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.EatToEndOfStatement();
887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
888ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
889ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
890ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Consume the EndOfStatement
891ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
892fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
893fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
894fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
895fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaParseDirective(AsmToken DirectiveID) {
896acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
897acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".ent") {
898acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
899acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
900acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
901acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
902acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
903acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".end") {
904acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
905acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
906acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
907acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
908acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
909acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".frame") {
910acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
911acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
912acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
913acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
914acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
915acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".set") {
916acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
917acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
918acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
919acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
920acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
921acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".fmask") {
922acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
923acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
924acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
925acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
926acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
927acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".mask") {
928acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
929acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
930acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
931acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
932acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
933acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".gpword") {
934acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    //ignore this directive for now
935acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
936acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
937acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
938acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
939fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
940fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
941fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
942fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
943fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
944fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
945fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
946fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
947fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
949ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
952