MipsAsmParser.cpp revision 25df6a93f3324bd30f44dcb95fd17aff0a92d438
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"
23fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
24fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm;
25fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
26fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace {
2730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions {
2830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic:
2930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  MipsAssemblerOptions():
3030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    aTReg(1), reorder(true), macro(true) {
3130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
3230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
3330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned getATRegNum() {return aTReg;}
3430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool setATReg(unsigned Reg);
35ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool isReorder() {return reorder;}
3730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setReorder() {reorder = true;}
3830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setNoreorder() {reorder = false;}
3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool isMacro() {return macro;}
4130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setMacro() {macro = true;}
4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  void setNomacro() {macro = false;}
4330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate:
4530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned aTReg;
4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reorder;
4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool macro;
4830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter};
4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
5130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace {
52fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser {
5372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
54f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  enum FpFormatTy {
55f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_NONE = -1,
56f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_S,
57f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_D,
58f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_L,
59f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FP_FORMAT_W
60f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  } FpFormat;
61f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
62ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCSubtargetInfo &STI;
63ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &Parser;
6410d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  MipsAssemblerOptions Options;
6530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
66ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack 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
81f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool parseMathOperation(StringRef Name, SMLoc NameLoc,
82f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
83f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
84fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseDirective(AsmToken DirectiveID);
85fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
86ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MipsAsmParser::OperandMatchResultTy
87ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
88ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
89ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
90ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
91ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
92ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
93ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
94ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
95ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
96ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
97ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
98ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
99ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
101ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
102ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
103038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
104c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
105c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter                         unsigned RegisterClass);
106c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
107ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
108ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                    StringRef Mnemonic);
109ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
110ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int tryParseRegister(bool is64BitReg);
111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
112ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
113ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter                               bool is64BitReg);
114ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1159d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  bool needsExpansion(MCInst &Inst);
1169d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
1179d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
1182490dc650895149423bb59538dc03ca352222702Jack Carter                         SmallVectorImpl<MCInst> &Instructions);
1199d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1202490dc650895149423bb59538dc03ca352222702Jack Carter                     SmallVectorImpl<MCInst> &Instructions);
1212f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1222f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
1232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
12525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
12625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     SmallVectorImpl<MCInst> &Instructions,
12725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     bool isLoad,bool isImmOpnd);
12830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reportParseError(StringRef ErrorMsg);
12930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  bool parseMemOffset(const MCExpr *&Res);
131ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool parseRelocOperand(const MCExpr *&Res);
13230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
13330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseDirectiveSet();
13430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
13530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetAtDirective();
13630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoAtDirective();
13730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetMacroDirective();
13830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoMacroDirective();
13930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetReorderDirective();
14030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoReorderDirective();
14130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
142c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool parseSetAssignment();
143c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
144801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  bool parseDirectiveWord(unsigned Size, SMLoc L);
145801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
147f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
148ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool isMips64() const {
149ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
151ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
152f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool isFP64() const {
153f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
154f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
155f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
156ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterName(StringRef Symbol, bool is64BitReg);
157ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
15899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int matchCPURegisterName(StringRef Symbol);
15999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
160ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
161ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
162f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(FpFormatTy Format) {
163f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = Format;
164f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
165f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
166f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setDefaultFpFormat();
167f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
168f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(StringRef Format);
169f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
170f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormatTy getFpFormat() {return FpFormat;}
171f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool requestsDoubleOperand(StringRef Mnemonic);
173f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  unsigned getReg(int RC,int RegNo);
175038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
17699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int getATReg();
17725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
17825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
17925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                        SmallVectorImpl<MCInst> &Instructions);
180fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
181fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
182ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    : MCTargetAsmParser(), STI(sti), Parser(parser) {
183ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
184ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
185fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  }
186fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
187ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &getParser() const { return Parser; }
188ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
189ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
190fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
191fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
192fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
19372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
19472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
19572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
19772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
198ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
199ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic:
200ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  enum RegisterKind {
201ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_None,
202ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_CPURegs,
203ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_CPU64Regs,
204ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_HWRegs,
205ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_HW64Regs,
206ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_FGR32Regs,
207ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_FGR64Regs,
20899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    Kind_AFGR64Regs,
209ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_CCRRegs
210ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  };
211ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
212ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate:
21372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
21472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CondCode,
21572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CoprocNum,
21672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Immediate,
21772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Memory,
21872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_PostIndexRegister,
21972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Register,
22072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Token
22172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
22272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
22372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
224ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
225a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct Token {
226a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
227a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
228a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
229a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
230a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct RegOp {
231a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned RegNum;
232a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    RegisterKind Kind;
233a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
234a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
235a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
236a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
237a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
238a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
239a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
240a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Base;
241a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Off;
242a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
243a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
244ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
245a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct Token Tok;
246a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
247a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
248a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
249ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
250ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
251ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
252ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
25372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
25472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addRegOperands(MCInst &Inst, unsigned N) const {
255ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
256ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.addOperand(MCOperand::CreateReg(getReg()));
25772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
258ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
25972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
260ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
261ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Expr == 0)
262ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(0));
263ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
264ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateExpr(Expr));
26772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
26972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
271ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    addExpr(Inst,Expr);
27372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
274ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
27572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
2766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
2776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
2796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
2816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    addExpr(Inst,Expr);
28272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
28372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
28472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isReg() const { return Kind == k_Register; }
28572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isImm() const { return Kind == k_Immediate; }
28672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isToken() const { return Kind == k_Token; }
28772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isMem() const { return Kind == k_Memory; }
28872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
28972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
29072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
29272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
29372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  unsigned getReg() const {
29572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert((Kind == k_Register) && "Invalid access!");
296ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Reg.RegNum;
297ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
299ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void setRegKind(RegisterKind RegKind) {
300ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Reg.Kind = RegKind;
302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
304ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
305ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert((Kind == k_Immediate) && "Invalid access!");
306ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  unsigned getMemBase() const {
3106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
3116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
3126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
3146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
3156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
3166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
3176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
319ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
320ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Token);
321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Register);
330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Reg.RegNum = RegNum;
331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
336ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
337ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Immediate);
338ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Imm.Val = Val;
339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
34272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
34372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
3446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
3456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                 SMLoc S, SMLoc E) {
3466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MipsOperand *Op = new MipsOperand(k_Memory);
3476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Base = Base;
3486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
3496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
3506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
3516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
3526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
354ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCPURegsAsm() const {
355a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi    return Kind == k_Register && Reg.Kind == Kind_CPURegs;
356ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
357ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const {
358ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
359ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
360ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
361ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCPU64RegsAsm() const {
362a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi    return Kind == k_Register && Reg.Kind == Kind_CPU64Regs;
363ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
364ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const {
365ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
366ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
367ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
368ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isHWRegsAsm() const {
369ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
370ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_HWRegs;
371ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
372ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const {
373ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
374ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
375ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
376ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isHW64RegsAsm() const {
377ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
378ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_HW64Regs;
379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const {
381ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
382ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
383ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addCCRAsmOperands(MCInst &Inst, unsigned N) const {
385ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
386ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
388ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCCRAsm() const {
389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_CCRRegs;
391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
392ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
393ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
394ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc getStartLoc() const { return StartLoc; }
395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
396ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc getEndLoc() const { return EndLoc; }
397ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
39872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  virtual void print(raw_ostream &OS) const {
39972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    llvm_unreachable("unimplemented!");
40072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
40172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka};
40272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka}
40372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
40425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm {
40525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[];
40625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
40725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
40825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return MipsInsts[Opcode];
40925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
41025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
41125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
41225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                        SmallVectorImpl<MCInst> &Instructions) {
41325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
41425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Inst.setLoc(IDLoc);
41525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (MCID.mayLoad() || MCID.mayStore()) {
41625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // Check the offset of memory operand, if it is a symbol
41725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // reference or immediate we may have to expand instructions
41825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    for (unsigned i=0;i<MCID.getNumOperands();i++) {
41925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
42025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
42125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
42225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        MCOperand &Op = Inst.getOperand(i);
42325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        if (Op.isImm()) {
42425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          int MemOffset = Op.getImm();
42525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          if (MemOffset < -32768 || MemOffset > 32767) {
42625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            // Offset can't exceed 16bit value
42725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            expandMemInst(Inst,IDLoc,Instructions,MCID.mayLoad(),true);
42825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            return false;
42925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
43025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        } else if (Op.isExpr()) {
43125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          const MCExpr *Expr = Op.getExpr();
43225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          if (Expr->getKind() == MCExpr::SymbolRef){
43325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            const MCSymbolRefExpr *SR =
43425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                    static_cast<const MCSymbolRefExpr*>(Expr);
43525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
43625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              // Expand symbol
43725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              expandMemInst(Inst,IDLoc,Instructions,MCID.mayLoad(),false);
43825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              return false;
43925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            }
44025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
44125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        }
44225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      }
44325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
44425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
44525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
44625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (needsExpansion(Inst))
44725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    expandInstruction(Inst, IDLoc, Instructions);
44825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else
44925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    Instructions.push_back(Inst);
45025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
45125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return false;
45225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
45325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
4549d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) {
4559d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
4569d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  switch(Inst.getOpcode()) {
4579d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    case Mips::LoadImm32Reg:
4582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    case Mips::LoadAddr32Imm:
4592f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    case Mips::LoadAddr32Reg:
4609d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter      return true;
4619d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    default:
4629d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter      return false;
4639d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
4649d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
4652490dc650895149423bb59538dc03ca352222702Jack Carter
4669d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
4672490dc650895149423bb59538dc03ca352222702Jack Carter                        SmallVectorImpl<MCInst> &Instructions){
4689d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  switch(Inst.getOpcode()) {
4699d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    case Mips::LoadImm32Reg:
4709d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter      return expandLoadImm(Inst, IDLoc, Instructions);
4712f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    case Mips::LoadAddr32Imm:
4722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter      return expandLoadAddressImm(Inst,IDLoc,Instructions);
4732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    case Mips::LoadAddr32Reg:
4742f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter      return expandLoadAddressReg(Inst,IDLoc,Instructions);
4759d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    }
4769d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
4772490dc650895149423bb59538dc03ca352222702Jack Carter
4789d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
4792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                                  SmallVectorImpl<MCInst> &Instructions){
4802490dc650895149423bb59538dc03ca352222702Jack Carter  MCInst tmpInst;
4819d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
4822f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
4839d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &RegOp = Inst.getOperand(0);
4849d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  assert(RegOp.isReg() && "expected register operand kind");
4859d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
4869d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  int ImmValue = ImmOp.getImm();
4872490dc650895149423bb59538dc03ca352222702Jack Carter  tmpInst.setLoc(IDLoc);
4889d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  if ( 0 <= ImmValue && ImmValue <= 65535) {
4892490dc650895149423bb59538dc03ca352222702Jack Carter    // for 0 <= j <= 65535.
4909d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => ori d,$zero,j
491ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
4922490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
4932490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(
494ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter              MCOperand::CreateReg(Mips::ZERO));
4952490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
4969d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
4979d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  } else if ( ImmValue < 0 && ImmValue >= -32768) {
4982490dc650895149423bb59538dc03ca352222702Jack Carter    // for -32768 <= j < 0.
4999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => addiu d,$zero,j
500ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5012490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5022490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(
503ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter              MCOperand::CreateReg(Mips::ZERO));
5042490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5059d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5069d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  } else {
5079d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // for any other value of j that is representable as a 32-bit integer.
5089d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => lui d,hi16(j)
5092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //           ori d,d,lo16(j)
510ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5112490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5122490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5139d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5142490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.clear();
515ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5162490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5172490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5182490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
5192490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.setLoc(IDLoc);
5209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5219d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
5229d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
5232490dc650895149423bb59538dc03ca352222702Jack Carter
5242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
5252f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                                         SmallVectorImpl<MCInst> &Instructions){
5262f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
5272f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(2);
5282f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
5292f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &SrcRegOp = Inst.getOperand(1);
5302f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(SrcRegOp.isReg() && "expected register operand kind");
5312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &DstRegOp = Inst.getOperand(0);
5322f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(DstRegOp.isReg() && "expected register operand kind");
5332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
5342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  if ( -32768 <= ImmValue && ImmValue <= 65535) {
5352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //for -32768 <= j <= 65535.
5362f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //la d,j(s) => addiu d,s,j
537ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
5402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5412f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5422f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
5432f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //for any other value of j that is representable as a 32-bit integer.
5442f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //la d,j(s) => lui d,hi16(j)
5452f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //             ori d,d,lo16(j)
5462f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //             addu d,d,s
547ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5482f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5492f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5502f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5512f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
552ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5532f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5542f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5552f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
5562f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5572f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
5582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDu);
5592f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5602f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5612f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
5622f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5632f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
5642f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
5652f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
5662f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
5672f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                                         SmallVectorImpl<MCInst> &Instructions){
5682f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
5692f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
5702f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
5712f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &RegOp = Inst.getOperand(0);
5722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(RegOp.isReg() && "expected register operand kind");
5732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
5742f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  if ( -32768 <= ImmValue && ImmValue <= 65535) {
5752f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //for -32768 <= j <= 65535.
5762f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //la d,j => addiu d,$zero,j
5772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(
580ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter              MCOperand::CreateReg(Mips::ZERO));
5812f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5822f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5832f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
5842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //for any other value of j that is representable as a 32-bit integer.
5852f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //la d,j => lui d,hi16(j)
5862f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //          ori d,d,lo16(j)
587ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5882f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5892f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5902f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5912f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
592ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5932f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5952f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
5962f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5972f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
5982f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
5992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
60025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
60125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     SmallVectorImpl<MCInst> &Instructions,
60225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     bool isLoad,bool isImmOpnd) {
60325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCSymbolRefExpr *SR;
60425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  MCInst TempInst;
60525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned ImmOffset,HiOffset,LoOffset;
60625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCExpr *ExprOffset;
60725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned TmpRegNum;
60825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID:
60925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                            Mips::CPURegsRegClassID,
61025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                            getATReg());
61125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // 1st operand is either source or dst register
61225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
61325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned RegOpNum = Inst.getOperand(0).getReg();
61425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // 2nd operand is base register
61525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
61625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned BaseRegNum = Inst.getOperand(1).getReg();
61725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // 3rd operand is either immediate or expression
61825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd) {
61925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
62025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ImmOffset = Inst.getOperand(2).getImm();
62125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    LoOffset = ImmOffset & 0x0000ffff;
62225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    HiOffset = (ImmOffset & 0xffff0000) >> 16;
62325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // If msb of LoOffset is 1(negative number) we must increment HiOffset
62425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (LoOffset & 0x8000)
62525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      HiOffset++;
62625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
62725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else
62825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ExprOffset = Inst.getOperand(2).getExpr();
62925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // All instructions will have the same location
63025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setLoc(IDLoc);
63125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // 1st instruction in expansion is LUi. For load instruction we can use
63225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // the dst register as a temporary if base and dst are different,
63325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // but for stores we must use $at
63425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum))?RegOpNum:AtRegNum;
63525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::LUi);
63625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
63725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
63825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
63925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
64025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
64125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
64225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::
64325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                        Create(SR->getSymbol().getName(),
64425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                        MCSymbolRefExpr::VK_Mips_ABS_HI,
64525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                        getContext());
64625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
64725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
64825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
64925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // Add the instruction to the list
65025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
65125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // and prepare TempInst for next instruction
65225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
65325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // which is add temp register to base
65425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::ADDu);
65525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
65625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
65725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
65825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
65925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
66025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // and finaly, create original instruction with low part
66125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // of offset and new base
66225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Inst.getOpcode());
66325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
66425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
66525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
66625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
66725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
66825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
66925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::
67025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                      Create(SR->getSymbol().getName(),
67125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                      MCSymbolRefExpr::VK_Mips_ABS_LO,
67225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                                      getContext());
67325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
67425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
67525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
67625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
67725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
67825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
67925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
680fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
68184125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
682fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
68384125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        MCStreamer &Out, unsigned &ErrorInfo,
68484125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        bool MatchingInlineAsm) {
685ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
68625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  SmallVector<MCInst, 8> Instructions;
6876e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
68884125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                                              MatchingInlineAsm);
689ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
690ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
691ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default: break;
692ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
69325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (processInstruction(Inst,IDLoc,Instructions))
69425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      return true;
69525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    for(unsigned i =0; i < Instructions.size(); i++)
69625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      Out.EmitInstruction(Instructions[i]);
697ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
698ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
699ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
700ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
701ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
702ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
703ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
704ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ErrorInfo != ~0U) {
705ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
706ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
707ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
708ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      ErrorLoc = ((MipsOperand*)Operands[ErrorInfo])->getStartLoc();
709ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorLoc == SMLoc()) ErrorLoc = IDLoc;
710ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
711ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
712ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
713ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
714ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
715ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
716ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
717fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
718fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
719fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
72099e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) {
721572e1bd109518f80b54d229de10699c4603944c3David Chisnall   int CC;
72299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
72399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (Name == "at")
72499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    return getATReg();
72599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
726572e1bd109518f80b54d229de10699c4603944c3David Chisnall    CC = StringSwitch<unsigned>(Name)
72799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("zero", 0)
72899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a0",   4)
72999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a1",   5)
73099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a2",   6)
73199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a3",   7)
73299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("v0",   2)
73399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("v1",   3)
73499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s0",  16)
73599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s1",  17)
73699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s2",  18)
73799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s3",  19)
73899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s4",  20)
73999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s5",  21)
74099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s6",  22)
74199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s7",  23)
74299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("k0",  26)
74399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("k1",  27)
74499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("sp",  29)
74599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("fp",  30)
74699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("gp",  28)
74799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("ra",  31)
74899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t0",   8)
74999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t1",   9)
75099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t2",  10)
75199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t3",  11)
75299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t4",  12)
75399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t5",  13)
75499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t6",  14)
75599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t7",  15)
75699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t8",  24)
75799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t9",  25)
75899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Default(-1);
75999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
76099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // Although SGI documentation just cut out t0-t3 for n32/n64,
76199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
76299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
76399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (isMips64() && 8 <= CC  && CC <= 11)
76499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    CC += 4;
76599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
76699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (CC == -1 && isMips64())
767572e1bd109518f80b54d229de10699c4603944c3David Chisnall    CC = StringSwitch<unsigned>(Name)
76899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a4",   8)
76999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a5",   9)
77099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a6",  10)
77199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a7",  11)
77299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("kt0", 26)
77399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("kt1", 27)
77499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("s8",  30)
775572e1bd109518f80b54d229de10699c4603944c3David Chisnall      .Default(-1);
776572e1bd109518f80b54d229de10699c4603944c3David Chisnall
77799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return CC;
77899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter}
77999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
78099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
78199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int CC;
78299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  CC = matchCPURegisterName(Name);
783572e1bd109518f80b54d229de10699c4603944c3David Chisnall  if (CC != -1)
78499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    return matchRegisterByNumber(CC,is64BitReg?Mips::CPU64RegsRegClassID:
78599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter                               Mips::CPURegsRegClassID);
786ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
787f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
788f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
789f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
790f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if( NumString.getAsInteger(10, IntVal))
7919d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter      return -1; // not integer
792f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (IntVal > 31)
793f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
794f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
795f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormatTy Format = getFpFormat();
796f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
797f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
798f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::FGR32RegClassID, IntVal);
799f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_D) {
800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if(isFP64()) {
801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return getReg(Mips::FGR64RegClassID, IntVal);
802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
8039d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter      // only even numbers available as register pairs
804f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if (( IntVal > 31) || (IntVal%2 !=  0))
805f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return -1;
806f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::AFGR64RegClassID, IntVal/2);
807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
809f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
810ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
811ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() {
813f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
814f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() || isFP64())
815f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_D;
816f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else
817f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_S;
818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
819f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
820f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
823f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldxc1", true)
824f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldc1",  true)
825f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdxc1", true)
826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdc1",  true)
827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(false);
828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return IsDouble;
830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) {
832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormat = StringSwitch<FpFormatTy>(Format.lower())
834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".s",  FP_FORMAT_S)
835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".d",  FP_FORMAT_D)
836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".l",  FP_FORMAT_L)
837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".w",  FP_FORMAT_W)
838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(FP_FORMAT_NONE);
839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
840ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
84130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) {
84230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Reg > 31)
84330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
84430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
84530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  aTReg = Reg;
84630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
84730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
84830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
84999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::getATReg() {
85099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return Options.getATRegNum();
85130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
85230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
85330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterunsigned MipsAsmParser::getReg(int RC,int RegNo) {
854ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
855ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
856ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
857ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
858ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
859ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNum > 31)
860ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return -1;
861ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
862ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return getReg(RegClass, RegNum);
863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
865ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::tryParseRegister(bool is64BitReg) {
866ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const AsmToken &Tok = Parser.getTok();
867ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNum = -1;
868ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
869ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Tok.is(AsmToken::Identifier)) {
870ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    std::string lowerCase = Tok.getString().lower();
871ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    RegNum = matchRegisterName(lowerCase, is64BitReg);
872ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  } else if (Tok.is(AsmToken::Integer))
8739d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
874ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter                                   is64BitReg ? Mips::CPU64RegsRegClassID
875ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter                                              : Mips::CPURegsRegClassID);
876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return RegNum;
877ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
878ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
879fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
880ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
881ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter                          bool is64BitReg){
882ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc S = Parser.getTok().getLoc();
884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNo = -1;
885f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
886ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  RegNo = tryParseRegister(is64BitReg);
887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNo == -1)
888ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
889ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
890ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
891ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter      Parser.getTok().getLoc()));
892ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Eat register token.
893ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
894ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
895ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
896ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
897ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                 StringRef Mnemonic) {
8989d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // Check if the current operand has a custom associated parser, if so, try to
8999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // custom parse the operand, or fallback to the general approach.
900ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
901ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
902ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
903ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
904ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
905ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
908ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
911ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
912ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
9149d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // parse register
915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
916ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.Lex(); // Eat dollar token.
9179d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // parse register operand
918ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (!tryParseRegisterOperand(Operands, isMips64())) {
919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (getLexer().is(AsmToken::LParen)) {
9209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter        // check if it is indexed addressing operand
921ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken("(", S));
9229d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter        Parser.Lex(); // eat parenthesis
923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (getLexer().isNot(AsmToken::Dollar))
924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
9269d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter        Parser.Lex(); // eat dollar
927ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter        if (tryParseRegisterOperand(Operands, isMips64()))
928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
930ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (!getLexer().is(AsmToken::RParen))
931ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        S = Parser.getTok().getLoc();
934ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken(")", S));
935ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex();
936ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
937ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
938ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
9399d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // maybe it is a symbol reference
940ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
941cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (Parser.parseIdentifier(Identifier))
942ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
943ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
944ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
945ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
94638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
947ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Otherwise create a symbol ref.
9496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                                getContext());
951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
952ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
953ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
954ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
955ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Identifier:
956c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    // Look for the existing symbol, we should check if
957c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    // we need to assigne the propper RegisterKind
958c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter   if (searchSymbolAlias(Operands,MipsOperand::Kind_None))
959c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter     return false;
960c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    //else drop to expression parsing
961ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
962ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
963ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
965ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
966ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter     // quoted label names
967ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *IdVal;
968ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
969cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(IdVal))
970ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
971ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
972ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
973ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
974ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
9756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
9769d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // it is a symbol reference or constant expression
9776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
9789d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    SMLoc S = Parser.getTok().getLoc(); // start location of the operand
979ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (parseRelocOperand(IdVal))
9806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
9816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
982ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
983ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
9846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
9856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
98630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // case AsmToken::Percent
98730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // switch(getLexer().getKind())
988fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
989fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
990fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
991ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
9926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
99330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // eat % token
9949d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const AsmToken &Tok = Parser.getTok(); // get next token, operation
9956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
9966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
9976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
99838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  std::string Str = Tok.getIdentifier().str();
9996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
10009d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  Parser.Lex(); // eat identifier
100130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // now make expression from the rest of the operand
10026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
1003ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc EndLoc;
10046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
10056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
10066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
100730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      Parser.Lex(); // eat '(' token
10086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
100930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter        Parser.Lex(); // eat % token
10106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
10116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
10126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
101338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
101438539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
101530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter        Parser.Lex(); // eat identifier
10166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
10176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
10186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
10196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
10206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
1021cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseParenExpression(IdVal,EndLoc))
10226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
10236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1024ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    while (getLexer().getKind() == AsmToken::RParen)
102530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      Parser.Lex(); // eat ')' token
10266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
10276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
102830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return true; // parenthesis must follow reloc operand
10296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
103030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // Check the type of the expression
103138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal)) {
103225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // It's a constant, evaluate lo or hi value
10336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    if (Str == "lo") {
103425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      short Val = MCE->getValue();
103525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      Res = MCConstantExpr::Create(Val, getContext());
10366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    } else if (Str == "hi") {
103725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      int Val = MCE->getValue();
103877217229ba1bbc92f3a53099fa91bcdaa7797da8Jack Carter      int LoSign = Val & 0x8000;
10396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Val = (Val & 0xffff0000) >> 16;
104025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      // Lower part is treated as a signed int, so if it is negative
104125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      // we must add 1 to the hi part to compensate
104277217229ba1bbc92f3a53099fa91bcdaa7797da8Jack Carter      if (LoSign)
104377217229ba1bbc92f3a53099fa91bcdaa7797da8Jack Carter        Val++;
104425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      Res = MCConstantExpr::Create(Val, getContext());
10456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
10466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
10476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
10486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
104938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(IdVal)) {
105025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // It's a symbol, create symbolic expression from symbol
105138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    StringRef Symbol = MSRE->getSymbol().getName();
10526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MCSymbolRefExpr::VariantKind VK = getVariantKind(Str);
10536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Res = MCSymbolRefExpr::Create(Symbol,VK,getContext());
10546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
10556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
10566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return true;
10576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
10586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1059ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1060ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
1061ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1062ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  StartLoc = Parser.getTok().getLoc();
1063ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  RegNo = tryParseRegister(isMips64());
1064ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  EndLoc = Parser.getTok().getLoc();
1065ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return (RegNo == (unsigned)-1);
1066ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1067ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
10686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res) {
1069ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1070ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
1071ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
10726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  switch(getLexer().getKind()) {
10736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
10746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
107525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  case AsmToken::Identifier:
10766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
10776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
10786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
1079cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    return (getParser().parseExpression(Res));
1080ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  case AsmToken::Percent:
1081ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return parseRelocOperand(Res);
10826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::LParen:
108330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;  // it's probably assuming 0
10846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
10856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return true;
10866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
10876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1088ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
1089ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
10906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
10916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal = 0;
1092ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
1093ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  // first operand is the offset
1094ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  S = Parser.getTok().getLoc();
10956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
10966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (parseMemOffset(IdVal))
10976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
10986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
109930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok(); // get next token
11006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::LParen)) {
11012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
11022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    if (Mnemonic->getToken() == "la") {
1103ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter      SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() -1);
11042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter      Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
11052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter      return MatchOperand_Success;
11062f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    }
11076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "'(' expected");
11086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
11096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
11106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); // Eat '(' token.
11126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11132f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const AsmToken &Tok1 = Parser.getTok(); // get next token
11146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok1.is(AsmToken::Dollar)) {
11156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Parser.Lex(); // Eat '$' token.
1116ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (tryParseRegisterOperand(Operands, isMips64())) {
11176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Error(Parser.getTok().getLoc(), "unexpected token in operand");
11186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return MatchOperand_ParseFail;
11196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
11206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else {
112230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
11236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
11246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
11256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
112630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok2 = Parser.getTok(); // get next token
11276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok2.isNot(AsmToken::RParen)) {
11286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
11296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
11306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
11316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1132ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1133ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
11346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Parser.Lex(); // Eat ')' token.
11356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (IdVal == 0)
11376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    IdVal = MCConstantExpr::Create(0, getContext());
11386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
113930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // now replace register operand with the mem operand
11406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
11416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  int RegNo = op->getReg();
114230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // remove register from operands
11436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
114430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // and add memory operand
11456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
11466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  delete op;
1147ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
1148ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1149ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1150ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1151ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1152ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1153ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (!isMips64())
1154ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1155c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().getKind() == AsmToken::Identifier) {
1156c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (searchSymbolAlias(Operands,MipsOperand::Kind_CPU64Regs))
1157c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return MatchOperand_Success;
1158c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return MatchOperand_NoMatch;
1159c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
1160ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  // if the first token is not '$' we have an error
1161ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1162ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1163ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1164ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1165ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if(!tryParseRegisterOperand(Operands, true)) {
1166ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    // set the proper register kind
1167ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1168ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    op->setRegKind(MipsOperand::Kind_CPU64Regs);
1169ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
1170ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
1171ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_NoMatch;
1172ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1173ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1174c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::
1175c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack CartersearchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
1176c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter                  unsigned RegisterKind) {
1177c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1178c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1179c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Sym) {
1180c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    SMLoc S = Parser.getTok().getLoc();
1181c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    const MCExpr *Expr;
1182c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (Sym->isVariable())
1183c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Expr = Sym->getVariableValue();
1184c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    else
1185c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return false;
1186c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (Expr->getKind() == MCExpr::SymbolRef) {
1187c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1188c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const StringRef DefSymbol = Ref->getSymbol().getName();
1189c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      if (DefSymbol.startswith("$")) {
1190c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        // Lookup for the register with corresponding name
1191c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        int RegNum = matchRegisterName(DefSymbol.substr(1),isMips64());
1192c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        if (RegNum > -1) {
1193c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          Parser.Lex();
1194c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          MipsOperand *op = MipsOperand::CreateReg(RegNum,S,
1195c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter                                         Parser.getTok().getLoc());
1196c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          op->setRegKind((MipsOperand::RegisterKind)RegisterKind);
1197c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          Operands.push_back(op);
1198c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          return true;
1199c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        }
1200c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      }
1201c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    } else if (Expr->getKind() == MCExpr::Constant) {
1202c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Parser.Lex();
1203c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
1204c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      MipsOperand *op = MipsOperand::CreateImm(Const,S,
1205c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter                                     Parser.getTok().getLoc());
1206c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Operands.push_back(op);
1207c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return true;
1208c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    }
1209c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
1210c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
1211c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
1212ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1213ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1214ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1215c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().getKind() == AsmToken::Identifier) {
1216c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (searchSymbolAlias(Operands,MipsOperand::Kind_CPURegs))
1217c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return MatchOperand_Success;
1218c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return MatchOperand_NoMatch;
1219c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
1220ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  // if the first token is not '$' we have an error
1221ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1222ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1223ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1224ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1225ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if(!tryParseRegisterOperand(Operands, false)) {
1226ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    // set the propper register kind
1227ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1228ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    op->setRegKind(MipsOperand::Kind_CPURegs);
1229ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
1230ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
1231ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_NoMatch;
1232ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1233ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1234ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1235ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1236ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1237c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  if (isMips64())
1238c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter    return MatchOperand_NoMatch;
1239c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter
1240ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  // if the first token is not '$' we have error
1241ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1242ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1243ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
1244ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1245ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1246ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  const AsmToken &Tok = Parser.getTok(); // get next token
1247ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.isNot(AsmToken::Integer))
1248ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1249ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1250ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum = Tok.getIntVal();
1251ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  // at the moment only hwreg29 is supported
1252ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (RegNum != 29)
1253ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_ParseFail;
1254ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1255ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
1256ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter        Parser.getTok().getLoc());
1257ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  op->setRegKind(MipsOperand::Kind_HWRegs);
1258ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1259ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1260ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat reg number
1261ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1262ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1263ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1264ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1265ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1266c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter
1267c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  if (!isMips64())
1268c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter    return MatchOperand_NoMatch;
1269ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    //if the first token is not '$' we have error
1270ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1271ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1272ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
1273ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1274ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1275ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  const AsmToken &Tok = Parser.getTok(); // get next token
1276ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.isNot(AsmToken::Integer))
1277ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1278ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1279ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum = Tok.getIntVal();
1280ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  // at the moment only hwreg29 is supported
1281ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (RegNum != 29)
1282ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_ParseFail;
1283ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1284ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
1285ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter        Parser.getTok().getLoc());
1286c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  op->setRegKind(MipsOperand::Kind_HW64Regs);
1287ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1288ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1289ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat reg number
1290ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1291ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1292ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1293ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1294ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1295ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum;
1296ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  //if the first token is not '$' we have error
1297ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1298ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1299ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
1300ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  const AsmToken &Tok = Parser.getTok(); // get next token
1303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.is(AsmToken::Integer)) {
1304ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    RegNum = Tok.getIntVal();
1305ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    // at the moment only fcc0 is supported
1306ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (RegNum != 0)
1307ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter      return MatchOperand_ParseFail;
1308ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  } else if (Tok.is(AsmToken::Identifier)) {
1309ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    // at the moment only fcc0 is supported
1310ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (Tok.getIdentifier() != "fcc0")
1311ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter      return MatchOperand_ParseFail;
1312ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  } else
1313ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1314ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1315ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
1316ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter        Parser.getTok().getLoc());
1317ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  op->setRegKind(MipsOperand::Kind_CCRRegs);
1318ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1319ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1320ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat reg number
1321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1322ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1323ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
13246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
13256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
13266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind VK
13276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
13286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
13296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
13306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
13316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
13326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
13336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
13346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
13356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
13366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
13376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
13386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
13396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
13406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
13416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
13426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
13436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
13446b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
13456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Default(MCSymbolRefExpr::VK_None);
13466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
13476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return VK;
13486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
13496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
13501ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) {
1351f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  int CC = StringSwitch<unsigned>(CondString)
1352f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".f",    0)
1353f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".un",   1)
1354f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".eq",   2)
1355f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ueq",  3)
1356f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".olt",  4)
1357f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ult",  5)
1358f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ole",  6)
1359f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ule",  7)
1360f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".sf",   8)
1361f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngle", 9)
1362f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".seq",  10)
1363f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngl",  11)
1364f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".lt",   12)
1365f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".nge",  13)
1366f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".le",   14)
1367f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Case(".ngt",  15)
1368f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      .Default(-1);
1369f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1370f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return CC;
1371f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
1372f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1373f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::
1374f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc,
137530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter                   SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
137630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // split the format
1377f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  size_t Start = Name.find('.'), Next = Name.rfind('.');
1378f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format1 = Name.slice(Start, Next);
137930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // and add the first format to the operands
1380f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
138130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // now for the second format
1382f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format2 = Name.slice(Next, StringRef::npos);
1383f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
1384f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
138530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // set the format for the first register
1386f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  setFpFormat(Format1);
1387f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1388f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  // Read the remaining operands.
1389f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1390f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Read the first operand.
1391f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
1392f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
1393cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1394f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
1395f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1396f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1397f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (getLexer().isNot(AsmToken::Comma)) {
1398f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
1399cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1400f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
1401f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1402f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1403f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Parser.Lex();  // Eat the comma.
1404f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1405f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    //set the format for the first register
1406f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(Format2);
1407f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1408f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Parse and remember the operand.
1409f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
1410f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
1411cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1412f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
1413f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1414f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1415f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1416f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1417f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    SMLoc Loc = getLexer().getLoc();
1418cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1419f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return Error(Loc, "unexpected token in argument list");
1420f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1421f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1422f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Parser.Lex(); // Consume the EndOfStatement
1423f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return false;
1424f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
1425f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1426fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
14276a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1428fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
142999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  StringRef Mnemonic;
143030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // floating point instructions: should register be treated as double?
1431f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (requestsDoubleOperand(Name)) {
1432f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(FP_FORMAT_D);
1433ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
143499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  Mnemonic = Name;
1435f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1436f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else {
1437f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setDefaultFpFormat();
1438f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Create the leading tokens for the mnemonic, split by '.' characters.
1439f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    size_t Start = 0, Next = Name.find('.');
144099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    Mnemonic = Name.slice(Start, Next);
1441f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1442f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
1443f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1444f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Next != StringRef::npos) {
144530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      // there is a format token in mnemonic
144630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      // StringRef Rest = Name.slice(Next, StringRef::npos);
1447f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      size_t Dot = Name.find('.', Next+1);
1448f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      StringRef Format = Name.slice(Next, Dot);
1449f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      if (Dot == StringRef::npos) //only one '.' in a string, it's a format
1450f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1451f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      else {
1452f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        if (Name.startswith("c.")){
1453f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          // floating point compare, add '.' and immediate represent for cc
1454f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
1455f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          int Cc = ConvertCcString(Format);
1456f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          if (Cc == -1) {
1457f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter            return Error(NameLoc, "Invalid conditional code");
1458f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          }
1459ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter          SMLoc E = SMLoc::getFromPointer(
1460ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter              Parser.getTok().getLoc().getPointer() -1 );
1461f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateImm(
1462f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter              MCConstantExpr::Create(Cc, getContext()), NameLoc, E));
1463f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        } else {
146430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter          // trunc, ceil, floor ...
1465f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          return parseMathOperation(Name, NameLoc, Operands);
1466f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        }
1467f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
146830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter        // the rest is a format
1469f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Format = Name.slice(Dot, StringRef::npos);
1470f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1471f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
1472f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1473f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      setFpFormat(Format);
1474f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1475f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1476ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1477ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
1478ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1479ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
148099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (ParseOperand(Operands, Mnemonic)) {
1481ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
1482cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1483ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
1484ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1485ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1486ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    while (getLexer().is(AsmToken::Comma) ) {
1487ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Parser.Lex();  // Eat the comma.
1488ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1489ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
1490ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ParseOperand(Operands, Name)) {
1491ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
1492cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
1493ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
1494ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
1495ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1496ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1498ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1499ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
1500cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1501ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
1502ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1503ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1504ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Consume the EndOfStatement
1505ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
1506fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1507fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
150830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
150930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter   SMLoc Loc = getLexer().getLoc();
1510cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach   Parser.eatToEndOfStatement();
151130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter   return Error(Loc, ErrorMsg);
151230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
151330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
151430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() {
1515c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  // Line should look like:
151630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  //  .set noat
151730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // set at reg to 0
151810d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setATReg(0);
151930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // eat noat
152030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
1521c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  // If this is not the end of the statement, report error
152230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
152330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
152430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
152530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
152630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
152730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
152830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
152930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() {
153030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // line can be
153130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  //  .set at - defaults to $1
153230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // or .set at=$reg
153399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int AtRegNo;
153430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  getParser().Lex();
153530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().is(AsmToken::EndOfStatement)) {
153610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter    Options.setATReg(1);
153730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // Consume the EndOfStatement
153830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
153930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (getLexer().is(AsmToken::Equal)) {
1540c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    getParser().Lex(); // eat '='
154130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::Dollar)) {
154230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
154330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
154430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
1545c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    Parser.Lex(); // Eat '$'
154699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    const AsmToken &Reg = Parser.getTok();
154799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (Reg.is(AsmToken::Identifier)) {
154899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
154999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else if (Reg.is(AsmToken::Integer)) {
155099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = Reg.getIntVal();
155199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else {
155230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
155330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
155430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
155599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
155699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if ( AtRegNo < 1 || AtRegNo > 31) {
155799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      reportParseError("unexpected token in statement");
155899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      return false;
155999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    }
156099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
156199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (!Options.setATReg(AtRegNo)) {
156230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
156330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
156430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
1565c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    getParser().Lex(); // Eat reg
156630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
156730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
156830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
156930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
157030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter     }
157130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // Consume the EndOfStatement
157230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
157330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else {
157430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
157530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
157630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
157730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
157830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
157930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() {
158030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
1581c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  // If this is not the end of the statement, report error
158230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
158330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
158430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
158530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
158610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setReorder();
158730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
158830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
158930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
159030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
159130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() {
159230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex();
159330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // if this is not the end of the statement, report error
159430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
159530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
159630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
159730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
159810d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter    Options.setNoreorder();
159930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Parser.Lex(); // Consume the EndOfStatement
160030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
160130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
160230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
160330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() {
160430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
160530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // if this is not the end of the statement, report error
160630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
160730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
160830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
160930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
161010d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setMacro();
161130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
161230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
161330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
161430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
161530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() {
161630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
161730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // if this is not the end of the statement, report error
161830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
161930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
162030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
162130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
162210d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  if (Options.isReorder()) {
162330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
162430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
162530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
162610d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setNomacro();
162730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex(); // Consume the EndOfStatement
162830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
162930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
1630c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1631c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() {
1632c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  StringRef Name;
1633c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  const MCExpr *Value;
1634c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1635c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseIdentifier(Name))
1636c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected identifier after .set");
1637c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1638c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().isNot(AsmToken::Comma))
1639c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("unexpected token in .set directive");
1640c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Lex(); //eat comma
1641c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1642c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseExpression(Value))
1643c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected valid expression after comma");
1644c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1645c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  // check if the Name already exists as a symbol
1646c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Name);
1647c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Sym) {
1648c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("symbol already defined");
1649c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
1650c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym = getContext().GetOrCreateSymbol(Name);
1651c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym->setVariableValue(Value);
1652c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1653c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
1654c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
165530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() {
165630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
165730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // get next token
165830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok();
165930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
166030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Tok.getString() == "noat") {
166130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoAtDirective();
166230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "at") {
166330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetAtDirective();
166430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "reorder") {
166530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetReorderDirective();
166630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "noreorder") {
166730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoReorderDirective();
166830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "macro") {
166930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetMacroDirective();
167030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomacro") {
167130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoMacroDirective();
167230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomips16") {
167330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1674cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
167530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
167630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomicromips") {
167730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1678cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
167930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
1680c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  } else {
1681c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    // it is just an identifier, look for assignment
1682c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    parseSetAssignment();
1683c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return false;
168430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
1685801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
168630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
168730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
168830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1689801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// parseDirectiveWord
1690801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter///  ::= .word [ expression (, expression)* ]
1691801c5838830d190a6b0d8e462bd43805f66ba50fJack Carterbool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1692801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1693801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    for (;;) {
1694801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      const MCExpr *Value;
1695cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
1696801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return true;
1697801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1698801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      getParser().getStreamer().EmitValue(Value, Size);
1699801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1700801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().is(AsmToken::EndOfStatement))
1701801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        break;
1702801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1703801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      // FIXME: Improve diagnostic.
1704801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().isNot(AsmToken::Comma))
1705801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return Error(L, "unexpected token in directive");
1706801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      Parser.Lex();
1707801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    }
1708801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
1709801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1710801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  Parser.Lex();
1711801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  return false;
1712801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter}
1713801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
171430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1715acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1716801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  StringRef IDVal = DirectiveID.getString();
1717801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1718801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if ( IDVal == ".ent") {
171930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1720acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1721acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1722acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1723acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1724801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".end") {
172530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1726acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1727acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1728acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1729acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1730801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".frame") {
173130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1732cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1733acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1734acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1735acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1736801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".set") {
173730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseDirectiveSet();
1738acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1739acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1740801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".fmask") {
174130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1742cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1743acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1744acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1745acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1746801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".mask") {
174730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1748cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1749acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1750acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1751acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1752801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".gpword") {
175330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    // ignore this directive for now
1754cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1755acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1756acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1757acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1758801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".word") {
1759801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    parseDirectiveWord(4, DirectiveID.getLoc());
1760801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    return false;
1761801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
1762801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1763fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1764fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1765fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
1766fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
1767fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1768fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1769fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1770fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1771fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1772ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1773ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
1774ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
1775ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
1776