1c5707112e7635d1dd2f2cc9c4f42e79a51302ccaJia Liu//===-- MipsAsmParser.cpp - Parse Mips assembly to MCInst instructions ----===//
2fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//
3fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//                     The LLVM Compiler Infrastructure
4fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//
5fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// This file is distributed under the University of Illinois Open Source
6fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola// License. See LICENSE.TXT for details.
7fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//
8fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola//===----------------------------------------------------------------------===//
9fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
10fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h"
11ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h"
12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h"
13ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h"
14ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h"
15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h"
16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h"
19ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h"
20ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h"
2172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h"
22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h"
23c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter#include "llvm/ADT/APInt.h"
24fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
25fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm;
26fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
27fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace {
2830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions {
2930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic:
3030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  MipsAssemblerOptions():
3130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    aTReg(1), reorder(true), macro(true) {
3230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
3330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
3430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned getATRegNum() {return aTReg;}
3530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool setATReg(unsigned Reg);
36ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool isReorder() {return reorder;}
3830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setReorder() {reorder = true;}
3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setNoreorder() {reorder = false;}
4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool isMacro() {return macro;}
4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setMacro() {macro = true;}
4330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setNomacro() {macro = false;}
4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate:
4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned aTReg;
4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reorder;
4830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool macro;
4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter};
5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
5130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
5230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace {
53fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser {
5472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  enum FpFormatTy {
56f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_NONE = -1,
57f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_S,
58f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_D,
59f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_L,
60f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_W
61f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  } FpFormat;
62f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCSubtargetInfo &STI;
64ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &Parser;
6510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  MipsAssemblerOptions Options;
6630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
6772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER
6872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc"
6972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
7084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
71fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7284125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               MCStreamer &Out, unsigned &ErrorInfo,
7384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               bool MatchingInlineAsm);
74fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
75fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
76fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
776a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
786a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier                        SMLoc NameLoc,
7972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
80fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
81fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseDirective(AsmToken DirectiveID);
82fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
83ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MipsAsmParser::OperandMatchResultTy
847231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
857231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic                         int RegKind);
86088483627720acb58c96951b7b634f67312c7272Vladimir Medic
87088483627720acb58c96951b7b634f67312c7272Vladimir Medic  MipsAsmParser::OperandMatchResultTy
88ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
89ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
90ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
911858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
92ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
93ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
941858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
95ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
96ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
97ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
98ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
99ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
101ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
102ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
103ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
104038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
10590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  MipsAsmParser::OperandMatchResultTy
10690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
10790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
10890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  MipsAsmParser::OperandMatchResultTy
10990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
11090b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
11190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  MipsAsmParser::OperandMatchResultTy
11290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
11390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
114b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  MipsAsmParser::OperandMatchResultTy
115b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
116b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
117a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  MipsAsmParser::OperandMatchResultTy
118a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
119a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
120c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1217231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic                         unsigned RegKind);
122c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
123ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
124ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                    StringRef Mnemonic);
125ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
126ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int tryParseRegister(bool is64BitReg);
127ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
128ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
129ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter                               bool is64BitReg);
130ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1319d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  bool needsExpansion(MCInst &Inst);
1329d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
1339d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
1342490dc650895149423bb59538dc03ca352222702Jack Carter                         SmallVectorImpl<MCInst> &Instructions);
1359d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1362490dc650895149423bb59538dc03ca352222702Jack Carter                     SmallVectorImpl<MCInst> &Instructions);
1372f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
1392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
14125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
14225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     SmallVectorImpl<MCInst> &Instructions,
14325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     bool isLoad,bool isImmOpnd);
14430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reportParseError(StringRef ErrorMsg);
14530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
147ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool parseRelocOperand(const MCExpr *&Res);
14830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
1508afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
1518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isEvaluated(const MCExpr *Expr);
15230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseDirectiveSet();
15330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
15430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetAtDirective();
15530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoAtDirective();
15630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetMacroDirective();
15730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoMacroDirective();
15830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetReorderDirective();
15930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoReorderDirective();
16030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
161c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool parseSetAssignment();
162c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
163801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  bool parseDirectiveWord(unsigned Size, SMLoc L);
164801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
166f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
167ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool isMips64() const {
168ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
169ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
170ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
171f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool isFP64() const {
172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
173f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
174f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
175ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterName(StringRef Symbol, bool is64BitReg);
176ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
17799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int matchCPURegisterName(StringRef Symbol);
17899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
179ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
180ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1817231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  int matchFPURegisterName(StringRef Name, FpFormatTy Format);
1827231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
183f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(FpFormatTy Format) {
184f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = Format;
185f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
186f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
187f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setDefaultFpFormat();
188f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
189f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(StringRef Format);
190f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
191f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormatTy getFpFormat() {return FpFormat;}
192f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
19386924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned getReg(int RC, int RegNo);
194038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
19599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int getATReg();
19625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
19725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
19825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                        SmallVectorImpl<MCInst> &Instructions);
199fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
200fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
201ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    : MCTargetAsmParser(), STI(sti), Parser(parser) {
202ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
203ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
204fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  }
205fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
206ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &getParser() const { return Parser; }
207ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
208ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
209fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
210fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
211fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
21272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
21372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
21472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
21572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
21672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
217ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
218ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic:
219ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  enum RegisterKind {
220ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_None,
2211858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    Kind_GPR32,
2221858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    Kind_GPR64,
223ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_HWRegs,
224ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_HW64Regs,
225ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_FGR32Regs,
226ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_FGR64Regs,
22799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    Kind_AFGR64Regs,
228b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic    Kind_CCRRegs,
229a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    Kind_FCCRegs,
230a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    Kind_ACRegsDSP
231ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  };
232ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
233ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate:
23472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
23572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CondCode,
23672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CoprocNum,
23772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Immediate,
23872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Memory,
23972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_PostIndexRegister,
24072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Register,
24172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Token
24272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
24372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
24472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
245ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
246a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct Token {
247a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
248a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
249a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
250a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
251a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct RegOp {
252a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned RegNum;
253a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    RegisterKind Kind;
254a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
255a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
256a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
257a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
258a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
259a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
260a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
261a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Base;
262a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Off;
263a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
264a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
266a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct Token Tok;
267a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
268a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
269a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
271ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
273ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
27472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
27572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addRegOperands(MCInst &Inst, unsigned N) const {
276ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
277ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.addOperand(MCOperand::CreateReg(getReg()));
27872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
279ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
28072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
281ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
282ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Expr == 0)
283ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(0));
284ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
285ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
286ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
287ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateExpr(Expr));
28872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
289ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
29072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
292ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
29386924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
295ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
29672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
2976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
2986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
3006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
3016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
30286924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
30372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
30472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
30572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isReg() const { return Kind == k_Register; }
30672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isImm() const { return Kind == k_Immediate; }
30772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isToken() const { return Kind == k_Token; }
30872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isMem() const { return Kind == k_Memory; }
30972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
31072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
31172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
312ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
31372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
31472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
31572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  unsigned getReg() const {
31672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert((Kind == k_Register) && "Invalid access!");
317ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Reg.RegNum;
318ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
320ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void setRegKind(RegisterKind RegKind) {
321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
322ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Reg.Kind = RegKind;
323ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
324ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert((Kind == k_Immediate) && "Invalid access!");
327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  unsigned getMemBase() const {
3316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
3326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
3336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
3356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
3366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
3376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
3386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Token);
342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
344ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
345ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
347ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
348ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
349ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
350ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Register);
351ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Reg.RegNum = RegNum;
352ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
353ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
354ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
355ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
356ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
357ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
358ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Immediate);
359ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Imm.Val = Val;
360ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
361ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
362ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
36372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
36472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
3656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
3666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                 SMLoc S, SMLoc E) {
3676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MipsOperand *Op = new MipsOperand(k_Memory);
3686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Base = Base;
3696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
3706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
3716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
3726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
3736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
3751858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  bool isGPR32Asm() const {
3761858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    return Kind == k_Register && Reg.Kind == Kind_GPR32;
377ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
378dd5fe2ffc6f564192876065d2617ecbc18d03f23Vladimir Medic  void addRegAsmOperands(MCInst &Inst, unsigned N) const {
379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
381ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
3821858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  bool isGPR64Asm() const {
3831858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    return Kind == k_Register && Reg.Kind == Kind_GPR64;
384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
385ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
386ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isHWRegsAsm() const {
387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
388ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_HWRegs;
389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isHW64RegsAsm() const {
392ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
393ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_HW64Regs;
394ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
395ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
396ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCCRAsm() const {
397ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
398ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_CCRRegs;
399ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
400ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
40190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic   bool isAFGR64Asm() const {
40290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic    return Kind == k_Register && Reg.Kind == Kind_AFGR64Regs;
40390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  }
40490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
40590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  bool isFGR64Asm() const {
40690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic    return Kind == k_Register && Reg.Kind == Kind_FGR64Regs;
40790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  }
40890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
40990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  bool isFGR32Asm() const {
41090b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic    return (Kind == k_Register) && Reg.Kind == Kind_FGR32Regs;
41190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  }
41290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
413b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  bool isFCCRegsAsm() const {
414b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic    return (Kind == k_Register) && Reg.Kind == Kind_FCCRegs;
415b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  }
416b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
417a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  bool isACRegsDSPAsm() const {
418a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    return Kind == k_Register && Reg.Kind == Kind_ACRegsDSP;
419a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  }
420a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
421ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
42286924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc getStartLoc() const {
42386924b4182537745659f2660244f3402c1e1ca4dJack Carter    return StartLoc;
42486924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
425ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
42686924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc getEndLoc() const {
42786924b4182537745659f2660244f3402c1e1ca4dJack Carter    return EndLoc;
42886924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
429ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
43072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  virtual void print(raw_ostream &OS) const {
43172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    llvm_unreachable("unimplemented!");
43272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
43386924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand
43486924b4182537745659f2660244f3402c1e1ca4dJack Carter}  // namespace
43572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
43625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm {
43725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[];
43825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
43925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
44025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return MipsInsts[Opcode];
44125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
44225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
44325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
44525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
44625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Inst.setLoc(IDLoc);
44797265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter  if (MCID.hasDelaySlot() && Options.isReorder()) {
44897265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    // If this instruction has a delay slot and .set reorder is active,
44997265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    // emit a NOP after it.
45097265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    Instructions.push_back(Inst);
45197265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    MCInst NopInst;
45297265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.setOpcode(Mips::SLL);
45397265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
45497265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
45597265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.addOperand(MCOperand::CreateImm(0));
45697265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    Instructions.push_back(NopInst);
45797265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    return false;
45897265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter  }
45997265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter
46025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (MCID.mayLoad() || MCID.mayStore()) {
46125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // Check the offset of memory operand, if it is a symbol
46286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // reference or immediate we may have to expand instructions.
46386924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
46425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
46586924b4182537745659f2660244f3402c1e1ca4dJack Carter      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
46686924b4182537745659f2660244f3402c1e1ca4dJack Carter          || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
46725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        MCOperand &Op = Inst.getOperand(i);
46825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        if (Op.isImm()) {
46925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          int MemOffset = Op.getImm();
47025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          if (MemOffset < -32768 || MemOffset > 32767) {
47186924b4182537745659f2660244f3402c1e1ca4dJack Carter            // Offset can't exceed 16bit value.
47286924b4182537745659f2660244f3402c1e1ca4dJack Carter            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
47325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            return false;
47425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
47525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        } else if (Op.isExpr()) {
47625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          const MCExpr *Expr = Op.getExpr();
47786924b4182537745659f2660244f3402c1e1ca4dJack Carter          if (Expr->getKind() == MCExpr::SymbolRef) {
47825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            const MCSymbolRefExpr *SR =
4798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                static_cast<const MCSymbolRefExpr*>(Expr);
48025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
48186924b4182537745659f2660244f3402c1e1ca4dJack Carter              // Expand symbol.
48286924b4182537745659f2660244f3402c1e1ca4dJack Carter              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
48325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              return false;
48425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            }
4858afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter          } else if (!isEvaluated(Expr)) {
48686924b4182537745659f2660244f3402c1e1ca4dJack Carter            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
4878afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter            return false;
48825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
48925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        }
49025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      }
49186924b4182537745659f2660244f3402c1e1ca4dJack Carter    } // for
49286924b4182537745659f2660244f3402c1e1ca4dJack Carter  } // if load/store
49325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
49425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (needsExpansion(Inst))
49525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    expandInstruction(Inst, IDLoc, Instructions);
49625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else
49725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    Instructions.push_back(Inst);
49825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
49925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return false;
50025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
50125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
5029d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) {
5039d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
50486924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
50586924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadImm32Reg:
50686924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Imm:
50786924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Reg:
50886924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true;
50986924b4182537745659f2660244f3402c1e1ca4dJack Carter  default:
51086924b4182537745659f2660244f3402c1e1ca4dJack Carter    return false;
5119d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
5129d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
5132490dc650895149423bb59538dc03ca352222702Jack Carter
5149d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
51586924b4182537745659f2660244f3402c1e1ca4dJack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
51686924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
51786924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadImm32Reg:
51886924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadImm(Inst, IDLoc, Instructions);
51986924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Imm:
52086924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadAddressImm(Inst, IDLoc, Instructions);
52186924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Reg:
52286924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadAddressReg(Inst, IDLoc, Instructions);
52386924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
5249d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
5252490dc650895149423bb59538dc03ca352222702Jack Carter
5269d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
52786924b4182537745659f2660244f3402c1e1ca4dJack Carter                                  SmallVectorImpl<MCInst> &Instructions) {
5282490dc650895149423bb59538dc03ca352222702Jack Carter  MCInst tmpInst;
5299d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
5302f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
5319d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &RegOp = Inst.getOperand(0);
5329d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  assert(RegOp.isReg() && "expected register operand kind");
5339d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
5349d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  int ImmValue = ImmOp.getImm();
5352490dc650895149423bb59538dc03ca352222702Jack Carter  tmpInst.setLoc(IDLoc);
53686924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (0 <= ImmValue && ImmValue <= 65535) {
53786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For 0 <= j <= 65535.
5389d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => ori d,$zero,j
539ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5402490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
54186924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
5422490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5439d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
54486924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else if (ImmValue < 0 && ImmValue >= -32768) {
54586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j < 0.
5469d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => addiu d,$zero,j
547ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5482490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
54986924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
5502490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5519d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5529d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  } else {
55386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
5549d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => lui d,hi16(j)
5552f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //           ori d,d,lo16(j)
556ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5572490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5582490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5599d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5602490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.clear();
561ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5622490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5632490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5642490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
5652490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.setLoc(IDLoc);
5669d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5679d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
5689d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
5692490dc650895149423bb59538dc03ca352222702Jack Carter
5702f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
57186924b4182537745659f2660244f3402c1e1ca4dJack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
5722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
5732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(2);
5742f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
5752f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &SrcRegOp = Inst.getOperand(1);
5762f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(SrcRegOp.isReg() && "expected register operand kind");
5772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &DstRegOp = Inst.getOperand(0);
5782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(DstRegOp.isReg() && "expected register operand kind");
5792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
58086924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (-32768 <= ImmValue && ImmValue <= 65535) {
58186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j <= 65535.
58286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j(s) => addiu d,s,j
583ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5852f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
5862f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5872f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5882f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
58986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
59086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j(s) => lui d,hi16(j)
59186924b4182537745659f2660244f3402c1e1ca4dJack Carter    //              ori d,d,lo16(j)
59286924b4182537745659f2660244f3402c1e1ca4dJack Carter    //              addu d,d,s
593ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5952f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5962f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5972f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
598ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
6002f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
6012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
6022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
6032f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
6042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDu);
6052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
6062f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
6072f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
6082f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
6092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
6102f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
6112f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
6122f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
61386924b4182537745659f2660244f3402c1e1ca4dJack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
6142f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
6152f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
6162f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
6172f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &RegOp = Inst.getOperand(0);
6182f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(RegOp.isReg() && "expected register operand kind");
6192f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
62086924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (-32768 <= ImmValue && ImmValue <= 65535) {
62186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j <= 65535.
62286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j => addiu d,$zero,j
6232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
6242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
62586924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
6262f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
6272f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
6282f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
62986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
63086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j => lui d,hi16(j)
63186924b4182537745659f2660244f3402c1e1ca4dJack Carter    //           ori d,d,lo16(j)
632ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
6332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
6342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
6352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
6362f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
637ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
6382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
6392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
6402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
6412f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
6422f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
6432f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
6442f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
64525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
64686924b4182537745659f2660244f3402c1e1ca4dJack Carter          SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
64725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCSymbolRefExpr *SR;
64825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  MCInst TempInst;
64986924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned ImmOffset, HiOffset, LoOffset;
65025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCExpr *ExprOffset;
65125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned TmpRegNum;
6521858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  unsigned AtRegNum = getReg((isMips64()) ? Mips::GPR64RegClassID
6531858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka                             : Mips::GPR32RegClassID, getATReg());
65486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 1st operand is either the source or destination register.
65525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
65625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned RegOpNum = Inst.getOperand(0).getReg();
65786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 2nd operand is the base register.
65825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
65925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned BaseRegNum = Inst.getOperand(1).getReg();
66086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 3rd operand is either an immediate or expression.
66125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd) {
66225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
66325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ImmOffset = Inst.getOperand(2).getImm();
66425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    LoOffset = ImmOffset & 0x0000ffff;
66525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    HiOffset = (ImmOffset & 0xffff0000) >> 16;
66686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
66725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (LoOffset & 0x8000)
66825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      HiOffset++;
66986924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else
67025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ExprOffset = Inst.getOperand(2).getExpr();
67186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // All instructions will have the same location.
67225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setLoc(IDLoc);
67325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // 1st instruction in expansion is LUi. For load instruction we can use
67425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // the dst register as a temporary if base and dst are different,
67586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // but for stores we must use $at.
67686924b4182537745659f2660244f3402c1e1ca4dJack Carter  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
67725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::LUi);
67825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
67925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
68025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
68125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
68225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
68325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
68486924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
68586924b4182537745659f2660244f3402c1e1ca4dJack Carter          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
68686924b4182537745659f2660244f3402c1e1ca4dJack Carter          getContext());
68725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
6888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else {
68986924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
6908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
69125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
69225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
69386924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the instruction to the list.
69425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
69586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Prepare TempInst for next instruction.
69625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
69786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add temp register to base.
69825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::ADDu);
69925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
70025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
70125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
70225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
70325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
7048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  // And finaly, create original instruction with low part
70586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // of offset and new base.
70625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Inst.getOpcode());
70725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
70825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
70925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
71025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
71125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
71225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
71386924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
71486924b4182537745659f2660244f3402c1e1ca4dJack Carter          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
71586924b4182537745659f2660244f3402c1e1ca4dJack Carter          getContext());
71625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
7178afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else {
71886924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
7198afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
72025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
72125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
72225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
72325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
72425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
72525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
726fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
72784125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
728fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
72984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        MCStreamer &Out, unsigned &ErrorInfo,
73084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        bool MatchingInlineAsm) {
731ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
73225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  SmallVector<MCInst, 8> Instructions;
7336e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
73484125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                                              MatchingInlineAsm);
735ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
736ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
73786924b4182537745659f2660244f3402c1e1ca4dJack Carter  default:
73886924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
739ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
74086924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (processInstruction(Inst, IDLoc, Instructions))
74125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      return true;
74286924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < Instructions.size(); i++)
74325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      Out.EmitInstruction(Instructions[i]);
744ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
745ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
746ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
747ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
748ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
749ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
750ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
751ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ErrorInfo != ~0U) {
752ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
753ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
754ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
75586924b4182537745659f2660244f3402c1e1ca4dJack Carter      ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
75686924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (ErrorLoc == SMLoc())
75786924b4182537745659f2660244f3402c1e1ca4dJack Carter        ErrorLoc = IDLoc;
758ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
759ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
760ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
761ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
762ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
763ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
764ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
765fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
766fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
767fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
76899e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) {
769572e1bd109518f80b54d229de10699c4603944c3David Chisnall   int CC;
77099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
77199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (Name == "at")
77299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    return getATReg();
77399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
774572e1bd109518f80b54d229de10699c4603944c3David Chisnall    CC = StringSwitch<unsigned>(Name)
77599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("zero", 0)
77699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a0",   4)
77799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a1",   5)
77899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a2",   6)
77999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a3",   7)
78099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("v0",   2)
78199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("v1",   3)
78299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s0",  16)
78399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s1",  17)
78499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s2",  18)
78599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s3",  19)
78699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s4",  20)
78799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s5",  21)
78899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s6",  22)
78999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s7",  23)
79099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("k0",  26)
79199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("k1",  27)
79299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("sp",  29)
79399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("fp",  30)
79499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("gp",  28)
79599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("ra",  31)
79699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t0",   8)
79799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t1",   9)
79899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t2",  10)
79999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t3",  11)
80099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t4",  12)
80199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t5",  13)
80299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t6",  14)
80399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t7",  15)
80499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t8",  24)
80599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t9",  25)
80699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Default(-1);
80799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
80886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Although SGI documentation just cuts out t0-t3 for n32/n64,
80999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
81099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
81186924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (isMips64() && 8 <= CC && CC <= 11)
81299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    CC += 4;
81399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
81499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (CC == -1 && isMips64())
815572e1bd109518f80b54d229de10699c4603944c3David Chisnall    CC = StringSwitch<unsigned>(Name)
81699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a4",   8)
81799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a5",   9)
81899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a6",  10)
81999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a7",  11)
82099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("kt0", 26)
82199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("kt1", 27)
82299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("s8",  30)
823572e1bd109518f80b54d229de10699c4603944c3David Chisnall      .Default(-1);
824572e1bd109518f80b54d229de10699c4603944c3David Chisnall
82599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return CC;
82699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter}
82786924b4182537745659f2660244f3402c1e1ca4dJack Carter
8287231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medicint MipsAsmParser::matchFPURegisterName(StringRef Name, FpFormatTy Format) {
829ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
83386924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (NumString.getAsInteger(10, IntVal))
83486924b4182537745659f2660244f3402c1e1ca4dJack Carter      return -1; // This is not an integer.
835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (IntVal > 31)
836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::FGR32RegClassID, IntVal);
840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_D) {
84186924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (isFP64()) {
842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return getReg(Mips::FGR64RegClassID, IntVal);
843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
84486924b4182537745659f2660244f3402c1e1ca4dJack Carter      // Only even numbers available as register pairs.
84586924b4182537745659f2660244f3402c1e1ca4dJack Carter      if ((IntVal > 31) || (IntVal % 2 != 0))
846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return -1;
84786924b4182537745659f2660244f3402c1e1ca4dJack Carter      return getReg(Mips::AFGR64RegClassID, IntVal / 2);
848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
850ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
851ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
85286924b4182537745659f2660244f3402c1e1ca4dJack Carter
8537231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medicint MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
8547231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
8557231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  if (Name.equals("fcc0"))
8567231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic    return Mips::FCC0;
8577231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
8587231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  int CC;
8597231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  CC = matchCPURegisterName(Name);
8607231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  if (CC != -1)
8611858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    return matchRegisterByNumber(CC, is64BitReg ? Mips::GPR64RegClassID
8621858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka                                                : Mips::GPR32RegClassID);
8637231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  return matchFPURegisterName(Name, getFpFormat());
8647231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic}
8657231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
866f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() {
867f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
868f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() || isFP64())
869f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_D;
870f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else
871f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_S;
872f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
873f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
874f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) {
875f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
876f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormat = StringSwitch<FpFormatTy>(Format.lower())
877f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".s",  FP_FORMAT_S)
878f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".d",  FP_FORMAT_D)
879f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".l",  FP_FORMAT_L)
880f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".w",  FP_FORMAT_W)
881f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(FP_FORMAT_NONE);
882f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
88430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) {
88530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Reg > 31)
88630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
88730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
88830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  aTReg = Reg;
88930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
89030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
89130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
89299e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::getATReg() {
89399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return Options.getATRegNum();
89430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
89530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
89686924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) {
89799cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
898ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
899ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
900ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
901ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
902ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNum > 31)
903ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return -1;
904ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
905ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return getReg(RegClass, RegNum);
906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
908ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::tryParseRegister(bool is64BitReg) {
909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const AsmToken &Tok = Parser.getTok();
910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNum = -1;
911ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
912ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Tok.is(AsmToken::Identifier)) {
913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    std::string lowerCase = Tok.getString().lower();
914ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    RegNum = matchRegisterName(lowerCase, is64BitReg);
915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  } else if (Tok.is(AsmToken::Integer))
9169d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
9171858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka        is64BitReg ? Mips::GPR64RegClassID : Mips::GPR32RegClassID);
918ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return RegNum;
919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
920ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
92186924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::tryParseRegisterOperand(
92286924b4182537745659f2660244f3402c1e1ca4dJack Carter             SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc S = Parser.getTok().getLoc();
925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNo = -1;
926f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
927ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  RegNo = tryParseRegister(is64BitReg);
928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNo == -1)
929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
930ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
931ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
93286924b4182537745659f2660244f3402c1e1ca4dJack Carter                                            Parser.getTok().getLoc()));
933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Eat register token.
934ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
935ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
936ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
937ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
938ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                 StringRef Mnemonic) {
9399d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // Check if the current operand has a custom associated parser, if so, try to
9409d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // custom parse the operand, or fallback to the general approach.
941ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
942ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
943ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
944ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
945ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
946ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
947ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
949ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
952ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
953ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
954ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
95586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Parse the register.
956ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
957ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.Lex(); // Eat dollar token.
95886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Parse the register operand.
959ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (!tryParseRegisterOperand(Operands, isMips64())) {
960ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (getLexer().is(AsmToken::LParen)) {
96186924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Check if it is indexed addressing operand.
962ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken("(", S));
96386924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the parenthesis.
964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (getLexer().isNot(AsmToken::Dollar))
965ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
966ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
96786924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the dollar
968ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter        if (tryParseRegisterOperand(Operands, isMips64()))
969ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
970ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
971ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (!getLexer().is(AsmToken::RParen))
972ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
973ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
974ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        S = Parser.getTok().getLoc();
975ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken(")", S));
976ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex();
977ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
978ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
979ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
98086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Maybe it is a symbol reference.
981ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
982cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (Parser.parseIdentifier(Identifier))
983ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
984ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
985ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
986ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
98738539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
988ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
98986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Otherwise create a symbol reference.
9906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
991ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                                getContext());
992ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
993ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
994ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
995ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
996ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Identifier:
997c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    // Look for the existing symbol, we should check if
99886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // we need to assigne the propper RegisterKind.
99986924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
100086924b4182537745659f2660244f3402c1e1ca4dJack Carter      return false;
100186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Else drop to expression parsing.
1002ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
1003ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
1004ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
1005ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
1006ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
100786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Quoted label names.
1008ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *IdVal;
1009ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
1010cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(IdVal))
1011ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
1012ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1013ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
1014ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
1015ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
10166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
101786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is a symbol reference or constant expression.
10186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
101986924b4182537745659f2660244f3402c1e1ca4dJack Carter    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1020ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (parseRelocOperand(IdVal))
10216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
10226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1023ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1024ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
10256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
10266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
102730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // case AsmToken::Percent
102830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // switch(getLexer().getKind())
1029fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1030fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1031fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
10328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterconst MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
10338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                               StringRef RelocStr) {
10348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const MCExpr *Res;
103586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Check the type of the expression.
10368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
103786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It's a constant, evaluate lo or hi value.
10388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (RelocStr == "lo") {
10398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      short Val = MCE->getValue();
10408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Res = MCConstantExpr::Create(Val, getContext());
10418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else if (RelocStr == "hi") {
10428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      int Val = MCE->getValue();
10438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      int LoSign = Val & 0x8000;
10448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Val = (Val & 0xffff0000) >> 16;
10458afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      // Lower part is treated as a signed int, so if it is negative
104686924b4182537745659f2660244f3402c1e1ca4dJack Carter      // we must add 1 to the hi part to compensate.
10478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (LoSign)
10488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        Val++;
10498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Res = MCConstantExpr::Create(Val, getContext());
1050ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov    } else {
1051ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov      llvm_unreachable("Invalid RelocStr value");
10528afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
105386924b4182537745659f2660244f3402c1e1ca4dJack Carter    return Res;
10548afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
105786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It's a symbol, create a symbolic expression from the symbol.
10588afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    StringRef Symbol = MSRE->getSymbol().getName();
10598afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
106086924b4182537745659f2660244f3402c1e1ca4dJack Carter    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
10618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return Res;
10628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
106586924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
106686924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
10678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
10688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return Res;
10698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
107286924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
107386924b4182537745659f2660244f3402c1e1ca4dJack Carter    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
107486924b4182537745659f2660244f3402c1e1ca4dJack Carter    return Res;
10758afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
107686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Just return the original expression.
10778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Expr;
10788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
10798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10808afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
10818afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10828afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  switch (Expr->getKind()) {
10838afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Constant:
10848afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return true;
10858afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::SymbolRef:
10868afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
10878afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Binary:
10888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
10898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (!isEvaluated(BE->getLHS()))
10908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return false;
10918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return isEvaluated(BE->getRHS());
10928afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
10938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Unary:
10948afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
10958afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  default:
10968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return false;
10978afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10988afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
10998afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
11006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
110186924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
110286924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the % token.
110386924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
11046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
11056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
11066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
110738539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  std::string Str = Tok.getIdentifier().str();
11086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
110986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the identifier.
111086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Now make an expression from the rest of the operand.
11116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
1112ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc EndLoc;
11136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
11156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
111686924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the '(' token.
11176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
111886924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the % token.
11196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
11206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
11216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
112238539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
112338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
112486924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the identifier.
11256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
11266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
11276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
11286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
11296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
113086924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (getParser().parseParenExpression(IdVal, EndLoc))
11316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
11326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1133ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    while (getLexer().getKind() == AsmToken::RParen)
113486924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the ')' token.
11356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
113786924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true; // Parenthesis must follow the relocation operand.
11386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
113986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Res = evaluateRelocExpr(IdVal, Str);
11408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
11416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
11426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1143ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1144ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
1145ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  StartLoc = Parser.getTok().getLoc();
1146ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  RegNo = tryParseRegister(isMips64());
1147ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  EndLoc = Parser.getTok().getLoc();
114886924b4182537745659f2660244f3402c1e1ca4dJack Carter  return (RegNo == (unsigned) -1);
1149ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
11518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1152ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
11538afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool Result = true;
11548afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
11558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  while (getLexer().getKind() == AsmToken::LParen)
11568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
1157ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
115886924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (getLexer().getKind()) {
11596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
11606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
116125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  case AsmToken::Identifier:
11628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case AsmToken::LParen:
11636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
11646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
11656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
11668afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (isParenExpr)
116786924b4182537745659f2660244f3402c1e1ca4dJack Carter      Result = getParser().parseParenExpression(Res, S);
11688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else
11698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Result = (getParser().parseExpression(Res));
117086924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().getKind() == AsmToken::RParen)
11718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Parser.Lex();
117286924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
1173ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  case AsmToken::Percent:
11748afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Result = parseRelocOperand(Res);
11756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
11768afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Result;
11776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
11786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1179ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
118086924b4182537745659f2660244f3402c1e1ca4dJack Carter                               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
11816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal = 0;
1183ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
11848afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isParenExpr = false;
118586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // First operand is the offset.
1186ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  S = Parser.getTok().getLoc();
11876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() == AsmToken::LParen) {
11898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
11908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    isParenExpr = true;
11918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
11926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() != AsmToken::Dollar) {
119486924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (parseMemOffset(IdVal, isParenExpr))
11958afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
11968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
119786924b4182537745659f2660244f3402c1e1ca4dJack Carter    const AsmToken &Tok = Parser.getTok(); // Get the next token.
11988afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (Tok.isNot(AsmToken::LParen)) {
11998afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
12008afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (Mnemonic->getToken() == "la") {
12018afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        SMLoc E = SMLoc::getFromPointer(
120286924b4182537745659f2660244f3402c1e1ca4dJack Carter            Parser.getTok().getLoc().getPointer() - 1);
12038afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
12048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
12058afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
12068afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (Tok.is(AsmToken::EndOfStatement)) {
12078afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        SMLoc E = SMLoc::getFromPointer(
120886924b4182537745659f2660244f3402c1e1ca4dJack Carter            Parser.getTok().getLoc().getPointer() - 1);
12098afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
121086924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Zero register assumed, add a memory operand with ZERO as its base.
121186924b4182537745659f2660244f3402c1e1ca4dJack Carter        Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
121286924b4182537745659f2660244f3402c1e1ca4dJack Carter                                                             : Mips::ZERO,
121386924b4182537745659f2660244f3402c1e1ca4dJack Carter                           IdVal, S, E));
12148afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
12158afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
12168afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Error(Parser.getTok().getLoc(), "'(' expected");
12178afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
12182f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    }
12196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
122086924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '(' token.
12218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
12226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
12238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const AsmToken &Tok1 = Parser.getTok(); // Get next token
12246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok1.is(AsmToken::Dollar)) {
122586924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '$' token.
1226ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (tryParseRegisterOperand(Operands, isMips64())) {
12276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Error(Parser.getTok().getLoc(), "unexpected token in operand");
12286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return MatchOperand_ParseFail;
12296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
12306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
12316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else {
123230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
12336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
12346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
12356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
123686924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok2 = Parser.getTok(); // Get next token.
12376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok2.isNot(AsmToken::RParen)) {
12386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
12396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
12406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
12416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1242ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1243ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
124486924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the ')' token.
12456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
12466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (IdVal == 0)
12476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    IdVal = MCConstantExpr::Create(0, getContext());
12486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
124986924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Replace the register operand with the memory operand.
12506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
12516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  int RegNo = op->getReg();
125286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Remove the register from the operands.
12536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
125486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the memory operand.
12558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
12568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    int64_t Imm;
12578afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (IdVal->EvaluateAsAbsolute(Imm))
12588afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      IdVal = MCConstantExpr::Create(Imm, getContext());
12598afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
12608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
12618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                   getContext());
12628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
12638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
12646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
12656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  delete op;
1266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
1267ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1269ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
12707231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::parseRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
12717231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic                         int RegKind) {
12727231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind)RegKind;
1273c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().getKind() == AsmToken::Identifier) {
12747231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic    if (searchSymbolAlias(Operands, Kind))
1275c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return MatchOperand_Success;
1276c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return MatchOperand_NoMatch;
1277c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
127886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$', we have an error.
1279ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1280ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1281ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1282ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1283a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  if (!tryParseRegisterOperand(Operands,
12841858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka                               RegKind == MipsOperand::Kind_GPR64)) {
128586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Set the proper register kind.
1286ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
12877231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic    op->setRegKind(Kind);
12881858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka    if ((Kind == MipsOperand::Kind_GPR32)
1289764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      && (getLexer().is(AsmToken::LParen))) {
1290764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      // Check if it is indexed addressing operand.
1291764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      Operands.push_back(MipsOperand::CreateToken("(", getLexer().getLoc()));
1292764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      Parser.Lex(); // Eat the parenthesis.
1293764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      if (parseRegs(Operands,RegKind) != MatchOperand_Success)
1294764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic        return MatchOperand_NoMatch;
1295764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      if (getLexer().isNot(AsmToken::RParen))
1296764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic        return MatchOperand_NoMatch;
1297764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      Operands.push_back(MipsOperand::CreateToken(")", getLexer().getLoc()));
1298764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic      Parser.Lex();
1299764f6f51257a0669acc58c8e5b4b802a29069302Vladimir Medic    }
1300ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
1301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
1302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_NoMatch;
1303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1304088483627720acb58c96951b7b634f67312c7272Vladimir Medic
13057231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy
13061858786285139b87961d9ca08de91dcd59364afbAkira HatanakaMipsAsmParser::parseGPR64(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
13077231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
13087231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic  if (!isMips64())
13097231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic    return MatchOperand_NoMatch;
13101858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka  return parseRegs(Operands, (int) MipsOperand::Kind_GPR64);
13117231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic}
13127231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
13137231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy
13141858786285139b87961d9ca08de91dcd59364afbAkira HatanakaMipsAsmParser::parseGPR32(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
13151858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka return parseRegs(Operands, (int) MipsOperand::Kind_GPR32);
13167231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic}
1317ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
131890b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::OperandMatchResultTy
131990b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::parseAFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
132090b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
132190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  if (isFP64())
132290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic    return MatchOperand_NoMatch;
132390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  // Double operand is expected, set appropriate format
132490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  setFpFormat(FP_FORMAT_D);
132590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
132690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  return parseRegs(Operands, (int) MipsOperand::Kind_AFGR64Regs);
132790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic}
132890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
132990b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::OperandMatchResultTy
133090b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::parseFGR64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
133190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  if (!isFP64())
133290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic    return MatchOperand_NoMatch;
133390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  // Double operand is expected, set appropriate format
133490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  setFpFormat(FP_FORMAT_D);
133590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
133690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic return parseRegs(Operands, (int) MipsOperand::Kind_FGR64Regs);
133790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic}
133890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
133990b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::OperandMatchResultTy
134090b1086b93708149ed7a3749e2eeccea264a037dVladimir MedicMipsAsmParser::parseFGR32Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
134190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic // Single operand is expected, set appropriate format
134290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  setFpFormat(FP_FORMAT_S);
134390b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  return parseRegs(Operands, (int) MipsOperand::Kind_FGR32Regs);
134490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic}
134590b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
1346b67775df0cc702cd94408200ff2d58cf83f1334aVladimir MedicMipsAsmParser::OperandMatchResultTy
1347b67775df0cc702cd94408200ff2d58cf83f1334aVladimir MedicMipsAsmParser::parseFCCRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1348b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  // If the first token is not '$' we have an error.
1349b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  if (Parser.getTok().isNot(AsmToken::Dollar))
1350b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic    return MatchOperand_NoMatch;
1351b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1352b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  SMLoc S = Parser.getTok().getLoc();
1353b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  Parser.Lex(); // Eat the '$'
1354b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1355b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  const AsmToken &Tok = Parser.getTok(); // Get next token.
1356b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1357b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  if (Tok.isNot(AsmToken::Identifier))
1358b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic    return MatchOperand_NoMatch;
1359b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1360b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  if (!Tok.getIdentifier().startswith("fcc"))
1361b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic    return MatchOperand_NoMatch;
1362b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1363b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  StringRef NumString = Tok.getIdentifier().substr(3);
1364b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1365b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  unsigned IntVal;
1366b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  if (NumString.getAsInteger(10, IntVal))
1367b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic    return MatchOperand_NoMatch;
1368b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1369b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  unsigned Reg = matchRegisterByNumber(IntVal, Mips::FCCRegClassID);
1370b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1371b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1372b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  Op->setRegKind(MipsOperand::Kind_FCCRegs);
1373b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  Operands.push_back(Op);
1374b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
1375b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  Parser.Lex(); // Eat the register number.
1376a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  return MatchOperand_Success;
1377a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka}
1378a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1379a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira HatanakaMipsAsmParser::OperandMatchResultTy
1380a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira HatanakaMipsAsmParser::parseACRegsDSP(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1381a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  // If the first token is not '$' we have an error.
1382a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  if (Parser.getTok().isNot(AsmToken::Dollar))
1383a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    return MatchOperand_NoMatch;
1384a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1385a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  SMLoc S = Parser.getTok().getLoc();
1386a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  Parser.Lex(); // Eat the '$'
1387a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1388a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  const AsmToken &Tok = Parser.getTok(); // Get next token.
1389a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1390a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  if (Tok.isNot(AsmToken::Identifier))
1391a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    return MatchOperand_NoMatch;
1392a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1393a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  if (!Tok.getIdentifier().startswith("acc"))
1394a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    return MatchOperand_NoMatch;
1395a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1396a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  StringRef NumString = Tok.getIdentifier().substr(3);
1397a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1398a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  unsigned IntVal;
1399a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  if (NumString.getAsInteger(10, IntVal))
1400a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka    return MatchOperand_NoMatch;
1401a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1402a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  unsigned Reg = matchRegisterByNumber(IntVal, Mips::ACRegsDSPRegClassID);
1403a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1404a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
1405a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  Op->setRegKind(MipsOperand::Kind_ACRegsDSP);
1406a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  Operands.push_back(Op);
1407a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka
1408a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  Parser.Lex(); // Eat the register number.
1409b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic  return MatchOperand_Success;
1410b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic}
1411b67775df0cc702cd94408200ff2d58cf83f1334aVladimir Medic
141286924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::searchSymbolAlias(
14137231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegKind) {
1414c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1415c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1416c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Sym) {
1417c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    SMLoc S = Parser.getTok().getLoc();
1418c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    const MCExpr *Expr;
1419c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (Sym->isVariable())
1420c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Expr = Sym->getVariableValue();
1421c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    else
1422c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return false;
1423c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (Expr->getKind() == MCExpr::SymbolRef) {
14247231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic      MipsOperand::RegisterKind Kind = (MipsOperand::RegisterKind) RegKind;
1425c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1426c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const StringRef DefSymbol = Ref->getSymbol().getName();
1427c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      if (DefSymbol.startswith("$")) {
1428c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter        int RegNum = -1;
1429c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter        APInt IntVal(32, -1);
1430c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter        if (!DefSymbol.substr(1).getAsInteger(10, IntVal))
1431c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter          RegNum = matchRegisterByNumber(IntVal.getZExtValue(),
1432088483627720acb58c96951b7b634f67312c7272Vladimir Medic                                     isMips64()
14331858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka                                       ? Mips::GPR64RegClassID
14341858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka                                       : Mips::GPR32RegClassID);
14357231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic        else {
14367231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          // Lookup for the register with the corresponding name.
14377231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          switch (Kind) {
14387231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          case MipsOperand::Kind_AFGR64Regs:
14397231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          case MipsOperand::Kind_FGR64Regs:
14407231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic            RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_D);
14417231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic            break;
14427231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          case MipsOperand::Kind_FGR32Regs:
14437231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic            RegNum = matchFPURegisterName(DefSymbol.substr(1), FP_FORMAT_S);
14447231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic            break;
14451858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka          case MipsOperand::Kind_GPR64:
14461858786285139b87961d9ca08de91dcd59364afbAkira Hatanaka          case MipsOperand::Kind_GPR32:
14477231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          default:
14487231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic            RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
14497231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic            break;
14507231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          }
14517231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic        }
1452c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        if (RegNum > -1) {
1453c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          Parser.Lex();
145486924b4182537745659f2660244f3402c1e1ca4dJack Carter          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
145586924b4182537745659f2660244f3402c1e1ca4dJack Carter                                                   Parser.getTok().getLoc());
14567231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic          op->setRegKind(Kind);
1457c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          Operands.push_back(op);
1458c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          return true;
1459c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        }
1460c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      }
1461c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    } else if (Expr->getKind() == MCExpr::Constant) {
1462c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Parser.Lex();
1463c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
146486924b4182537745659f2660244f3402c1e1ca4dJack Carter      MipsOperand *op = MipsOperand::CreateImm(Const, S,
1465088483627720acb58c96951b7b634f67312c7272Vladimir Medic          Parser.getTok().getLoc());
1466c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Operands.push_back(op);
1467c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return true;
1468c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    }
1469c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
1470c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
1471c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
147286924b4182537745659f2660244f3402c1e1ca4dJack Carter
1473ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1474ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1475ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
147686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have error.
1477ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1478ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1479ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
148086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the '$'.
1481ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
148286924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1483ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.isNot(AsmToken::Integer))
1484ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1485ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1486ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum = Tok.getIntVal();
148786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // At the moment only hwreg29 is supported.
1488ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (RegNum != 29)
1489ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_ParseFail;
1490ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1491ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
149286924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.getTok().getLoc());
1493ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  op->setRegKind(MipsOperand::Kind_HWRegs);
1494ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1495ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
149686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the register number.
1497ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1498ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1499ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1500ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
150186924b4182537745659f2660244f3402c1e1ca4dJack CarterMipsAsmParser::parseHW64Regs(
150286924b4182537745659f2660244f3402c1e1ca4dJack Carter    SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1503c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter
1504c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  if (!isMips64())
1505c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter    return MatchOperand_NoMatch;
150686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have an error.
1507ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1508ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1509ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
1510ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1511ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
151286924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1513ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.isNot(AsmToken::Integer))
1514ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1515ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1516ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum = Tok.getIntVal();
151786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // At the moment only hwreg29 is supported.
1518ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (RegNum != 29)
1519ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_ParseFail;
1520ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1521ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
152286924b4182537745659f2660244f3402c1e1ca4dJack Carter                                           Parser.getTok().getLoc());
1523c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  op->setRegKind(MipsOperand::Kind_HW64Regs);
1524ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1525ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
152686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the register number.
1527ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1528ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1529ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1530ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1531ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
153286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have an error.
1533ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
153494ce6dadd131ca80adf2ba05391f689684540601Akira Hatanaka    return MatchOperand_NoMatch;
15359a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka
1536ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
153786924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the '$'
1538ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
153986924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get next token.
1540ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
15419a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka  if (Tok.isNot(AsmToken::Integer))
154294ce6dadd131ca80adf2ba05391f689684540601Akira Hatanaka    return MatchOperand_NoMatch;
15439a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka
15449a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka  unsigned Reg = matchRegisterByNumber(Tok.getIntVal(), Mips::CCRRegClassID);
15459a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka
15469a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka  MipsOperand *Op = MipsOperand::CreateReg(Reg, S, Parser.getTok().getLoc());
15479a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka  Op->setRegKind(MipsOperand::Kind_CCRRegs);
15489a05b98ef9ec58c52f35ce04677f24ef62a79701Akira Hatanaka  Operands.push_back(Op);
1549ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
155086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the register number.
1551ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1552ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1553ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
15546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
15556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
15566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind VK
15576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
15586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
15596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
15606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
15616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
15626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
15636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
15646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
15656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
15666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
15676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
15686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
15696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
15706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
15716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
15726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
15736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
15746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
15756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Default(MCSymbolRefExpr::VK_None);
15766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
15776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return VK;
15786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
1579f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1580fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
15816a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1582fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1583fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic  // Check if we have valid mnemonic
1584f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  if (!mnemonicIsValid(Name, 0)) {
1585fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic    Parser.eatToEndOfStatement();
1586fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic    return Error(NameLoc, "Unknown instruction");
1587fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic  }
1588088483627720acb58c96951b7b634f67312c7272Vladimir Medic  // First operand in MCInst is instruction mnemonic.
1589088483627720acb58c96951b7b634f67312c7272Vladimir Medic  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
1590ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1591ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
1592ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1593ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
1594088483627720acb58c96951b7b634f67312c7272Vladimir Medic    if (ParseOperand(Operands, Name)) {
1595ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
1596cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1597ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
1598ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1599ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
160086924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().is(AsmToken::Comma)) {
160186924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the comma.
1602ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
1603ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ParseOperand(Operands, Name)) {
1604ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
1605cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
1606ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
1607ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
1608ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1609ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1610ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1611ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
1612cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1613ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
1614ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
161586924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
1616ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
1617fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1618fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
161930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
162086924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc Loc = getLexer().getLoc();
162186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.eatToEndOfStatement();
162286924b4182537745659f2660244f3402c1e1ca4dJack Carter  return Error(Loc, ErrorMsg);
162330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
162430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
162530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() {
162686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line should look like: ".set noat".
162786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // set at reg to 0.
162810d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setATReg(0);
162930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // eat noat
163030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
163186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
163230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
163330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
163430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
163530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
163686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
163730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
163830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
163986924b4182537745659f2660244f3402c1e1ca4dJack Carter
164030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() {
164186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line can be .set at - defaults to $1
164230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // or .set at=$reg
164399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int AtRegNo;
164430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  getParser().Lex();
164530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().is(AsmToken::EndOfStatement)) {
164610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter    Options.setATReg(1);
164786924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
164830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
164930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (getLexer().is(AsmToken::Equal)) {
165086924b4182537745659f2660244f3402c1e1ca4dJack Carter    getParser().Lex(); // Eat the '='.
165130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::Dollar)) {
165230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
165330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
165430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
165586924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '$'.
165699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    const AsmToken &Reg = Parser.getTok();
165799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (Reg.is(AsmToken::Identifier)) {
165899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
165999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else if (Reg.is(AsmToken::Integer)) {
166099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = Reg.getIntVal();
166199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else {
166230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
166330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
166430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
166599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
166686924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (AtRegNo < 1 || AtRegNo > 31) {
166799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      reportParseError("unexpected token in statement");
166899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      return false;
166999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    }
167099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
167199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (!Options.setATReg(AtRegNo)) {
167230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
167330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
167430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
167586924b4182537745659f2660244f3402c1e1ca4dJack Carter    getParser().Lex(); // Eat the register.
167630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
167730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
167830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
167930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
168086924b4182537745659f2660244f3402c1e1ca4dJack Carter    }
168186924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
168230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
168330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else {
168430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
168530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
168630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
168730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
168830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
168930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() {
169030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
169186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
169230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
169330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
169430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
169530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
169610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setReorder();
169786924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
169830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
169930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
170030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
170130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() {
170286924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex();
170386924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
170486924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
170586924b4182537745659f2660244f3402c1e1ca4dJack Carter    reportParseError("unexpected token in statement");
170630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
170786924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
170886924b4182537745659f2660244f3402c1e1ca4dJack Carter  Options.setNoreorder();
170986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
171086924b4182537745659f2660244f3402c1e1ca4dJack Carter  return false;
171130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
171230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
171330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() {
171430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
171586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
171630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
171730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
171830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
171930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
172010d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setMacro();
172186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
172230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
172330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
172430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
172530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() {
172630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
172786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
172830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
172930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
173030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
173130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
173210d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  if (Options.isReorder()) {
173330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
173430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
173530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
173610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setNomacro();
173786924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
173830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
173930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
1740c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1741c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() {
1742c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  StringRef Name;
1743c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  const MCExpr *Value;
1744c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1745c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseIdentifier(Name))
1746c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected identifier after .set");
1747c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1748c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().isNot(AsmToken::Comma))
1749c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("unexpected token in .set directive");
17508afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  Lex(); // Eat comma
1751c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1752c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter  if (getLexer().is(AsmToken::Dollar)) {
1753c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    MCSymbol *Symbol;
1754c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    SMLoc DollarLoc = getLexer().getLoc();
1755c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    // Consume the dollar sign, and check for a following identifier.
1756c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    Parser.Lex();
1757c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    // We have a '$' followed by something, make sure they are adjacent.
1758c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    if (DollarLoc.getPointer() + 1 != getTok().getLoc().getPointer())
1759c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter      return true;
1760c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    StringRef Res = StringRef(DollarLoc.getPointer(),
1761c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter        getTok().getEndLoc().getPointer() - DollarLoc.getPointer());
1762c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    Symbol = getContext().GetOrCreateSymbol(Res);
1763c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    Parser.Lex();
1764c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    Value = MCSymbolRefExpr::Create(Symbol, MCSymbolRefExpr::VK_None,
1765c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter                                    getContext());
1766c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter  } else if (Parser.parseExpression(Value))
1767c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    return reportParseError("expected valid expression after comma");
1768c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
176986924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Check if the Name already exists as a symbol.
1770c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Name);
177186924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (Sym)
1772c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("symbol already defined");
1773c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym = getContext().GetOrCreateSymbol(Name);
1774c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym->setVariableValue(Value);
1775c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1776c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
1777c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
177886924b4182537745659f2660244f3402c1e1ca4dJack Carter
177930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() {
178030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
178186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Get the next token.
178230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok();
178330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
178430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Tok.getString() == "noat") {
178530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoAtDirective();
178630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "at") {
178730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetAtDirective();
178830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "reorder") {
178930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetReorderDirective();
179030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "noreorder") {
179130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoReorderDirective();
179230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "macro") {
179330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetMacroDirective();
179430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomacro") {
179530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoMacroDirective();
179630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomips16") {
179786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1798cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
179930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
180030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomicromips") {
180186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1802cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
180330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
1804c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  } else {
180586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is just an identifier, look for an assignment.
1806c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    parseSetAssignment();
1807c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return false;
180830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
1809801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
181030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
181130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
181230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1813801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// parseDirectiveWord
1814801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter///  ::= .word [ expression (, expression)* ]
1815801c5838830d190a6b0d8e462bd43805f66ba50fJack Carterbool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1816801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1817801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    for (;;) {
1818801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      const MCExpr *Value;
1819cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
1820801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return true;
1821801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1822801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      getParser().getStreamer().EmitValue(Value, Size);
1823801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1824801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().is(AsmToken::EndOfStatement))
1825801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        break;
1826801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1827801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      // FIXME: Improve diagnostic.
1828801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().isNot(AsmToken::Comma))
1829801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return Error(L, "unexpected token in directive");
1830801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      Parser.Lex();
1831801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    }
1832801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
1833801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1834801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  Parser.Lex();
1835801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  return false;
1836801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter}
1837801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
183830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1839acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1840801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  StringRef IDVal = DirectiveID.getString();
1841801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
184286924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (IDVal == ".ent") {
184386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1844acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1845acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1846acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1847acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1848801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".end") {
184986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1850acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1851acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1852acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1853acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1854801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".frame") {
185586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1856cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1857acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1858acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1859acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1860801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".set") {
186130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseDirectiveSet();
1862acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1863acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1864801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".fmask") {
186586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1866cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1867acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1868acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1869acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1870801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".mask") {
187186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1872cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1873acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1874acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1875acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1876801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".gpword") {
187786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1878cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1879acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1880acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1881acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1882801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".word") {
1883801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    parseDirectiveWord(4, DirectiveID.getLoc());
1884801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    return false;
1885801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
1886801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1887fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1888fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1889fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
1890fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
1891fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1892fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1893fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1894fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1895fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1896ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1897ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
1898ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
1899ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
1900