MipsAsmParser.cpp revision 86924b4182537745659f2660244f3402c1e1ca4d
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
6672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER
6772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc"
6872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
6984125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
70fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                               SmallVectorImpl<MCParsedAsmOperand*> &Operands,
7184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               MCStreamer &Out, unsigned &ErrorInfo,
7284125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                               bool MatchingInlineAsm);
73fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
74fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc);
75fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
766a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
776a020a71173a3ea7738a9df69982e85ddbfe0303Chad Rosier                        SMLoc NameLoc,
7872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
79fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
80f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool parseMathOperation(StringRef Name, SMLoc NameLoc,
81f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter                        SmallVectorImpl<MCParsedAsmOperand*> &Operands);
82f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
83fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  bool ParseDirective(AsmToken DirectiveID);
84fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
85ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MipsAsmParser::OperandMatchResultTy
86ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseMemOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
87ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
88ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
89ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
90ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
91ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
92ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
93ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
94ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
95ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
96ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
97ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
98ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseHW64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
99ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsAsmParser::OperandMatchResultTy
101ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands);
102038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
103c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool searchSymbolAlias(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
104c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter                         unsigned RegisterClass);
105c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
106ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &,
107ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                    StringRef Mnemonic);
108ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
109ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int tryParseRegister(bool is64BitReg);
110ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
111ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool tryParseRegisterOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands,
112ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter                               bool is64BitReg);
113ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1149d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  bool needsExpansion(MCInst &Inst);
1159d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
1169d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  void expandInstruction(MCInst &Inst, SMLoc IDLoc,
1172490dc650895149423bb59538dc03ca352222702Jack Carter                         SmallVectorImpl<MCInst> &Instructions);
1189d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  void expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1192490dc650895149423bb59538dc03ca352222702Jack Carter                     SmallVectorImpl<MCInst> &Instructions);
1202f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  void expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1212f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
1222f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  void expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
12425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
12525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     SmallVectorImpl<MCInst> &Instructions,
12625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                     bool isLoad,bool isImmOpnd);
12730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reportParseError(StringRef ErrorMsg);
12830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
130ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool parseRelocOperand(const MCExpr *&Res);
13130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const MCExpr* evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
1338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
1348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isEvaluated(const MCExpr *Expr);
13530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseDirectiveSet();
13630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
13730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetAtDirective();
13830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoAtDirective();
13930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetMacroDirective();
14030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoMacroDirective();
14130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetReorderDirective();
14230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoReorderDirective();
14330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
144c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool parseSetAssignment();
145c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
146801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  bool parseDirectiveWord(unsigned Size, SMLoc L);
147801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
149f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  bool isMips64() const {
151ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return (STI.getFeatureBits() & Mips::FeatureMips64) != 0;
152ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
153ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
154f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool isFP64() const {
155f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return (STI.getFeatureBits() & Mips::FeatureFP64Bit) != 0;
156f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
157f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
158ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterName(StringRef Symbol, bool is64BitReg);
159ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
16099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int matchCPURegisterName(StringRef Symbol);
16199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
162ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
163ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
164f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(FpFormatTy Format) {
165f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = Format;
166f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
167f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
168f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setDefaultFpFormat();
169f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
170f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  void setFpFormat(StringRef Format);
171f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormatTy getFpFormat() {return FpFormat;}
173f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
174f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool requestsDoubleOperand(StringRef Mnemonic);
175f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
17686924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned getReg(int RC, int RegNo);
177038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
17899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int getATReg();
17925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
18025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
18125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter                        SmallVectorImpl<MCInst> &Instructions);
182fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
183fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser)
184ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    : MCTargetAsmParser(), STI(sti), Parser(parser) {
185ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
186ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
187fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  }
188fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
189ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &getParser() const { return Parser; }
190ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
191ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
192fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
193fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
194fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
19572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
19672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
19772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
19872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
19972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
200ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
201ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic:
202ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  enum RegisterKind {
203ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_None,
204ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_CPURegs,
205ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_CPU64Regs,
206ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_HWRegs,
207ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_HW64Regs,
208ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_FGR32Regs,
209ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_FGR64Regs,
21099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    Kind_AFGR64Regs,
211ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Kind_CCRRegs
212ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  };
213ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
214ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate:
21572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
21672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CondCode,
21772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_CoprocNum,
21872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Immediate,
21972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Memory,
22072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_PostIndexRegister,
22172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Register,
22272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    k_Token
22372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
22472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
22572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  MipsOperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
226ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
227a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct Token {
228a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
229a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
230a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
231a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
232a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct RegOp {
233a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned RegNum;
234a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    RegisterKind Kind;
235a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
236a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
237a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
238a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
239a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
240a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
241a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
242a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Base;
243a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Off;
244a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
245a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
246ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
247a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct Token Tok;
248a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct RegOp Reg;
249a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
250a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
251ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
252ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
253ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
254ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
25572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
25672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addRegOperands(MCInst &Inst, unsigned N) const {
257ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
258ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Inst.addOperand(MCOperand::CreateReg(getReg()));
25972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
260ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
26172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addExpr(MCInst &Inst, const MCExpr *Expr) const{
262ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
263ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (Expr == 0)
264ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(0));
265ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
266ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
267ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
268ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateExpr(Expr));
26972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
270ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
27172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
272ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
273ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
27486924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
27572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
276ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
27772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
2786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
2796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Inst.addOperand(MCOperand::CreateReg(getMemBase()));
2816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
28386924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
28472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
28572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
28672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isReg() const { return Kind == k_Register; }
28772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isImm() const { return Kind == k_Immediate; }
28872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isToken() const { return Kind == k_Token; }
28972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  bool isMem() const { return Kind == k_Memory; }
29072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
29172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
29272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
293ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
29472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
29572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
29672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  unsigned getReg() const {
29772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert((Kind == k_Register) && "Invalid access!");
298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Reg.RegNum;
299ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
300ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
301ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void setRegKind(RegisterKind RegKind) {
302ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
303ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Reg.Kind = RegKind;
304ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
305ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
306ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert((Kind == k_Immediate) && "Invalid access!");
308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
309ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
310ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  unsigned getMemBase() const {
3126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
3136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
3146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
3166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
3176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
3186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
3196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
321ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateToken(StringRef Str, SMLoc S) {
322ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Token);
323ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
324ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
325ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
326ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
327ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
328ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
329ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
330ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateReg(unsigned RegNum, SMLoc S, SMLoc E) {
331ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Register);
332ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Reg.RegNum = RegNum;
333ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
334ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
335ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
336ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
337ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
338ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  static MipsOperand *CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
339ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    MipsOperand *Op = new MipsOperand(k_Immediate);
340ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Imm.Val = Val;
341ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
342ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = E;
343ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
34472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
34572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
3466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  static MipsOperand *CreateMem(unsigned Base, const MCExpr *Off,
3476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                                 SMLoc S, SMLoc E) {
3486b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    MipsOperand *Op = new MipsOperand(k_Memory);
3496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Base = Base;
3506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
3516b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
3526b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
3536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
3546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
3556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
356ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCPURegsAsm() const {
357a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi    return Kind == k_Register && Reg.Kind == Kind_CPURegs;
358ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
359ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addCPURegsAsmOperands(MCInst &Inst, unsigned N) const {
360ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
361ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
362ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
363ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCPU64RegsAsm() const {
364a96a96cefaa3196bde76a7bda8e57c95893f723bNAKAMURA Takumi    return Kind == k_Register && Reg.Kind == Kind_CPU64Regs;
365ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
366ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addCPU64RegsAsmOperands(MCInst &Inst, unsigned N) const {
367ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
368ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
369ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
370ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isHWRegsAsm() const {
371ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
372ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_HWRegs;
373ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
374ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addHWRegsAsmOperands(MCInst &Inst, unsigned N) const {
375ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
376ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
377ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
378ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isHW64RegsAsm() const {
379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_HW64Regs;
381ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
382ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addHW64RegsAsmOperands(MCInst &Inst, unsigned N) const {
383ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
385ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
386ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  void addCCRAsmOperands(MCInst &Inst, unsigned N) const {
387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    Inst.addOperand(MCOperand::CreateReg(Reg.RegNum));
388ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool isCCRAsm() const {
391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    assert((Kind == k_Register) && "Invalid access!");
392ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return Reg.Kind == Kind_CCRRegs;
393ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
394ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
39686924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc getStartLoc() const {
39786924b4182537745659f2660244f3402c1e1ca4dJack Carter    return StartLoc;
39886924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
399ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
40086924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc getEndLoc() const {
40186924b4182537745659f2660244f3402c1e1ca4dJack Carter    return EndLoc;
40286924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
403ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
40472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  virtual void print(raw_ostream &OS) const {
40572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    llvm_unreachable("unimplemented!");
40672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
40786924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand
40886924b4182537745659f2660244f3402c1e1ca4dJack Carter}  // namespace
40972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
41025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm {
41125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[];
41225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
41325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
41425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return MipsInsts[Opcode];
41525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
41625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
41725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
4188afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
41925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
42025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Inst.setLoc(IDLoc);
42125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (MCID.mayLoad() || MCID.mayStore()) {
42225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // Check the offset of memory operand, if it is a symbol
42386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // reference or immediate we may have to expand instructions.
42486924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
42525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
42686924b4182537745659f2660244f3402c1e1ca4dJack Carter      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY)
42786924b4182537745659f2660244f3402c1e1ca4dJack Carter          || (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
42825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        MCOperand &Op = Inst.getOperand(i);
42925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        if (Op.isImm()) {
43025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          int MemOffset = Op.getImm();
43125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          if (MemOffset < -32768 || MemOffset > 32767) {
43286924b4182537745659f2660244f3402c1e1ca4dJack Carter            // Offset can't exceed 16bit value.
43386924b4182537745659f2660244f3402c1e1ca4dJack Carter            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
43425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            return false;
43525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
43625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        } else if (Op.isExpr()) {
43725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          const MCExpr *Expr = Op.getExpr();
43886924b4182537745659f2660244f3402c1e1ca4dJack Carter          if (Expr->getKind() == MCExpr::SymbolRef) {
43925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            const MCSymbolRefExpr *SR =
4408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                static_cast<const MCSymbolRefExpr*>(Expr);
44125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
44286924b4182537745659f2660244f3402c1e1ca4dJack Carter              // Expand symbol.
44386924b4182537745659f2660244f3402c1e1ca4dJack Carter              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
44425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              return false;
44525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            }
4468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter          } else if (!isEvaluated(Expr)) {
44786924b4182537745659f2660244f3402c1e1ca4dJack Carter            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
4488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter            return false;
44925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
45025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        }
45125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      }
45286924b4182537745659f2660244f3402c1e1ca4dJack Carter    } // for
45386924b4182537745659f2660244f3402c1e1ca4dJack Carter  } // if load/store
45425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
45525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (needsExpansion(Inst))
45625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    expandInstruction(Inst, IDLoc, Instructions);
45725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else
45825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    Instructions.push_back(Inst);
45925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
46025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return false;
46125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
46225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
4639d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) {
4649d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
46586924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
46686924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadImm32Reg:
46786924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Imm:
46886924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Reg:
46986924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true;
47086924b4182537745659f2660244f3402c1e1ca4dJack Carter  default:
47186924b4182537745659f2660244f3402c1e1ca4dJack Carter    return false;
4729d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
4739d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
4742490dc650895149423bb59538dc03ca352222702Jack Carter
4759d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
47686924b4182537745659f2660244f3402c1e1ca4dJack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
47786924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
47886924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadImm32Reg:
47986924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadImm(Inst, IDLoc, Instructions);
48086924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Imm:
48186924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadAddressImm(Inst, IDLoc, Instructions);
48286924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Reg:
48386924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadAddressReg(Inst, IDLoc, Instructions);
48486924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
4859d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
4862490dc650895149423bb59538dc03ca352222702Jack Carter
4879d577c861414c28967d77c2a1edf64b68efdeaeeJack Cartervoid MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
48886924b4182537745659f2660244f3402c1e1ca4dJack Carter                                  SmallVectorImpl<MCInst> &Instructions) {
4892490dc650895149423bb59538dc03ca352222702Jack Carter  MCInst tmpInst;
4909d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
4912f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
4929d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &RegOp = Inst.getOperand(0);
4939d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  assert(RegOp.isReg() && "expected register operand kind");
4949d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
4959d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  int ImmValue = ImmOp.getImm();
4962490dc650895149423bb59538dc03ca352222702Jack Carter  tmpInst.setLoc(IDLoc);
49786924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (0 <= ImmValue && ImmValue <= 65535) {
49886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For 0 <= j <= 65535.
4999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => ori d,$zero,j
500ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5012490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
50286924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
5032490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5049d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
50586924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else if (ImmValue < 0 && ImmValue >= -32768) {
50686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j < 0.
5079d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => addiu d,$zero,j
508ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5092490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
51086924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
5112490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5129d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5139d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  } else {
51486924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
5159d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => lui d,hi16(j)
5162f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //           ori d,d,lo16(j)
517ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5182490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5192490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5212490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.clear();
522ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5232490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5242490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5252490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
5262490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.setLoc(IDLoc);
5279d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
5289d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
5299d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
5302490dc650895149423bb59538dc03ca352222702Jack Carter
5312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
53286924b4182537745659f2660244f3402c1e1ca4dJack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
5332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
5342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(2);
5352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
5362f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &SrcRegOp = Inst.getOperand(1);
5372f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(SrcRegOp.isReg() && "expected register operand kind");
5382f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &DstRegOp = Inst.getOperand(0);
5392f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(DstRegOp.isReg() && "expected register operand kind");
5402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
54186924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (-32768 <= ImmValue && ImmValue <= 65535) {
54286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j <= 65535.
54386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j(s) => addiu d,s,j
544ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5452f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5462f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
5472f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5482f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5492f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
55086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
55186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j(s) => lui d,hi16(j)
55286924b4182537745659f2660244f3402c1e1ca4dJack Carter    //              ori d,d,lo16(j)
55386924b4182537745659f2660244f3402c1e1ca4dJack Carter    //              addu d,d,s
554ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5552f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5562f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5572f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
559ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5602f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5612f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5622f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
5632f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5642f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
5652f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDu);
5662f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5672f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
5682f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
5692f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5702f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
5712f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
5722f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
5732f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Cartervoid MipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
57486924b4182537745659f2660244f3402c1e1ca4dJack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
5752f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
5762f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
5772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
5782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &RegOp = Inst.getOperand(0);
5792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(RegOp.isReg() && "expected register operand kind");
5802f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
58186924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (-32768 <= ImmValue && ImmValue <= 65535) {
58286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j <= 65535.
58386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j => addiu d,$zero,j
5842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
5852f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
58686924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
5872f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
5882f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5892f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
59086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
59186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j => lui d,hi16(j)
59286924b4182537745659f2660244f3402c1e1ca4dJack Carter    //           ori d,d,lo16(j)
593ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
5942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
5952f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
5962f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
5972f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
598ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
5992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
6002f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
6012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
6022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
6032f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
6042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
6052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
60625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
60786924b4182537745659f2660244f3402c1e1ca4dJack Carter          SmallVectorImpl<MCInst> &Instructions, bool isLoad, bool isImmOpnd) {
60825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCSymbolRefExpr *SR;
60925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  MCInst TempInst;
61086924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned ImmOffset, HiOffset, LoOffset;
61125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCExpr *ExprOffset;
61225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned TmpRegNum;
61386924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned AtRegNum = getReg((isMips64()) ? Mips::CPU64RegsRegClassID
61486924b4182537745659f2660244f3402c1e1ca4dJack Carter                             : Mips::CPURegsRegClassID, getATReg());
61586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 1st operand is either the source or destination register.
61625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
61725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned RegOpNum = Inst.getOperand(0).getReg();
61886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 2nd operand is the base register.
61925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
62025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned BaseRegNum = Inst.getOperand(1).getReg();
62186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 3rd operand is either an immediate or expression.
62225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd) {
62325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
62425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ImmOffset = Inst.getOperand(2).getImm();
62525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    LoOffset = ImmOffset & 0x0000ffff;
62625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    HiOffset = (ImmOffset & 0xffff0000) >> 16;
62786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
62825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (LoOffset & 0x8000)
62925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      HiOffset++;
63086924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else
63125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ExprOffset = Inst.getOperand(2).getExpr();
63286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // All instructions will have the same location.
63325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setLoc(IDLoc);
63425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // 1st instruction in expansion is LUi. For load instruction we can use
63525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  // the dst register as a temporary if base and dst are different,
63686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // but for stores we must use $at.
63786924b4182537745659f2660244f3402c1e1ca4dJack Carter  TmpRegNum = (isLoad && (BaseRegNum != RegOpNum)) ? RegOpNum : AtRegNum;
63825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::LUi);
63925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
64025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
64125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
64225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
64325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
64425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      SR = static_cast<const MCSymbolRefExpr*>(ExprOffset);
64586924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
64686924b4182537745659f2660244f3402c1e1ca4dJack Carter          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
64786924b4182537745659f2660244f3402c1e1ca4dJack Carter          getContext());
64825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
6498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else {
65086924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
6518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
65225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
65325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
65486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the instruction to the list.
65525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
65686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Prepare TempInst for next instruction.
65725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
65886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add temp register to base.
65925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::ADDu);
66025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
66125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
66225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
66325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
66425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
6658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  // And finaly, create original instruction with low part
66686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // of offset and new base.
66725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Inst.getOpcode());
66825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
66925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
67025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
67125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
67225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
67325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
67486924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
67586924b4182537745659f2660244f3402c1e1ca4dJack Carter          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
67686924b4182537745659f2660244f3402c1e1ca4dJack Carter          getContext());
67725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
6788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else {
67986924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
6808afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
68125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
68225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
68325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
68425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
68525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
68625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
687fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
68884125ca43c758fd21fdab2b05196e0df57c55c96Chad RosierMatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
689fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                        SmallVectorImpl<MCParsedAsmOperand*> &Operands,
69084125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        MCStreamer &Out, unsigned &ErrorInfo,
69184125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                        bool MatchingInlineAsm) {
692ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
69325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  SmallVector<MCInst, 8> Instructions;
6946e006d3de882784527d4d9cc92b1a91f6773505eChad Rosier  unsigned MatchResult = MatchInstructionImpl(Operands, Inst, ErrorInfo,
69584125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier                                              MatchingInlineAsm);
696ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
697ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
69886924b4182537745659f2660244f3402c1e1ca4dJack Carter  default:
69986924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
700ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
70186924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (processInstruction(Inst, IDLoc, Instructions))
70225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      return true;
70386924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < Instructions.size(); i++)
70425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      Out.EmitInstruction(Instructions[i]);
705ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
706ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
707ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
708ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
709ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
710ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
711ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
712ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ErrorInfo != ~0U) {
713ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
714ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
715ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
71686924b4182537745659f2660244f3402c1e1ca4dJack Carter      ErrorLoc = ((MipsOperand*) Operands[ErrorInfo])->getStartLoc();
71786924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (ErrorLoc == SMLoc())
71886924b4182537745659f2660244f3402c1e1ca4dJack Carter        ErrorLoc = IDLoc;
719ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
720ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
721ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
722ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
723ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
724ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
725ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
726fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
727fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
728fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
72999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) {
730572e1bd109518f80b54d229de10699c4603944c3David Chisnall   int CC;
73199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
73299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (Name == "at")
73399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    return getATReg();
73499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
735572e1bd109518f80b54d229de10699c4603944c3David Chisnall    CC = StringSwitch<unsigned>(Name)
73699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("zero", 0)
73799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a0",   4)
73899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a1",   5)
73999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a2",   6)
74099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("a3",   7)
74199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("v0",   2)
74299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("v1",   3)
74399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s0",  16)
74499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s1",  17)
74599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s2",  18)
74699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s3",  19)
74799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s4",  20)
74899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s5",  21)
74999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s6",  22)
75099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("s7",  23)
75199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("k0",  26)
75299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("k1",  27)
75399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("sp",  29)
75499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("fp",  30)
75599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("gp",  28)
75699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("ra",  31)
75799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t0",   8)
75899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t1",   9)
75999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t2",  10)
76099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t3",  11)
76199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t4",  12)
76299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t5",  13)
76399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t6",  14)
76499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t7",  15)
76599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t8",  24)
76699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Case("t9",  25)
76799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    .Default(-1);
76899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
76986924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Although SGI documentation just cuts out t0-t3 for n32/n64,
77099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
77199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
77286924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (isMips64() && 8 <= CC && CC <= 11)
77399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    CC += 4;
77499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
77599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  if (CC == -1 && isMips64())
776572e1bd109518f80b54d229de10699c4603944c3David Chisnall    CC = StringSwitch<unsigned>(Name)
77799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a4",   8)
77899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a5",   9)
77999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a6",  10)
78099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("a7",  11)
78199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("kt0", 26)
78299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("kt1", 27)
78399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      .Case("s8",  30)
784572e1bd109518f80b54d229de10699c4603944c3David Chisnall      .Default(-1);
785572e1bd109518f80b54d229de10699c4603944c3David Chisnall
78699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return CC;
78799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter}
78886924b4182537745659f2660244f3402c1e1ca4dJack Carter
78999e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchRegisterName(StringRef Name, bool is64BitReg) {
79099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
791b8145e3881872fffbac15693c94536446f060330Jack Carter  if (Name.equals("fcc0"))
792b8145e3881872fffbac15693c94536446f060330Jack Carter    return Mips::FCC0;
793b8145e3881872fffbac15693c94536446f060330Jack Carter
79499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int CC;
79599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  CC = matchCPURegisterName(Name);
796572e1bd109518f80b54d229de10699c4603944c3David Chisnall  if (CC != -1)
79786924b4182537745659f2660244f3402c1e1ca4dJack Carter    return matchRegisterByNumber(CC, is64BitReg ? Mips::CPU64RegsRegClassID
79886924b4182537745659f2660244f3402c1e1ca4dJack Carter                                                : Mips::CPURegsRegClassID);
799ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
800f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
801f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
802f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
80386924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (NumString.getAsInteger(10, IntVal))
80486924b4182537745659f2660244f3402c1e1ca4dJack Carter      return -1; // This is not an integer.
805f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (IntVal > 31)
806f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
807f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
808f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormatTy Format = getFpFormat();
809f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
810f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_S || Format == FP_FORMAT_W)
811f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return getReg(Mips::FGR32RegClassID, IntVal);
812f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Format == FP_FORMAT_D) {
81386924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (isFP64()) {
814f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return getReg(Mips::FGR64RegClassID, IntVal);
815f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
81686924b4182537745659f2660244f3402c1e1ca4dJack Carter      // Only even numbers available as register pairs.
81786924b4182537745659f2660244f3402c1e1ca4dJack Carter      if ((IntVal > 31) || (IntVal % 2 != 0))
818f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        return -1;
81986924b4182537745659f2660244f3402c1e1ca4dJack Carter      return getReg(Mips::AFGR64RegClassID, IntVal / 2);
820f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
821f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
822f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
823ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
824ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
82586924b4182537745659f2660244f3402c1e1ca4dJack Carter
826f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setDefaultFpFormat() {
827f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
828f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (isMips64() || isFP64())
829f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_D;
830f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  else
831f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    FpFormat = FP_FORMAT_S;
832f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
833f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
834f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::requestsDoubleOperand(StringRef Mnemonic){
835f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
836f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  bool IsDouble = StringSwitch<bool>(Mnemonic.lower())
837f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldxc1", true)
838f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("ldc1",  true)
839f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdxc1", true)
840f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case("sdc1",  true)
841f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(false);
842f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
843f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return IsDouble;
844f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
84586924b4182537745659f2660244f3402c1e1ca4dJack Carter
846f740d6e328bd10904b079e1ce6583f436d6c9817Jack Cartervoid MipsAsmParser::setFpFormat(StringRef Format) {
847f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
848f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  FpFormat = StringSwitch<FpFormatTy>(Format.lower())
849f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".s",  FP_FORMAT_S)
850f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".d",  FP_FORMAT_D)
851f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".l",  FP_FORMAT_L)
852f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Case(".w",  FP_FORMAT_W)
853f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    .Default(FP_FORMAT_NONE);
854f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
855ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
85630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) {
85730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Reg > 31)
85830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
85930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
86030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  aTReg = Reg;
86130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
86230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
86330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
86499e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::getATReg() {
86599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return Options.getATRegNum();
86630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
86730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
86886924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) {
869ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return *(getContext().getRegisterInfo().getRegClass(RC).begin() + RegNo);
870ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
871ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
872ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
873ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
874ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNum > 31)
875ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return -1;
876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
877ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return getReg(RegClass, RegNum);
878ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
879ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
880ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::tryParseRegister(bool is64BitReg) {
881ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const AsmToken &Tok = Parser.getTok();
882ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNum = -1;
883ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (Tok.is(AsmToken::Identifier)) {
885ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    std::string lowerCase = Tok.getString().lower();
886ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    RegNum = matchRegisterName(lowerCase, is64BitReg);
887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  } else if (Tok.is(AsmToken::Integer))
8889d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    RegNum = matchRegisterByNumber(static_cast<unsigned>(Tok.getIntVal()),
88986924b4182537745659f2660244f3402c1e1ca4dJack Carter        is64BitReg ? Mips::CPU64RegsRegClassID : Mips::CPURegsRegClassID);
890ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return RegNum;
891ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
892ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
89386924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::tryParseRegisterOperand(
89486924b4182537745659f2660244f3402c1e1ca4dJack Carter             SmallVectorImpl<MCParsedAsmOperand*> &Operands, bool is64BitReg) {
895ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
896ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc S = Parser.getTok().getLoc();
897ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  int RegNo = -1;
898f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
899ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  RegNo = tryParseRegister(is64BitReg);
900ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (RegNo == -1)
901ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
902ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
903ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(MipsOperand::CreateReg(RegNo, S,
90486924b4182537745659f2660244f3402c1e1ca4dJack Carter                                            Parser.getTok().getLoc()));
905ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  Parser.Lex(); // Eat register token.
906ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
907ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
908ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
909ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseOperand(SmallVectorImpl<MCParsedAsmOperand*>&Operands,
910ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                 StringRef Mnemonic) {
9119d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // Check if the current operand has a custom associated parser, if so, try to
9129d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // custom parse the operand, or fallback to the general approach.
913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
914ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
915ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
916ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
917ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
918ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
919ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
920ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
921ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
922ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
923ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
924ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
925ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
926ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
92786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Parse the register.
928ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
929ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Parser.Lex(); // Eat dollar token.
93086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Parse the register operand.
931ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (!tryParseRegisterOperand(Operands, isMips64())) {
932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (getLexer().is(AsmToken::LParen)) {
93386924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Check if it is indexed addressing operand.
934ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken("(", S));
93586924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the parenthesis.
936ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (getLexer().isNot(AsmToken::Dollar))
937ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
938ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
93986924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the dollar
940ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter        if (tryParseRegisterOperand(Operands, isMips64()))
941ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
942ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
943ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        if (!getLexer().is(AsmToken::RParen))
944ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter          return true;
945ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
946ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        S = Parser.getTok().getLoc();
947ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Operands.push_back(MipsOperand::CreateToken(")", S));
948ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        Parser.Lex();
949ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
950ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
951ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
95286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Maybe it is a symbol reference.
953ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
954cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (Parser.parseIdentifier(Identifier))
955ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
956ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
957ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
958ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
95938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
960ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
96186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Otherwise create a symbol reference.
9626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Res = MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None,
963ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                                getContext());
964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
965ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(Res, S, E));
966ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
967ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
968ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Identifier:
969c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    // Look for the existing symbol, we should check if
97086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // we need to assigne the propper RegisterKind.
97186924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (searchSymbolAlias(Operands, MipsOperand::Kind_None))
97286924b4182537745659f2660244f3402c1e1ca4dJack Carter      return false;
97386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Else drop to expression parsing.
974ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
975ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
976ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
977ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
978ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
97986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Quoted label names.
980ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *IdVal;
981ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
982cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (getParser().parseExpression(IdVal))
983ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
984ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
985ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
986ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
987ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
9886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
98986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is a symbol reference or constant expression.
9906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
99186924b4182537745659f2660244f3402c1e1ca4dJack Carter    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
992ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (parseRelocOperand(IdVal))
9936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
9946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
995ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
996ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
9976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
9986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
99930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // case AsmToken::Percent
100030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // switch(getLexer().getKind())
1001fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1002fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1003fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
10048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterconst MCExpr* MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
10058afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                               StringRef RelocStr) {
10068afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const MCExpr *Res;
100786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Check the type of the expression.
10088afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
100986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It's a constant, evaluate lo or hi value.
10108afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (RelocStr == "lo") {
10118afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      short Val = MCE->getValue();
10128afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Res = MCConstantExpr::Create(Val, getContext());
10138afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else if (RelocStr == "hi") {
10148afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      int Val = MCE->getValue();
10158afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      int LoSign = Val & 0x8000;
10168afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Val = (Val & 0xffff0000) >> 16;
10178afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      // Lower part is treated as a signed int, so if it is negative
101886924b4182537745659f2660244f3402c1e1ca4dJack Carter      // we must add 1 to the hi part to compensate.
10198afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (LoSign)
10208afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        Val++;
10218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Res = MCConstantExpr::Create(Val, getContext());
1022ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov    } else {
1023ce47d5ba8cf7e30cbf0d6b80d3f7d10916c7fe31Evgeniy Stepanov      llvm_unreachable("Invalid RelocStr value");
10248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
102586924b4182537745659f2660244f3402c1e1ca4dJack Carter    return Res;
10268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
102986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It's a symbol, create a symbolic expression from the symbol.
10308afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    StringRef Symbol = MSRE->getSymbol().getName();
10318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
103286924b4182537745659f2660244f3402c1e1ca4dJack Carter    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
10338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return Res;
10348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
103786924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
103886924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
10398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
10408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return Res;
10418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
104486924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
104586924b4182537745659f2660244f3402c1e1ca4dJack Carter    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
104686924b4182537745659f2660244f3402c1e1ca4dJack Carter    return Res;
10478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
104886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Just return the original expression.
10498afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Expr;
10508afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
10518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10528afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
10538afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
10548afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  switch (Expr->getKind()) {
10558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Constant:
10568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return true;
10578afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::SymbolRef:
10588afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
10598afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Binary:
10608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
10618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (!isEvaluated(BE->getLHS()))
10628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return false;
10638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return isEvaluated(BE->getRHS());
10648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
10658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Unary:
10668afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
10678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  default:
10688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return false;
10698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
10708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
10718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
10726b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
107386924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
107486924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the % token.
107586924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
10766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
10776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
10786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
107938539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  std::string Str = Tok.getIdentifier().str();
10806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
108186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the identifier.
108286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Now make an expression from the rest of the operand.
10836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
1084ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc EndLoc;
10856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
10866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
10876b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
108886924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the '(' token.
10896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
109086924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the % token.
10916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
10926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
10936b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
109438539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
109538539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
109686924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the identifier.
10976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
10986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
10996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
11006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
11016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
110286924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (getParser().parseParenExpression(IdVal, EndLoc))
11036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
11046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1105ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    while (getLexer().getKind() == AsmToken::RParen)
110686924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the ')' token.
11076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
110986924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true; // Parenthesis must follow the relocation operand.
11106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
111186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Res = evaluateRelocExpr(IdVal, Str);
11128afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
11136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
11146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1115ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1116ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
1117ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  StartLoc = Parser.getTok().getLoc();
1118ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  RegNo = tryParseRegister(isMips64());
1119ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  EndLoc = Parser.getTok().getLoc();
112086924b4182537745659f2660244f3402c1e1ca4dJack Carter  return (RegNo == (unsigned) -1);
1121ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1122ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
11238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1124ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
11258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool Result = true;
11268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
11278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  while (getLexer().getKind() == AsmToken::LParen)
11288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
1129ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
113086924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (getLexer().getKind()) {
11316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
11326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
113325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  case AsmToken::Identifier:
11348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case AsmToken::LParen:
11356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
11366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
11376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
11388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (isParenExpr)
113986924b4182537745659f2660244f3402c1e1ca4dJack Carter      Result = getParser().parseParenExpression(Res, S);
11408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else
11418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Result = (getParser().parseExpression(Res));
114286924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().getKind() == AsmToken::RParen)
11438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Parser.Lex();
114486924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
1145ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  case AsmToken::Percent:
11468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Result = parseRelocOperand(Res);
11476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
11488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Result;
11496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
11506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1151ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack CarterMipsAsmParser::OperandMatchResultTy MipsAsmParser::parseMemOperand(
115286924b4182537745659f2660244f3402c1e1ca4dJack Carter                               SmallVectorImpl<MCParsedAsmOperand*>&Operands) {
11536b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal = 0;
1155ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
11568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isParenExpr = false;
115786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // First operand is the offset.
1158ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  S = Parser.getTok().getLoc();
11596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() == AsmToken::LParen) {
11618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
11628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    isParenExpr = true;
11638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
11646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() != AsmToken::Dollar) {
116686924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (parseMemOffset(IdVal, isParenExpr))
11678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
11688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
116986924b4182537745659f2660244f3402c1e1ca4dJack Carter    const AsmToken &Tok = Parser.getTok(); // Get the next token.
11708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (Tok.isNot(AsmToken::LParen)) {
11718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      MipsOperand *Mnemonic = static_cast<MipsOperand*>(Operands[0]);
11728afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (Mnemonic->getToken() == "la") {
11738afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        SMLoc E = SMLoc::getFromPointer(
117486924b4182537745659f2660244f3402c1e1ca4dJack Carter            Parser.getTok().getLoc().getPointer() - 1);
11758afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E));
11768afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
11778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
11788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (Tok.is(AsmToken::EndOfStatement)) {
11798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        SMLoc E = SMLoc::getFromPointer(
118086924b4182537745659f2660244f3402c1e1ca4dJack Carter            Parser.getTok().getLoc().getPointer() - 1);
11818afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
118286924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Zero register assumed, add a memory operand with ZERO as its base.
118386924b4182537745659f2660244f3402c1e1ca4dJack Carter        Operands.push_back(MipsOperand::CreateMem(isMips64() ? Mips::ZERO_64
118486924b4182537745659f2660244f3402c1e1ca4dJack Carter                                                             : Mips::ZERO,
118586924b4182537745659f2660244f3402c1e1ca4dJack Carter                           IdVal, S, E));
11868afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
11878afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
11888afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Error(Parser.getTok().getLoc(), "'(' expected");
11898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
11902f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    }
11916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
119286924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '(' token.
11938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
11946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11958afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const AsmToken &Tok1 = Parser.getTok(); // Get next token
11966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok1.is(AsmToken::Dollar)) {
119786924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '$' token.
1198ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (tryParseRegisterOperand(Operands, isMips64())) {
11996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      Error(Parser.getTok().getLoc(), "unexpected token in operand");
12006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return MatchOperand_ParseFail;
12016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
12026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
12036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else {
120430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
12056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
12066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
12076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
120886924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok2 = Parser.getTok(); // Get next token.
12096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok2.isNot(AsmToken::RParen)) {
12106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
12116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
12126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
12136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1214ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1215ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
121686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the ')' token.
12176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
12186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (IdVal == 0)
12196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    IdVal = MCConstantExpr::Create(0, getContext());
12206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
122186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Replace the register operand with the memory operand.
12226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
12236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  int RegNo = op->getReg();
122486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Remove the register from the operands.
12256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
122686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the memory operand.
12278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
12288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    int64_t Imm;
12298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (IdVal->EvaluateAsAbsolute(Imm))
12308afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      IdVal = MCConstantExpr::Create(Imm, getContext());
12318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
12328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
12338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                   getContext());
12348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
12358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
12366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.push_back(MipsOperand::CreateMem(RegNo, IdVal, S, E));
12376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  delete op;
1238ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
1239ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1240ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1241ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1242ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPU64Regs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1243ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1244ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (!isMips64())
1245ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1246c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().getKind() == AsmToken::Identifier) {
124786924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (searchSymbolAlias(Operands, MipsOperand::Kind_CPU64Regs))
1248c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return MatchOperand_Success;
1249c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return MatchOperand_NoMatch;
1250c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
125186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$', we have an error.
1252ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1253ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1254ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1255ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
125686924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (!tryParseRegisterOperand(Operands, true)) {
125786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Set the proper register kind.
1258ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1259ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    op->setRegKind(MipsOperand::Kind_CPU64Regs);
1260ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
1261ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
1262ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_NoMatch;
1263ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1264ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
126586924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::searchSymbolAlias(
126686924b4182537745659f2660244f3402c1e1ca4dJack Carter    SmallVectorImpl<MCParsedAsmOperand*> &Operands, unsigned RegisterKind) {
1267c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1268c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
1269c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Sym) {
1270c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    SMLoc S = Parser.getTok().getLoc();
1271c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    const MCExpr *Expr;
1272c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (Sym->isVariable())
1273c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Expr = Sym->getVariableValue();
1274c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    else
1275c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return false;
1276c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    if (Expr->getKind() == MCExpr::SymbolRef) {
1277c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr*>(Expr);
1278c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const StringRef DefSymbol = Ref->getSymbol().getName();
1279c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      if (DefSymbol.startswith("$")) {
128086924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Lookup for the register with the corresponding name.
128186924b4182537745659f2660244f3402c1e1ca4dJack Carter        int RegNum = matchRegisterName(DefSymbol.substr(1), isMips64());
1282c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        if (RegNum > -1) {
1283c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          Parser.Lex();
128486924b4182537745659f2660244f3402c1e1ca4dJack Carter          MipsOperand *op = MipsOperand::CreateReg(RegNum, S,
128586924b4182537745659f2660244f3402c1e1ca4dJack Carter                                                   Parser.getTok().getLoc());
128686924b4182537745659f2660244f3402c1e1ca4dJack Carter          op->setRegKind((MipsOperand::RegisterKind) RegisterKind);
1287c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          Operands.push_back(op);
1288c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter          return true;
1289c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter        }
1290c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      }
1291c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    } else if (Expr->getKind() == MCExpr::Constant) {
1292c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Parser.Lex();
1293c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      const MCConstantExpr *Const = static_cast<const MCConstantExpr*>(Expr);
129486924b4182537745659f2660244f3402c1e1ca4dJack Carter      MipsOperand *op = MipsOperand::CreateImm(Const, S,
129586924b4182537745659f2660244f3402c1e1ca4dJack Carter          Parser.getTok().getLoc());
1296c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      Operands.push_back(op);
1297c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return true;
1298c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    }
1299c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
1300c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
1301c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
130286924b4182537745659f2660244f3402c1e1ca4dJack Carter
1303ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1304ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCPURegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1305ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1306c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().getKind() == AsmToken::Identifier) {
130786924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (searchSymbolAlias(Operands, MipsOperand::Kind_CPURegs))
1308c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter      return MatchOperand_Success;
1309c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return MatchOperand_NoMatch;
1310c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
131186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have an error.
1312ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1313ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1314ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1315ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
131686924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (!tryParseRegisterOperand(Operands, false)) {
131786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Set the proper register kind.
1318ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    MipsOperand* op = static_cast<MipsOperand*>(Operands.back());
1319ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    op->setRegKind(MipsOperand::Kind_CPURegs);
1320ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
1321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
1322ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_NoMatch;
1323ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1324ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1325ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1326ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseHWRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1327ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1328c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  if (isMips64())
1329c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter    return MatchOperand_NoMatch;
1330c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter
133186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have error.
1332ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1333ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1334ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
133586924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the '$'.
1336ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
133786924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1338ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.isNot(AsmToken::Integer))
1339ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1340ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1341ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum = Tok.getIntVal();
134286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // At the moment only hwreg29 is supported.
1343ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (RegNum != 29)
1344ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_ParseFail;
1345ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1346ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29, S,
134786924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.getTok().getLoc());
1348ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  op->setRegKind(MipsOperand::Kind_HWRegs);
1349ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1350ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
135186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the register number.
1352ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1353ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1354ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1355ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
135686924b4182537745659f2660244f3402c1e1ca4dJack CarterMipsAsmParser::parseHW64Regs(
135786924b4182537745659f2660244f3402c1e1ca4dJack Carter    SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1358c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter
1359c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  if (!isMips64())
1360c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter    return MatchOperand_NoMatch;
136186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have an error.
1362ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1363ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1364ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
1365ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Parser.Lex(); // Eat $
1366ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
136786924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get the next token.
1368ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.isNot(AsmToken::Integer))
1369ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1370ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1371ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum = Tok.getIntVal();
137286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // At the moment only hwreg29 is supported.
1373ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (RegNum != 29)
1374ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_ParseFail;
1375ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1376ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::HWR29_64, S,
137786924b4182537745659f2660244f3402c1e1ca4dJack Carter                                           Parser.getTok().getLoc());
1378c147b678206db510336ee95c3b55dc9c0ff19595Jack Carter  op->setRegKind(MipsOperand::Kind_HW64Regs);
1379ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1380ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
138186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the register number.
1382ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1383ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1384ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1385ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1386ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::parseCCRRegs(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
1387ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  unsigned RegNum;
138886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If the first token is not '$' we have an error.
1389ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Parser.getTok().isNot(AsmToken::Dollar))
1390ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1391ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S = Parser.getTok().getLoc();
139286924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the '$'
1393ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
139486924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get next token.
1395ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  if (Tok.is(AsmToken::Integer)) {
1396ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    RegNum = Tok.getIntVal();
139786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // At the moment only fcc0 is supported.
1398ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (RegNum != 0)
1399ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter      return MatchOperand_ParseFail;
1400ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  } else if (Tok.is(AsmToken::Identifier)) {
140186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // At the moment only fcc0 is supported.
1402ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (Tok.getIdentifier() != "fcc0")
1403ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter      return MatchOperand_ParseFail;
1404ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  } else
1405ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_NoMatch;
1406ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1407ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  MipsOperand *op = MipsOperand::CreateReg(Mips::FCC0, S,
140886924b4182537745659f2660244f3402c1e1ca4dJack Carter                                           Parser.getTok().getLoc());
1409ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  op->setRegKind(MipsOperand::Kind_CCRRegs);
1410ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  Operands.push_back(op);
1411ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
141286924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the register number.
1413ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return MatchOperand_Success;
1414ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
1415ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
14166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
14176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
14186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind VK
14196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter                   = StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
14206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi",          MCSymbolRefExpr::VK_Mips_ABS_HI)
14216b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo",          MCSymbolRefExpr::VK_Mips_ABS_LO)
14226b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gp_rel",      MCSymbolRefExpr::VK_Mips_GPREL)
14236b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("call16",      MCSymbolRefExpr::VK_Mips_GOT_CALL)
14246b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got",         MCSymbolRefExpr::VK_Mips_GOT)
14256b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsgd",       MCSymbolRefExpr::VK_Mips_TLSGD)
14266b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tlsldm",      MCSymbolRefExpr::VK_Mips_TLSLDM)
14276b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_hi",   MCSymbolRefExpr::VK_Mips_DTPREL_HI)
14286b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("dtprel_lo",   MCSymbolRefExpr::VK_Mips_DTPREL_LO)
14296b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("gottprel",    MCSymbolRefExpr::VK_Mips_GOTTPREL)
14306b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_hi",    MCSymbolRefExpr::VK_Mips_TPREL_HI)
14316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("tprel_lo",    MCSymbolRefExpr::VK_Mips_TPREL_LO)
14326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_disp",    MCSymbolRefExpr::VK_Mips_GOT_DISP)
14336b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_page",    MCSymbolRefExpr::VK_Mips_GOT_PAGE)
14346b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("got_ofst",    MCSymbolRefExpr::VK_Mips_GOT_OFST)
14356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("hi(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_HI)
14366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Case("lo(%neg(%gp_rel",    MCSymbolRefExpr::VK_Mips_GPOFF_LO)
14376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    .Default(MCSymbolRefExpr::VK_None);
14386b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
14396b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return VK;
14406b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
14416b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
14421ac4587eb32e639576973b793d465c5d9577bef7Benjamin Kramerstatic int ConvertCcString(StringRef CondString) {
1443f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  int CC = StringSwitch<unsigned>(CondString)
144486924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".f",    0)
144586924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".un",   1)
144686924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".eq",   2)
144786924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ueq",  3)
144886924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".olt",  4)
144986924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ult",  5)
145086924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ole",  6)
145186924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ule",  7)
145286924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".sf",   8)
145386924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ngle", 9)
145486924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".seq",  10)
145586924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ngl",  11)
145686924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".lt",   12)
145786924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".nge",  13)
145886924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".le",   14)
145986924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Case(".ngt",  15)
146086924b4182537745659f2660244f3402c1e1ca4dJack Carter    .Default(-1);
1461f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1462f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return CC;
1463f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
1464f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1465f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carterbool MipsAsmParser::
1466f740d6e328bd10904b079e1ce6583f436d6c9817Jack CarterparseMathOperation(StringRef Name, SMLoc NameLoc,
146730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter                   SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
146886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Split the format.
1469f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  size_t Start = Name.find('.'), Next = Name.rfind('.');
1470f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format1 = Name.slice(Start, Next);
147186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the first format to the operands.
1472f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format1, NameLoc));
147386924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Now for the second format.
1474f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  StringRef Format2 = Name.slice(Next, StringRef::npos);
1475f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  Operands.push_back(MipsOperand::CreateToken(Format2, NameLoc));
1476f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
147786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Set the format for the first register.
1478f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  setFpFormat(Format1);
1479f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1480f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  // Read the remaining operands.
1481f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1482f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Read the first operand.
1483f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
1484f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
1485cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1486f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
1487f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1488f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1489f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (getLexer().isNot(AsmToken::Comma)) {
1490f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
1491cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1492f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
1493f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
149486924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the comma.
1495f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
14968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    // Set the format for the first register
1497f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(Format2);
1498f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1499f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Parse and remember the operand.
1500f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (ParseOperand(Operands, Name)) {
1501f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      SMLoc Loc = getLexer().getLoc();
1502cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1503f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return Error(Loc, "unexpected token in argument list");
1504f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1505f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1506f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1507f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1508f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    SMLoc Loc = getLexer().getLoc();
1509cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1510f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    return Error(Loc, "unexpected token in argument list");
1511f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1512f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
151386924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
1514f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  return false;
1515f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter}
1516f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1517fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolabool MipsAsmParser::
15186a020a71173a3ea7738a9df69982e85ddbfe0303Chad RosierParseInstruction(ParseInstructionInfo &Info, StringRef Name, SMLoc NameLoc,
1519fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola                 SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
152099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  StringRef Mnemonic;
152186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Floating point instructions: Should the register be treated as a double?
1522f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (requestsDoubleOperand(Name)) {
1523f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setFpFormat(FP_FORMAT_D);
152486924b4182537745659f2660244f3402c1e1ca4dJack Carter    Operands.push_back(MipsOperand::CreateToken(Name, NameLoc));
152586924b4182537745659f2660244f3402c1e1ca4dJack Carter    Mnemonic = Name;
152686924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else {
1527f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    setDefaultFpFormat();
1528f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    // Create the leading tokens for the mnemonic, split by '.' characters.
1529f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    size_t Start = 0, Next = Name.find('.');
153099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    Mnemonic = Name.slice(Start, Next);
1531f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1532f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    Operands.push_back(MipsOperand::CreateToken(Mnemonic, NameLoc));
1533f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1534f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    if (Next != StringRef::npos) {
153586924b4182537745659f2660244f3402c1e1ca4dJack Carter      // There is a format token in mnemonic.
153686924b4182537745659f2660244f3402c1e1ca4dJack Carter      size_t Dot = Name.find('.', Next + 1);
1537f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      StringRef Format = Name.slice(Next, Dot);
153886924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (Dot == StringRef::npos) // Only one '.' in a string, it's a format.
1539f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1540f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      else {
154186924b4182537745659f2660244f3402c1e1ca4dJack Carter        if (Name.startswith("c.")) {
154286924b4182537745659f2660244f3402c1e1ca4dJack Carter          // Floating point compare, add '.' and immediate represent for cc.
1543f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          Operands.push_back(MipsOperand::CreateToken(".", NameLoc));
1544f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          int Cc = ConvertCcString(Format);
1545f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          if (Cc == -1) {
1546f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter            return Error(NameLoc, "Invalid conditional code");
1547f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          }
1548ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter          SMLoc E = SMLoc::getFromPointer(
154986924b4182537745659f2660244f3402c1e1ca4dJack Carter              Parser.getTok().getLoc().getPointer() - 1);
155086924b4182537745659f2660244f3402c1e1ca4dJack Carter          Operands.push_back(
155186924b4182537745659f2660244f3402c1e1ca4dJack Carter              MipsOperand::CreateImm(MCConstantExpr::Create(Cc, getContext()),
155286924b4182537745659f2660244f3402c1e1ca4dJack Carter                                     NameLoc, E));
1553f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        } else {
155430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter          // trunc, ceil, floor ...
1555f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter          return parseMathOperation(Name, NameLoc, Operands);
1556f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        }
1557f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
155886924b4182537745659f2660244f3402c1e1ca4dJack Carter        // The rest is a format.
1559f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Format = Name.slice(Dot, StringRef::npos);
1560f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter        Operands.push_back(MipsOperand::CreateToken(Format, NameLoc));
1561f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      }
1562f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1563f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      setFpFormat(Format);
1564f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    }
1565f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1566ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1567ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
1568ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1569ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
157099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (ParseOperand(Operands, Mnemonic)) {
1571ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
1572cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
1573ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
1574ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1575ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
157686924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().is(AsmToken::Comma)) {
157786924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the comma.
1578ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1579ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
1580ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ParseOperand(Operands, Name)) {
1581ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
1582cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
1583ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
1584ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
1585ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1586ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1587ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1588ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1589ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
1590cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1591ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
1592ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1593ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
159486924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
1595ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
1596fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1597fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
159830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::reportParseError(StringRef ErrorMsg) {
159986924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc Loc = getLexer().getLoc();
160086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.eatToEndOfStatement();
160186924b4182537745659f2660244f3402c1e1ca4dJack Carter  return Error(Loc, ErrorMsg);
160230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
160330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
160430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() {
160586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line should look like: ".set noat".
160686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // set at reg to 0.
160710d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setATReg(0);
160830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // eat noat
160930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
161086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
161130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
161230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
161330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
161430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
161586924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
161630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
161730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
161886924b4182537745659f2660244f3402c1e1ca4dJack Carter
161930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() {
162086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line can be .set at - defaults to $1
162130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // or .set at=$reg
162299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int AtRegNo;
162330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  getParser().Lex();
162430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().is(AsmToken::EndOfStatement)) {
162510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter    Options.setATReg(1);
162686924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
162730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
162830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (getLexer().is(AsmToken::Equal)) {
162986924b4182537745659f2660244f3402c1e1ca4dJack Carter    getParser().Lex(); // Eat the '='.
163030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::Dollar)) {
163130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
163230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
163330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
163486924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '$'.
163599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    const AsmToken &Reg = Parser.getTok();
163699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (Reg.is(AsmToken::Identifier)) {
163799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
163899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else if (Reg.is(AsmToken::Integer)) {
163999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = Reg.getIntVal();
164099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else {
164130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
164230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
164330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
164499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
164586924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (AtRegNo < 1 || AtRegNo > 31) {
164699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      reportParseError("unexpected token in statement");
164799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      return false;
164899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    }
164999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
165099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (!Options.setATReg(AtRegNo)) {
165130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
165230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
165330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
165486924b4182537745659f2660244f3402c1e1ca4dJack Carter    getParser().Lex(); // Eat the register.
165530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
165630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
165730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
165830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
165986924b4182537745659f2660244f3402c1e1ca4dJack Carter    }
166086924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
166130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
166230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else {
166330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
166430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
166530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
166630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
166730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
166830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() {
166930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
167086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
167130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
167230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
167330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
167430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
167510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setReorder();
167686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
167730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
167830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
167930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
168030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() {
168186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex();
168286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
168386924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
168486924b4182537745659f2660244f3402c1e1ca4dJack Carter    reportParseError("unexpected token in statement");
168530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
168686924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
168786924b4182537745659f2660244f3402c1e1ca4dJack Carter  Options.setNoreorder();
168886924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
168986924b4182537745659f2660244f3402c1e1ca4dJack Carter  return false;
169030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
169130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
169230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() {
169330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
169486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
169530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
169630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
169730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
169830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
169910d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setMacro();
170086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
170130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
170230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
170330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
170430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() {
170530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
170686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
170730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
170830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
170930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
171030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
171110d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  if (Options.isReorder()) {
171230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
171330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
171430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
171510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setNomacro();
171686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
171730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
171830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
1719c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1720c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() {
1721c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  StringRef Name;
1722c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  const MCExpr *Value;
1723c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1724c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseIdentifier(Name))
1725c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected identifier after .set");
1726c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1727c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().isNot(AsmToken::Comma))
1728c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("unexpected token in .set directive");
17298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  Lex(); // Eat comma
1730c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1731c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseExpression(Value))
1732c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected valid expression after comma");
1733c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
173486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Check if the Name already exists as a symbol.
1735c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Name);
173686924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (Sym)
1737c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("symbol already defined");
1738c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym = getContext().GetOrCreateSymbol(Name);
1739c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym->setVariableValue(Value);
1740c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
1741c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
1742c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
174386924b4182537745659f2660244f3402c1e1ca4dJack Carter
174430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() {
174530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
174686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Get the next token.
174730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok();
174830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
174930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Tok.getString() == "noat") {
175030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoAtDirective();
175130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "at") {
175230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetAtDirective();
175330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "reorder") {
175430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetReorderDirective();
175530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "noreorder") {
175630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoReorderDirective();
175730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "macro") {
175830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetMacroDirective();
175930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomacro") {
176030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoMacroDirective();
176130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomips16") {
176286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1763cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
176430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
176530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomicromips") {
176686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1767cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
176830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
1769c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  } else {
177086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is just an identifier, look for an assignment.
1771c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    parseSetAssignment();
1772c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return false;
177330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
1774801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
177530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
177630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
177730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1778801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter/// parseDirectiveWord
1779801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter///  ::= .word [ expression (, expression)* ]
1780801c5838830d190a6b0d8e462bd43805f66ba50fJack Carterbool MipsAsmParser::parseDirectiveWord(unsigned Size, SMLoc L) {
1781801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
1782801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    for (;;) {
1783801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      const MCExpr *Value;
1784cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
1785801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return true;
1786801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1787801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      getParser().getStreamer().EmitValue(Value, Size);
1788801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1789801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().is(AsmToken::EndOfStatement))
1790801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        break;
1791801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1792801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      // FIXME: Improve diagnostic.
1793801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().isNot(AsmToken::Comma))
1794801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return Error(L, "unexpected token in directive");
1795801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      Parser.Lex();
1796801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    }
1797801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
1798801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1799801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  Parser.Lex();
1800801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  return false;
1801801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter}
1802801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
180330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
1804acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1805801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  StringRef IDVal = DirectiveID.getString();
1806801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
180786924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (IDVal == ".ent") {
180886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1809acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1810acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1811acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1812acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1813801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".end") {
181486924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1815acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
1816acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1817acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1818acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1819801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".frame") {
182086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1821cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1822acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1823acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1824acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1825801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".set") {
182630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseDirectiveSet();
1827acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1828acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1829801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".fmask") {
183086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1831cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1832acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1833acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1834acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1835801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".mask") {
183686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1837cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1838acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1839acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1840acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1841801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".gpword") {
184286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
1843cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
1844acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
1845acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
1846acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
1847801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".word") {
1848801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    parseDirectiveWord(4, DirectiveID.getLoc());
1849801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    return false;
1850801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
1851801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1852fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1853fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1854fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
1855fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
1856fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
1857fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
1858fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
1859fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
1860fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1861ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1862ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
1863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
1864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
1865