MipsAsmParser.cpp revision 6e006d3de882784527d4d9cc92b1a91f6773505e
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//
33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//                     The LLVM Compiler Infrastructure
43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//
53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// This file is distributed under the University of Illinois Open Source
63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy// License. See LICENSE.TXT for details.
73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//
83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy//===----------------------------------------------------------------------===//
93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "MCTargetDesc/MipsMCTargetDesc.h"
113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "MipsRegisterInfo.h"
123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/ADT/StringSwitch.h"
133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCContext.h"
143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCExpr.h"
153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCInst.h"
16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy#include "llvm/MC/MCStreamer.h"
173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCSubtargetInfo.h"
183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCSymbol.h"
193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCParser/MCAsmLexer.h"
207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/MC/MCTargetAsmParser.h"
223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "llvm/Support/TargetRegistry.h"
233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
243ed852eea50f9d4cd633efb8c2b054b8e33c253cristyusing namespace llvm;
253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
263ed852eea50f9d4cd633efb8c2b054b8e33c253cristynamespace {
273ed852eea50f9d4cd633efb8c2b054b8e33c253cristyclass MipsAssemblerOptions {
283ed852eea50f9d4cd633efb8c2b054b8e33c253cristypublic:
293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MipsAssemblerOptions():
303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    aTReg(1), reorder(true), macro(true) {
313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned getATRegNum() {return aTReg;}
343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool setATReg(unsigned Reg);
353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool isReorder() {return reorder;}
373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void setReorder() {reorder = true;}
383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void setNoreorder() {reorder = false;}
393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool isMacro() {return macro;}
413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void setMacro() {macro = true;}
423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void setNomacro() {macro = false;}
433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
443ed852eea50f9d4cd633efb8c2b054b8e33c253cristyprivate:
454c08aed51c5899665ade97263692328eea4af106cristy  unsigned aTReg;
464c08aed51c5899665ade97263692328eea4af106cristy  bool reorder;
475ff4eaf57b3cd47d0371f204f865cbba614674a0cristy  bool macro;
484c08aed51c5899665ade97263692328eea4af106cristy};
494c08aed51c5899665ade97263692328eea4af106cristy}
50c9afe1687cd4da5d2382a9ca3ca12f30d8baa96fcristy
514c08aed51c5899665ade97263692328eea4af106cristynamespace {
524c08aed51c5899665ade97263692328eea4af106cristyclass MipsAsmParser : public MCTargetAsmParser {
534c08aed51c5899665ade97263692328eea4af106cristy
5454b92627b2e9657853beee431546d08234276477cristy  enum FpFormatTy {
554c08aed51c5899665ade97263692328eea4af106cristy    FP_FORMAT_NONE = -1,
564c08aed51c5899665ade97263692328eea4af106cristy    FP_FORMAT_S,
574c08aed51c5899665ade97263692328eea4af106cristy    FP_FORMAT_D,
584c08aed51c5899665ade97263692328eea4af106cristy    FP_FORMAT_L,
594c08aed51c5899665ade97263692328eea4af106cristy    FP_FORMAT_W
603644bdf56f0081bcae1f4dbc69c2d06713f6203bcristy  } FpFormat;
614c08aed51c5899665ade97263692328eea4af106cristy
624c08aed51c5899665ade97263692328eea4af106cristy  MCSubtargetInfo &STI;
634c08aed51c5899665ade97263692328eea4af106cristy  MCAsmParser &Parser;
644c08aed51c5899665ade97263692328eea4af106cristy  MipsAssemblerOptions Options;
654c08aed51c5899665ade97263692328eea4af106cristy
664c08aed51c5899665ade97263692328eea4af106cristy
674c08aed51c5899665ade97263692328eea4af106cristy#define GET_ASSEMBLER_HEADER
684c08aed51c5899665ade97263692328eea4af106cristy#include "MipsGenAsmMatcher.inc"
694c08aed51c5899665ade97263692328eea4af106cristy
704c08aed51c5899665ade97263692328eea4af106cristy  bool MatchAndEmitInstruction(SMLoc IDLoc,
714c08aed51c5899665ade97263692328eea4af106cristy                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
724c08aed51c5899665ade97263692328eea4af106cristy                               MCStreamer &Out);
734c08aed51c5899665ade97263692328eea4af106cristy
744c08aed51c5899665ade97263692328eea4af106cristy  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
754c08aed51c5899665ade97263692328eea4af106cristy
764c08aed51c5899665ade97263692328eea4af106cristy  bool ParseInstruction(StringRef Name, SMLoc NameLoc,
774c08aed51c5899665ade97263692328eea4af106cristy                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
784c08aed51c5899665ade97263692328eea4af106cristy
79d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy  bool parseMathOperation(StringRef Name, SMLoc NameLoc,
80bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
814c08aed51c5899665ade97263692328eea4af106cristy
823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool ParseDirective(AsmToken DirectiveID);
8307a3cca00593c795eb8e0427f5bc4c2bcad3f0fbcristy
843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MipsAsmParser::OperandMatchResultTy
853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*>&);
8603f187ee83f1927717c93c57af06d5e030a194becristy
873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                    StringRef Mnemonic);
893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int tryParseRegister(StringRef Mnemonic);
913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                               StringRef Mnemonic);
943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool needsExpansion(MCInst &Inst);
963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                         SmallVectorImpl<MCInst> &Instructions);
993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                     SmallVectorImpl<MCInst> &Instructions);
1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            SmallVectorImpl<MCInst> &Instructions);
1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                            SmallVectorImpl<MCInst> &Instructions);
1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool reportParseError(StringRef ErrorMsg);
1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool parseMemOffset(const MCExpr *&Res);
10869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseRelocOperand(const MCExpr *&Res);
10969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
11069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseDirectiveSet();
11169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
11269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseSetAtDirective();
11369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseSetNoAtDirective();
11469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseSetMacroDirective();
11569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseSetNoMacroDirective();
11669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseSetReorderDirective();
11769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool parseSetNoReorderDirective();
11869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
11969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
12069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
12169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool isMips64() const {
12269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
12369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
12469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
12569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  bool isFP64() const {
12669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
12769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
12869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
12969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  int matchRegisterName(StringRef Symbol);
1303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic);
132d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
133d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  void setFpFormat(FpFormatTy Format) {
134d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    FpFormat = Format;
135d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  }
136d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
137d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  void setDefaultFpFormat();
1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void setFpFormat(StringRef Format);
1403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1415cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  FpFormatTy getFpFormat() {return FpFormat;}
1425cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
1435cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  bool requestsDoubleOperand(StringRef Mnemonic);
1445cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned getReg(int RC,int RegNo);
1465cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
1475cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  unsigned getATReg();
1485cbc016effaa2d7ee617f46ca0a2371533d4ae17cristypublic:
1493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
1503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    : MCTargetAsmParser(), STI(sti), Parser(parser) {
1513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // Initialize the set of available features.
1523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
1533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
155d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  MCAsmParser &getParser() const { return Parser; }
156d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
157d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
158d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy};
159d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy}
160d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
161d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristynamespace {
162d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
163d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/// MipsOperand - Instances of this class represent a parsed Mips machine
164d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/// instruction.
165d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristyclass MipsOperand : public MCParsedAsmOperand {
166d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
167d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  enum KindTy {
1685ff4eaf57b3cd47d0371f204f865cbba614674a0cristy    k_CondCode,
169d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    k_CoprocNum,
1707c9770650f31145e0fe8811d10b2e0ecd47697c8cristy    k_Immediate,
1717c9770650f31145e0fe8811d10b2e0ecd47697c8cristy    k_Memory,
172d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    k_PostIndexRegister,
173d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    k_Register,
174d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    k_Token
175d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  } Kind;
176d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
177d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
178d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
179d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  union {
180d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    struct {
181d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy      const char *Data;
182d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy      unsigned Length;
183d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    } Tok;
184d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
185d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    struct {
186d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy      unsigned RegNum;
187d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    } Reg;
188d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
189d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    struct {
190d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy      const MCExpr *Val;
191d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    } Imm;
192d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
1935ff4eaf57b3cd47d0371f204f865cbba614674a0cristy    struct {
194d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy      unsigned Base;
195d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy      const MCExpr *Off;
19604b11db5504ecdf205114ae7e9e68774a1ff0b9bcristy    } Mem;
1973d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy  };
198d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
199d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  SMLoc StartLoc, EndLoc;
200d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy
201d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristypublic:
202d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy  void addRegOperands(MCInst &Inst, unsigned N) const {
203d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    assert(N == 1 && "Invalid number of operands!");
204d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy    Inst.addOperand(MCOperand::CreateReg(getReg()));
2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // Add as immediate when possible.  Null MCExpr = 0.
2093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Expr == 0)
2103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Inst.addOperand(MCOperand::CreateImm(0));
2113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
2123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
2133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
2143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Inst.addOperand(MCOperand::CreateExpr(Expr));
215528127ac76bc2eda65c7e8407b11669b25513149cristy  }
216528127ac76bc2eda65c7e8407b11669b25513149cristy
217528127ac76bc2eda65c7e8407b11669b25513149cristy  void addImmOperands(MCInst &Inst, unsigned N) const {
218528127ac76bc2eda65c7e8407b11669b25513149cristy    assert(N == 1 && "Invalid number of operands!");
219528127ac76bc2eda65c7e8407b11669b25513149cristy    const MCExpr *Expr = getImm();
220528127ac76bc2eda65c7e8407b11669b25513149cristy    addExpr(Inst,Expr);
221528127ac76bc2eda65c7e8407b11669b25513149cristy  }
222528127ac76bc2eda65c7e8407b11669b25513149cristy
223528127ac76bc2eda65c7e8407b11669b25513149cristy  void addMemOperands(MCInst &Inst, unsigned N) const {
224528127ac76bc2eda65c7e8407b11669b25513149cristy    assert(N == 2 && "Invalid number of operands!");
225528127ac76bc2eda65c7e8407b11669b25513149cristy
226528127ac76bc2eda65c7e8407b11669b25513149cristy    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
227528127ac76bc2eda65c7e8407b11669b25513149cristy
228528127ac76bc2eda65c7e8407b11669b25513149cristy    const MCExpr *Expr = getMemOff();
229528127ac76bc2eda65c7e8407b11669b25513149cristy    addExpr(Inst,Expr);
230528127ac76bc2eda65c7e8407b11669b25513149cristy  }
231528127ac76bc2eda65c7e8407b11669b25513149cristy
232528127ac76bc2eda65c7e8407b11669b25513149cristy  bool isReg() const { return Kind == k_Register; }
233528127ac76bc2eda65c7e8407b11669b25513149cristy  bool isImm() const { return Kind == k_Immediate; }
234528127ac76bc2eda65c7e8407b11669b25513149cristy  bool isToken() const { return Kind == k_Token; }
235528127ac76bc2eda65c7e8407b11669b25513149cristy  bool isMem() const { return Kind == k_Memory; }
236528127ac76bc2eda65c7e8407b11669b25513149cristy
237528127ac76bc2eda65c7e8407b11669b25513149cristy  StringRef getToken() const {
238528127ac76bc2eda65c7e8407b11669b25513149cristy    assert(Kind == k_Token && "Invalid access!");
239528127ac76bc2eda65c7e8407b11669b25513149cristy    return StringRef(Tok.Data, Tok.Length);
240528127ac76bc2eda65c7e8407b11669b25513149cristy  }
241528127ac76bc2eda65c7e8407b11669b25513149cristy
242528127ac76bc2eda65c7e8407b11669b25513149cristy  unsigned getReg() const {
243528127ac76bc2eda65c7e8407b11669b25513149cristy    assert((Kind == k_Register) && "Invalid access!");
244528127ac76bc2eda65c7e8407b11669b25513149cristy    return Reg.RegNum;
245528127ac76bc2eda65c7e8407b11669b25513149cristy  }
246528127ac76bc2eda65c7e8407b11669b25513149cristy
247528127ac76bc2eda65c7e8407b11669b25513149cristy  const MCExpr *getImm() const {
248528127ac76bc2eda65c7e8407b11669b25513149cristy    assert((Kind == k_Immediate) && "Invalid access!");
249528127ac76bc2eda65c7e8407b11669b25513149cristy    return Imm.Val;
250528127ac76bc2eda65c7e8407b11669b25513149cristy  }
251528127ac76bc2eda65c7e8407b11669b25513149cristy
252528127ac76bc2eda65c7e8407b11669b25513149cristy  unsigned getMemBase() const {
253528127ac76bc2eda65c7e8407b11669b25513149cristy    assert((Kind == k_Memory) && "Invalid access!");
254528127ac76bc2eda65c7e8407b11669b25513149cristy    return Mem.Base;
255528127ac76bc2eda65c7e8407b11669b25513149cristy  }
256528127ac76bc2eda65c7e8407b11669b25513149cristy
257528127ac76bc2eda65c7e8407b11669b25513149cristy  const MCExpr *getMemOff() const {
258528127ac76bc2eda65c7e8407b11669b25513149cristy    assert((Kind == k_Memory) && "Invalid access!");
259528127ac76bc2eda65c7e8407b11669b25513149cristy    return Mem.Off;
260528127ac76bc2eda65c7e8407b11669b25513149cristy  }
261528127ac76bc2eda65c7e8407b11669b25513149cristy
2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MipsOperand *Op = new MipsOperand(k_Token);
2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->Tok.Data = Str.data();
2655cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    Op->Tok.Length = Str.size();
2665cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    Op->StartLoc = S;
2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->EndLoc = S;
2683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return Op;
2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MipsOperand *Op = new MipsOperand(k_Register);
2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->Reg.RegNum = RegNum;
2745cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    Op->StartLoc = S;
2755cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    Op->EndLoc = E;
2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return Op;
2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2785cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MipsOperand *Op = new MipsOperand(k_Immediate);
281151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    Op->Imm.Val = Val;
2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->StartLoc = S;
2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->EndLoc = E;
2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return Op;
2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 SMLoc S, SMLoc E) {
2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MipsOperand *Op = new MipsOperand(k_Memory);
2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->Mem.Base = Base;
2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->Mem.Off = Off;
2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->StartLoc = S;
2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Op->EndLoc = E;
2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return Op;
2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /// getStartLoc - Get the location of the first token of this operand.
2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SMLoc getStartLoc() const { return StartLoc; }
2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  /// getEndLoc - Get the location of the last token of this operand.
300bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  SMLoc getEndLoc() const { return EndLoc; }
3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  virtual void print(raw_ostream &OS) const {
3033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    llvm_unreachable("unimplemented!");
3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy};
3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::needsExpansion(MCInst &Inst) {
309bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy
3105846039e7fade723e168819490eb771446e4b81fcristy  switch(Inst.getOpcode()) {
3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case Mips::LoadImm32Reg:
3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case Mips::LoadAddr32Imm:
3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case Mips::LoadAddr32Reg:
314e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy      return true;
3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    default:
3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return false;
3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
318e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy}
3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        SmallVectorImpl<MCInst> &Instructions){
3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch(Inst.getOpcode()) {
3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case Mips::LoadImm32Reg:
3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return expandLoadImm(Inst, IDLoc, Instructions);
3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case Mips::LoadAddr32Imm:
3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return expandLoadAddressImm(Inst,IDLoc,Instructions);
3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    case Mips::LoadAddr32Reg:
3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return expandLoadAddressReg(Inst,IDLoc,Instructions);
3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
330bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy}
3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                  SmallVectorImpl<MCInst> &Instructions){
3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MCInst tmpInst;
3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &ImmOp = Inst.getOperand(1);
3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(ImmOp.isImm() && "expected immediate operand kind");
3373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &RegOp = Inst.getOperand(0);
3385cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  assert(RegOp.isReg() && "expected register operand kind");
3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int ImmValue = ImmOp.getImm();
3415cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  tmpInst.setLoc(IDLoc);
3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ( 0 <= ImmValue && ImmValue <= 65535) {
343a6400b1cfc3594644a0f02f3d77d920092f078eecristy    // for 0 <= j <= 65535.
3440c81d063030f7b30a97c7856e95534243cdc9e13cristy    // li d,j => ori d,$zero,j
3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi);
3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(
3483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO));
3493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if ( ImmValue < 0 && ImmValue >= -32768) {
3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // for -32768 <= j < 0.
3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // li d,j => addiu d,$zero,j
3545cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files?
355bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
3565846039e7fade723e168819490eb771446e4b81fcristy    tmpInst.addOperand(
3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MCOperand::CreateReg(isMips64() ? Mips::ZERO_64 : Mips::ZERO));
3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // for any other value of j that is representable as a 32-bit integer.
3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // li d,j => lui d,hi16(j)
3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //           ori d,d,lo16(j)
3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64() ? Mips::LUi64 : Mips::LUi);
3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.clear();
3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64() ? Mips::ORi64 : Mips::ORi);
3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setLoc(IDLoc);
3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                         SmallVectorImpl<MCInst> &Instructions){
3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MCInst tmpInst;
3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &ImmOp = Inst.getOperand(2);
3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(ImmOp.isImm() && "expected immediate operand kind");
3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &SrcRegOp = Inst.getOperand(1);
3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(SrcRegOp.isReg() && "expected register operand kind");
3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &DstRegOp = Inst.getOperand(0);
3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(DstRegOp.isReg() && "expected register operand kind");
3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int ImmValue = ImmOp.getImm();
3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ( -32768 <= ImmValue && ImmValue <= 65535) {
3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //for -32768 <= j <= 65535.
3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //la d,j(s) => addiu d,s,j
3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(Mips::ADDiu); //TODO:no ADDiu64 in td files?
3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //for any other value of j that is representable as a 32-bit integer.
3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //la d,j(s) => lui d,hi16(j)
3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //             ori d,d,lo16(j)
4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //             addu d,d,s
4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64()?Mips::LUi64:Mips::LUi);
4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.clear();
4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64()?Mips::ORi64:Mips::ORi);
4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
4087096f1cf18bfd18730112b4783146547a97854dacristy    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.clear();
4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(Mips::ADDu);
4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristyvoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                         SmallVectorImpl<MCInst> &Instructions){
42270aa59ba920fd758a05dfd1e59a446638b3dd2a9Cristy  MCInst tmpInst;
4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &ImmOp = Inst.getOperand(1);
4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(ImmOp.isImm() && "expected immediate operand kind");
4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCOperand &RegOp = Inst.getOperand(0);
4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  assert(RegOp.isReg() && "expected register operand kind");
4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int ImmValue = ImmOp.getImm();
4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ( -32768 <= ImmValue && ImmValue <= 65535) {
4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //for -32768 <= j <= 65535.
4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //la d,j => addiu d,$zero,j
4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(Mips::ADDiu);
4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(
4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MCOperand::CreateReg(isMips64()?Mips::ZERO_64:Mips::ZERO));
4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
4367096f1cf18bfd18730112b4783146547a97854dacristy    Instructions.push_back(tmpInst);
4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //for any other value of j that is representable as a 32-bit integer.
4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //la d,j => lui d,hi16(j)
4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    //          ori d,d,lo16(j)
4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64()?Mips::LUi64:Mips::LUi);
4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.clear();
4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.setOpcode(isMips64()?Mips::ORi64:Mips::ORi);
4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Instructions.push_back(tmpInst);
4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::
4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMatchAndEmitInstruction(SMLoc IDLoc,
4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                        MCStreamer &Out) {
4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MCInst Inst;
4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned ErrorInfo;
4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                              /*matchingInlineAsm*/ false);
4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch (MatchResult) {
4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default: break;
4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case Match_Success: {
4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (needsExpansion(Inst)) {
4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      SmallVector<MCInst, 4> Instructions;
4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      expandInstruction(Inst, IDLoc, Instructions);
4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      for(unsigned i =0; i < Instructions.size(); i++){
4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Out.EmitInstruction(Instructions[i]);
4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } else {
4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Inst.setLoc(IDLoc);
4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Out.EmitInstruction(Inst);
4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case Match_MissingFeature:
4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true;
4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case Match_InvalidOperand: {
4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    SMLoc ErrorLoc = IDLoc;
4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (ErrorInfo != ~0U) {
4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ErrorInfo >= Operands.size())
4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return Error(IDLoc, "too few operands for instruction");
4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc();
4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return Error(ErrorLoc, "invalid operand for instruction");
4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case Match_MnemonicFail:
4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return Error(IDLoc, "invalid instruction");
4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return true;
4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint MipsAsmParser::matchRegisterName(StringRef Name) {
5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5014c08aed51c5899665ade97263692328eea4af106cristy   int CC;
5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   if (!isMips64())
5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    CC = StringSwitch<unsigned>(Name)
5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("zero",  Mips::ZERO)
5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a0",  Mips::A0)
5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a1",  Mips::A1)
5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a2",  Mips::A2)
5083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a3",  Mips::A3)
5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("v0",  Mips::V0)
5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("v1",  Mips::V1)
5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s0",  Mips::S0)
5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s1",  Mips::S1)
5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s2",  Mips::S2)
514151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      .Case("s3",  Mips::S3)
515dcc02b0a70d924b55afa7ce2089c4c15b25f2e1fcristy      .Case("s4",  Mips::S4)
5163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s5",  Mips::S5)
517018f07f7333b25743d0afff892450cebdb905c1acristy      .Case("s6",  Mips::S6)
5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s7",  Mips::S7)
5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("k0",  Mips::K0)
5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("k1",  Mips::K1)
5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("sp",  Mips::SP)
522151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      .Case("fp",  Mips::FP)
523a8549b176173db7680652304c372c64bb1a51737cristy      .Case("gp",  Mips::GP)
5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("ra",  Mips::RA)
5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t0",  Mips::T0)
5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t1",  Mips::T1)
5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t2",  Mips::T2)
5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t3",  Mips::T3)
529018f07f7333b25743d0afff892450cebdb905c1acristy      .Case("t4",  Mips::T4)
5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t5",  Mips::T5)
5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t6",  Mips::T6)
5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t7",  Mips::T7)
5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t8",  Mips::T8)
5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t9",  Mips::T9)
5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("at",  Mips::AT)
5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("fcc0",  Mips::FCC0)
537018f07f7333b25743d0afff892450cebdb905c1acristy      .Default(-1);
5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   else
5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    CC = StringSwitch<unsigned>(Name)
5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("zero", Mips::ZERO_64)
5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("at", Mips::AT_64)
5425cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy      .Case("v0", Mips::V0_64)
5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("v1", Mips::V1_64)
5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a0", Mips::A0_64)
5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a1", Mips::A1_64)
5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a2", Mips::A2_64)
5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a3", Mips::A3_64)
5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a4", Mips::T0_64)
5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a5", Mips::T1_64)
550018f07f7333b25743d0afff892450cebdb905c1acristy      .Case("a6", Mips::T2_64)
5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("a7", Mips::T3_64)
5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t4", Mips::T4_64)
5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t5", Mips::T5_64)
5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t6", Mips::T6_64)
5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t7", Mips::T7_64)
5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s0", Mips::S0_64)
5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s1", Mips::S1_64)
5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s2", Mips::S2_64)
5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s3", Mips::S3_64)
5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s4", Mips::S4_64)
5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s5", Mips::S5_64)
5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s6", Mips::S6_64)
5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s7", Mips::S7_64)
5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t8", Mips::T8_64)
5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("t9", Mips::T9_64)
5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("kt0", Mips::K0_64)
5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("kt1", Mips::K1_64)
5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("gp", Mips::GP_64)
5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("sp", Mips::SP_64)
5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("fp", Mips::FP_64)
5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("s8", Mips::FP_64)
5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case("ra", Mips::RA_64)
5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Default(-1);
5743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (CC != -1)
5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return CC;
5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Name[0] == 'f') {
5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    StringRef NumString = Name.substr(1);
580bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    unsigned IntVal;
5815cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    if( NumString.getAsInteger(10, IntVal))
5825cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy      return -1; // not integer
5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (IntVal > 31)
5843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return -1;
5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    FpFormatTy Format = getFpFormat();
5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
5883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
5893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return getReg(Mips::FGR32RegClassID, IntVal);
5906b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy    if (Format == FP_FORMAT_D) {
5916b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy      if(isFP64()) {
5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return getReg(Mips::FGR64RegClassID, IntVal);
5933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
5946b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy      // only even numbers available as register pairs
5956b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy      if (( IntVal > 31) || (IntVal%2 !=  0))
5965cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy        return -1;
5975cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy      return getReg(Mips::AFGR64RegClassID, IntVal/2);
5983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
599bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy  }
6005cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
6015cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  return -1;
6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
60374966dbfe99011d1f7bea577e97a3d9a7b9836c7cristyvoid MipsAsmParser::setDefaultFpFormat() {
60474966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy
60574966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy  if (isMips64() || isFP64())
6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    FpFormat = FP_FORMAT_D;
6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  else
6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    FpFormat = FP_FORMAT_S;
6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
614bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    .Case("ldxc1", true)
6153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("ldc1",  true)
6163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("sdxc1", true)
617bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy    .Case("sdc1",  true)
6183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Default(false);
6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6206193b86c0b59030b647a10c75f37ec82d73e3695cristy  return IsDouble;
6216193b86c0b59030b647a10c75f37ec82d73e3695cristy}
6226193b86c0b59030b647a10c75f37ec82d73e3695cristyvoid MipsAsmParser::setFpFormat(StringRef Format) {
62374966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy
6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  FpFormat = StringSwitch<FpFormatTy>(Format.lower())
6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case(".s",  FP_FORMAT_S)
6263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case(".d",  FP_FORMAT_D)
6273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case(".l",  FP_FORMAT_L)
6283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case(".w",  FP_FORMAT_W)
6293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Default(FP_FORMAT_NONE);
6302911f2d54257d36e1086061dbcc312fdad781070cristy}
631e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy
632bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristybool MipsAssemblerOptions::setATReg(unsigned Reg) {
6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Reg > 31)
6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
6355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
6363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  aTReg = Reg;
6373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return true;
63878fed5ea9a7f0a35e641ce3bc6f835fb099c4d20cristy}
63974966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy
6406193b86c0b59030b647a10c75f37ec82d73e3695cristyunsigned MipsAsmParser::getATReg() {
64174966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy  unsigned Reg = Options.getATRegNum();
6424aa314e7f9e09c30fcedcd112156b1dfb712b62dcristy  if (isMips64())
6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return getReg(Mips::CPU64RegsRegClassID,Reg);
6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return getReg(Mips::CPURegsRegClassID,Reg);
6463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6484aa314e7f9e09c30fcedcd112156b1dfb712b62dcristyunsigned MipsAsmParser::getReg(int RC,int RegNo) {
6496b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy  return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
6506b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy}
6516b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy
6523ed852eea50f9d4cd633efb8c2b054b8e33c253cristyint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, StringRef Mnemonic) {
6536b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy
6546b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy  if (Mnemonic.lower() == "rdhwr") {
6556b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy    // at the moment only hwreg29 is supported
6566b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy    if (RegNum != 29)
6576b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy      return -1;
6586b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy    return Mips::HWR29;
6596b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy  }
6606b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy
6616b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy  if (RegNum > 31)
6626b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy    return -1;
6636b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy
6646b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy  // MIPS64 registers are numbered 1 after the 32-bit equivalents
6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return getReg(Mips::CPURegsRegClassID, RegNum) + isMips64();
6666193b86c0b59030b647a10c75f37ec82d73e3695cristy}
6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
66874966dbfe99011d1f7bea577e97a3d9a7b9836c7cristyint MipsAsmParser::tryParseRegister(StringRef Mnemonic) {
6696193b86c0b59030b647a10c75f37ec82d73e3695cristy  const AsmToken &Tok = Parser.getTok();
6703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int RegNum = -1;
6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6726193b86c0b59030b647a10c75f37ec82d73e3695cristy  if (Tok.is(AsmToken::Identifier)) {
6736193b86c0b59030b647a10c75f37ec82d73e3695cristy    std::string lowerCase = Tok.getString().lower();
6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    RegNum = matchRegisterName(lowerCase);
6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (Tok.is(AsmToken::Integer))
6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                   Mnemonic.lower());
6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    else
6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return RegNum;  //error
6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // 64 bit div operations require Mips::ZERO instead of MIPS::ZERO_64
6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (isMips64() && RegNum == Mips::ZERO_64) {
6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Mnemonic.find("ddiv") != StringRef::npos)
6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RegNum = Mips::ZERO;
6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return RegNum;
6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::
6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                          StringRef Mnemonic){
6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SMLoc S = Parser.getTok().getLoc();
6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int RegNo = -1;
6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // FIXME: we should make a more generic method for CCR
6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if ((Mnemonic == "cfc1" || Mnemonic == "ctc1")
6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      && Operands.size() == 2 && Parser.getTok().is(AsmToken::Integer)){
6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    RegNo = Parser.getTok().getIntVal();  // get the int value
6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // at the moment only fcc0 is supported
7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (RegNo ==  0)
7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      RegNo = Mips::FCC0;
7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else
7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    RegNo = tryParseRegister(Mnemonic);
7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (RegNo == -1)
7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true;
7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Parser.getTok().getLoc()));
7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // Eat register token.
7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return false;
7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
7125cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                 StringRef Mnemonic) {
7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // Check if the current operand has a custom associated parser, if so, try to
7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // custom parse the operand, or fallback to the general approach.
7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (ResTy == MatchOperand_Success)
7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
7203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // If there wasn't a custom match, try the generic matcher below. Otherwise,
7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // there was a match, but an error occurred, in which case, just return that
7225cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  // the operand parsing failed.
7235cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  if (ResTy == MatchOperand_ParseFail)
7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true;
7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7265cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  switch (getLexer().getKind()) {
7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default:
7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Error(Parser.getTok().getLoc(), "unexpected token in operand");
7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true;
7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Dollar: {
7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // parse register
7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    SMLoc S = Parser.getTok().getLoc();
7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex(); // Eat dollar token.
7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // parse register operand
7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (!tryParseRegisterOperand(Operands, Mnemonic)) {
7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (getLexer().is(AsmToken::LParen)) {
737bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy        // check if it is indexed addressing operand
7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Operands.push_back(MipsOperand::CreateToken("(", S));
7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Parser.Lex(); // eat parenthesis
7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (getLexer().isNot(AsmToken::Dollar))
7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return true;
7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Parser.Lex(); // eat dollar
744e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy        if (tryParseRegisterOperand(Operands, Mnemonic))
7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return true;
7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (!getLexer().is(AsmToken::RParen))
7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return true;
749e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy
7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        S = Parser.getTok().getLoc();
7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Operands.push_back(MipsOperand::CreateToken(")", S));
7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Parser.Lex();
7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return false;
7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // maybe it is a symbol reference
7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    StringRef Identifier;
7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Parser.ParseIdentifier(Identifier))
7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return true;
7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
761024843f38984cd26602f0b3b28a0768dfa056bb5cristy    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // Otherwise create a symbol ref.
7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                                                getContext());
7685cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Identifier:
7735cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  case AsmToken::LParen:
7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Minus:
7753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Plus:
7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Integer:
777e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy  case AsmToken::String: {
778e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy     // quoted label names
7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const MCExpr *IdVal;
7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    SMLoc S = Parser.getTok().getLoc();
7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (getParser().ParseExpression(IdVal))
7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return true;
7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Percent: {
7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // it is a symbol reference or constant expression
7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const MCExpr *IdVal;
7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    SMLoc S = Parser.getTok().getLoc(); // start location of the operand
7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (parseRelocOperand(IdVal))
7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return true;
7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } // case AsmToken::Percent
7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } // switch(getLexer().getKind())
8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return true;
8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // eat % token
8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const AsmToken &Tok = Parser.getTok(); // get next token, operation
8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Tok.isNot(AsmToken::Identifier))
8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true;
8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  std::string Str = Tok.getIdentifier().str();
8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // eat identifier
8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // now make expression from the rest of the operand
8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCExpr *IdVal;
8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SMLoc EndLoc;
8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().getKind() == AsmToken::LParen) {
8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (1) {
8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Parser.Lex(); // eat '(' token
8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (getLexer().getKind() == AsmToken::Percent) {
8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Parser.Lex(); // eat % token
8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        const AsmToken &nextTok = Parser.getTok();
8235cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy        if (nextTok.isNot(AsmToken::Identifier))
8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return true;
8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Str += "(%";
8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Str += nextTok.getIdentifier();
8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Parser.Lex(); // eat identifier
8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        if (getLexer().getKind() != AsmToken::LParen)
8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          return true;
8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      } else
8313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        break;
8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8335cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    if (getParser().ParseParenExpression(IdVal,EndLoc))
8345cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy      return true;
8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (getLexer().getKind() == AsmToken::RParen)
8375cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy      Parser.Lex(); // eat ')' token
8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else
8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true; // parenthesis must follow reloc operand
8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // Check the type of the expression
8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // it's a constant, evaluate lo or hi value
8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    int Val = MCE->getValue();
8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Str == "lo") {
8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Val = Val & 0xffff;
8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    } else if (Str == "hi") {
849e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy      Val = (Val & 0xffff0000) >> 16;
8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Res = MCConstantExpr::Create(Val, getContext());
8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
854e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy
8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // it's a symbol, create symbolic expression from symbol
857024843f38984cd26602f0b3b28a0768dfa056bb5cristy    StringRef Symbol = MSRE->getSymbol().getName();
8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
8615cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  }
8623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return true;
8633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
864e7f5109f30fc7242d04a26174a9138483dda5b6acristy
865a8549b176173db7680652304c372c64bb1a51737cristybool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
866e7f5109f30fc7242d04a26174a9138483dda5b6acristy                                  SMLoc &EndLoc) {
8673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StartLoc = Parser.getTok().getLoc();
8694c08aed51c5899665ade97263692328eea4af106cristy  RegNo = tryParseRegister("");
8704c08aed51c5899665ade97263692328eea4af106cristy  EndLoc = Parser.getTok().getLoc();
8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return (RegNo == (unsigned)-1);
8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SMLoc S;
8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  switch(getLexer().getKind()) {
8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  default:
8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return true;
8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Integer:
8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Minus:
8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Plus:
8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return (getParser().ParseExpression(Res));
8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::Percent:
8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return parseRelocOperand(Res);
8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  case AsmToken::LParen:
8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;  // it's probably assuming 0
8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return true;
8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8935cbc016effaa2d7ee617f46ca0a2371533d4ae17cristyMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const MCExpr *IdVal = 0;
8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  SMLoc S;
8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // first operand is the offset
8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  S = Parser.getTok().getLoc();
9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (parseMemOffset(IdVal))
9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return MatchOperand_ParseFail;
9033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const AsmToken &Tok = Parser.getTok(); // get next token
9055cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  if (Tok.isNot(AsmToken::LParen)) {
9065cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Mnemonic->getToken() == "la") {
9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer()-1);
9095cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy      Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return MatchOperand_Success;
9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Error(Parser.getTok().getLoc(), "'(' expected");
9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return MatchOperand_ParseFail;
9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // Eat '(' token.
9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const AsmToken &Tok1 = Parser.getTok(); // get next token
9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Tok1.is(AsmToken::Dollar)) {
9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex(); // Eat '$' token.
9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (tryParseRegisterOperand(Operands,"")) {
9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Error(Parser.getTok().getLoc(), "unexpected token in operand");
9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return MatchOperand_ParseFail;
9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9265cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  } else {
9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Error(Parser.getTok().getLoc(), "unexpected token in operand");
9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return MatchOperand_ParseFail;
9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9305cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const AsmToken &Tok2 = Parser.getTok(); // get next token
9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Tok2.isNot(AsmToken::RParen)) {
9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Error(Parser.getTok().getLoc(), "')' expected");
9345cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    return MatchOperand_ParseFail;
9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9375cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9395cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  Parser.Lex(); // Eat ')' token.
940efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy
9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (IdVal == 0)
9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    IdVal = MCConstantExpr::Create(0, getContext());
9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // now replace register operand with the mem operand
9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
9465cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  int RegNo = op->getReg();
9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // remove register from operands
9485cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  Operands.pop_back();
949efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy  // and add memory operand
9503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
9513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  delete op;
952d984f27fbbb96073787c88f4c9409d7f836cedc5cristy  return MatchOperand_Success;
9535cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy}
954d984f27fbbb96073787c88f4c9409d7f836cedc5cristy
955cbb34a4def108d6db032ca9631a433afd3ea5a5dcristyMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
9565cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
9573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  MCSymbolRefExpr::VariantKind VK
958704acaaebbfeec018847456e79de0ce301db126ecristy                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
9595cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
960704acaaebbfeec018847456e79de0ce301db126ecristy    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
9616193b86c0b59030b647a10c75f37ec82d73e3695cristy    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
9625cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
9636193b86c0b59030b647a10c75f37ec82d73e3695cristy    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
9655cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
9675cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
968704acaaebbfeec018847456e79de0ce301db126ecristy    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
9705cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
9715cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    .Default(MCSymbolRefExpr::VK_None);
9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
9783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return VK;
9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
9805cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
9815cbc016effaa2d7ee617f46ca0a2371533d4ae17cristystatic int ConvertCcString(StringRef CondString) {
9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  int CC = StringSwitch<unsigned>(CondString)
9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".f",    0)
9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".un",   1)
9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".eq",   2)
9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ueq",  3)
9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".olt",  4)
9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ult",  5)
9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ole",  6)
9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ule",  7)
9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".sf",   8)
9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ngle", 9)
9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".seq",  10)
9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ngl",  11)
9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".lt",   12)
9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".nge",  13)
9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".le",   14)
9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Case(".ngt",  15)
9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      .Default(-1);
10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return CC;
10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
10035cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
10045cbc016effaa2d7ee617f46ca0a2371533d4ae17cristybool MipsAsmParser::
10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristyparseMathOperation(StringRef Name, SMLoc NameLoc,
10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy                   SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // split the format
10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  size_t Start = Name.find('.'), Next = Name.rfind('.');
10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringRef Format1 = Name.slice(Start, Next);
10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // and add the first format to the operands
10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // now for the second format
10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  StringRef Format2 = Name.slice(Next, StringRef::npos);
10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // set the format for the first register
10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  setFpFormat(Format1);
10185cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
10195cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  // Read the remaining operands.
10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
10213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // Read the first operand.
10223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (ParseOperand(Operands, Name)) {
10232857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy      SMLoc Loc = getLexer().getLoc();
102469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      Parser.EatToEndOfStatement();
102569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      return Error(Loc, "unexpected token in argument list");
102669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    }
102769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
102869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    if (getLexer().isNot(AsmToken::Comma)) {
102969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      SMLoc Loc = getLexer().getLoc();
103069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      Parser.EatToEndOfStatement();
103169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      return Error(Loc, "unexpected token in argument list");
103269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
103369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    }
103469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    Parser.Lex();  // Eat the comma.
103569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
103669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    //set the format for the first register
103769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    setFpFormat(Format2);
103869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
103969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    // Parse and remember the operand.
104069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    if (ParseOperand(Operands, Name)) {
104169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      SMLoc Loc = getLexer().getLoc();
104269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      Parser.EatToEndOfStatement();
104369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      return Error(Loc, "unexpected token in argument list");
104469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    }
104569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
104669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
104769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
104869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    SMLoc Loc = getLexer().getLoc();
104969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    Parser.EatToEndOfStatement();
105069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    return Error(Loc, "unexpected token in argument list");
105169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
105269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
105369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  Parser.Lex(); // Consume the EndOfStatement
105469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  return false;
105569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy}
105669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
105769a0d3b5699c573f650e6b61f98ce4579d6f218cCristybool MipsAsmParser::
105869a0d3b5699c573f650e6b61f98ce4579d6f218cCristyParseInstruction(StringRef Name, SMLoc NameLoc,
105969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
106069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  // floating point instructions: should register be treated as double?
106169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  if (requestsDoubleOperand(Name)) {
106269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    setFpFormat(FP_FORMAT_D);
106369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
106469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
106569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  else {
106669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    setDefaultFpFormat();
106769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    // Create the leading tokens for the mnemonic, split by '.' characters.
106869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    size_t Start = 0, Next = Name.find('.');
106969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    StringRef Mnemonic = Name.slice(Start, Next);
107069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy
10713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
10723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (Next != StringRef::npos) {
10743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      // there is a format token in mnemonic
10753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      // StringRef Rest = Name.slice(Next, StringRef::npos);
10763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      size_t Dot = Name.find('.', Next+1);
10773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      StringRef Format = Name.slice(Next, Dot);
1078151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy      if (Dot == StringRef::npos) //only one '.' in a string, it's a format
10793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
10803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      else {
10819c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy        if (Name.startswith("c.")){
10829c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy          // floating point compare, add '.' and immediate represent for cc
10839c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy          Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
10843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          int Cc = ConvertCcString(Format);
10853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          if (Cc == -1) {
10863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy            return Error(NameLoc, "Invalid conditional code");
10873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          }
10883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          SMLoc E = SMLoc::getFromPointer(
10893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              Parser.getTok().getLoc().getPointer() -1 );
10903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          Operands.push_back(MipsOperand::CreateImm(
10913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy              MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
10923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        } else {
10933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy          // trunc, ceil, floor ...
1094151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy          return parseMathOperation(Name, NameLoc, Operands);
10953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        }
10963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
10979c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy        // the rest is a format
10989c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy        Format = Name.slice(Dot, StringRef::npos);
10993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
11003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      setFpFormat(Format);
11033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // Read the remaining operands.
11073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
11083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // Read the first operand.
1109151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy    if (ParseOperand(Operands, Name)) {
11103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      SMLoc Loc = getLexer().getLoc();
11113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Parser.EatToEndOfStatement();
11129c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy      return Error(Loc, "unexpected token in argument list");
11139c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy    }
11143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    while (getLexer().is(AsmToken::Comma) ) {
11163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      Parser.Lex();  // Eat the comma.
11173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      // Parse and remember the operand.
11193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      if (ParseOperand(Operands, Name)) {
11203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        SMLoc Loc = getLexer().getLoc();
11213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        Parser.EatToEndOfStatement();
11223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy        return Error(Loc, "unexpected token in argument list");
11233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      }
11243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
1125151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy  }
11263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
11289c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy    SMLoc Loc = getLexer().getLoc();
11299c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy    Parser.EatToEndOfStatement();
11309c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy    return Error(Loc, "unexpected token in argument list");
11313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // Consume the EndOfStatement
11343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return false;
11353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy
11375cbc016effaa2d7ee617f46ca0a2371533d4ae17cristybool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
11383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   SMLoc Loc = getLexer().getLoc();
11393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   Parser.EatToEndOfStatement();
11403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy   return Error(Loc, ErrorMsg);
11413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11433ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseSetNoAtDirective() {
11443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // line should look like:
11453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  //  .set noat
11463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // set at reg to 0
11473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Options.setATReg(0);
11483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // eat noat
11493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex();
11503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // if this is not the end of the statement, report error
11513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
11523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reportParseError("unexpected token in statement");
11533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
11543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // Consume the EndOfStatement
11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return false;
11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseSetAtDirective() {
11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // line can be
11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  //  .set at - defaults to $1
11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // or .set at=$reg
11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  getParser().Lex();
11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().is(AsmToken::EndOfStatement)) {
11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Options.setATReg(1);
11653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex(); // Consume the EndOfStatement
11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (getLexer().is(AsmToken::Equal)) {
11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    getParser().Lex(); //eat '='
11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (getLexer().isNot(AsmToken::Dollar)) {
11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      reportParseError("unexpected token in statement");
1171f8f295fde25dd8b1a50470d53b641d5265c0871fcristy      return false;
11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex(); // eat '$'
11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (getLexer().isNot(AsmToken::Integer)) {
11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      reportParseError("unexpected token in statement");
11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return false;
11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    const AsmToken &Reg = Parser.getTok();
11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (!Options.setATReg(Reg.getIntVal())) {
11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      reportParseError("unexpected token in statement");
11813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return false;
11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    }
11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    getParser().Lex(); //eat reg
11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    if (getLexer().isNot(AsmToken::EndOfStatement)) {
11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      reportParseError("unexpected token in statement");
11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy      return false;
11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy     }
11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex(); // Consume the EndOfStatement
11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else {
11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reportParseError("unexpected token in statement");
11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
1195f8f295fde25dd8b1a50470d53b641d5265c0871fcristy}
1196f8f295fde25dd8b1a50470d53b641d5265c0871fcristy
1197f8f295fde25dd8b1a50470d53b641d5265c0871fcristybool MipsAsmParser::parseSetReorderDirective() {
11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex();
11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // if this is not the end of the statement, report error
12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reportParseError("unexpected token in statement");
120269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    return false;
120369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
120469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  Options.setReorder();
120569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  Parser.Lex(); // Consume the EndOfStatement
120669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  return false;
120769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy}
12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseSetNoReorderDirective() {
12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex();
121169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    // if this is not the end of the statement, report error
121269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    if (getLexer().isNot(AsmToken::EndOfStatement)) {
121369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      reportParseError("unexpected token in statement");
121469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy      return false;
121569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    }
121669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy    Options.setNoreorder();
12179d314ff2c17a77996c05413c2013880387e50f0ecristy    Parser.Lex(); // Consume the EndOfStatement
12189d314ff2c17a77996c05413c2013880387e50f0ecristy    return false;
12199d314ff2c17a77996c05413c2013880387e50f0ecristy}
12209d314ff2c17a77996c05413c2013880387e50f0ecristy
12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseSetMacroDirective() {
12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex();
12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // if this is not the end of the statement, report error
12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reportParseError("unexpected token in statement");
12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Options.setMacro();
12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // Consume the EndOfStatement
12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return false;
12312857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy}
12322857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy
12332857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristybool MipsAsmParser::parseSetNoMacroDirective() {
12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex();
12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  // if this is not the end of the statement, report error
12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1237f8f295fde25dd8b1a50470d53b641d5265c0871fcristy    reportParseError("`noreorder' must be set before `nomacro'");
1238f8f295fde25dd8b1a50470d53b641d5265c0871fcristy    return false;
12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Options.isReorder()) {
12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    reportParseError("`noreorder' must be set before `nomacro'");
12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Options.setNomacro();
12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  Parser.Lex(); // Consume the EndOfStatement
12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return false;
12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::parseDirectiveSet() {
12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
1250f8f295fde25dd8b1a50470d53b641d5265c0871fcristy  // get next token
12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  const AsmToken &Tok = Parser.getTok();
1252f8f295fde25dd8b1a50470d53b641d5265c0871fcristy
12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (Tok.getString() == "noat") {
12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return parseSetNoAtDirective();
12555cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  } else if (Tok.getString() == "at") {
1256efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy    return parseSetAtDirective();
12575cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy  } else if (Tok.getString() == "reorder") {
12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return parseSetReorderDirective();
12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (Tok.getString() == "noreorder") {
12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return parseSetNoReorderDirective();
12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (Tok.getString() == "macro") {
12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return parseSetMacroDirective();
1263f8f295fde25dd8b1a50470d53b641d5265c0871fcristy  } else if (Tok.getString() == "nomacro") {
1264f8f295fde25dd8b1a50470d53b641d5265c0871fcristy    return parseSetNoMacroDirective();
1265f8f295fde25dd8b1a50470d53b641d5265c0871fcristy  } else if (Tok.getString() == "nomips16") {
12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.EatToEndOfStatement();
12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  } else if (Tok.getString() == "nomicromips") {
12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.EatToEndOfStatement();
12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  return true;
12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristybool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (DirectiveID.getString() == ".ent") {
12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex();
12823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (DirectiveID.getString() == ".end") {
12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.Lex();
12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (DirectiveID.getString() == ".frame") {
12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.EatToEndOfStatement();
12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
12953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
12963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
12973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (DirectiveID.getString() == ".set") {
1298f8f295fde25dd8b1a50470d53b641d5265c0871fcristy    return parseDirectiveSet();
1299f8f295fde25dd8b1a50470d53b641d5265c0871fcristy  }
1300e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy
1301e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy  if (DirectiveID.getString() == ".fmask") {
1302e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy    // ignore this directive for now
1303e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy    Parser.EatToEndOfStatement();
1304e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy    return false;
13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (DirectiveID.getString() == ".mask") {
13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.EatToEndOfStatement();
13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  }
13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  if (DirectiveID.getString() == ".gpword") {
13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    // ignore this directive for now
13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    Parser.EatToEndOfStatement();
13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy    return false;
131769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  }
13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
131969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy  return true;
13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
132269a0d3b5699c573f650e6b61f98ce4579d6f218cCristyextern "C" void LLVMInitializeMipsAsmParser() {
13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1325f8f295fde25dd8b1a50470d53b641d5265c0871fcristy  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy}
13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy
13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define GET_REGISTER_MATCHER
13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define GET_MATCHER_IMPLEMENTATION
13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#include "MipsGenAsmMatcher.inc"
13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy