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
1036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/MipsMCExpr.h"
11fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h"
12ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h"
13320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "MipsTargetStreamer.h"
1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/APInt.h"
15ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/ADT/StringSwitch.h"
16ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h"
17ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h"
18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h"
1936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCInstBuilder.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h"
21d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
22ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h"
23ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h"
24ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h"
2572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "llvm/MC/MCTargetAsmParser.h"
2636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Debug.h"
2736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MathExtras.h"
28ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/Support/TargetRegistry.h"
29fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
30fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm;
31fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mips-asm-parser"
33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
34715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Goulynamespace llvm {
35715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Goulyclass MCInstrInfo;
36715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly}
37715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly
38fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace {
3930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions {
4030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic:
412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  MipsAssemblerOptions() : aTReg(1), reorder(true), macro(true) {}
4230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
432263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  unsigned getATRegNum() { return aTReg; }
4430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool setATReg(unsigned Reg);
45ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  bool isReorder() { return reorder; }
472263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  void setReorder() { reorder = true; }
482263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  void setNoreorder() { reorder = false; }
4930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
502263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  bool isMacro() { return macro; }
512263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  void setMacro() { macro = true; }
522263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  void setNomacro() { macro = false; }
5330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
5430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate:
5530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  unsigned aTReg;
5630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool reorder;
5730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool macro;
5830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter};
5930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
6030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
6130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace {
62fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser {
63320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  MipsTargetStreamer &getTargetStreamer() {
6436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCTargetStreamer &TS = *Parser.getStreamer().getTargetStreamer();
65320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    return static_cast<MipsTargetStreamer &>(TS);
66320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  }
67320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
68ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCSubtargetInfo &STI;
69ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &Parser;
7010d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  MipsAssemblerOptions Options;
7130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
7272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER
7372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc"
7472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
75cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
76cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
7784125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
78cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                               OperandVector &Operands, MCStreamer &Out,
79cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                               unsigned &ErrorInfo,
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               bool MatchingInlineAsm) override;
81fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Parse a register as used in CFI directives
83dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
84fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
85cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool ParseParenSuffix(StringRef Name, OperandVector &Operands);
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool ParseBracketSuffix(StringRef Name, OperandVector &Operands);
8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
89cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
90cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                        SMLoc NameLoc, OperandVector &Operands) override;
91fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseDirective(AsmToken DirectiveID) override;
93fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsAsmParser::OperandMatchResultTy parseMemOperand(OperandVector &Operands);
9542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
9642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  MipsAsmParser::OperandMatchResultTy
97cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
98cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                    StringRef Identifier, SMLoc S);
9942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
10042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  MipsAsmParser::OperandMatchResultTy
101cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S);
10242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
103cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsAsmParser::OperandMatchResultTy ParseAnyRegister(OperandVector &Operands);
10442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsAsmParser::OperandMatchResultTy ParseImm(OperandVector &Operands);
106006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsAsmParser::OperandMatchResultTy ParseJumpTarget(OperandVector &Operands);
108d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic
109cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsAsmParser::OperandMatchResultTy parseInvNum(OperandVector &Operands);
11095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
111cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsAsmParser::OperandMatchResultTy ParseLSAImm(OperandVector &Operands);
112c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
113cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool searchSymbolAlias(OperandVector &Operands);
114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool ParseOperand(OperandVector &, StringRef Mnemonic);
116ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1179d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  bool needsExpansion(MCInst &Inst);
1189d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Expands assembly pseudo instructions.
120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Returns false on success, true otherwise.
121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool expandInstruction(MCInst &Inst, SMLoc IDLoc,
1222490dc650895149423bb59538dc03ca352222702Jack Carter                         SmallVectorImpl<MCInst> &Instructions);
123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool expandLoadImm(MCInst &Inst, SMLoc IDLoc,
1252490dc650895149423bb59538dc03ca352222702Jack Carter                     SmallVectorImpl<MCInst> &Instructions);
126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
1282f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
1312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter                            SmallVectorImpl<MCInst> &Instructions);
132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
13325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  void expandMemInst(MCInst &Inst, SMLoc IDLoc,
1342263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                     SmallVectorImpl<MCInst> &Instructions, bool isLoad,
1352263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                     bool isImmOpnd);
136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool reportParseError(Twine ErrorMsg);
137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
13830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
140ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool parseRelocOperand(const MCExpr *&Res);
14130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1422263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
1438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
1448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isEvaluated(const MCExpr *Expr);
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseSetFeature(uint64_t Feature);
146dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseDirectiveCPLoad(SMLoc Loc);
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveCPSetup();
148dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseDirectiveNaN();
14930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseDirectiveSet();
15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveOption();
15130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
15230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetAtDirective();
15330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoAtDirective();
15430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetMacroDirective();
15530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoMacroDirective();
15630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetReorderDirective();
15730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoReorderDirective();
15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseSetNoMips16Directive();
159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseSetFpDirective();
16030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
161c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool parseSetAssignment();
162c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDataDirective(unsigned Size, SMLoc L);
1642263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  bool parseDirectiveGpWord();
16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveGpDWord();
166cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseDirectiveModule();
167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseDirectiveModuleFP();
168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                       StringRef Directive);
170801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
1716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  MCSymbolRefExpr::VariantKind getVariantKind(StringRef Symbol);
172f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
17336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool eatComma(StringRef ErrorStr);
174ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
17599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int matchCPURegisterName(StringRef Symbol);
17699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
177ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  int matchRegisterByNumber(unsigned RegNum, unsigned RegClass);
178ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
179bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  int matchFPURegisterName(StringRef Name);
1807231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
181bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  int matchFCCRegisterName(StringRef Name);
182f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
183bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  int matchACRegisterName(StringRef Name);
184f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
18542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  int matchMSA128RegisterName(StringRef Name);
18642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
187006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  int matchMSA128CtrlRegisterName(StringRef Name);
188006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
18986924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned getReg(int RC, int RegNo);
190038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
19136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getGPR(int RegNo);
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
193cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  int getATReg(SMLoc Loc);
19425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
19525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  bool processInstruction(MCInst &Inst, SMLoc IDLoc,
1962263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                          SmallVectorImpl<MCInst> &Instructions);
19745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
19845ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  // Helper function that checks if the value of a vector index is within the
19945ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  // boundaries of accepted values for each RegisterKind
20045ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
20145ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  bool validateMSAIndex(int Val, int RegKind);
20245ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
20336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void setFeatureBits(unsigned Feature, StringRef FeatureString) {
20436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!(STI.getFeatureBits() & Feature)) {
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      setAvailableFeatures(
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
20736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
20836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
20936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
21036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void clearFeatureBits(unsigned Feature, StringRef FeatureString) {
21136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (STI.getFeatureBits() & Feature) {
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      setAvailableFeatures(
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
21436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
21536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
21636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
217fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  enum MipsMatchResultTy {
219cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY
220cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#define GET_OPERAND_DIAGNOSTIC_TYPES
221cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "MipsGenAsmMatcher.inc"
222cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#undef GET_OPERAND_DIAGNOSTIC_TYPES
223cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
224cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  };
225cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
226715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly  MipsAsmParser(MCSubtargetInfo &sti, MCAsmParser &parser,
227cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                const MCInstrInfo &MII, const MCTargetOptions &Options)
22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : MCTargetAsmParser(), STI(sti), Parser(parser) {
229ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
230ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    setAvailableFeatures(ComputeAvailableFeatures(STI.getFeatureBits()));
23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
232cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    getTargetStreamer().updateABIInfo(*this);
233cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
23436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Assert exactly one ABI was chosen.
23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((((STI.getFeatureBits() & Mips::FeatureO32) != 0) +
23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ((STI.getFeatureBits() & Mips::FeatureEABI) != 0) +
23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ((STI.getFeatureBits() & Mips::FeatureN32) != 0) +
23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            ((STI.getFeatureBits() & Mips::FeatureN64) != 0)) == 1);
239cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
240cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isABI_O32() && !allowOddSPReg() != 0)
241cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      report_fatal_error("-mno-odd-spreg requires the O32 ABI");
242fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  }
243fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
244ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmParser &getParser() const { return Parser; }
245ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCAsmLexer &getLexer() const { return Parser.getLexer(); }
24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
247cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
248cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
249cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isGP64bit() const { return STI.getFeatureBits() & Mips::FeatureGP64Bit; }
251cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isFP64bit() const { return STI.getFeatureBits() & Mips::FeatureFP64Bit; }
252cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isABI_N32() const { return STI.getFeatureBits() & Mips::FeatureN32; }
253cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isABI_N64() const { return STI.getFeatureBits() & Mips::FeatureN64; }
254cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isABI_O32() const { return STI.getFeatureBits() & Mips::FeatureO32; }
255cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isABI_FPXX() const { return false; } // TODO: add check for FeatureXX
256cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
257cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool allowOddSPReg() const {
258cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return !(STI.getFeatureBits() & Mips::FeatureNoOddSPReg);
259cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
260cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
261cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool inMicroMipsMode() const {
262cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return STI.getFeatureBits() & Mips::FeatureMicroMips;
263cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
264cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips1() const { return STI.getFeatureBits() & Mips::FeatureMips1; }
265cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips2() const { return STI.getFeatureBits() & Mips::FeatureMips2; }
266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips3() const { return STI.getFeatureBits() & Mips::FeatureMips3; }
267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips4() const { return STI.getFeatureBits() & Mips::FeatureMips4; }
268cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips5() const { return STI.getFeatureBits() & Mips::FeatureMips5; }
269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips32() const {
270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return (STI.getFeatureBits() & Mips::FeatureMips32);
271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
272cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips64() const {
273cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return (STI.getFeatureBits() & Mips::FeatureMips64);
274cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
275cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips32r2() const {
276cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return (STI.getFeatureBits() & Mips::FeatureMips32r2);
277cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
278cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips64r2() const {
279cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return (STI.getFeatureBits() & Mips::FeatureMips64r2);
280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips32r6() const {
282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return (STI.getFeatureBits() & Mips::FeatureMips32r6);
283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMips64r6() const {
285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return (STI.getFeatureBits() & Mips::FeatureMips64r6);
286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasDSP() const { return (STI.getFeatureBits() & Mips::FeatureDSP); }
288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasDSPR2() const { return (STI.getFeatureBits() & Mips::FeatureDSPR2); }
289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool hasMSA() const { return (STI.getFeatureBits() & Mips::FeatureMSA); }
290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool inMips16Mode() const {
292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return STI.getFeatureBits() & Mips::FeatureMips16;
293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // TODO: see how can we get this info.
295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool mipsSEUsesSoftFloat() const { return false; }
296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Warn if RegNo is the current assembler temporary.
29836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void WarnIfAssemblerTemporary(int RegNo, SMLoc Loc);
299fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
300fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
301fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
30272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
30372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
30472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
30572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
30672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
307ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic:
30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Broad categories of register classes
30936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// The exact class is finalized by the render method.
31036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  enum RegKind {
311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
31236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                          /// isFP64bit())
31436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_FCC = 4,      /// FCC
31536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
31636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_MSACtrl = 16, /// MSA control registers
31736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_COP2 = 32,    /// COP2
31836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
31936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          /// context).
32036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_CCR = 128,    /// CCR
32136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_HWRegs = 256, /// HWRegs
322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RegKind_COP3 = 512,   /// COP3
32336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
32436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// Potentially any (e.g. $1)
32536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                      RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                      RegKind_CCR | RegKind_HWRegs | RegKind_COP3
328ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  };
329ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
330ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate:
33172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
33236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Immediate,     /// An immediate (possibly involving symbol references)
33336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Memory,        /// Base + Offset Memory Address
33436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_PhysRegister,  /// A physical register from the Mips namespace
33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_RegisterIndex, /// A register index in one or more RegKind.
33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Token          /// A simple token
33772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
33872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
339cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinespublic:
34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MipsOperand(KindTy K, MipsAsmParser &Parser)
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
343cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesprivate:
34436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// For diagnostics, and checking the assembler temporary
34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MipsAsmParser &AsmParser;
346ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
347a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct Token {
348a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
349a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
350a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
351a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
35236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct PhysRegOp {
35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Num; /// Register Number
35436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  };
35536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
35636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct RegIdxOp {
35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Index; /// Index into the register class
35836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind Kind;   /// Bitfield of the kinds it could possibly be
35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCRegisterInfo *RegInfo;
360a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
361a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
362a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
363a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
364a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
365a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
366a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
36736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MipsOperand *Base;
368a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Off;
369a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
370a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
371ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
372a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct Token Tok;
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct PhysRegOp PhysReg;
37436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct RegIdxOp RegIdx;
375a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
376a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
377ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
378ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
379ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
380ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Internal constructor for register kinds
382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                const MCRegisterInfo *RegInfo,
384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                SMLoc S, SMLoc E,
385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                MipsAsmParser &Parser) {
386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->RegIdx.Index = Index;
38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->RegIdx.RegInfo = RegInfo;
38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->RegIdx.Kind = RegKind;
39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->StartLoc = S;
39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->EndLoc = E;
39236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
39336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
39436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
39572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
39636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to GPR32 and return the real register for the current
39736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
39836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getGPR32Reg() const {
39936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
40036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    AsmParser.WarnIfAssemblerTemporary(RegIdx.Index, StartLoc);
40136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::GPR32RegClassID;
40236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
40372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
404ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
40536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to GPR64 and return the real register for the current
40636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
40736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getGPR64Reg() const {
40836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
40936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::GPR64RegClassID;
41036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
41136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
41236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to AFGR64 and return the real register for the current
41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getAFGR64Reg() const {
41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RegIdx.Index % 2 != 0)
41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AsmParser.Warning(StartLoc, "Float register should be even.");
42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index / 2);
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FGR64 and return the real register for the current
42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFGR64Reg() const {
42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FGR32 and return the real register for the current
43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFGR32Reg() const {
43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FGRH32 and return the real register for the current
44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFGRH32Reg() const {
44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FCC and return the real register for the current
44936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
45036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFCCReg() const {
45136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
45236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to MSA128 and return the real register for the current
45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getMSA128Reg() const {
45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
46136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // identical
46236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::MSA128BRegClassID;
46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
46436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
46636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to MSACtrl and return the real register for the
46736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
46836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getMSACtrlReg() const {
46936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
47036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::MSACtrlRegClassID;
47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
47236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
47336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
47436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to COP2 and return the real register for the
47536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
47636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getCOP2Reg() const {
47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
47836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::COP2RegClassID;
47936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
48136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Coerce the register to COP3 and return the real register for the
483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// current target.
484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getCOP3Reg() const {
485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ClassID = Mips::COP3RegClassID;
487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
488dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
489dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
49036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to ACC64DSP and return the real register for the
49136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getACC64DSPReg() const {
49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::ACC64DSPRegClassID;
49536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
49636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
49736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to HI32DSP and return the real register for the
49936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getHI32DSPReg() const {
50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::HI32DSPRegClassID;
50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to LO32DSP and return the real register for the
50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getLO32DSPReg() const {
50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::LO32DSPRegClassID;
51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to CCR and return the real register for the
51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getCCRReg() const {
51736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::CCRRegClassID;
51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to HWRegs and return the real register for the
52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getHWRegsReg() const {
52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::HWRegsRegClassID;
52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
528a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka  }
529a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
53036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
5312263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
532ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Expr)
534ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(0));
535ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
536ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateImm(CE->getValue()));
537ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
538ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      Inst.addOperand(MCOperand::CreateExpr(Expr));
53972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
540ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addRegOperands(MCInst &Inst, unsigned N) const {
54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Use a custom parser instead");
54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Render the operand to an MCInst as a GPR32
54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Asserts if the wrong number of operands are requested, or the operand
54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// is not a k_RegisterIndex compatible with RegKind_GPR
54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getGPR32Reg()));
55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
55336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Render the operand to an MCInst as a GPR64
55436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Asserts if the wrong number of operands are requested, or the operand
55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// is not a k_RegisterIndex compatible with RegKind_GPR
55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getGPR64Reg()));
55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getAFGR64Reg()));
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getFGR64Reg()));
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getFGR32Reg()));
574cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!AsmParser.allowOddSPReg() && RegIdx.Index & 1)
576cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
577cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                "registers");
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
58136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
58236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getFGRH32Reg()));
58336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
58736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getFCCReg()));
58836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
59136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
59236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getMSA128Reg()));
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
59636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getMSACtrlReg()));
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
59936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
60036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
60136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
60236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getCOP2Reg()));
60336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
60436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
605dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
606dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
607dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Inst.addOperand(MCOperand::CreateReg(getCOP3Reg()));
608dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
609dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
61036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
61136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
61236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getACC64DSPReg()));
61336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
61436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
61536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
61736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getHI32DSPReg()));
61836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getLO32DSPReg()));
62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getCCRReg()));
62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getHWRegsReg()));
63336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
63572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
636ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
637ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
63886924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
63972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
640ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
64172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
6426b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
6436b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Inst.addOperand(MCOperand::CreateReg(getMemBase()->getGPR32Reg()));
6456b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
6466b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
64786924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
64872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
64972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isReg() const override {
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // As a special case until we sort out the definition of div/divu, pretend
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
65336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (isGPRAsmReg() && RegIdx.Index == 0)
65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
65536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
65636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Kind == k_PhysRegister;
65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
65836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isRegIdx() const { return Kind == k_RegisterIndex; }
659dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm() const override { return Kind == k_Immediate; }
66036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isConstantImm() const {
66136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isImm() && dyn_cast<MCConstantExpr>(getImm());
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
663dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isToken() const override {
66436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Note: It's not possible to pretend that other operand kinds are tokens.
66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // The matcher emitter checks tokens first.
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Kind == k_Token;
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMem() const override { return Kind == k_Memory; }
669cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool isConstantMemOff() const {
670cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return isMem() && dyn_cast<MCConstantExpr>(getMemOff());
671cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
672cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  template <unsigned Bits> bool isMemWithSimmOffset() const {
673cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff());
674cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
675d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  bool isInvNum() const { return Kind == k_Immediate; }
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isLSAImm() const {
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!isConstantImm())
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t Val = getConstantImm();
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 1 <= Val && Val <= 4;
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
68272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
68372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
68472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
685ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
68672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
68772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getReg() const override {
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // As a special case until we sort out the definition of div/divu, pretend
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // that $0/$zero are k_PhysRegister so that MCK_ZERO works correctly.
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        RegIdx.Kind & RegKind_GPR)
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return getGPR32Reg(); // FIXME: GPR64 too
694a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(Kind == k_PhysRegister && "Invalid access!");
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return PhysReg.Num;
697ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
698ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
699ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_Immediate) && "Invalid access!");
701ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
702ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
703ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t getConstantImm() const {
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Val = getImm();
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return static_cast<const MCConstantExpr *>(Val)->getValue();
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MipsOperand *getMemBase() const {
7106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
7116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
7126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
7136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
7146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
7156b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
7166b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
7176b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
7186b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
719cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  int64_t getConstantMemOff() const {
720cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
721cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
722cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
723cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
724cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                  MipsAsmParser &Parser) {
725cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<MipsOperand>(k_Token, Parser);
726ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
727ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
728ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
729ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
730ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
731ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
732ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a numeric register (e.g. $1). The exact register remains
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// unresolved until an instruction successfully matches
735cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
736cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
737cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                   SMLoc E, MipsAsmParser &Parser) {
73836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << "CreateNumericReg(" << Index << ", ...)\n");
73936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
740ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
741ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
74236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely a GPR.
74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $gp.
744cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
745cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
746cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines               MipsAsmParser &Parser) {
74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
748a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka  }
749a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely a FGR.
75136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $f0.
752cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
753cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
754cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines               MipsAsmParser &Parser) {
75536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
75636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
75736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
75836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an FCC.
75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $fcc0.
760cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
761cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
762cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines               MipsAsmParser &Parser) {
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an ACC.
76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $ac0.
768cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
769cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
770cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines               MipsAsmParser &Parser) {
77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an MSA128.
77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $w0.
776cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
777cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
778cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                  SMLoc E, MipsAsmParser &Parser) {
77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an MSACtrl.
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $msaaccess.
784cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
785cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
786cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                   SMLoc E, MipsAsmParser &Parser) {
78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
78872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
78972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
790cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
791cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
792cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
79395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Op->Imm.Val = Val;
79495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Op->StartLoc = S;
79595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Op->EndLoc = E;
79695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    return Op;
79795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  }
79895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  static std::unique_ptr<MipsOperand>
800cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
801cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            SMLoc E, MipsAsmParser &Parser) {
802cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    auto Op = make_unique<MipsOperand>(k_Memory, Parser);
803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Op->Mem.Base = Base.release();
8046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
8056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
8066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
8076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
8086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
8096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isGPRAsmReg() const {
81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
81290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  }
81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isFGRAsmReg() const {
81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AFGR64 is $0-$15 but we handle this in getAFGR64()
81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
816a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  }
81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isHWRegsAsmReg() const {
81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
81988373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka  }
82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isCCRAsmReg() const {
82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
82288373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka  }
82336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isFCCAsmReg() const {
824cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
825cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
826cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!AsmParser.hasEightFccRegisters())
827cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return RegIdx.Index == 0;
828cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return RegIdx.Index <= 7;
82942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
83036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isACCAsmReg() const {
83136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
83242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
83336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isCOP2AsmReg() const {
83436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
83542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
836dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isCOP3AsmReg() const {
837dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
838dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isMSA128AsmReg() const {
84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
84142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
84236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isMSACtrlAsmReg() const {
84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
844006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  }
845006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
846ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
847dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getStartLoc() const override { return StartLoc; }
848ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
849dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getEndLoc() const override { return EndLoc; }
850ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
851dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  virtual ~MipsOperand() {
852dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Kind) {
853dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Immediate:
854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
855dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Memory:
856dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      delete Mem.Base;
857dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
858dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_PhysRegister:
859dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_RegisterIndex:
860dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Token:
861dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
862dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
863dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
864dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
865dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void print(raw_ostream &OS) const override {
86636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Kind) {
86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Immediate:
86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Imm<";
86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Imm.Val->print(OS);
87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ">";
87136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Memory:
87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Mem<";
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Mem.Base->print(OS);
87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ", ";
87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Mem.Off->print(OS);
87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ">";
87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_PhysRegister:
88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "PhysReg<" << PhysReg.Num << ">";
88136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_RegisterIndex:
88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
88436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
88536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Token:
88636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << Tok.Data;
88736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
88836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
88972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
89086924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand
8912263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic} // namespace
89272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
89325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm {
89425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[];
89525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
89625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
89725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return MipsInsts[Opcode];
89825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
89925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
90025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
9018afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                       SmallVectorImpl<MCInst> &Instructions) {
90225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Inst.setLoc(IDLoc);
90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MCID.isBranch() || MCID.isCall()) {
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const unsigned Opcode = Inst.getOpcode();
90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCOperand Offset;
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Opcode) {
91136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default:
91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BEQ:
91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BNE:
91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BEQ_MM:
91636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BNE_MM:
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Offset = Inst.getOperand(2);
91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Offset.isImm())
92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break; // We'll deal with this situation later on when applying fixups.
921cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch target out of range");
923cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (OffsetToAlignment(Offset.getImm(),
924cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                            1LL << (inMicroMipsMode() ? 1 : 2)))
92536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch to misaligned address");
92636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
92736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZ:
92836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGTZ:
92936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLEZ:
93036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZ:
93136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZAL:
93236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZAL:
93336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1F:
93436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1T:
93536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZ_MM:
93636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGTZ_MM:
93736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLEZ_MM:
93836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZ_MM:
93936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZAL_MM:
94036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZAL_MM:
94136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1F_MM:
94236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1T_MM:
94336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
94436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Offset = Inst.getOperand(1);
94536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Offset.isImm())
94636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break; // We'll deal with this situation later on when applying fixups.
947cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
94836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch target out of range");
949cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (OffsetToAlignment(Offset.getImm(),
950cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                            1LL << (inMicroMipsMode() ? 1 : 2)))
95136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch to misaligned address");
95236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
95336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
95436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
95536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
956cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // SSNOP is deprecated on MIPS32r6/MIPS64r6
957cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // We still accept it but it is a normal nop.
958cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
959cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
960cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
961cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                      "nop instruction");
962cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
963cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
96497265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter  if (MCID.hasDelaySlot() && Options.isReorder()) {
96597265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    // If this instruction has a delay slot and .set reorder is active,
96697265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    // emit a NOP after it.
96797265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    Instructions.push_back(Inst);
96897265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    MCInst NopInst;
96997265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.setOpcode(Mips::SLL);
97097265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
97197265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
97297265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    NopInst.addOperand(MCOperand::CreateImm(0));
97397265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    Instructions.push_back(NopInst);
97497265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter    return false;
97597265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter  }
97697265a48895a2cda7f04e47bfe935c4fdd71f8aeJack Carter
97725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (MCID.mayLoad() || MCID.mayStore()) {
97825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // Check the offset of memory operand, if it is a symbol
97986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // reference or immediate we may have to expand instructions.
98086924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
98125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
9822263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
9832263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
98425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        MCOperand &Op = Inst.getOperand(i);
98525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        if (Op.isImm()) {
98625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          int MemOffset = Op.getImm();
98725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          if (MemOffset < -32768 || MemOffset > 32767) {
98886924b4182537745659f2660244f3402c1e1ca4dJack Carter            // Offset can't exceed 16bit value.
98986924b4182537745659f2660244f3402c1e1ca4dJack Carter            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), true);
99025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            return false;
99125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
99225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        } else if (Op.isExpr()) {
99325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          const MCExpr *Expr = Op.getExpr();
99486924b4182537745659f2660244f3402c1e1ca4dJack Carter          if (Expr->getKind() == MCExpr::SymbolRef) {
99525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            const MCSymbolRefExpr *SR =
9962263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                static_cast<const MCSymbolRefExpr *>(Expr);
99725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
99886924b4182537745659f2660244f3402c1e1ca4dJack Carter              // Expand symbol.
99986924b4182537745659f2660244f3402c1e1ca4dJack Carter              expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
100025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              return false;
100125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            }
10028afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter          } else if (!isEvaluated(Expr)) {
100386924b4182537745659f2660244f3402c1e1ca4dJack Carter            expandMemInst(Inst, IDLoc, Instructions, MCID.mayLoad(), false);
10048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter            return false;
100525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
100625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        }
100725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      }
100886924b4182537745659f2660244f3402c1e1ca4dJack Carter    } // for
10092263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  }   // if load/store
101025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
101125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (needsExpansion(Inst))
1012cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return expandInstruction(Inst, IDLoc, Instructions);
101325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else
101425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    Instructions.push_back(Inst);
101525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
101625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return false;
101725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
101825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
10199d577c861414c28967d77c2a1edf64b68efdeaeeJack Carterbool MipsAsmParser::needsExpansion(MCInst &Inst) {
10209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
102186924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
102286924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadImm32Reg:
102386924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Imm:
102486924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Reg:
1025cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Mips::LoadImm64Reg:
102686924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true;
102786924b4182537745659f2660244f3402c1e1ca4dJack Carter  default:
102886924b4182537745659f2660244f3402c1e1ca4dJack Carter    return false;
10299d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
10309d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
10312490dc650895149423bb59538dc03ca352222702Jack Carter
1032cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::expandInstruction(MCInst &Inst, SMLoc IDLoc,
10332263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                                      SmallVectorImpl<MCInst> &Instructions) {
103486924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
1035cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  default:
1036cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    assert(0 && "unimplemented expansion");
1037cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return true;
103886924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadImm32Reg:
103986924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadImm(Inst, IDLoc, Instructions);
1040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Mips::LoadImm64Reg:
1041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isGP64bit()) {
1042cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1043cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return true;
1044cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1045cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return expandLoadImm(Inst, IDLoc, Instructions);
104686924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Imm:
104786924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadAddressImm(Inst, IDLoc, Instructions);
104886924b4182537745659f2660244f3402c1e1ca4dJack Carter  case Mips::LoadAddr32Reg:
104986924b4182537745659f2660244f3402c1e1ca4dJack Carter    return expandLoadAddressReg(Inst, IDLoc, Instructions);
105086924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
10519d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
10522490dc650895149423bb59538dc03ca352222702Jack Carter
1053cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesnamespace {
1054cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinestemplate <int Shift, bool PerformShift>
1055cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid createShiftOr(int64_t Value, unsigned RegNo, SMLoc IDLoc,
1056cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                   SmallVectorImpl<MCInst> &Instructions) {
1057cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCInst tmpInst;
1058cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (PerformShift) {
1059cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.setOpcode(Mips::DSLL);
1060cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1061cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1062cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.addOperand(MCOperand::CreateImm(16));
1063cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.setLoc(IDLoc);
1064cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Instructions.push_back(tmpInst);
1065cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.clear();
1066cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1067cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  tmpInst.setOpcode(Mips::ORi);
1068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1069cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  tmpInst.addOperand(MCOperand::CreateReg(RegNo));
1070cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  tmpInst.addOperand(
1071cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      MCOperand::CreateImm(((Value & (0xffffLL << Shift)) >> Shift)));
1072cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  tmpInst.setLoc(IDLoc);
1073cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Instructions.push_back(tmpInst);
1074cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1075cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1077cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::expandLoadImm(MCInst &Inst, SMLoc IDLoc,
107886924b4182537745659f2660244f3402c1e1ca4dJack Carter                                  SmallVectorImpl<MCInst> &Instructions) {
10792490dc650895149423bb59538dc03ca352222702Jack Carter  MCInst tmpInst;
10809d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
10812f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
10829d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  const MCOperand &RegOp = Inst.getOperand(0);
10839d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  assert(RegOp.isReg() && "expected register operand kind");
10849d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
1085cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  int64_t ImmValue = ImmOp.getImm();
10862490dc650895149423bb59538dc03ca352222702Jack Carter  tmpInst.setLoc(IDLoc);
1087cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // FIXME: gas has a special case for values that are 000...1111, which
1088cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // becomes a li -1 and then a dsrl
108986924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (0 <= ImmValue && ImmValue <= 65535) {
109086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For 0 <= j <= 65535.
10919d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => ori d,$zero,j
1092ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
10932490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
109486924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
10952490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
10969d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
109786924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else if (ImmValue < 0 && ImmValue >= -32768) {
109886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j < 0.
10999d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => addiu d,$zero,j
1100ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
11012490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
110286924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
11032490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
11049d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
1105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if ((ImmValue & 0xffffffff) == ImmValue) {
1106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // For any value of j that is representable as a 32-bit integer, create
1107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // a sequence of:
11089d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    // li d,j => lui d,hi16(j)
11092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    //           ori d,d,lo16(j)
1110ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
11112490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
11122490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
11139d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
1114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    createShiftOr<0, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1115cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if ((ImmValue & (0xffffLL << 48)) == 0) {
1116cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isGP64bit()) {
1117cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return true;
1119cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1120cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //            <-------  lo32 ------>
1122cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // <-------  hi32 ------>
1123cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // <- hi16 ->             <- lo16 ->
1124cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //  _________________________________
1125cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // |          |          |          |
1126cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // | 16-bytes | 16-bytes | 16-bytes |
1127cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // |__________|__________|__________|
1128cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //
1129cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // For any value of j that is representable as a 48-bit integer, create
1130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // a sequence of:
1131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // li d,j => lui d,hi16(j)
1132cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           ori d,d,hi16(lo32(j))
1133cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           dsll d,d,16
1134cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           ori d,d,lo16(lo32(j))
1135cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.setOpcode(Mips::LUi);
11362490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.addOperand(
1138cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        MCOperand::CreateImm((ImmValue & (0xffffLL << 32)) >> 32));
1139cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Instructions.push_back(tmpInst);
1140cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    createShiftOr<16, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1141cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1142cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else {
1143cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isGP64bit()) {
1144cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1145cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return true;
1146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
1147cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1148cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // <-------  hi32 ------> <-------  lo32 ------>
1149cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // <- hi16 ->                        <- lo16 ->
1150cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //  ___________________________________________
1151cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // |          |          |          |          |
1152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // | 16-bytes | 16-bytes | 16-bytes | 16-bytes |
1153cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // |__________|__________|__________|__________|
1154cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //
1155cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // For any value of j that isn't representable as a 48-bit integer.
1156cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // li d,j => lui d,hi16(j)
1157cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           ori d,d,lo16(hi32(j))
1158cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           dsll d,d,16
1159cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           ori d,d,hi16(lo32(j))
1160cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           dsll d,d,16
1161cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    //           ori d,d,lo16(lo32(j))
1162cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.setOpcode(Mips::LUi);
11632490dc650895149423bb59538dc03ca352222702Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
1164cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    tmpInst.addOperand(
1165cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        MCOperand::CreateImm((ImmValue & (0xffffLL << 48)) >> 48));
11669d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter    Instructions.push_back(tmpInst);
1167cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    createShiftOr<32, false>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1168cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    createShiftOr<16, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
1169cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    createShiftOr<0, true>(ImmValue, RegOp.getReg(), IDLoc, Instructions);
11709d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
1171cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
11729d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
11732490dc650895149423bb59538dc03ca352222702Jack Carter
1174cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool
11752263a2ca72e21206d45a69532004a0b17881e733Vladimir MedicMipsAsmParser::expandLoadAddressReg(MCInst &Inst, SMLoc IDLoc,
11762263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                                    SmallVectorImpl<MCInst> &Instructions) {
11772f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
11782f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(2);
11792f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
11802f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &SrcRegOp = Inst.getOperand(1);
11812f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(SrcRegOp.isReg() && "expected register operand kind");
11822f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &DstRegOp = Inst.getOperand(0);
11832f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(DstRegOp.isReg() && "expected register operand kind");
11842f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
118586924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (-32768 <= ImmValue && ImmValue <= 65535) {
118686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j <= 65535.
118786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j(s) => addiu d,s,j
1188ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
11892f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
11902f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
11912f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
11922f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
11932f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
119486924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
119586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j(s) => lui d,hi16(j)
119686924b4182537745659f2660244f3402c1e1ca4dJack Carter    //              ori d,d,lo16(j)
119786924b4182537745659f2660244f3402c1e1ca4dJack Carter    //              addu d,d,s
1198ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
11992f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
12002f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
12012f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
12022f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
1203ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
12042f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
12052f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
12062f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
12072f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
12082f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
12092f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDu);
12102f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
12112f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(DstRegOp.getReg()));
12122f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(SrcRegOp.getReg()));
12132f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
12142f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
1215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
12162f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
12172f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
1218cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool
12192263a2ca72e21206d45a69532004a0b17881e733Vladimir MedicMipsAsmParser::expandLoadAddressImm(MCInst &Inst, SMLoc IDLoc,
12202263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                                    SmallVectorImpl<MCInst> &Instructions) {
12212f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  MCInst tmpInst;
12222f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &ImmOp = Inst.getOperand(1);
12232f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(ImmOp.isImm() && "expected immediate operand kind");
12242f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  const MCOperand &RegOp = Inst.getOperand(0);
12252f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  assert(RegOp.isReg() && "expected register operand kind");
12262f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  int ImmValue = ImmOp.getImm();
122786924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (-32768 <= ImmValue && ImmValue <= 65535) {
122886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For -32768 <= j <= 65535.
122986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j => addiu d,$zero,j
12302f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.setOpcode(Mips::ADDiu);
12312f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
123286924b4182537745659f2660244f3402c1e1ca4dJack Carter    tmpInst.addOperand(MCOperand::CreateReg(Mips::ZERO));
12332f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue));
12342f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
12352f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  } else {
123686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // For any other value of j that is representable as a 32-bit integer.
123786924b4182537745659f2660244f3402c1e1ca4dJack Carter    // la d,j => lui d,hi16(j)
123886924b4182537745659f2660244f3402c1e1ca4dJack Carter    //           ori d,d,lo16(j)
1239ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::LUi);
12402f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
12412f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm((ImmValue & 0xffff0000) >> 16));
12422f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
12432f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.clear();
1244ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    tmpInst.setOpcode(Mips::ORi);
12452f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
12462f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateReg(RegOp.getReg()));
12472f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    tmpInst.addOperand(MCOperand::CreateImm(ImmValue & 0xffff));
12482f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    Instructions.push_back(tmpInst);
12492f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter  }
1250cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
12512f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
12522f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
125325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Cartervoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc,
12542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                                  SmallVectorImpl<MCInst> &Instructions,
12552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                                  bool isLoad, bool isImmOpnd) {
125625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCSymbolRefExpr *SR;
125725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  MCInst TempInst;
125886924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned ImmOffset, HiOffset, LoOffset;
125925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCExpr *ExprOffset;
126025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned TmpRegNum;
126186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 1st operand is either the source or destination register.
126225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(0).isReg() && "expected register operand kind");
126325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned RegOpNum = Inst.getOperand(0).getReg();
126486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 2nd operand is the base register.
126525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  assert(Inst.getOperand(1).isReg() && "expected register operand kind");
126625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  unsigned BaseRegNum = Inst.getOperand(1).getReg();
126786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // 3rd operand is either an immediate or expression.
126825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd) {
126925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    assert(Inst.getOperand(2).isImm() && "expected immediate operand kind");
127025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ImmOffset = Inst.getOperand(2).getImm();
127125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    LoOffset = ImmOffset & 0x0000ffff;
127225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    HiOffset = (ImmOffset & 0xffff0000) >> 16;
127386924b4182537745659f2660244f3402c1e1ca4dJack Carter    // If msb of LoOffset is 1(negative number) we must increment HiOffset.
127425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (LoOffset & 0x8000)
127525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      HiOffset++;
127686924b4182537745659f2660244f3402c1e1ca4dJack Carter  } else
127725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    ExprOffset = Inst.getOperand(2).getExpr();
127886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // All instructions will have the same location.
127925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setLoc(IDLoc);
1280cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // These are some of the types of expansions we perform here:
1281cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // 1) lw $8, sym        => lui $8, %hi(sym)
1282cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         lw $8, %lo(sym)($8)
1283cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // 2) lw $8, offset($9) => lui $8, %hi(offset)
1284cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         add $8, $8, $9
1285cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         lw $8, %lo(offset)($9)
1286cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // 3) lw $8, offset($8) => lui $at, %hi(offset)
1287cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         add $at, $at, $8
1288cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         lw $8, %lo(offset)($at)
1289cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // 4) sw $8, sym        => lui $at, %hi(sym)
1290cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         sw $8, %lo(sym)($at)
1291cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // 5) sw $8, offset($8) => lui $at, %hi(offset)
1292cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         add $at, $at, $8
1293cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         sw $8, %lo(offset)($at)
1294cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // 6) ldc1 $f0, sym     => lui $at, %hi(sym)
1295cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //                         ldc1 $f0, %lo(sym)($at)
1296cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //
1297cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // For load instructions we can use the destination register as a temporary
1298cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // if base and dst are different (examples 1 and 2) and if the base register
1299cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // is general purpose otherwise we must use $at (example 6) and error if it's
1300cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // not available. For stores we must use $at (examples 4 and 5) because we
1301cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // must not clobber the source register setting up the offset.
1302cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
1303cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  int16_t RegClassOp0 = Desc.OpInfo[0].RegClass;
1304cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned RegClassIDOp0 =
1305cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      getContext().getRegisterInfo()->getRegClass(RegClassOp0).getID();
1306cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  bool IsGPR = (RegClassIDOp0 == Mips::GPR32RegClassID) ||
1307cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines               (RegClassIDOp0 == Mips::GPR64RegClassID);
1308cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (isLoad && IsGPR && (BaseRegNum != RegOpNum))
1309cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    TmpRegNum = RegOpNum;
1310cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  else {
1311cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    int AT = getATReg(IDLoc);
1312cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // At this point we need AT to perform the expansions and we exit if it is
1313cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // not available.
1314cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!AT)
1315cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return;
1316cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    TmpRegNum = getReg(
1317cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, AT);
1318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
1319cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
132025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::LUi);
132125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
132225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
132325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(HiOffset));
132425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
132525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
13262263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      SR = static_cast<const MCSymbolRefExpr *>(ExprOffset);
132786924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCSymbolRefExpr *HiExpr = MCSymbolRefExpr::Create(
132886924b4182537745659f2660244f3402c1e1ca4dJack Carter          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_HI,
132986924b4182537745659f2660244f3402c1e1ca4dJack Carter          getContext());
133025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
13318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else {
133286924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCExpr *HiExpr = evaluateRelocExpr(ExprOffset, "hi");
13338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(HiExpr));
133425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
133525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
133686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the instruction to the list.
133725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
133886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Prepare TempInst for next instruction.
133925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
134086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add temp register to base.
134125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Mips::ADDu);
134225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
134325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
134425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(BaseRegNum));
134525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
134625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
134736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // And finally, create original instruction with low part
134886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // of offset and new base.
134925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.setOpcode(Inst.getOpcode());
135025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(RegOpNum));
135125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.addOperand(MCOperand::CreateReg(TmpRegNum));
135225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (isImmOpnd)
135325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    TempInst.addOperand(MCOperand::CreateImm(LoOffset));
135425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  else {
135525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    if (ExprOffset->getKind() == MCExpr::SymbolRef) {
135686924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCSymbolRefExpr *LoExpr = MCSymbolRefExpr::Create(
135786924b4182537745659f2660244f3402c1e1ca4dJack Carter          SR->getSymbol().getName(), MCSymbolRefExpr::VK_Mips_ABS_LO,
135886924b4182537745659f2660244f3402c1e1ca4dJack Carter          getContext());
135925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
13608afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    } else {
136186924b4182537745659f2660244f3402c1e1ca4dJack Carter      const MCExpr *LoExpr = evaluateRelocExpr(ExprOffset, "lo");
13628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      TempInst.addOperand(MCOperand::CreateExpr(LoExpr));
136325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
136425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
136525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Instructions.push_back(TempInst);
136625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  TempInst.clear();
136725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
136825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
1369cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesunsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
1370cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // As described by the Mips32r2 spec, the registers Rd and Rs for
1371cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // jalr.hb must be different.
1372cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  unsigned Opcode = Inst.getOpcode();
1373cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1374cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Opcode == Mips::JALR_HB &&
1375cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg()))
1376cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return Match_RequiresDifferentSrcAndDst;
1377cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1378cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return Match_Success;
1379cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
1380cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1381cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
1382cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                            OperandVector &Operands,
1383cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                            MCStreamer &Out,
1384cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                            unsigned &ErrorInfo,
1385cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                            bool MatchingInlineAsm) {
1386cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
1387ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
138825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  SmallVector<MCInst, 8> Instructions;
13892263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  unsigned MatchResult =
13902263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
1391ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1392ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
139386924b4182537745659f2660244f3402c1e1ca4dJack Carter  default:
139486924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
1395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
139686924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (processInstruction(Inst, IDLoc, Instructions))
139725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      return true;
139886924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < Instructions.size(); i++)
139936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Out.EmitInstruction(Instructions[i], STI);
1400ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
1401ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1402ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
1403ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
1404ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
1405ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
1406ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
1407ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    if (ErrorInfo != ~0U) {
1408ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
1409ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
1410ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1411cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      ErrorLoc = ((MipsOperand &)*Operands[ErrorInfo]).getStartLoc();
141286924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (ErrorLoc == SMLoc())
141386924b4182537745659f2660244f3402c1e1ca4dJack Carter        ErrorLoc = IDLoc;
1414ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
1415ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1416ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
1417ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1418ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
1419ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
1420cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case Match_RequiresDifferentSrcAndDst:
1421cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return Error(IDLoc, "source and destination must be different");
1422ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1423fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1424fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1425fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
142636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid MipsAsmParser::WarnIfAssemblerTemporary(int RegIndex, SMLoc Loc) {
142736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((RegIndex != 0) && ((int)Options.getATRegNum() == RegIndex)) {
142836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RegIndex == 1)
142936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Warning(Loc, "Used $at without \".set noat\"");
143036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
143136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Warning(Loc, Twine("Used $") + Twine(RegIndex) + " with \".set at=$" +
143236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                       Twine(RegIndex) + "\"");
143336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
143436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
143536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
143699e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) {
14372263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  int CC;
143899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
14392263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  CC = StringSwitch<unsigned>(Name)
14402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("zero", 0)
144136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           .Case("at", 1)
14422263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a0", 4)
14432263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a1", 5)
14442263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a2", 6)
14452263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a3", 7)
14462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("v0", 2)
14472263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("v1", 3)
14482263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s0", 16)
14492263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s1", 17)
14502263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s2", 18)
14512263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s3", 19)
14522263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s4", 20)
14532263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s5", 21)
14542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s6", 22)
14552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s7", 23)
14562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("k0", 26)
14572263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("k1", 27)
145836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           .Case("gp", 28)
14592263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("sp", 29)
14602263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("fp", 30)
146136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           .Case("s8", 30)
14622263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("ra", 31)
14632263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t0", 8)
14642263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t1", 9)
14652263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t2", 10)
14662263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t3", 11)
14672263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t4", 12)
14682263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t5", 13)
14692263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t6", 14)
14702263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t7", 15)
14712263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t8", 24)
14722263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t9", 25)
14732263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Default(-1);
147499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
1475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (isABI_N32() || isABI_N64()) {
147636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Although SGI documentation just cuts out t0-t3 for n32/n64,
147736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
147836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
147936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (8 <= CC && CC <= 11)
148036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CC += 4;
148136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
148236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (CC == -1)
148336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      CC = StringSwitch<unsigned>(Name)
148436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Case("a4", 8)
148536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Case("a5", 9)
148636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Case("a6", 10)
148736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Case("a7", 11)
148836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Case("kt0", 26)
148936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Case("kt1", 27)
149036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines               .Default(-1);
149136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
1492572e1bd109518f80b54d229de10699c4603944c3David Chisnall
149399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return CC;
149499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter}
149586924b4182537745659f2660244f3402c1e1ca4dJack Carter
1496bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchFPURegisterName(StringRef Name) {
1497ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1498f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
1499f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
1500f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
150186924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (NumString.getAsInteger(10, IntVal))
15022263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      return -1;     // This is not an integer.
1503bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (IntVal > 31) // Maximum index for fpu register.
1504f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
1505bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return IntVal;
1506bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  }
1507bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  return -1;
1508bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic}
1509f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
1510bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchFCCRegisterName(StringRef Name) {
1511bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic
1512bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (Name.startswith("fcc")) {
1513bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    StringRef NumString = Name.substr(3);
1514bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    unsigned IntVal;
1515bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (NumString.getAsInteger(10, IntVal))
15162263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      return -1;    // This is not an integer.
1517bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (IntVal > 7) // There are only 8 fcc registers.
1518bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic      return -1;
1519bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return IntVal;
1520f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
1521ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
1522ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
152386924b4182537745659f2660244f3402c1e1ca4dJack Carter
1524bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchACRegisterName(StringRef Name) {
1525bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic
1526899ee589f5182a35495f068ae15b5f2b5ff4ef8aAkira Hatanaka  if (Name.startswith("ac")) {
1527899ee589f5182a35495f068ae15b5f2b5ff4ef8aAkira Hatanaka    StringRef NumString = Name.substr(2);
1528bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    unsigned IntVal;
1529bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (NumString.getAsInteger(10, IntVal))
15302263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      return -1;    // This is not an integer.
1531bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (IntVal > 3) // There are only 3 acc registers.
1532bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic      return -1;
1533bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return IntVal;
1534bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  }
1535bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  return -1;
1536bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic}
15377231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
153842d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carterint MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
153942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  unsigned IntVal;
154042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
154142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
154242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter    return -1;
154342d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
154442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  if (IntVal > 31)
154542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter    return -1;
154642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
154742d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  return IntVal;
154842d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter}
154942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
1550006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeidaint MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
1551006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  int CC;
1552006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
1553006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  CC = StringSwitch<unsigned>(Name)
15542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msair", 0)
15552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msacsr", 1)
15562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msaaccess", 2)
15572263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msasave", 3)
15582263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msamodify", 4)
15592263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msarequest", 5)
15602263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msamap", 6)
15612263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msaunmap", 7)
15622263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Default(-1);
1563006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
1564006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  return CC;
1565006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida}
1566006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
156730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAssemblerOptions::setATReg(unsigned Reg) {
156830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Reg > 31)
156930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
157030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
157130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  aTReg = Reg;
157230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
157330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
157430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
1575cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesint MipsAsmParser::getATReg(SMLoc Loc) {
157636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int AT = Options.getATRegNum();
157736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (AT == 0)
1578cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError(Loc,
1579cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                     "Pseudo instruction requires $at, which is not available");
158036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return AT;
158136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
158230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
158386924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) {
158499cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
1585ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1586ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
158736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesunsigned MipsAsmParser::getGPR(int RegNo) {
1588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return getReg(isGP64bit() ? Mips::GPR64RegClassID : Mips::GPR32RegClassID,
158936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                RegNo);
159036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
159136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1592ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterint MipsAsmParser::matchRegisterByNumber(unsigned RegNum, unsigned RegClass) {
1593bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (RegNum >
159436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      getContext().getRegisterInfo()->getRegClass(RegClass).getNumRegs() - 1)
1595ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return -1;
1596ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1597ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  return getReg(RegClass, RegNum);
1598ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1599ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1600cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseOperand(OperandVector &Operands, StringRef Mnemonic) {
160136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "ParseOperand\n");
160236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
16039d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // Check if the current operand has a custom associated parser, if so, try to
16049d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // custom parse the operand, or fallback to the general approach.
1605ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
1606ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
1607ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
1608ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
1609ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
1610ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
1611ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
1612ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
1613ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
161436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << ".. Generic Parser\n");
161536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1616ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
1617ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
1618ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
1619ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
1620ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
162186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Parse the register.
1622ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
1623ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
162436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Almost all registers have been parsed by custom parsers. There is only
162536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // one exception to this. $zero (and it's alias $0) will reach this point
162636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // for div, divu, and similar instructions because it is not an operand
162736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // to the instruction definition but an explicit register. Special case
162836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // this situation for now.
162936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ParseAnyRegister(Operands) != MatchOperand_NoMatch)
1630ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
163136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
163286924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Maybe it is a symbol reference.
1633ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
1634cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (Parser.parseIdentifier(Identifier))
1635ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
1636ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1637ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
163838539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer    MCSymbol *Sym = getContext().GetOrCreateSymbol("$" + Identifier);
163986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Otherwise create a symbol reference.
16402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    const MCExpr *Res =
16412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic        MCSymbolRefExpr::Create(Sym, MCSymbolRefExpr::VK_None, getContext());
1642ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
164336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
1644ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
1645ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
16462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  // Else drop to expression parsing.
1647ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
1648ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
1649ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
1650ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
1651cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case AsmToken::Tilde:
1652ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
165336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. generic integer\n");
165436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OperandMatchResultTy ResTy = ParseImm(Operands);
165536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy != MatchOperand_Success;
1656ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
16576b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
165886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is a symbol reference or constant expression.
16596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
166086924b4182537745659f2660244f3402c1e1ca4dJack Carter    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
1661ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (parseRelocOperand(IdVal))
16626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
16636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1664ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1665ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
166636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
16676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
166830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // case AsmToken::Percent
166930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // switch(getLexer().getKind())
1670fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
1671fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
1672fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
16732263a2ca72e21206d45a69532004a0b17881e733Vladimir Medicconst MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
16748afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                               StringRef RelocStr) {
16758afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  const MCExpr *Res;
167686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Check the type of the expression.
16778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Expr)) {
167836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // It's a constant, evaluate reloc value.
167936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int16_t Val;
168036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (getVariantKind(RelocStr)) {
168136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MCSymbolRefExpr::VK_Mips_ABS_LO:
168236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Get the 1st 16-bits.
168336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Val = MCE->getValue() & 0xffff;
168436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
168536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MCSymbolRefExpr::VK_Mips_ABS_HI:
168636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Get the 2nd 16-bits. Also add 1 if bit 15 is 1, to compensate for low
168736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // 16 bits being negative.
168836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Val = ((MCE->getValue() + 0x8000) >> 16) & 0xffff;
168936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
169036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MCSymbolRefExpr::VK_Mips_HIGHER:
169136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Get the 3rd 16-bits.
169236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Val = ((MCE->getValue() + 0x80008000LL) >> 32) & 0xffff;
169336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
169436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case MCSymbolRefExpr::VK_Mips_HIGHEST:
169536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Get the 4th 16-bits.
169636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Val = ((MCE->getValue() + 0x800080008000LL) >> 48) & 0xffff;
169736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
169836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default:
169936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      report_fatal_error("Unsupported reloc value!");
17008afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
170136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MCConstantExpr::Create(Val, getContext());
17028afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
17038afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
17048afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCSymbolRefExpr *MSRE = dyn_cast<MCSymbolRefExpr>(Expr)) {
170586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It's a symbol, create a symbolic expression from the symbol.
17068afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    StringRef Symbol = MSRE->getSymbol().getName();
17078afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
170886924b4182537745659f2660244f3402c1e1ca4dJack Carter    Res = MCSymbolRefExpr::Create(Symbol, VK, getContext());
17098afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return Res;
17108afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
17118afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
17128afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
171336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCSymbolRefExpr::VariantKind VK = getVariantKind(RelocStr);
171436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
171536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Try to create target expression.
171636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (MipsMCExpr::isSupportedBinaryExpr(VK, BE))
171736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return MipsMCExpr::Create(VK, Expr, getContext());
171836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
171986924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *LExp = evaluateRelocExpr(BE->getLHS(), RelocStr);
172086924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *RExp = evaluateRelocExpr(BE->getRHS(), RelocStr);
17218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Res = MCBinaryExpr::Create(BE->getOpcode(), LExp, RExp, getContext());
17228afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return Res;
17238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
17248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
17258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCUnaryExpr *UN = dyn_cast<MCUnaryExpr>(Expr)) {
172686924b4182537745659f2660244f3402c1e1ca4dJack Carter    const MCExpr *UnExp = evaluateRelocExpr(UN->getSubExpr(), RelocStr);
172786924b4182537745659f2660244f3402c1e1ca4dJack Carter    Res = MCUnaryExpr::Create(UN->getOpcode(), UnExp, getContext());
172886924b4182537745659f2660244f3402c1e1ca4dJack Carter    return Res;
17298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
173086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Just return the original expression.
17318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Expr;
17328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
17338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
17348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
17358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
17368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  switch (Expr->getKind()) {
17378afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Constant:
17388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return true;
17398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::SymbolRef:
17408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
17418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Binary:
17428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
17438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (!isEvaluated(BE->getLHS()))
17448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return false;
17458afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return isEvaluated(BE->getRHS());
17468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
17478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Unary:
17488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
174936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::Target:
175036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
17518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
17528afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
17538afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
17546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
175586924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
17562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  Parser.Lex();                          // Eat the % token.
175786924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
17586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
17596b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
17606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
176138539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer  std::string Str = Tok.getIdentifier().str();
17626b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
176386924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the identifier.
176486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Now make an expression from the rest of the operand.
17656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
1766ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc EndLoc;
17676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
17686b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
17696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
177086924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the '(' token.
17716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
177286924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the % token.
17736b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
17746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
17756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
177638539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
177738539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
177886924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the identifier.
17796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
17806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
17816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
17826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
17836b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
178486924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (getParser().parseParenExpression(IdVal, EndLoc))
17856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
17866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1787ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    while (getLexer().getKind() == AsmToken::RParen)
178886924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the ')' token.
17896b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
17906b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
179186924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true; // Parenthesis must follow the relocation operand.
17926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
179386924b4182537745659f2660244f3402c1e1ca4dJack Carter  Res = evaluateRelocExpr(IdVal, Str);
17948afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
17956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
17966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1797ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
1798ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
1799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
180036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OperandMatchResultTy ResTy = ParseAnyRegister(Operands);
180136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy == MatchOperand_Success) {
180236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(Operands.size() == 1);
1803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
180436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StartLoc = Operand.getStartLoc();
180536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EndLoc = Operand.getEndLoc();
180636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
180736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AFAIK, we only support numeric registers and named GPR's in CFI
180836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // directives.
180936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Don't worry about eating tokens before failing. Using an unrecognised
181036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // register is a parse error.
181136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Operand.isGPRAsmReg()) {
181236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Resolve to GPR32 or GPR64 appropriately.
1813cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
181436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
181536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
181636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return (RegNo == (unsigned)-1);
181736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
181836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
181936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Operands.size() == 0);
18202263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  return (RegNo == (unsigned)-1);
1821ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1822ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
18238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
1824ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
18258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool Result = true;
18268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
18278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  while (getLexer().getKind() == AsmToken::LParen)
18288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
1829ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
183086924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (getLexer().getKind()) {
18316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
18326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
183325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  case AsmToken::Identifier:
18348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case AsmToken::LParen:
18356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
18366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
18376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
18388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (isParenExpr)
183986924b4182537745659f2660244f3402c1e1ca4dJack Carter      Result = getParser().parseParenExpression(Res, S);
18408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else
18418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Result = (getParser().parseExpression(Res));
184286924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().getKind() == AsmToken::RParen)
18438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Parser.Lex();
184486924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
1845ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  case AsmToken::Percent:
18468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Result = parseRelocOperand(Res);
18476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
18488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Result;
18496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
18506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1851cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::OperandMatchResultTy
1852cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::parseMemOperand(OperandVector &Operands) {
185336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "parseMemOperand\n");
1854dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *IdVal = nullptr;
1855ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
18568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isParenExpr = false;
1857bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
185886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // First operand is the offset.
1859ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  S = Parser.getTok().getLoc();
18606b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
18618afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() == AsmToken::LParen) {
18628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
18638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    isParenExpr = true;
18648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
18656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
18668afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() != AsmToken::Dollar) {
186786924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (parseMemOffset(IdVal, isParenExpr))
18688afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
18698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
187086924b4182537745659f2660244f3402c1e1ca4dJack Carter    const AsmToken &Tok = Parser.getTok(); // Get the next token.
18718afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (Tok.isNot(AsmToken::LParen)) {
1872cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
1873cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (Mnemonic.getToken() == "la") {
18742263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic        SMLoc E =
18752263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
187636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
18778afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
18788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
18798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (Tok.is(AsmToken::EndOfStatement)) {
18802263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic        SMLoc E =
18812263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
18828afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
188386924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Zero register assumed, add a memory operand with ZERO as its base.
1884dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // "Base" will be managed by k_Memory.
1885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        auto Base = MipsOperand::CreateGPRReg(0, getContext().getRegisterInfo(),
1886cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                              S, E, *this);
1887cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Operands.push_back(
1888cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines            MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
18898afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
18908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
18918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Error(Parser.getTok().getLoc(), "'(' expected");
18928afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
18932f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    }
18946b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
189586924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '(' token.
18968afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
18976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
189836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Res = ParseAnyRegister(Operands);
1899bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (Res != MatchOperand_Success)
1900bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return Res;
19016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1902bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (Parser.getTok().isNot(AsmToken::RParen)) {
19036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
19046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
19056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
19066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1907ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
1908ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
190986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the ')' token.
19106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1911dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!IdVal)
19126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    IdVal = MCConstantExpr::Create(0, getContext());
19136b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
191486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Replace the register operand with the memory operand.
1915cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  std::unique_ptr<MipsOperand> op(
1916cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      static_cast<MipsOperand *>(Operands.back().release()));
191786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Remove the register from the operands.
1918dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // "op" will be managed by k_Memory.
19196b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
192086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the memory operand.
19218afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
19228afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    int64_t Imm;
19238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (IdVal->EvaluateAsAbsolute(Imm))
19248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      IdVal = MCConstantExpr::Create(Imm, getContext());
19258afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
19268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      IdVal = MCBinaryExpr::Create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
19278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                   getContext());
19288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
19298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
1930cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
1931ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
1932ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
1933ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1934cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
1935a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
193636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbol *Sym = getContext().LookupSymbol(Parser.getTok().getIdentifier());
193736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Sym) {
193836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SMLoc S = Parser.getTok().getLoc();
193936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Expr;
194036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Sym->isVariable())
194136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Expr = Sym->getVariableValue();
194236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
1943a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka      return false;
194436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Expr->getKind() == MCExpr::SymbolRef) {
194536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
194636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const StringRef DefSymbol = Ref->getSymbol().getName();
194736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (DefSymbol.startswith("$")) {
194836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OperandMatchResultTy ResTy =
194936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            MatchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
195036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (ResTy == MatchOperand_Success) {
195136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Parser.Lex();
195236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return true;
195336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        } else if (ResTy == MatchOperand_ParseFail)
195436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          llvm_unreachable("Should never ParseFail");
195536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
195636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
195736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    } else if (Expr->getKind() == MCExpr::Constant) {
195836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex();
195936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const MCConstantExpr *Const = static_cast<const MCConstantExpr *>(Expr);
1960cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Operands.push_back(
1961cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines          MipsOperand::CreateImm(Const, S, Parser.getTok().getLoc(), *this));
196236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
196336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
1964a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka  }
196536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
1966a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka}
1967a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
1968ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
1969cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::MatchAnyRegisterNameWithoutDollar(OperandVector &Operands,
1970cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                 StringRef Identifier,
1971cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                                 SMLoc S) {
197236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int Index = matchCPURegisterName(Identifier);
197336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
197436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateGPRReg(
197536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
1976ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
1977ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
197845ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
197936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchFPURegisterName(Identifier);
198036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
198136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateFGRReg(
198236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
198336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
198445ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  }
198545ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
198636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchFCCRegisterName(Identifier);
198736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
198836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateFCCReg(
198936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
199036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
199142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
199242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
199336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchACRegisterName(Identifier);
199436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
199536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateACCReg(
199636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
199745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida    return MatchOperand_Success;
199836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
199945ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
200036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchMSA128RegisterName(Identifier);
200136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
200236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateMSA128Reg(
200336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
200445ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida    return MatchOperand_Success;
200545ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  }
200645ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
200736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchMSA128CtrlRegisterName(Identifier);
200836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
200936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateMSACtrlReg(
201036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
201136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
201245ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  }
201345ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
201436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_NoMatch;
20157231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic}
20167231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
20177231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy
2018cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::MatchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
201936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  auto Token = Parser.getLexer().peekTok(false);
202036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
202136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Token.is(AsmToken::Identifier)) {
202236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. identifier\n");
202336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef Identifier = Token.getIdentifier();
202436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OperandMatchResultTy ResTy =
202536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MatchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
202636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
202736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Token.is(AsmToken::Integer)) {
202836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. integer\n");
202936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateNumericReg(
203036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
203136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        *this));
203236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
203336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
203490b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
203536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
203690b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
203736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_NoMatch;
203890b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic}
203990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
2040cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::OperandMatchResultTy
2041cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseAnyRegister(OperandVector &Operands) {
204236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "ParseAnyRegister\n");
204388373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
204436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  auto Token = Parser.getTok();
204588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
204636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc S = Token.getLoc();
204788373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
204836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Token.isNot(AsmToken::Dollar)) {
204936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
205036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Token.is(AsmToken::Identifier)) {
205136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (searchSymbolAlias(Operands))
205236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return MatchOperand_Success;
205336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
205436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
205588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka    return MatchOperand_NoMatch;
205636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
205736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << ".. $\n");
205888373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
205936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OperandMatchResultTy ResTy = MatchAnyRegisterWithoutDollar(Operands, S);
206036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy == MatchOperand_Success) {
206136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // $
206236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // identifier
206336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
206436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ResTy;
206588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka}
206688373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
2067e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir MedicMipsAsmParser::OperandMatchResultTy
2068cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseImm(OperandVector &Operands) {
206936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (getLexer().getKind()) {
207036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
2071e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic    return MatchOperand_NoMatch;
207236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::LParen:
207336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Minus:
207436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Plus:
207536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Integer:
2076cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  case AsmToken::Tilde:
207736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::String:
207836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
207936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
2080e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic
208136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *IdVal;
2082e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic  SMLoc S = Parser.getTok().getLoc();
208336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getParser().parseExpression(IdVal))
208436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_ParseFail;
2085e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic
208636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
208736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
2088e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic  return MatchOperand_Success;
2089e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic}
2090e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic
2091cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::OperandMatchResultTy
2092cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseJumpTarget(OperandVector &Operands) {
209336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "ParseJumpTarget\n");
209442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
209536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc S = getLexer().getLoc();
209642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
209736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Integers and expressions are acceptable
209836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  OperandMatchResultTy ResTy = ParseImm(Operands);
209936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy != MatchOperand_NoMatch)
210036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
2101006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
210236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Registers are a valid target and have priority over symbols.
210336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  ResTy = ParseAnyRegister(Operands);
210436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy != MatchOperand_NoMatch)
210536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
2106c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
210736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *Expr = nullptr;
210836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.parseExpression(Expr)) {
210936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We have no way of knowing if a symbol was consumed so we must ParseFail
211036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_ParseFail;
2111c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
211236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(
211336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
211436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_Success;
2115ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
2116ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
2117d59ad8a8013fd76177fb61c741562af3024d34cdVladimir MedicMipsAsmParser::OperandMatchResultTy
2118cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::parseInvNum(OperandVector &Operands) {
2119d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  const MCExpr *IdVal;
2120d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  // If the first token is '$' we may have register operand.
2121d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  if (Parser.getTok().is(AsmToken::Dollar))
2122d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic    return MatchOperand_NoMatch;
2123d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  SMLoc S = Parser.getTok().getLoc();
2124d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  if (getParser().parseExpression(IdVal))
2125d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic    return MatchOperand_ParseFail;
2126d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
21272263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  assert(MCE && "Unexpected MCExpr type.");
2128d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  int64_t Val = MCE->getValue();
2129d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
2130d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  Operands.push_back(MipsOperand::CreateImm(
213136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MCConstantExpr::Create(0 - Val, getContext()), S, E, *this));
2132d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  return MatchOperand_Success;
2133d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic}
2134d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic
213595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus AlmeidaMipsAsmParser::OperandMatchResultTy
2136cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen HinesMipsAsmParser::ParseLSAImm(OperandVector &Operands) {
213795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  switch (getLexer().getKind()) {
213895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  default:
213995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    return MatchOperand_NoMatch;
214095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  case AsmToken::LParen:
214195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  case AsmToken::Plus:
214295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  case AsmToken::Minus:
214395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  case AsmToken::Integer:
214495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    break;
214595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  }
214695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
214795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  const MCExpr *Expr;
214895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  SMLoc S = Parser.getTok().getLoc();
214995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
215095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  if (getParser().parseExpression(Expr))
215195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    return MatchOperand_ParseFail;
215295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
215395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  int64_t Val;
215495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  if (!Expr->EvaluateAsAbsolute(Val)) {
215595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Error(S, "expected immediate value");
215695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    return MatchOperand_ParseFail;
215795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  }
215895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
215995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  // The LSA instruction allows a 2-bit unsigned immediate. For this reason
216095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  // and because the CPU always adds one to the immediate field, the allowed
216195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  // range becomes 1..4. We'll only check the range here and will deal
216295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  // with the addition/subtraction when actually decoding/encoding
216395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  // the instruction.
216495adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  if (Val < 1 || Val > 4) {
216595adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Error(S, "immediate not in range (1..4)");
216695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    return MatchOperand_ParseFail;
216795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  }
216895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
216936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(
217036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MipsOperand::CreateImm(Expr, S, Parser.getTok().getLoc(), *this));
217195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  return MatchOperand_Success;
217295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida}
217395adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
21746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack CarterMCSymbolRefExpr::VariantKind MipsAsmParser::getVariantKind(StringRef Symbol) {
21756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
21762263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  MCSymbolRefExpr::VariantKind VK =
21772263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      StringSwitch<MCSymbolRefExpr::VariantKind>(Symbol)
21782263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("hi", MCSymbolRefExpr::VK_Mips_ABS_HI)
21792263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("lo", MCSymbolRefExpr::VK_Mips_ABS_LO)
21802263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("gp_rel", MCSymbolRefExpr::VK_Mips_GPREL)
21812263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("call16", MCSymbolRefExpr::VK_Mips_GOT_CALL)
21822263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("got", MCSymbolRefExpr::VK_Mips_GOT)
21832263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("tlsgd", MCSymbolRefExpr::VK_Mips_TLSGD)
21842263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("tlsldm", MCSymbolRefExpr::VK_Mips_TLSLDM)
21852263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("dtprel_hi", MCSymbolRefExpr::VK_Mips_DTPREL_HI)
21862263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("dtprel_lo", MCSymbolRefExpr::VK_Mips_DTPREL_LO)
21872263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("gottprel", MCSymbolRefExpr::VK_Mips_GOTTPREL)
21882263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("tprel_hi", MCSymbolRefExpr::VK_Mips_TPREL_HI)
21892263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("tprel_lo", MCSymbolRefExpr::VK_Mips_TPREL_LO)
21902263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("got_disp", MCSymbolRefExpr::VK_Mips_GOT_DISP)
21912263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("got_page", MCSymbolRefExpr::VK_Mips_GOT_PAGE)
21922263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("got_ofst", MCSymbolRefExpr::VK_Mips_GOT_OFST)
21932263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("hi(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_HI)
21942263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Case("lo(%neg(%gp_rel", MCSymbolRefExpr::VK_Mips_GPOFF_LO)
219536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .Case("got_hi", MCSymbolRefExpr::VK_Mips_GOT_HI16)
219636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .Case("got_lo", MCSymbolRefExpr::VK_Mips_GOT_LO16)
219736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .Case("call_hi", MCSymbolRefExpr::VK_Mips_CALL_HI16)
219836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .Case("call_lo", MCSymbolRefExpr::VK_Mips_CALL_LO16)
219936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .Case("higher", MCSymbolRefExpr::VK_Mips_HIGHER)
220036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          .Case("highest", MCSymbolRefExpr::VK_Mips_HIGHEST)
2201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("pcrel_hi", MCSymbolRefExpr::VK_Mips_PCREL_HI16)
2202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          .Case("pcrel_lo", MCSymbolRefExpr::VK_Mips_PCREL_LO16)
22032263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          .Default(MCSymbolRefExpr::VK_None);
22046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
2205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  assert(VK != MCSymbolRefExpr::VK_None);
220636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
22076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  return VK;
22086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
2209f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
221036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Sometimes (i.e. load/stores) the operand may be followed immediately by
221136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// either this.
221236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '(', register, ')'
221336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handle it before we iterate so we don't get tripped up by the lack of
221436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a comma.
2215cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseParenSuffix(StringRef Name, OperandVector &Operands) {
221636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().is(AsmToken::LParen)) {
221736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
221836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
221936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
222036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ParseOperand(Operands, Name)) {
222136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
222236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
222336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token in argument list");
222436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
222536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::RParen)) {
222636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
222736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
222836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token, expected ')'");
222936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
223036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
223136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
223236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
223336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
223436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
223536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
223636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
223736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Sometimes (i.e. in MSA) the operand may be followed immediately by
223836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// either one of these.
223936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '[', register, ']'
224036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '[', integer, ']'
224136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handle it before we iterate so we don't get tripped up by the lack of
224236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a comma.
2243cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseBracketSuffix(StringRef Name,
2244cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                       OperandVector &Operands) {
224536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().is(AsmToken::LBrac)) {
224636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
224736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
224836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
224936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (ParseOperand(Operands, Name)) {
225036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
225136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
225236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token in argument list");
225336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
225436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::RBrac)) {
225536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
225636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
225736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token, expected ']'");
225836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
225936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
226036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
226136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
226236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
226336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
226436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
226536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2266cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
2267cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                     SMLoc NameLoc, OperandVector &Operands) {
226836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "ParseInstruction\n");
2269cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // We have reached first instruction, module directive after
2270cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // this is forbidden.
2271cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getTargetStreamer().setCanHaveModuleDir(false);
2272fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic  // Check if we have valid mnemonic
2273f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  if (!mnemonicIsValid(Name, 0)) {
2274fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic    Parser.eatToEndOfStatement();
2275fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic    return Error(NameLoc, "Unknown instruction");
2276fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic  }
2277088483627720acb58c96951b7b634f67312c7272Vladimir Medic  // First operand in MCInst is instruction mnemonic.
227836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
2279ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
2280ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
2281ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2282ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
2283088483627720acb58c96951b7b634f67312c7272Vladimir Medic    if (ParseOperand(Operands, Name)) {
2284ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
2285cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
2286ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
2287ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
228836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (getLexer().is(AsmToken::LBrac) && ParseBracketSuffix(Name, Operands))
228936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
229036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AFAIK, parenthesis suffixes are never on the first operand
2291ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
229286924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().is(AsmToken::Comma)) {
229386924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the comma.
2294ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
2295ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ParseOperand(Operands, Name)) {
2296ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
2297cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
2298ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
2299ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
230036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Parse bracket and parenthesis suffixes before we iterate
230136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (getLexer().is(AsmToken::LBrac)) {
230236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (ParseBracketSuffix(Name, Operands))
230336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return true;
230436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else if (getLexer().is(AsmToken::LParen) &&
230536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                 ParseParenSuffix(Name, Operands))
230636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return true;
2307ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
2308ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
2309ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2310ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
2311cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
2312ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
2313ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
231486924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
2315ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
2316fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
2317fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
2318cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::reportParseError(Twine ErrorMsg) {
231986924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc Loc = getLexer().getLoc();
232086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.eatToEndOfStatement();
232186924b4182537745659f2660244f3402c1e1ca4dJack Carter  return Error(Loc, ErrorMsg);
232230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
232330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
2324cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
2325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Error(Loc, ErrorMsg);
2326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
232830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() {
232986924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line should look like: ".set noat".
233086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // set at reg to 0.
233110d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setATReg(0);
233230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // eat noat
233330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
233486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
233530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
233630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
233730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
233830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
233986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
234030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
234130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
234286924b4182537745659f2660244f3402c1e1ca4dJack Carter
234330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() {
234486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line can be .set at - defaults to $1
234530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  // or .set at=$reg
234699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int AtRegNo;
234730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  getParser().Lex();
234830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().is(AsmToken::EndOfStatement)) {
234910d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter    Options.setATReg(1);
235086924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
235130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
235230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (getLexer().is(AsmToken::Equal)) {
235386924b4182537745659f2660244f3402c1e1ca4dJack Carter    getParser().Lex(); // Eat the '='.
235430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::Dollar)) {
235530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
235630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
235730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
235886924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '$'.
235999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    const AsmToken &Reg = Parser.getTok();
236099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (Reg.is(AsmToken::Identifier)) {
236199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = matchCPURegisterName(Reg.getIdentifier());
236299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else if (Reg.is(AsmToken::Integer)) {
236399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      AtRegNo = Reg.getIntVal();
236499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else {
236530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
236630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
236730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
236899e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
236936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (AtRegNo < 0 || AtRegNo > 31) {
237099e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      reportParseError("unexpected token in statement");
237199e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      return false;
237299e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    }
237399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
237499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    if (!Options.setATReg(AtRegNo)) {
237530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
237630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
237730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    }
237886924b4182537745659f2660244f3402c1e1ca4dJack Carter    getParser().Lex(); // Eat the register.
237930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
238030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    if (getLexer().isNot(AsmToken::EndOfStatement)) {
238130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      reportParseError("unexpected token in statement");
238230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
238386924b4182537745659f2660244f3402c1e1ca4dJack Carter    }
238486924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
238530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
238630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else {
238730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
238830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
238930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
239030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
239130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
239230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() {
239330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
239486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
239530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
239630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
239730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
239830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
239910d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setReorder();
240036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getTargetStreamer().emitDirectiveSetReorder();
240186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
240230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
240330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
240430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
240530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() {
240686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex();
240786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
240886924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
240986924b4182537745659f2660244f3402c1e1ca4dJack Carter    reportParseError("unexpected token in statement");
241030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
241186924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
241286924b4182537745659f2660244f3402c1e1ca4dJack Carter  Options.setNoreorder();
241336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getTargetStreamer().emitDirectiveSetNoReorder();
241486924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
241586924b4182537745659f2660244f3402c1e1ca4dJack Carter  return false;
241630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
241730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
241830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() {
241930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
242086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
242130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
242230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("unexpected token in statement");
242330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
242430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
242510d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setMacro();
242686924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
242730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
242830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
242930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
243030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() {
243130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
243286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
243330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
243430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
243530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
243630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
243710d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  if (Options.isReorder()) {
243830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
243930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
244030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
244110d5ff6b1dceec77c23cd200ef200e2e9dec4c85Jack Carter  Options.setNomacro();
244286924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
244330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
244430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
2445c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
244636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseSetNoMips16Directive() {
244736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex();
244836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If this is not the end of the statement, report an error.
244936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
245036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    reportParseError("unexpected token in statement");
245136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
245236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
245336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // For now do nothing.
245436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Consume the EndOfStatement.
245536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
245636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
245736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2458cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseSetFpDirective() {
2459cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsABIFlagsSection::FpABIKind FpAbiVal;
2460cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Line can be: .set fp=32
2461cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //              .set fp=xx
2462cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  //              .set fp=64
2463cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Eat fp token
2464cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  AsmToken Tok = Parser.getTok();
2465cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Tok.isNot(AsmToken::Equal)) {
2466cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError("unexpected token in statement");
2467cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2468cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2469cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Eat '=' token.
2470cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Tok = Parser.getTok();
2471cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2472cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!parseFpABIValue(FpAbiVal, ".set"))
2473cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2474cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2475cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2476cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError("unexpected token in statement");
2477cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2478cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2479cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
2480cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Consume the EndOfStatement.
2481cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
2482cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
2483cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2484c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() {
2485c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  StringRef Name;
2486c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  const MCExpr *Value;
2487c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
2488c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseIdentifier(Name))
2489c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected identifier after .set");
2490c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
2491c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().isNot(AsmToken::Comma))
2492c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("unexpected token in .set directive");
24938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  Lex(); // Eat comma
2494c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
249536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.parseExpression(Value))
2496c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    return reportParseError("expected valid expression after comma");
2497c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
249886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Check if the Name already exists as a symbol.
2499c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  MCSymbol *Sym = getContext().LookupSymbol(Name);
250086924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (Sym)
2501c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return reportParseError("symbol already defined");
2502c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym = getContext().GetOrCreateSymbol(Name);
2503c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym->setVariableValue(Value);
2504c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
2505c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
2506c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
250786924b4182537745659f2660244f3402c1e1ca4dJack Carter
250836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseSetFeature(uint64_t Feature) {
250936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex();
251036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
251136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return reportParseError("unexpected token in .set directive");
251236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Feature) {
2514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
2515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unimplemented feature");
2516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureDSP:
2517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    setFeatureBits(Mips::FeatureDSP, "dsp");
2518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetDsp();
251936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
2520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMicroMips:
2521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMicroMips();
252236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
2523dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips16:
2524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips16();
252536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
2526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips32r2:
2527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    setFeatureBits(Mips::FeatureMips32r2, "mips32r2");
2528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips32R2();
252936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
2530dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips64:
2531dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    setFeatureBits(Mips::FeatureMips64, "mips64");
2532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips64();
253336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
2534dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips64r2:
2535dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    setFeatureBits(Mips::FeatureMips64r2, "mips64r2");
2536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips64R2();
253736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
253836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
253936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
254036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
254136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
254236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::eatComma(StringRef ErrorStr) {
254336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::Comma)) {
254436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SMLoc Loc = getLexer().getLoc();
254536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.eatToEndOfStatement();
254636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(Loc, ErrorStr);
254736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
254836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat the comma.
255036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
255136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
255236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool MipsAsmParser::parseDirectiveCPLoad(SMLoc Loc) {
2554dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Options.isReorder())
2555dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Warning(Loc, ".cpload in reorder section");
2556dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2557dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // FIXME: Warn if cpload is used in Mips16 mode.
2558dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2559cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
2560dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OperandMatchResultTy ResTy = ParseAnyRegister(Reg);
2561dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
2562dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    reportParseError("expected register containing function address");
2563dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
2564dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2566cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
2567cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!RegOpnd.isGPRAsmReg()) {
2568cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError(RegOpnd.getStartLoc(), "invalid register");
2569dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
2570dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2571dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2572cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getTargetStreamer().emitDirectiveCpload(RegOpnd.getGPR32Reg());
2573dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2575dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
257636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveCPSetup() {
257736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned FuncReg;
257836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Save;
257936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SaveIsReg = true;
258036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2581cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
2582cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  OperandMatchResultTy ResTy = ParseAnyRegister(TmpReg);
2583cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (ResTy == MatchOperand_NoMatch) {
2584cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError("expected register containing function address");
2585cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.eatToEndOfStatement();
2586cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2587cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2588cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2589cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2590cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!FuncRegOpnd.isGPRAsmReg()) {
2591cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
2592cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.eatToEndOfStatement();
2593cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2594cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2595cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2596cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  FuncReg = FuncRegOpnd.getGPR32Reg();
2597cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  TmpReg.clear();
259836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
259936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!eatComma("expected comma parsing directive"))
260036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
260136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2602cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  ResTy = ParseAnyRegister(TmpReg);
2603cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (ResTy == MatchOperand_NoMatch) {
260436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const AsmToken &Tok = Parser.getTok();
260536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Tok.is(AsmToken::Integer)) {
260636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Save = Tok.getIntVal();
260736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SaveIsReg = false;
260836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.Lex();
2609cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    } else {
2610cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      reportParseError("expected save register or stack offset");
2611cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Parser.eatToEndOfStatement();
2612cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2613cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2614cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else {
2615cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
2616cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!SaveOpnd.isGPRAsmReg()) {
2617cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      reportParseError(SaveOpnd.getStartLoc(), "invalid register");
2618cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      Parser.eatToEndOfStatement();
2619cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2620cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2621cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Save = SaveOpnd.getGPR32Reg();
2622cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
262336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
262436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (!eatComma("expected comma parsing directive"))
262536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
262636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
262736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Name;
262836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.parseIdentifier(Name))
262936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    reportParseError("expected identifier");
263036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MCSymbol *Sym = getContext().GetOrCreateSymbol(Name);
263136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, *Sym, SaveIsReg);
2633dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
2634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
263536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool MipsAsmParser::parseDirectiveNaN() {
2637dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2638dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const AsmToken &Tok = Parser.getTok();
2639dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2640dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Tok.getString() == "2008") {
2641dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex();
2642dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      getTargetStreamer().emitDirectiveNaN2008();
2643dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2644dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (Tok.getString() == "legacy") {
2645dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex();
2646dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      getTargetStreamer().emitDirectiveNaNLegacy();
2647dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
2648dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
2649dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
2650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If we don't recognize the option passed to the .nan
2651dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // directive (e.g. no option or unknown option), emit an error.
2652dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  reportParseError("invalid option in .nan directive");
265336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
265436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
265536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
265630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() {
265730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
265886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Get the next token.
265930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok();
266030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
266130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Tok.getString() == "noat") {
266230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoAtDirective();
266330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "at") {
266430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetAtDirective();
2665cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  } else if (Tok.getString() == "fp") {
2666cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return parseSetFpDirective();
266730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "reorder") {
266830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetReorderDirective();
266930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "noreorder") {
267030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoReorderDirective();
267130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "macro") {
267230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetMacroDirective();
267330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomacro") {
267430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoMacroDirective();
267536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips16") {
267636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseSetFeature(Mips::FeatureMips16);
267730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomips16") {
267836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseSetNoMips16Directive();
267930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomicromips") {
268036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveSetNoMicroMips();
2681cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
268230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
268336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "micromips") {
2684dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMicroMips);
268536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips32r2") {
2686dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMips32r2);
268736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips64") {
2688dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMips64);
268936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips64r2") {
2690dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMips64r2);
269136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "dsp") {
2692dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureDSP);
2693c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  } else {
269486924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is just an identifier, look for an assignment.
2695c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    parseSetAssignment();
2696c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return false;
269730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
2698801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
269930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
270030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
270130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
270236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// parseDataDirective
2703801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter///  ::= .word [ expression (, expression)* ]
270436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
2705801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2706801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    for (;;) {
2707801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      const MCExpr *Value;
2708cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
2709801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return true;
2710801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
2711801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      getParser().getStreamer().EmitValue(Value, Size);
2712801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
2713801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().is(AsmToken::EndOfStatement))
2714801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        break;
2715801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
2716801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      // FIXME: Improve diagnostic.
2717801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().isNot(AsmToken::Comma))
2718801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return Error(L, "unexpected token in directive");
2719801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      Parser.Lex();
2720801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    }
2721801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
2722801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
2723801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  Parser.Lex();
2724801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  return false;
2725801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter}
2726801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
27272263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic/// parseDirectiveGpWord
27282263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic///  ::= .gpword local_sym
27292263a2ca72e21206d45a69532004a0b17881e733Vladimir Medicbool MipsAsmParser::parseDirectiveGpWord() {
27302263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  const MCExpr *Value;
27312263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  // EmitGPRel32Value requires an expression, so we are using base class
27322263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  // method to evaluate the expression.
27332263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  if (getParser().parseExpression(Value))
27342263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    return true;
27352263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  getParser().getStreamer().EmitGPRel32Value(Value);
27362263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic
2737c0fad4d9fdb1aebe029bcb54311fad7059b1a9e5Vladimir Medic  if (getLexer().isNot(AsmToken::EndOfStatement))
27382263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    return Error(getLexer().getLoc(), "unexpected token in directive");
2739c0fad4d9fdb1aebe029bcb54311fad7059b1a9e5Vladimir Medic  Parser.Lex(); // Eat EndOfStatement token.
27402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  return false;
27412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic}
27422263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic
274336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// parseDirectiveGpDWord
274436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///  ::= .gpdword local_sym
274536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveGpDWord() {
274636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *Value;
274736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // EmitGPRel64Value requires an expression, so we are using base class
274836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // method to evaluate the expression.
274936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getParser().parseExpression(Value))
275036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
275136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getParser().getStreamer().EmitGPRel64Value(Value);
275236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
275336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
275436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(getLexer().getLoc(), "unexpected token in directive");
275536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Eat EndOfStatement token.
275636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
275736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
2758acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
275936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveOption() {
276036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Get the option token.
276136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AsmToken Tok = Parser.getTok();
276236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // At the moment only identifiers are supported.
276336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Tok.isNot(AsmToken::Identifier)) {
276436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Error(Parser.getTok().getLoc(), "unexpected token in .option directive");
276536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.eatToEndOfStatement();
276636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
276736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
276836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
276936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Option = Tok.getIdentifier();
277036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
277136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Option == "pic0") {
277236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveOptionPic0();
277336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
277436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
277536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Error(Parser.getTok().getLoc(),
277636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            "unexpected token in .option pic0 directive");
277736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
277836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
277936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
278036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
278136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
278236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Option == "pic2") {
278336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveOptionPic2();
278436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
278536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
278636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Error(Parser.getTok().getLoc(),
278736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines            "unexpected token in .option pic2 directive");
278836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
278936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
279036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
279136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
279236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
279336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Unknown option.
279436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Warning(Parser.getTok().getLoc(), "unknown option in .option directive");
279536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.eatToEndOfStatement();
279636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
279736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
279836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2799cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveModule
2800cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= .module oddspreg
2801cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= .module nooddspreg
2802cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= .module fp=value
2803cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseDirectiveModule() {
2804cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCAsmLexer &Lexer = getLexer();
2805cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  SMLoc L = Lexer.getLoc();
2806cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2807cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!getTargetStreamer().getCanHaveModuleDir()) {
2808cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // TODO : get a better message.
2809cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError(".module directive must appear before any code");
2810cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2811cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2812cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2813cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Lexer.is(AsmToken::Identifier)) {
2814cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    StringRef Option = Parser.getTok().getString();
2815cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.Lex();
2816cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2817cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Option == "oddspreg") {
2818cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      getTargetStreamer().emitDirectiveModuleOddSPReg(true, isABI_O32());
2819cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2820cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2821cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (getLexer().isNot(AsmToken::EndOfStatement)) {
2822cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        reportParseError("Expected end of statement");
2823cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return false;
2824cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
2825cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2826cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2827cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    } else if (Option == "nooddspreg") {
2828cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (!isABI_O32()) {
2829cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        Error(L, "'.module nooddspreg' requires the O32 ABI");
2830cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return false;
2831cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
2832cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2833cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      getTargetStreamer().emitDirectiveModuleOddSPReg(false, isABI_O32());
2834cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
2835cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2836cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (getLexer().isNot(AsmToken::EndOfStatement)) {
2837cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        reportParseError("Expected end of statement");
2838cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return false;
2839cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
2840cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2841cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2842cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    } else if (Option == "fp") {
2843cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return parseDirectiveModuleFP();
2844cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2845cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2846cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
2847cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2848cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2849cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
2850cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
2851cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2852cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines/// parseDirectiveModuleFP
2853cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= =32
2854cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= =xx
2855cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines///  ::= =64
2856cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseDirectiveModuleFP() {
2857cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCAsmLexer &Lexer = getLexer();
2858cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2859cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Lexer.isNot(AsmToken::Equal)) {
2860cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError("unexpected token in statement");
2861cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2862cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2863cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Eat '=' token.
2864cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2865cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MipsABIFlagsSection::FpABIKind FpABI;
2866cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (!parseFpABIValue(FpABI, ".module"))
2867cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2868cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2869cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
2870cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    reportParseError("unexpected token in statement");
2871cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return false;
2872cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2873cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2874cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // Emit appropriate flags.
2875cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  getTargetStreamer().emitDirectiveModuleFP(FpABI, isABI_O32());
2876cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  Parser.Lex(); // Consume the EndOfStatement.
2877cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
2878cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
2879cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2880cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesbool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
2881cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines                                    StringRef Directive) {
2882cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  MCAsmLexer &Lexer = getLexer();
2883cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2884cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Lexer.is(AsmToken::Identifier)) {
2885cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    StringRef Value = Parser.getTok().getString();
2886cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.Lex();
2887cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2888cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Value != "xx") {
2889cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      reportParseError("unsupported value, expected 'xx', '32' or '64'");
2890cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2891cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2892cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2893cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (!isABI_O32()) {
2894cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
2895cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2896cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2897cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2898cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    FpABI = MipsABIFlagsSection::FpABIKind::XX;
2899cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return true;
2900cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2901cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2902cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (Lexer.is(AsmToken::Integer)) {
2903cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    unsigned Value = Parser.getTok().getIntVal();
2904cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    Parser.Lex();
2905cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2906cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Value != 32 && Value != 64) {
2907cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      reportParseError("unsupported value, expected 'xx', '32' or '64'");
2908cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      return false;
2909cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    }
2910cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2911cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    if (Value == 32) {
2912cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      if (!isABI_O32()) {
2913cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
2914cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines        return false;
2915cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      }
2916cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2917cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      FpABI = MipsABIFlagsSection::FpABIKind::S32;
2918cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    } else
2919cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      FpABI = MipsABIFlagsSection::FpABIKind::S64;
2920cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2921cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return true;
2922cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  }
2923cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
2924cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  return false;
2925cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines}
2926cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
292736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
2928801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  StringRef IDVal = DirectiveID.getString();
2929801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
2930dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal == ".cpload")
2931dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveCPLoad(DirectiveID.getLoc());
293236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".dword") {
293336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    parseDataDirective(8, DirectiveID.getLoc());
293436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
293536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
293636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
293786924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (IDVal == ".ent") {
293886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
2939acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
2940acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
2941acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2942acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
2943801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".end") {
294486924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
2945acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    Parser.Lex();
2946acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
2947acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2948acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
2949801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".frame") {
295086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
2951cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
2952acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
2953acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2954acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
2955801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".set") {
295630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseDirectiveSet();
2957acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2958acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
2959801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".fmask") {
296086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
2961cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
2962acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
2963acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2964acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
2965801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".mask") {
296686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Ignore this directive for now.
2967cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
2968acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
2969acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2970acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
2971dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal == ".nan")
2972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveNaN();
2973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
2974801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".gpword") {
29752263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    parseDirectiveGpWord();
2976acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
2977acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
2978acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
297936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".gpdword") {
298036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    parseDirectiveGpDWord();
298136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
298236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
298336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
2984801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".word") {
298536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    parseDataDirective(4, DirectiveID.getLoc());
2986801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    return false;
2987801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
2988801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
298936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".option")
299036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveOption();
299136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
299236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".abicalls") {
299336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveAbiCalls();
299436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
299536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Error(Parser.getTok().getLoc(), "unexpected token in directive");
299636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Clear line
299736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
299836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
299936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
300036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
3001a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling
300236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".cpsetup")
300336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseDirectiveCPSetup();
3004a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling
3005cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  if (IDVal == ".module")
3006cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    return parseDirectiveModule();
3007cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
3008fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
3009fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
3010fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
3011fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
3012fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
3013fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
3014fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
3015fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
3016fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
3017ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3018ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
3019ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
3020ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
3021