MipsAsmParser.cpp revision 30116cd2e24a4a2b6c2771ef2665d655de93b984
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 {
2730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions {
2830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic:
2930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  MipsAssemblerOptions():
3030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    aTReg(1), reorder(true), macro(true) {
3130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
3230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
3330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned getATRegNum() {return aTReg;}
3430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool setATReg(unsigned Reg);
35ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool isReorder() {return reorder;}
3730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setReorder() {reorder = true;}
3830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setNoreorder() {reorder = false;}
3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool isMacro() {return macro;}
4130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setMacro() {macro = true;}
4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setNomacro() {macro = false;}
4330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate:
4530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned aTReg;
4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reorder;
4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool macro;
4830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter};
4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
5130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace {
52fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser {
5372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
54f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  enum FpFormatTy {
55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_NONE = -1,
56f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_S,
57f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_D,
58f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_L,
59f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_W
60f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  } FpFormat;
61f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
62ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCSubtargetInfo &STI;
63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &Parser;
6430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  MipsAssemblerOptions *Options;
6530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
66ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
6772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER
6872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc"
6972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
70fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool MatchAndEmitInstruction(SMLoc IDLoc,
71fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
72fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                               MCStreamer &Out);
73fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
74fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
75fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
76fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
7772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
78fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
79f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool parseMathOperation(StringRef Name, SMLoc NameLoc,
80f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
81f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
82fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseDirective(AsmToken DirectiveID);
83fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
84ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MipsAsmParser::OperandMatchResultTy
85ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
86038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
87ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
88ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                    StringRef Mnemonic);
89ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
90ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int tryParseRegister(StringRef Mnemonic);
91ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
92ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
93ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                               StringRef Mnemonic);
94ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
9530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reportParseError(StringRef ErrorMsg);
9630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  bool parseMemOffset(const MCExpr *&Res);
986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  bool parseRelocOperand(const MCExpr *&Res);
9930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
10030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseDirectiveSet();
10130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
10230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetAtDirective();
10330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoAtDirective();
10430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetMacroDirective();
10530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoMacroDirective();
10630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetReorderDirective();
10730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoReorderDirective();
10830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
110f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool isMips64() const {
112ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
113ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
114ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
115f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool isFP64() const {
116f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
117f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
118f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
119ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int matchRegisterName(StringRef Symbol);
120ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
121ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic);
122ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
123f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(FpFormatTy Format) {
124f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = Format;
125f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
126f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
127f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setDefaultFpFormat();
128f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
129f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(StringRef Format);
130f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
131f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormatTy getFpFormat() {return FpFormat;}
132f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
133f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool requestsDoubleOperand(StringRef Mnemonic);
134f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
135ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned getReg(int RC,int RegNo);
136038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
13730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned getATReg();
138fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
139fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
140ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    : MCTargetAsmParser(), STI(sti), Parser(parser) {
141ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
142ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
14330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Options = new MipsAssemblerOptions();
144fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  }
145fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
146ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &getParser() const { return Parser; }
147ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
148ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
149fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
150fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
151fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
15272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
15372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
15472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
15572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
15672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
157ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
15872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
15972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CondCode,
16072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CoprocNum,
16172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Immediate,
16272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Memory,
16372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_PostIndexRegister,
16472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Register,
16572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Token
16672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
16772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
16872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
169ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
170ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
171ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    struct {
172ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      const char *Data;
173ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      unsigned Length;
174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    } Tok;
175ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
176ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    struct {
177ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      unsigned RegNum;
178ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    } Reg;
179ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
180ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    struct {
181ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      const MCExpr *Val;
182ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    } Imm;
1836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    struct {
1856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      unsigned Base;
1866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      const MCExpr *Off;
1876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    } Mem;
188ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
189ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
190ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
191ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
19272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
19372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addRegOperands(MCInst &Inst, unsigned N) const {
194ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
195ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.addOperand(MCOperand::CreateReg(getReg()));
19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
197ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
19872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
199ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
200ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Expr == 0)
201ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(0));
202ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
203ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
204ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
205ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateExpr(Expr));
20672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
207ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
20872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
209ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
210ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
211ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    addExpr(Inst,Expr);
21272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
213ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
21472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
2156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
2166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
2186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
2206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    addExpr(Inst,Expr);
22172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
22272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
22372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isReg() const { return Kind == k_Register; }
22472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isImm() const { return Kind == k_Immediate; }
22572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isToken() const { return Kind == k_Token; }
22672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isMem() const { return Kind == k_Memory; }
22772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
22872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
22972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
230ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
23172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
23272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
23372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  unsigned getReg() const {
23472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert((Kind == k_Register) && "Invalid access!");
235ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Reg.RegNum;
236ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
237ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
238ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
239ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert((Kind == k_Immediate) && "Invalid access!");
240ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
241ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
242ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
2436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  unsigned getMemBase() const {
2446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
2456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
2466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
2476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
2496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
2506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
2516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
2526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
253ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
254ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Token);
255ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
256ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
257ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
258ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
259ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
260ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
261ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
262ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
263ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Register);
264ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Reg.RegNum = RegNum;
265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
267ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
269ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
271ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Immediate);
272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Imm.Val = Val;
273ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
274ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
275ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
27672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
27772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
2786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
2796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                 SMLoc S, SMLoc E) {
2806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MipsOperand *Op = new MipsOperand(k_Memory);
2816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Base = Base;
2826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
2836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
2846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
2856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
2866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
2876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
288ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
289ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc getStartLoc() const { return StartLoc; }
290ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc getEndLoc() const { return EndLoc; }
292ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
29372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  virtual void print(raw_ostream &OS) const {
29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    llvm_unreachable("unimplemented!");
29572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
29672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka};
29772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka}
29872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
299fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
300fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaMatchAndEmitInstruction(SMLoc IDLoc,
301fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
302fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        MCStreamer &Out) {
303ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
304ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned Kind;
30522685876ed7231f32f7d1698c00acab22825b74cChad Rosier  unsigned ErrorInfo;
30622685876ed7231f32f7d1698c00acab22825b74cChad Rosier  SmallVector<std::pair< unsigned, std::string >, 4> MapAndConstraints;
30722685876ed7231f32f7d1698c00acab22825b74cChad Rosier  unsigned MatchResult = MatchInstructionImpl(Operands, Kind, Inst,
30822685876ed7231f32f7d1698c00acab22825b74cChad Rosier                                              MapAndConstraints, ErrorInfo,
30922685876ed7231f32f7d1698c00acab22825b74cChad Rosier                                              /*matchingInlineAsm*/ false);
310ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
311ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
312ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default: break;
313ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
314ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.setLoc(IDLoc);
315ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Out.EmitInstruction(Inst);
316ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
317ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
318ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
320ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ErrorInfo != ~0U) {
324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc();
328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
336fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
337fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
338fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name) {
340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter   int CC = StringSwitch<unsigned>(Name)
342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("zero",  Mips::ZERO)
343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a0",  Mips::A0)
344ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a1",  Mips::A1)
345ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a2",  Mips::A2)
346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("a3",  Mips::A3)
347ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("v0",  Mips::V0)
348ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("v1",  Mips::V1)
349ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s0",  Mips::S0)
350ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s1",  Mips::S1)
351ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s2",  Mips::S2)
352ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s3",  Mips::S3)
353ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s4",  Mips::S4)
354ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s5",  Mips::S5)
355ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s6",  Mips::S6)
356ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("s7",  Mips::S7)
357ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("k0",  Mips::K0)
358ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("k1",  Mips::K1)
359ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("sp",  Mips::SP)
360ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("fp",  Mips::FP)
361ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("gp",  Mips::GP)
362ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("ra",  Mips::RA)
363ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t0",  Mips::T0)
364ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t1",  Mips::T1)
365ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t2",  Mips::T2)
366ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t3",  Mips::T3)
367ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t4",  Mips::T4)
368ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t5",  Mips::T5)
369ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t6",  Mips::T6)
370ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t7",  Mips::T7)
371ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t8",  Mips::T8)
372ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("t9",  Mips::T9)
373ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("at",  Mips::AT)
374ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Case("fcc0",  Mips::FCC0)
375ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    .Default(-1);
376ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
377ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (CC != -1) {
378ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //64 bit register in Mips are following 32 bit definitions.
379ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (isMips64())
380ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      CC++;
381ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return CC;
382ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
383ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
384f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
385f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
386f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
387f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if( NumString.getAsInteger(10, IntVal))
388f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1; //not integer
389f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (IntVal > 31)
390f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
391f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
392f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormatTy Format = getFpFormat();
393f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
394f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
395f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::FGR32RegClassID, IntVal);
396f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_D) {
397f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if(isFP64()) {
398f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return getReg(Mips::FGR64RegClassID, IntVal);
399f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
400f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      //only even numbers available as register pairs
401f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if (( IntVal > 31) || (IntVal%2 !=  0))
402f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return -1;
403f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::AFGR64RegClassID, IntVal/2);
404f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
405f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
406f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
407ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
408ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
409f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() {
410f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
411f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() || isFP64())
412f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_D;
413f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else
414f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_S;
415f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
416f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
417f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
418f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
419f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
420f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldxc1", true)
421f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldc1",  true)
422f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdxc1", true)
423f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdc1",  true)
424f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(false);
425f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
426f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return IsDouble;
427f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
428f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) {
429f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
430f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormat = StringSwitch<FpFormatTy>(Format.lower())
431f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".s",  FP_FORMAT_S)
432f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".d",  FP_FORMAT_D)
433f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".l",  FP_FORMAT_L)
434f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".w",  FP_FORMAT_W)
435f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(FP_FORMAT_NONE);
436f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
437ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
43830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) {
43930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Reg > 31)
44030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
44130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
44230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  aTReg = Reg;
44330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
44430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
44530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
44630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterunsigned MipsAsmParser::getATReg() {
44730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned Reg = Options->getATRegNum();
44830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (isMips64())
44930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return getReg(Mips::CPU64RegsRegClassID,Reg);
45030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  else
45130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return getReg(Mips::CPURegsRegClassID,Reg);
45230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
45330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
45430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterunsigned MipsAsmParser::getReg(int RC,int RegNo) {
455ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
456ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
457ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
45830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) {
459ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
460ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Mnemonic.lower() == "rdhwr") {
461ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //at the moment only hwreg29 is supported
462ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (RegNum != 29)
463ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return -1;
464ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Mips::HWR29;
465ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
466ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
467ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNum > 31)
468ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return -1;
469ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
47030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return getReg(Mips::CPURegsRegClassID, RegNum);
471ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
472ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
473ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterint MipsAsmParser::tryParseRegister(StringRef Mnemonic) {
474ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const AsmToken &Tok = Parser.getTok();
475ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNum = -1;
476ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
477ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Tok.is(AsmToken::Identifier)) {
478ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    std::string lowerCase = Tok.getString().lower();
479ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    RegNum = matchRegisterName(lowerCase);
480ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  } else if (Tok.is(AsmToken::Integer))
4816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    RegNum = matchRegisterByNumber(static_cast<unsigned> (Tok.getIntVal()),
4826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                   Mnemonic.lower());
483f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    else
484f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return RegNum;  //error
485f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64
486f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() && RegNum == Mips::ZERO_64) {
487f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Mnemonic.find("ddiv") != StringRef::npos)
488f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      RegNum = Mips::ZERO;
489f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
490ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return RegNum;
491ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
492ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
493fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
494ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
495ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                          StringRef Mnemonic){
496ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc S = Parser.getTok().getLoc();
498ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNo = -1;
499f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
500f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  //FIXME: we should make a more generic method for CCR
501f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if ((Mnemonic == "cfc1" || Mnemonic == "ctc1")
502f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){
503f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    RegNo = Parser.getTok().getIntVal();  //get the int value
504f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    //at the moment only fcc0 is supported
505f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (RegNo ==  0)
506f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      RegNo = Mips::FCC0;
507f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  } else
508f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    RegNo = tryParseRegister(Mnemonic);
509ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNo == -1)
510ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
511ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
512ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
513f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.getTok().getLoc()));
514ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Eat register token.
515ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
516ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
517ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
518ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
519ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                 StringRef Mnemonic) {
520ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  //Check if the current operand has a custom associated parser, if so, try to
521ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  //custom parse the operand, or fallback to the general approach.
522ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
523ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
524ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
525ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
526ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
527ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
528ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
529ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
530ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
531ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
532ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
533ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
534ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
535ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
536ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //parse register
537ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
538ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.Lex(); // Eat dollar token.
539ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //parse register operand
540ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (!tryParseRegisterOperand(Operands,Mnemonic)) {
541ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (getLexer().is(AsmToken::LParen)) {
542ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        //check if it is indexed addressing operand
543ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken("(", S));
544ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex(); //eat parenthesis
545ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (getLexer().isNot(AsmToken::Dollar))
546ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
547ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
548ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex(); //eat dollar
549ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (tryParseRegisterOperand(Operands,Mnemonic))
550ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
551ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
552ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (!getLexer().is(AsmToken::RParen))
553ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
554ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
555ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        S = Parser.getTok().getLoc();
556ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken(")", S));
557ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex();
558ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
559ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
560ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
561ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    //maybe it is a symbol reference
562ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
563ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Parser.ParseIdentifier(Identifier))
564ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
565ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
5666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
567ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
56838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
569ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
570ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Otherwise create a symbol ref.
5716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
572ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                                getContext());
573ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
574ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
575ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
576ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
577ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Identifier:
578ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
579ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
580ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
581ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
582ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
583ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter     // quoted label names
584ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *IdVal;
585ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
586ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (getParser().ParseExpression(IdVal))
587ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
5886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
589ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
590ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
591ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
5926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
5936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    //it is a symbol reference or constant expression
5946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
5956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc S = Parser.getTok().getLoc(); //start location of the operand
5966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (parseRelocOperand(IdVal))
5976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
5986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
5996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
6006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
6026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
60330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // case AsmToken::Percent
60430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // switch(getLexer().getKind())
605fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
606fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
607fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
6086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
6096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
61030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // eat % token
6116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const AsmToken &Tok = Parser.getTok(); //get next token, operation
6126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
6136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
6146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
61538539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  std::string Str = Tok.getIdentifier().str();
6166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); //eat identifier
61830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // now make expression from the rest of the operand
6196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
6206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc EndLoc;
6216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
6236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
62430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      Parser.Lex(); // eat '(' token
6256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
62630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter        Parser.Lex(); // eat % token
6276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
6286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
6296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
63038539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
63138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
63230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter        Parser.Lex(); // eat identifier
6336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
6346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
6356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
6366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
6376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
6386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (getParser().ParseParenExpression(IdVal,EndLoc))
6396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
6406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (getLexer().getKind() == AsmToken::RParen)
64230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      Parser.Lex(); // eat ')' token
6436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
64530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return true; // parenthesis must follow reloc operand
6466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
64730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // Check the type of the expression
64838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
6496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    //it's a constant, evaluate lo or hi value
65038539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    int Val = MCE->getValue();
6516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (Str == "lo") {
6526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Val = Val & 0xffff;
6536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    } else if (Str == "hi") {
6546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Val = (Val & 0xffff0000) >> 16;
6556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
6566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Res = MCConstantExpr::Create(Val, getContext());
6576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
6586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
66038539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
66130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // it's a symbol, create symbolic expression from symbol
66238539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    StringRef Symbol = MSRE->getSymbol().getName();
6636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
6646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
6656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
6666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return true;
6686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
6696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
670ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
671ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
672ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
673ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  StartLoc = Parser.getTok().getLoc();
674ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  RegNo = tryParseRegister("");
675ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  EndLoc = Parser.getTok().getLoc();
676ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return (RegNo == (unsigned)-1);
677ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
678ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
6796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
6806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc S;
6826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  switch(getLexer().getKind()) {
6846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
6856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
6866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
6876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
6886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
6896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return (getParser().ParseExpression(Res));
690f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  case AsmToken::Percent:
6916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return parseRelocOperand(Res);
6926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::LParen:
69330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;  // it's probably assuming 0
6946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
6956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return true;
6966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
6976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
698ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
699ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
7006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal = 0;
7026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc S;
70330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // first operand is the offset
7046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  S = Parser.getTok().getLoc();
7056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (parseMemOffset(IdVal))
7076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
7086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
70930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok(); // get next token
7106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::LParen)) {
7116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "'(' expected");
7126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
7136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
7146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); // Eat '(' token.
7166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const AsmToken &Tok1 = Parser.getTok(); //get next token
7186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok1.is(AsmToken::Dollar)) {
7196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Parser.Lex(); // Eat '$' token.
7206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (tryParseRegisterOperand(Operands,"")) {
7216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Error(Parser.getTok().getLoc(), "unexpected token in operand");
7226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return MatchOperand_ParseFail;
7236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
7246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else {
72630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
7276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
7286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
7296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
73030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok2 = Parser.getTok(); // get next token
7316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok2.isNot(AsmToken::RParen)) {
7326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
7336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
7346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
7356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
7376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); // Eat ')' token.
7396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (IdVal == 0)
7416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    IdVal = MCConstantExpr::Create(0, getContext());
7426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
74330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // now replace register operand with the mem operand
7446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
7456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  int RegNo = op->getReg();
74630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // remove register from operands
7476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
74830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // and add memory operand
7496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
7506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  delete op;
751ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
752ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
753ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
7546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
7556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind VK
7576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
7586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
7596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
7606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
7616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
7626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
7636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
7646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
7656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
7666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
7676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
7686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
7696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
7706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
7716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
7726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
7736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
7746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
7756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Default(MCSymbolRefExpr::VK_None);
7766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return VK;
7786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
7796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7801ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) {
781f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  int CC = StringSwitch<unsigned>(CondString)
782f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".f",    0)
783f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".un",   1)
784f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".eq",   2)
785f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ueq",  3)
786f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".olt",  4)
787f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ult",  5)
788f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ole",  6)
789f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ule",  7)
790f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".sf",   8)
791f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngle", 9)
792f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".seq",  10)
793f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngl",  11)
794f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".lt",   12)
795f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".nge",  13)
796f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".le",   14)
797f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngt",  15)
798f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Default(-1);
799f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return CC;
801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
803f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::
804f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc,
80530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter                   SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
80630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // split the format
807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  size_t Start = Name.find('.'), Next = Name.rfind('.');
808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format1 = Name.slice(Start, Next);
80930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // and add the first format to the operands
810f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
81130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // now for the second format
812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format2 = Name.slice(Next, StringRef::npos);
813f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
814f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
81530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // set the format for the first register
816f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  setFpFormat(Format1);
817f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  // Read the remaining operands.
819f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
820f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Read the first operand.
821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
823f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.EatToEndOfStatement();
824f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
825f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (getLexer().isNot(AsmToken::Comma)) {
828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.EatToEndOfStatement();
830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Parser.Lex();  // Eat the comma.
834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    //set the format for the first register
836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(Format2);
837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Parse and remember the operand.
839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
841f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      Parser.EatToEndOfStatement();
842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
844f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
845f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
847f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    SMLoc Loc = getLexer().getLoc();
848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Parser.EatToEndOfStatement();
849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return Error(Loc, "unexpected token in argument list");
850f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
851f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
852f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Parser.Lex(); // Consume the EndOfStatement
853f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return false;
854f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
855f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
856fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
857fddf80459747198d2ee33974c90f6137ea29cbd8Rafael EspindolaParseInstruction(StringRef Name, SMLoc NameLoc,
858fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
85930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // floating point instructions: should register be treated as double?
860f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (requestsDoubleOperand(Name)) {
861f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(FP_FORMAT_D);
862ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
863f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
864f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else {
865f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setDefaultFpFormat();
866f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Create the leading tokens for the mnemonic, split by '.' characters.
867f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    size_t Start = 0, Next = Name.find('.');
868f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef Mnemonic = Name.slice(Start, Next);
869f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
870f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
871f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
872f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Next != StringRef::npos) {
87330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      // there is a format token in mnemonic
87430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      // StringRef Rest = Name.slice(Next, StringRef::npos);
875f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      size_t Dot = Name.find('.', Next+1);
876f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      StringRef Format = Name.slice(Next, Dot);
877f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if (Dot == StringRef::npos) //only one '.' in a string, it's a format
878f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
879f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      else {
880f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        if (Name.startswith("c.")){
881f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          // floating point compare, add '.' and immediate represent for cc
882f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
883f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          int Cc = ConvertCcString(Format);
884f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          if (Cc == -1) {
885f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter            return Error(NameLoc, "Invalid conditional code");
886f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          }
887f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          SMLoc E = SMLoc::getFromPointer(
888f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter              Parser.getTok().getLoc().getPointer() -1 );
889f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateImm(
890f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter              MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
891f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        } else {
89230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter          // trunc, ceil, floor ...
893f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          return parseMathOperation(Name, NameLoc, Operands);
894f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        }
895f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
89630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter        // the rest is a format
897f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Format = Name.slice(Dot, StringRef::npos);
898f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
899f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
900f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
901f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      setFpFormat(Format);
902f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
903f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
904ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
905ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
908ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ParseOperand(Operands, Name)) {
909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Parser.EatToEndOfStatement();
911ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
912ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
914ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    while (getLexer().is(AsmToken::Comma) ) {
915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Parser.Lex();  // Eat the comma.
916ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
917ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
918ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ParseOperand(Operands, Name)) {
919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
920ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.EatToEndOfStatement();
921ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
922ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
926ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
927ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.EatToEndOfStatement();
929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
930ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
931ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Consume the EndOfStatement
933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
934fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
935fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
93630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
93730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter   SMLoc Loc = getLexer().getLoc();
93830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter   Parser.EatToEndOfStatement();
93930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter   return Error(Loc, ErrorMsg);
94030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
94130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
94230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() {
94330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // line should look like:
94430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  //  .set noat
94530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // set at reg to 0
94630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Options->setATReg(0);
94730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // eat noat
94830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
94930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // if this is not the end of the statement, report error
95030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
95130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
95230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
95330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
95430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
95530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
95630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
95730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() {
95830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // line can be
95930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  //  .set at - defaults to $1
96030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // or .set at=$reg
96130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  getParser().Lex();
96230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().is(AsmToken::EndOfStatement)) {
96330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Options->setATReg(1);
96430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // Consume the EndOfStatement
96530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
96630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (getLexer().is(AsmToken::Equal)) {
96730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    getParser().Lex(); //eat '='
96830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::Dollar)) {
96930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
97030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
97130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
97230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // eat '$'
97330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::Integer)) {
97430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
97530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
97630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
97730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    const AsmToken &Reg = Parser.getTok();
97830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (!Options->setATReg(Reg.getIntVal())) {
97930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
98030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
98130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
98230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    getParser().Lex(); //eat reg
98330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
98430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
98530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
98630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
98730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter     }
98830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // Consume the EndOfStatement
98930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
99030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else {
99130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
99230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
99330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
99430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
99530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
99630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() {
99730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
99830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // if this is not the end of the statement, report error
99930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
100030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
100130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
100230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
100330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Options->setReorder();
100430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
100530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
100630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
100730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
100830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() {
100930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex();
101030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // if this is not the end of the statement, report error
101130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
101230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
101330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
101430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
101530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Options->setNoreorder();
101630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // Consume the EndOfStatement
101730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
101830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
101930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
102030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() {
102130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
102230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // if this is not the end of the statement, report error
102330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
102430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
102530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
102630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
102730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Options->setMacro();
102830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
102930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
103030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
103130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
103230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() {
103330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
103430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // if this is not the end of the statement, report error
103530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
103630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
103730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
103830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
103930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Options->isReorder()) {
104030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
104130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
104230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
104330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Options->setNomacro();
104430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
104530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
104630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
104730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() {
104830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
104930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // get next token
105030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok();
105130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
105230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Tok.getString() == "noat") {
105330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoAtDirective();
105430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "at") {
105530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetAtDirective();
105630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "reorder") {
105730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetReorderDirective();
105830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "noreorder") {
105930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoReorderDirective();
106030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "macro") {
106130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetMacroDirective();
106230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomacro") {
106330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoMacroDirective();
106430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomips16") {
106530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
106630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.EatToEndOfStatement();
106730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
106830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomicromips") {
106930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
107030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.EatToEndOfStatement();
107130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
107230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
107330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
107430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
107530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
107630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1077acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1078acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".ent") {
107930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1080acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1081acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1082acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1083acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1084acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".end") {
108530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1086acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1087acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1088acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1089acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1090acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".frame") {
109130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1092acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
1093acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1094acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1095acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1096acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".set") {
109730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
109830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    //Parser.EatToEndOfStatement();
109930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseDirectiveSet();
1100acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1101acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1102acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".fmask") {
110330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1104acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
1105acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1106acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1107acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1108acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".mask") {
110930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1110acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
1111acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1112acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1113acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1114acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  if (DirectiveID.getString() == ".gpword") {
111530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1116acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.EatToEndOfStatement();
1117acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1118acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1119acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1120fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1121fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1122fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
1123fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
1124fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1125fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1126fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1127fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1128fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1129ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1130ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
1131ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
1132ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
1133