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
10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "MCTargetDesc/MipsABIInfo.h"
1136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "MCTargetDesc/MipsMCExpr.h"
12fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola#include "MCTargetDesc/MipsMCTargetDesc.h"
13ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsRegisterInfo.h"
14f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar#include "MipsTargetObjectFile.h"
15320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola#include "MipsTargetStreamer.h"
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/ADT/SmallVector.h"
17ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/ADT/StringSwitch.h"
18ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCContext.h"
19ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCExpr.h"
20ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCInst.h"
2136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/MC/MCInstBuilder.h"
22d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCAsmLexer.h"
23d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
24de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/MC/MCParser/MCTargetAsmParser.h"
25de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/MC/MCSectionELF.h"
26ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCStreamer.h"
27ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSubtargetInfo.h"
28ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "llvm/MC/MCSymbol.h"
2936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/Debug.h"
30de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/Support/ELF.h"
3136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/MathExtras.h"
3237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Support/SourceMgr.h"
33ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/TargetRegistry.h"
344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar#include "llvm/Support/raw_ostream.h"
3537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include <memory>
36fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
37fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolausing namespace llvm;
38fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
39dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "mips-asm-parser"
40dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
41715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Goulynamespace llvm {
42715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Goulyclass MCInstrInfo;
43715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly}
44715d98d657491b3fb8ea0e14643e9801b2f9628cJoey Gouly
45fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolanamespace {
4630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterclass MipsAssemblerOptions {
4730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterpublic:
486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MipsAssemblerOptions(const FeatureBitset &Features_) :
4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ATReg(1), Reorder(true), Macro(true), Features(Features_) {}
5030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MipsAssemblerOptions(const MipsAssemblerOptions *Opts) {
526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    ATReg = Opts->getATRegIndex();
5337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Reorder = Opts->isReorder();
5437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Macro = Opts->isMacro();
5537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Features = Opts->getFeatures();
5637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
57ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned getATRegIndex() const { return ATReg; }
596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool setATRegIndex(unsigned Reg) {
604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    if (Reg > 31)
614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar      return false;
624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    ATReg = Reg;
644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    return true;
654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
6630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
6737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool isReorder() const { return Reorder; }
6837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void setReorder() { Reorder = true; }
6937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void setNoReorder() { Reorder = false; }
7037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool isMacro() const { return Macro; }
7237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void setMacro() { Macro = true; }
7337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void setNoMacro() { Macro = false; }
7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const FeatureBitset &getFeatures() const { return Features; }
766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void setFeatures(const FeatureBitset &Features_) { Features = Features_; }
7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
7837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Set of features that are either architecture features or referenced
7937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // by them (e.g.: FeatureNaN2008 implied by FeatureMips32r6).
8037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The full table can be found in MipsGenSubtargetInfo.inc (MipsFeatureKV[]).
8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The reason we need this mask is explained in the selectArch function.
8237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // FIXME: Ideally we would like TableGen to generate this information.
836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  static const FeatureBitset AllArchRelatedMask;
8430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
8530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterprivate:
8637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned ATReg;
8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Reorder;
8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool Macro;
896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  FeatureBitset Features;
9030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter};
9130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
9230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarconst FeatureBitset MipsAssemblerOptions::AllArchRelatedMask = {
946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips1, Mips::FeatureMips2, Mips::FeatureMips3,
956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips3_32, Mips::FeatureMips3_32r2, Mips::FeatureMips4,
966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips4_32, Mips::FeatureMips4_32r2, Mips::FeatureMips5,
976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips5_32r2, Mips::FeatureMips32, Mips::FeatureMips32r2,
986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips32r3, Mips::FeatureMips32r5, Mips::FeatureMips32r6,
996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips64, Mips::FeatureMips64r2, Mips::FeatureMips64r3,
1006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureMips64r5, Mips::FeatureMips64r6, Mips::FeatureCnMips,
1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Mips::FeatureFP64Bit, Mips::FeatureGP64Bit, Mips::FeatureNaN2008
1026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar};
1036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
10430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carternamespace {
105fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaclass MipsAsmParser : public MCTargetAsmParser {
106320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  MipsTargetStreamer &getTargetStreamer() {
10737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MCTargetStreamer &TS = *getParser().getStreamer().getTargetStreamer();
108320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola    return static_cast<MipsTargetStreamer &>(TS);
109320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola  }
110320296a4cfe414ce59f406b8a5ce15272f563103Rafael Espindola
111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MipsABIInfo ABI;
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<std::unique_ptr<MipsAssemblerOptions>, 2> AssemblerOptions;
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCSymbol *CurrentFn; // Pointer to the function being parsed. It may be a
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       // nullptr, which indicates that no function is currently
11537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       // selected. This usually happens after an '.end func'
11637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       // directive.
117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool IsLittleEndian;
118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool IsPicEnabled;
119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool IsCpRestoreSet;
120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int CpRestoreOffset;
121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned CpSaveLocation;
122f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// If true, then CpSaveLocation is a register, otherwise it's an offset.
123f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool     CpSaveLocationIsRegister;
12437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
12537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Print a warning along with its fix-it message at the given range.
12637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
12737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             SMRange Range, bool ShowColors = true);
12830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
12972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#define GET_ASSEMBLER_HEADER
13072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka#include "MipsGenAsmMatcher.inc"
13172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
132c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  unsigned checkTargetMatchPredicate(MCInst &Inst) override;
133c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
13484125ca43c758fd21fdab2b05196e0df57c55c96Chad Rosier  bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
135c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                               OperandVector &Operands, MCStreamer &Out,
13637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               uint64_t &ErrorInfo,
137dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                               bool MatchingInlineAsm) override;
138fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
13936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Parse a register as used in CFI directives
140dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
141fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
14237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseParenSuffix(StringRef Name, OperandVector &Operands);
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
14437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseBracketSuffix(StringRef Name, OperandVector &Operands);
14536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
146c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                        SMLoc NameLoc, OperandVector &Operands) override;
148fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool ParseDirective(AsmToken DirectiveID) override;
150fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseMemOperand(OperandVector &Operands);
152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy
15337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
154c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                    StringRef Identifier, SMLoc S);
155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy matchAnyRegisterWithoutDollar(OperandVector &Operands,
156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                                     SMLoc S);
157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseAnyRegister(OperandVector &Operands);
158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseImm(OperandVector &Operands);
159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseJumpTarget(OperandVector &Operands);
160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseInvNum(OperandVector &Operands);
161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseRegisterPair(OperandVector &Operands);
162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseMovePRegPair(OperandVector &Operands);
163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  OperandMatchResultTy parseRegisterList(OperandVector &Operands);
164c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
165c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool searchSymbolAlias(OperandVector &Operands);
166c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
16737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseOperand(OperandVector &, StringRef Mnemonic);
168ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  enum MacroExpanderResultTy {
170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MER_NotAMacro,
171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MER_Success,
172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MER_Fail,
173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  };
1749d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
175c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Expands assembly pseudo instructions.
176de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MacroExpanderResultTy tryExpandInstruction(MCInst &Inst, SMLoc IDLoc,
177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                             MCStreamer &Out,
178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                             const MCSubtargetInfo *STI);
179c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandJalWithRegs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         const MCSubtargetInfo *STI);
182ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool loadImmediate(int64_t ImmValue, unsigned DstReg, unsigned SrcReg,
184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                     bool Is32BitImm, bool IsAddress, SMLoc IDLoc,
185de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     MCStreamer &Out, const MCSubtargetInfo *STI);
186c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool loadAndAddSymbolAddress(const MCExpr *SymExpr, unsigned DstReg,
188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                               unsigned SrcReg, bool Is32BitSym, SMLoc IDLoc,
189de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                               MCStreamer &Out, const MCSubtargetInfo *STI);
190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     MCStreamer &Out, const MCSubtargetInfo *STI);
1936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool expandLoadAddress(unsigned DstReg, unsigned BaseReg,
195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                         const MCOperand &Offset, bool Is32BitAddress,
196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         SMLoc IDLoc, MCStreamer &Out,
197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         const MCSubtargetInfo *STI);
198c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                  const MCSubtargetInfo *STI);
201c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     const MCSubtargetInfo *STI, bool IsLoad, bool IsImmOpnd);
204ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      const MCSubtargetInfo *STI, bool IsImmOpnd);
207ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       const MCSubtargetInfo *STI, bool IsImmOpnd);
210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                               const MCSubtargetInfo *STI);
2136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandAliasImmediate(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                            const MCSubtargetInfo *STI);
216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       const MCSubtargetInfo *STI);
219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandCondBranches(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                          const MCSubtargetInfo *STI);
222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 const MCSubtargetInfo *STI, const bool IsMips64,
225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 const bool Signed);
226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU, SMLoc IDLoc,
228de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCStreamer &Out, const MCSubtargetInfo *STI);
229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc, MCStreamer &Out,
231de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 const MCSubtargetInfo *STI);
2324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
233de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
234de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 const MCSubtargetInfo *STI);
235f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandRotation(MCInst &Inst, SMLoc IDLoc,
237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      MCStreamer &Out, const MCSubtargetInfo *STI);
238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         const MCSubtargetInfo *STI);
240de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       const MCSubtargetInfo *STI);
242de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandDRotationImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                          const MCSubtargetInfo *STI);
244de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
246de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 const MCSubtargetInfo *STI);
2476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
248c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool reportParseError(Twine ErrorMsg);
249c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool reportParseError(SMLoc Loc, Twine ErrorMsg);
25030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
2518afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool parseMemOffset(const MCExpr *&Res, bool isParenExpr);
252ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  bool parseRelocOperand(const MCExpr *&Res);
25330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
2542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  const MCExpr *evaluateRelocExpr(const MCExpr *Expr, StringRef RelocStr);
2558afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
2568afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isEvaluated(const MCExpr *Expr);
25737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetMips0Directive();
25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetArchDirective();
25936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseSetFeature(uint64_t Feature);
260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isPicAndNotNxxAbi(); // Used by .cpload, .cprestore, and .cpsetup.
26137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseDirectiveCpLoad(SMLoc Loc);
262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool parseDirectiveCpRestore(SMLoc Loc);
26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveCPSetup();
264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool parseDirectiveCPReturn();
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool parseDirectiveNaN();
26630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseDirectiveSet();
26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveOption();
2680c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  bool parseInsnDirective();
269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool parseSSectionDirective(StringRef Section, unsigned Type);
27030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
27130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetAtDirective();
27230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoAtDirective();
27330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetMacroDirective();
27430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoMacroDirective();
27537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetMsaDirective();
27637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetNoMsaDirective();
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetNoDspDirective();
27830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetReorderDirective();
27930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  bool parseSetNoReorderDirective();
28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetMips16Directive();
28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseSetNoMips16Directive();
282c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool parseSetFpDirective();
283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool parseSetOddSPRegDirective();
284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool parseSetNoOddSPRegDirective();
28537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetPopDirective();
28637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool parseSetPushDirective();
2876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool parseSetSoftFloatDirective();
2886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool parseSetHardFloatDirective();
28930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
290c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  bool parseSetAssignment();
291c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDataDirective(unsigned Size, SMLoc L);
2932263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  bool parseDirectiveGpWord();
29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool parseDirectiveGpDWord();
295c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool parseDirectiveModule();
296c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool parseDirectiveModuleFP();
297c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
298c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                       StringRef Directive);
299801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
3004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  bool parseInternalDirectiveReallowModule();
3014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool eatComma(StringRef ErrorStr);
303ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
30499e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  int matchCPURegisterName(StringRef Symbol);
30599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
30637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int matchHWRegsRegisterName(StringRef Symbol);
30737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
308bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  int matchFPURegisterName(StringRef Name);
3097231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
310bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  int matchFCCRegisterName(StringRef Name);
311f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
312bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  int matchACRegisterName(StringRef Name);
313f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
31442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  int matchMSA128RegisterName(StringRef Name);
31542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
316006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  int matchMSA128CtrlRegisterName(StringRef Name);
317006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
31886924b4182537745659f2660244f3402c1e1ca4dJack Carter  unsigned getReg(int RC, int RegNo);
319038f3e31276f8cc86d91d0e4513e1a3ddb8509baChad Rosier
3200c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /// Returns the internal register number for the current AT. Also checks if
3210c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /// the current AT is unavailable (set to $0) and gives an error if it is.
3220c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  /// This should be used in pseudo-instruction expansions which need AT.
3230c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  unsigned getATReg(SMLoc Loc);
32425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                          const MCSubtargetInfo *STI);
32745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
32845ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  // Helper function that checks if the value of a vector index is within the
32945ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  // boundaries of accepted values for each RegisterKind
33045ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  // Example: INSERT.B $w0[n], $1 => 16 > n >= 0
33145ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  bool validateMSAIndex(int Val, int RegKind);
33245ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Selects a new architecture by updating the FeatureBits with the necessary
33437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // info including implied dependencies.
33537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Internally, it clears all the feature bits related to *any* architecture
33637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // and selects the new one using the ToggleFeature functionality of the
33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // MCSubtargetInfo object that handles implied dependencies. The reason we
33837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // clear all the arch related bits manually is because ToggleFeature only
33937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // clears the features that imply the feature being cleared and not the
34037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // features implied by the feature being cleared. This is easier to see
34137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // with an example:
34237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //  --------------------------------------------------
34337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | Feature         | Implies                        |
34437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | -------------------------------------------------|
34537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | FeatureMips1    | None                           |
34637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | FeatureMips2    | FeatureMips1                   |
34737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | FeatureMips3    | FeatureMips2 | FeatureMipsGP64 |
34837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | FeatureMips4    | FeatureMips3                   |
34937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // | ...             |                                |
35037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //  --------------------------------------------------
35137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  //
35237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Setting Mips3 is equivalent to set: (FeatureMips3 | FeatureMips2 |
35337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // FeatureMipsGP64 | FeatureMips1)
35437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Clearing Mips3 is equivalent to clear (FeatureMips3 | FeatureMips4).
35537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void selectArch(StringRef ArchFeature) {
356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MCSubtargetInfo &STI = copySTI();
3576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    FeatureBitset FeatureBits = STI.getFeatureBits();
35837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    FeatureBits &= ~MipsAssemblerOptions::AllArchRelatedMask;
35937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    STI.setFeatureBits(FeatureBits);
36037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    setAvailableFeatures(
36137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        ComputeAvailableFeatures(STI.ToggleFeature(ArchFeature)));
3626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
36337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
36437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void setFeatureBits(uint64_t Feature, StringRef FeatureString) {
366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!(getSTI().getFeatureBits()[Feature])) {
367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MCSubtargetInfo &STI = copySTI();
368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      setAvailableFeatures(
369dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
3706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
37236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
37437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void clearFeatureBits(uint64_t Feature, StringRef FeatureString) {
375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (getSTI().getFeatureBits()[Feature]) {
376f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      MCSubtargetInfo &STI = copySTI();
377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      setAvailableFeatures(
378dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          ComputeAvailableFeatures(STI.ToggleFeature(FeatureString)));
3796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      AssemblerOptions.back()->setFeatures(STI.getFeatureBits());
38036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
38136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
38236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
383f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void setModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
384f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setFeatureBits(Feature, FeatureString);
385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void clearModuleFeatureBits(uint64_t Feature, StringRef FeatureString) {
389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    clearFeatureBits(Feature, FeatureString);
390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AssemblerOptions.front()->setFeatures(getSTI().getFeatureBits());
391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
393fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolapublic:
394c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  enum MipsMatchResultTy {
395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Match_RequiresDifferentSrcAndDst = FIRST_TARGET_MATCH_RESULT_TY,
396de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Match_RequiresDifferentOperands,
397de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Match_RequiresNoZeroRegister,
398c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#define GET_OPERAND_DIAGNOSTIC_TYPES
399c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "MipsGenAsmMatcher.inc"
400c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#undef GET_OPERAND_DIAGNOSTIC_TYPES
401c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  };
402c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
403f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MipsAsmParser(const MCSubtargetInfo &sti, MCAsmParser &parser,
404c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                const MCInstrInfo &MII, const MCTargetOptions &Options)
405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    : MCTargetAsmParser(Options, sti),
406ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        ABI(MipsABIInfo::computeTargetABI(Triple(sti.getTargetTriple()),
407ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                          sti.getCPU(), Options)) {
40837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MCAsmParserExtension::Initialize(parser);
40937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    parser.addAliasForDirective(".asciiz", ".asciz");
4116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
412ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Initialize the set of available features.
413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
41537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Remember the initial assembler options. The user can not modify these.
41637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    AssemblerOptions.push_back(
417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
41937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Create an assembler options environment for the user to modify.
42037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    AssemblerOptions.push_back(
421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        llvm::make_unique<MipsAssemblerOptions>(getSTI().getFeatureBits()));
42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
423c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    getTargetStreamer().updateABIInfo(*this);
424c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
42537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!isABI_O32() && !useOddSPReg() != 0)
426c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      report_fatal_error("-mno-odd-spreg requires the O32 ABI");
427fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
42837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CurrentFn = nullptr;
429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    IsPicEnabled = getContext().getObjectFileInfo()->isPositionIndependent();
431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsCpRestoreSet = false;
433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CpRestoreOffset = -1;
434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const Triple &TheTriple = sti.getTargetTriple();
436f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if ((TheTriple.getArch() == Triple::mips) ||
437f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        (TheTriple.getArch() == Triple::mips64))
438f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      IsLittleEndian = false;
439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      IsLittleEndian = true;
44137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
443c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  /// True if all of $fcc0 - $fcc7 exist for the current ISA.
444c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasEightFccRegisters() const { return hasMips4() || hasMips32(); }
445c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isGP64bit() const {
447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureGP64Bit];
448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isFP64bit() const {
450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureFP64Bit];
451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
452ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const MipsABIInfo &getABI() const { return ABI; }
453ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isABI_N32() const { return ABI.IsN32(); }
454ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isABI_N64() const { return ABI.IsN64(); }
455ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isABI_O32() const { return ABI.IsO32(); }
456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isABI_FPXX() const {
457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureFPXX];
458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
459c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
46037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool useOddSPReg() const {
461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return !(getSTI().getFeatureBits()[Mips::FeatureNoOddSPReg]);
462c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
463c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
464c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool inMicroMipsMode() const {
465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMicroMips];
466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasMips1() const {
468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips1];
469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasMips2() const {
471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips2];
472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasMips3() const {
474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips3];
475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasMips4() const {
477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips4];
478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasMips5() const {
480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips5];
481c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
482c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasMips32() const {
483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips32];
484c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
485c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasMips64() const {
486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips64];
487c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
488c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasMips32r2() const {
489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips32r2];
490c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
491c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasMips64r2() const {
492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips64r2];
493c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
494ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasMips32r3() const {
495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return (getSTI().getFeatureBits()[Mips::FeatureMips32r3]);
496ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
497ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasMips64r3() const {
498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return (getSTI().getFeatureBits()[Mips::FeatureMips64r3]);
499ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
500ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasMips32r5() const {
501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return (getSTI().getFeatureBits()[Mips::FeatureMips32r5]);
502ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
503ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasMips64r5() const {
504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return (getSTI().getFeatureBits()[Mips::FeatureMips64r5]);
505ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
506c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasMips32r6() const {
507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips32r6];
508c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
509c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool hasMips64r6() const {
510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips64r6];
511c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasDSP() const {
514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureDSP];
515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasDSPR2() const {
517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureDSPR2];
518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasDSPR3() const {
520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureDSPR3];
521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool hasMSA() const {
523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMSA];
524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool hasCnMips() const {
526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return (getSTI().getFeatureBits()[Mips::FeatureCnMips]);
527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool inPicMode() {
530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return IsPicEnabled;
531ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
532c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
533c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool inMips16Mode() const {
534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureMips16];
535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool useTraps() const {
538f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureUseTCCInDIV];
5396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
5406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
5416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool useSoftFloat() const {
542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSTI().getFeatureBits()[Mips::FeatureSoftFloat];
543c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
544c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  /// Warn if RegIndex is the same as the current AT.
5466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc);
5476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
5486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  void warnIfNoMacro(SMLoc Loc);
549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isLittle() const { return IsLittleEndian; }
551fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola};
552fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
553fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
55472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakanamespace {
55572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
55672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// MipsOperand - Instances of this class represent a parsed Mips machine
55772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka/// instruction.
55872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakaclass MipsOperand : public MCParsedAsmOperand {
559ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterpublic:
56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Broad categories of register classes
56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// The exact class is finalized by the render method.
56236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  enum RegKind {
563c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    RegKind_GPR = 1,      /// GPR32 and GPR64 (depending on isGP64bit())
56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_FGR = 2,      /// FGR32, FGR64, AFGR64 (depending on context and
565c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                          /// isFP64bit())
56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_FCC = 4,      /// FCC
56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_MSA128 = 8,   /// MSA128[BHWD] (makes no difference which)
56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_MSACtrl = 16, /// MSA control registers
56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_COP2 = 32,    /// COP2
57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_ACC = 64,     /// HI32DSP, LO32DSP, and ACC64DSP (depending on
57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                          /// context).
57236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_CCR = 128,    /// CCR
57336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_HWRegs = 256, /// HWRegs
574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    RegKind_COP3 = 512,   /// COP3
575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RegKind_COP0 = 1024,  /// COP0
57636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    /// Potentially any (e.g. $1)
57736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind_Numeric = RegKind_GPR | RegKind_FGR | RegKind_FCC | RegKind_MSA128 |
57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                      RegKind_MSACtrl | RegKind_COP2 | RegKind_ACC |
579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                      RegKind_CCR | RegKind_HWRegs | RegKind_COP3 | RegKind_COP0
580ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  };
581ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
582ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carterprivate:
58372e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  enum KindTy {
58436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Immediate,     /// An immediate (possibly involving symbol references)
58536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_Memory,        /// Base + Offset Memory Address
58636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    k_RegisterIndex, /// A register index in one or more RegKind.
58737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    k_Token,         /// A simple token
588ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    k_RegList,       /// A physical register list
589ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    k_RegPair        /// A pair of physical register
59072e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  } Kind;
59172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
592c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinespublic:
59336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MipsOperand(KindTy K, MipsAsmParser &Parser)
59436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      : MCParsedAsmOperand(), Kind(K), AsmParser(Parser) {}
59536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
596c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesprivate:
59736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// For diagnostics, and checking the assembler temporary
59836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MipsAsmParser &AsmParser;
599ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
600a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct Token {
601a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const char *Data;
602a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    unsigned Length;
603a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
604a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
60536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  struct RegIdxOp {
60636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned Index; /// Index into the register class
60736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    RegKind Kind;   /// Bitfield of the kinds it could possibly be
60836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCRegisterInfo *RegInfo;
609a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
610a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
611a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct ImmOp {
612a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Val;
613a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
614a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
615a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  struct MemOp {
61636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MipsOperand *Base;
617a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    const MCExpr *Off;
618a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher  };
619a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher
62037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  struct RegListOp {
62137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallVector<unsigned, 10> *List;
62237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  };
62337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
624ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  union {
625a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct Token Tok;
62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    struct RegIdxOp RegIdx;
627a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct ImmOp Imm;
628a286fc065a5bc846d73c8407a534a1d3c1d70b59Eric Christopher    struct MemOp Mem;
62937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    struct RegListOp RegList;
630ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  };
631ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
632ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  SMLoc StartLoc, EndLoc;
633ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
63436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Internal constructor for register kinds
635c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand> CreateReg(unsigned Index, RegKind RegKind,
636c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                const MCRegisterInfo *RegInfo,
637c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                SMLoc S, SMLoc E,
638c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                MipsAsmParser &Parser) {
639c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<MipsOperand>(k_RegisterIndex, Parser);
64036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->RegIdx.Index = Index;
64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->RegIdx.RegInfo = RegInfo;
64236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->RegIdx.Kind = RegKind;
64336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->StartLoc = S;
64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Op->EndLoc = E;
64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Op;
64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
64736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
64872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanakapublic:
64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to GPR32 and return the real register for the current
65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getGPR32Reg() const {
65236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
6536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    AsmParser.warnIfRegIndexIsAT(RegIdx.Index, StartLoc);
65437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    unsigned ClassID = Mips::GPR32RegClassID;
65537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
65637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
65737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
65837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// Coerce the register to GPR32 and return the real register for the current
65937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// target.
66037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned getGPRMM16Reg() const {
66137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
66236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::GPR32RegClassID;
66336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
66472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
665ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to GPR64 and return the real register for the current
66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getGPR64Reg() const {
66936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_GPR) && "Invalid access!");
67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::GPR64RegClassID;
67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
67236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
67336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
67436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesprivate:
67536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to AFGR64 and return the real register for the current
67636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
67736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getAFGR64Reg() const {
67836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
67936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (RegIdx.Index % 2 != 0)
68036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      AsmParser.Warning(StartLoc, "Float register should be even.");
68136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::AFGR64RegClassID)
68236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index / 2);
68336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
68436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FGR64 and return the real register for the current
68636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFGR64Reg() const {
68836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FGR64RegClassID)
69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FGR32 and return the real register for the current
69436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
69536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFGR32Reg() const {
69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FGR32RegClassID)
69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FGRH32 and return the real register for the current
70236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
70336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFGRH32Reg() const {
70436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FGR) && "Invalid access!");
70536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FGRH32RegClassID)
70636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
70736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to FCC and return the real register for the current
71036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getFCCReg() const {
71236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_FCC) && "Invalid access!");
71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(Mips::FCCRegClassID)
71436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        .getRegister(RegIdx.Index);
71536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
71636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to MSA128 and return the real register for the current
71836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// target.
71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getMSA128Reg() const {
72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSA128) && "Invalid access!");
72136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // It doesn't matter which of the MSA128[BHWD] classes we use. They are all
72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // identical
72336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::MSA128BRegClassID;
72436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
72536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
72636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
72736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to MSACtrl and return the real register for the
72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getMSACtrlReg() const {
73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_MSACtrl) && "Invalid access!");
73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::MSACtrlRegClassID;
73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// Coerce the register to COP0 and return the real register for the
736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  /// current target.
737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned getCOP0Reg() const {
738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP0) && "Invalid access!");
739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned ClassID = Mips::COP0RegClassID;
740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
74336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to COP2 and return the real register for the
74436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
74536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getCOP2Reg() const {
74636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP2) && "Invalid access!");
74736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::COP2RegClassID;
74836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
74936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
75036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
751dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// Coerce the register to COP3 and return the real register for the
752dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  /// current target.
753dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getCOP3Reg() const {
754dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_COP3) && "Invalid access!");
755dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    unsigned ClassID = Mips::COP3RegClassID;
756dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
757dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
758dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
75936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to ACC64DSP and return the real register for the
76036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
76136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getACC64DSPReg() const {
76236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
76336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::ACC64DSPRegClassID;
76436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
76536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
76636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
76736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to HI32DSP and return the real register for the
76836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
76936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getHI32DSPReg() const {
77036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
77136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::HI32DSPRegClassID;
77236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
77336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
77436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
77536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to LO32DSP and return the real register for the
77636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
77736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getLO32DSPReg() const {
77836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_ACC) && "Invalid access!");
77936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::LO32DSPRegClassID;
78036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
78136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
78236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
78336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to CCR and return the real register for the
78436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
78536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getCCRReg() const {
78636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_CCR) && "Invalid access!");
78736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::CCRRegClassID;
78836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
78936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
79036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
79136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Coerce the register to HWRegs and return the real register for the
79236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// current target.
79336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned getHWRegsReg() const {
79436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(isRegIdx() && (RegIdx.Kind & RegKind_HWRegs) && "Invalid access!");
79536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    unsigned ClassID = Mips::HWRegsRegClassID;
79636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return RegIdx.RegInfo->getRegClass(ClassID).getRegister(RegIdx.Index);
797a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka  }
798a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
79936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic:
8002263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  void addExpr(MCInst &Inst, const MCExpr *Expr) const {
801ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Add as immediate when possible.  Null MCExpr = 0.
802dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!Expr)
8036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createImm(0));
804ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
8056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createImm(CE->getValue()));
806ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    else
8076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createExpr(Expr));
80872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
809ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
81036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addRegOperands(MCInst &Inst, unsigned N) const {
81136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    llvm_unreachable("Use a custom parser instead");
81236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
81336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
81436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Render the operand to an MCInst as a GPR32
81536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Asserts if the wrong number of operands are requested, or the operand
81636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// is not a k_RegisterIndex compatible with RegKind_GPR
81736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addGPR32AsmRegOperands(MCInst &Inst, unsigned N) const {
81836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getGPR32Reg()));
82036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
82136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
82237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void addGPRMM16AsmRegOperands(MCInst &Inst, unsigned N) const {
82337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
82537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
82637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
827ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addGPRMM16AsmRegZeroOperands(MCInst &Inst, unsigned N) const {
828ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(N == 1 && "Invalid number of operands!");
8296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
830ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
831ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addGPRMM16AsmRegMovePOperands(MCInst &Inst, unsigned N) const {
833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(N == 1 && "Invalid number of operands!");
8346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getGPRMM16Reg()));
835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
836ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
83736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Render the operand to an MCInst as a GPR64
83836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Asserts if the wrong number of operands are requested, or the operand
83936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// is not a k_RegisterIndex compatible with RegKind_GPR
84036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addGPR64AsmRegOperands(MCInst &Inst, unsigned N) const {
84136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getGPR64Reg()));
84336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
84436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
84536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addAFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
84636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getAFGR64Reg()));
84836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
84936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
85036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFGR64AsmRegOperands(MCInst &Inst, unsigned N) const {
85136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getFGR64Reg()));
85336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
85436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
85536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFGR32AsmRegOperands(MCInst &Inst, unsigned N) const {
85636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getFGR32Reg()));
858c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    // FIXME: We ought to do this for -integrated-as without -via-file-asm too.
85937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!AsmParser.useOddSPReg() && RegIdx.Index & 1)
860c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      AsmParser.Error(StartLoc, "-mno-odd-spreg prohibits the use of odd FPU "
861c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                "registers");
86236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
86336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
86436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFGRH32AsmRegOperands(MCInst &Inst, unsigned N) const {
86536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getFGRH32Reg()));
86736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
86836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
86936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addFCCAsmRegOperands(MCInst &Inst, unsigned N) const {
87036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getFCCReg()));
87236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
87336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addMSA128AsmRegOperands(MCInst &Inst, unsigned N) const {
87536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getMSA128Reg()));
87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addMSACtrlAsmRegOperands(MCInst &Inst, unsigned N) const {
88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getMSACtrlReg()));
88236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
88336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void addCOP0AsmRegOperands(MCInst &Inst, unsigned N) const {
885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(N == 1 && "Invalid number of operands!");
886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getCOP0Reg()));
887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
88936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addCOP2AsmRegOperands(MCInst &Inst, unsigned N) const {
89036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
8916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getCOP2Reg()));
89236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
89336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void addCOP3AsmRegOperands(MCInst &Inst, unsigned N) const {
895dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    assert(N == 1 && "Invalid number of operands!");
8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getCOP3Reg()));
897dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
898dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
89936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addACC64DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
90036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
9016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getACC64DSPReg()));
90236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
90336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addHI32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
90536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getHI32DSPReg()));
90736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
90836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
90936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addLO32DSPAsmRegOperands(MCInst &Inst, unsigned N) const {
91036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
9116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getLO32DSPReg()));
91236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
91336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addCCRAsmRegOperands(MCInst &Inst, unsigned N) const {
91536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
9166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getCCRReg()));
91736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
91836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
91936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  void addHWRegsAsmRegOperands(MCInst &Inst, unsigned N) const {
92036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(N == 1 && "Invalid number of operands!");
9216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getHWRegsReg()));
92236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
92336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  void addConstantUImmOperands(MCInst &Inst, unsigned N) const {
926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(N == 1 && "Invalid number of operands!");
927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t Imm = getConstantImm() - Offset;
928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Imm &= (1 << Bits) - 1;
929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Imm += Offset;
930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Imm += AdjustOffset;
931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createImm(Imm));
932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
934de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits>
935de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addSImmOperands(MCInst &Inst, unsigned N) const {
936de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (isImm() && !isConstantImm()) {
937de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      addExpr(Inst, getImm());
938de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return;
939de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
940de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    addConstantSImmOperands<Bits, 0, 0>(Inst, N);
941de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
942de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
943de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits>
944de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addUImmOperands(MCInst &Inst, unsigned N) const {
945de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (isImm() && !isConstantImm()) {
946de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      addExpr(Inst, getImm());
947de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return;
948de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
949de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    addConstantUImmOperands<Bits, 0, 0>(Inst, N);
950de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
951de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
952de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits, int Offset = 0, int AdjustOffset = 0>
953de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  void addConstantSImmOperands(MCInst &Inst, unsigned N) const {
954de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    assert(N == 1 && "Invalid number of operands!");
955de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    int64_t Imm = getConstantImm() - Offset;
956de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Imm = SignExtend64<Bits>(Imm);
957de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Imm += Offset;
958de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Imm += AdjustOffset;
959de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Inst.addOperand(MCOperand::createImm(Imm));
960de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
961de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
96272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addImmOperands(MCInst &Inst, unsigned N) const {
963ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    assert(N == 1 && "Invalid number of operands!");
964ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    const MCExpr *Expr = getImm();
96586924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
96672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
967ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
96872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  void addMemOperands(MCInst &Inst, unsigned N) const {
9696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert(N == 2 && "Invalid number of operands!");
9706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(AsmParser.getABI().ArePtrs64bit()
972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                             ? getMemBase()->getGPR64Reg()
973f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                             : getMemBase()->getGPR32Reg()));
9746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
9756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *Expr = getMemOff();
97686924b4182537745659f2660244f3402c1e1ca4dJack Carter    addExpr(Inst, Expr);
97772e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
97872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addMicroMipsMemOperands(MCInst &Inst, unsigned N) const {
980ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(N == 2 && "Invalid number of operands!");
981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
9826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(getMemBase()->getGPRMM16Reg()));
983ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const MCExpr *Expr = getMemOff();
985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    addExpr(Inst, Expr);
986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
98837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  void addRegListOperands(MCInst &Inst, unsigned N) const {
98937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(N == 1 && "Invalid number of operands!");
99037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
99137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    for (auto RegNo : getRegList())
9926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createReg(RegNo));
99337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
99437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
995ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addRegPairOperands(MCInst &Inst, unsigned N) const {
996ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(N == 2 && "Invalid number of operands!");
997de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    assert((RegIdx.Kind & RegKind_GPR) && "Invalid access!");
998ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned RegNo = getRegPair();
999de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    AsmParser.warnIfRegIndexIsAT(RegNo, StartLoc);
1000de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(
1001de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      RegIdx.RegInfo->getRegClass(
1002de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        AsmParser.getABI().AreGprs64bit()
1003de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          ? Mips::GPR64RegClassID
1004de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          : Mips::GPR32RegClassID).getRegister(RegNo++)));
1005de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(
1006de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      RegIdx.RegInfo->getRegClass(
1007de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        AsmParser.getABI().AreGprs64bit()
1008de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          ? Mips::GPR64RegClassID
1009de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          : Mips::GPR32RegClassID).getRegister(RegNo)));
1010ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1011ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1012ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  void addMovePRegPairOperands(MCInst &Inst, unsigned N) const {
1013ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(N == 2 && "Invalid number of operands!");
1014ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (auto RegNo : getRegList())
10156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createReg(RegNo));
1016ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1017ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1018dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isReg() const override {
1019de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // As a special case until we sort out the definition of div/divu, accept
1020de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // $0/$zero here so that MCK_ZERO works correctly.
1021de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isGPRAsmReg() && RegIdx.Index == 0;
102236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
102336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isRegIdx() const { return Kind == k_RegisterIndex; }
1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isImm() const override { return Kind == k_Immediate; }
102536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isConstantImm() const {
1026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return isImm() && isa<MCConstantExpr>(getImm());
1027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isConstantImmz() const {
1029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return isConstantImm() && getConstantImm() == 0;
103036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
1031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <unsigned Bits, int Offset = 0> bool isConstantUImm() const {
1032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return isConstantImm() && isUInt<Bits>(getConstantImm() - Offset);
1033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits> bool isSImm() const {
1035de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isConstantImm() ? isInt<Bits>(getConstantImm()) : isImm();
1036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1037de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits> bool isUImm() const {
1038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isConstantImm() ? isUInt<Bits>(getConstantImm()) : isImm();
1039de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1040de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits> bool isAnyImm() const {
1041de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isConstantImm() ? (isInt<Bits>(getConstantImm()) ||
1042de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              isUInt<Bits>(getConstantImm()))
1043de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                           : isImm();
1044de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1045de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits, int Offset = 0> bool isConstantSImm() const {
1046de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isConstantImm() && isInt<Bits>(getConstantImm() - Offset);
1047de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1048de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bottom, unsigned Top> bool isConstantUImmRange() const {
1049de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isConstantImm() && getConstantImm() >= Bottom &&
1050de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           getConstantImm() <= Top;
10516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
1052dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isToken() const override {
105336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Note: It's not possible to pretend that other operand kinds are tokens.
105436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // The matcher emitter checks tokens first.
105536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Kind == k_Token;
105636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
1057dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isMem() const override { return Kind == k_Memory; }
1058c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  bool isConstantMemOff() const {
1059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return isMem() && isa<MCConstantExpr>(getMemOff());
1060c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1061de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Allow relocation operators.
1062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // FIXME: This predicate and others need to look through binary expressions
1063de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  //        and determine whether a Value is a constant or not.
1064de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits, unsigned ShiftAmount = 0>
1065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isMemWithSimmOffset() const {
1066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!isMem())
1067de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return false;
1068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!getMemBase()->isGPRAsmReg())
1069de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return false;
1070de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (isa<MCTargetExpr>(getMemOff()) ||
1071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (isConstantMemOff() &&
1072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar         isShiftedInt<Bits, ShiftAmount>(getConstantMemOff())))
1073de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return true;
1074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MCValue Res;
1075de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    bool IsReloc = getMemOff()->evaluateAsRelocatable(Res, nullptr, nullptr);
1076de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return IsReloc && isShiftedInt<Bits, ShiftAmount>(Res.getConstant());
1077c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1078ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isMemWithGRPMM16Base() const {
1079ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return isMem() && getMemBase()->isMM16AsmReg();
1080ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1081ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  template <unsigned Bits> bool isMemWithUimmOffsetSP() const {
1082ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1083ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && getMemBase()->isRegIdx() && (getMemBase()->getGPR32Reg() == Mips::SP);
1084ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1085ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  template <unsigned Bits> bool isMemWithUimmWordAlignedOffsetSP() const {
1086ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return isMem() && isConstantMemOff() && isUInt<Bits>(getConstantMemOff())
1087ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1088ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      && (getMemBase()->getGPR32Reg() == Mips::SP);
1089ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1090de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits> bool isMemWithSimmWordAlignedOffsetGP() const {
1091de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isMem() && isConstantMemOff() && isInt<Bits>(getConstantMemOff())
1092de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      && (getConstantMemOff() % 4 == 0) && getMemBase()->isRegIdx()
1093de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      && (getMemBase()->getGPR32Reg() == Mips::GP);
1094de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1095f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  template <unsigned Bits, unsigned ShiftLeftAmount>
1096f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isScaledUImm() const {
1097f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return isConstantImm() &&
1098f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           isShiftedUInt<Bits, ShiftLeftAmount>(getConstantImm());
1099f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1100de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  template <unsigned Bits, unsigned ShiftLeftAmount>
1101de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isScaledSImm() const {
1102de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return isConstantImm() &&
1103de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar           isShiftedInt<Bits, ShiftLeftAmount>(getConstantImm());
1104de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
1105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isRegList16() const {
1106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!isRegList())
1107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
1108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    int Size = RegList.List->size();
1110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Size < 2 || Size > 5)
1111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
1112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned R0 = RegList.List->front();
1114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned R1 = RegList.List->back();
1115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!((R0 == Mips::S0 && R1 == Mips::RA) ||
1116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          (R0 == Mips::S0_64 && R1 == Mips::RA_64)))
1117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
1118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    int PrevReg = *RegList.List->begin();
1120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    for (int i = 1; i < Size - 1; i++) {
1121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      int Reg = (*(RegList.List))[i];
1122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if ( Reg != PrevReg + 1)
1123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return false;
1124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      PrevReg = Reg;
1125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return true;
1128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1129d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  bool isInvNum() const { return Kind == k_Immediate; }
113036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isLSAImm() const {
113136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (!isConstantImm())
113236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return false;
113336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    int64_t Val = getConstantImm();
113436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return 1 <= Val && Val <= 4;
113536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
113637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool isRegList() const { return Kind == k_RegList; }
1137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isMovePRegPair() const {
1138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (Kind != k_RegList || RegList.List->size() != 2)
1139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
1140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned R0 = RegList.List->front();
1142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    unsigned R1 = RegList.List->back();
1143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if ((R0 == Mips::A1 && R1 == Mips::A2) ||
1145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (R0 == Mips::A1 && R1 == Mips::A3) ||
1146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (R0 == Mips::A2 && R1 == Mips::A3) ||
1147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (R0 == Mips::A0 && R1 == Mips::S5) ||
1148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (R0 == Mips::A0 && R1 == Mips::S6) ||
1149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (R0 == Mips::A0 && R1 == Mips::A1) ||
1150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        (R0 == Mips::A0 && R1 == Mips::A2) ||
1151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A0 && R1 == Mips::A3) ||
1152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A1_64 && R1 == Mips::A2_64) ||
1153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A1_64 && R1 == Mips::A3_64) ||
1154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A2_64 && R1 == Mips::A3_64) ||
1155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A0_64 && R1 == Mips::S5_64) ||
1156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A0_64 && R1 == Mips::S6_64) ||
1157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A0_64 && R1 == Mips::A1_64) ||
1158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A0_64 && R1 == Mips::A2_64) ||
1159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        (R0 == Mips::A0_64 && R1 == Mips::A3_64))
1160ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return true;
1161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
1163ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
116472e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
116572e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  StringRef getToken() const {
116672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka    assert(Kind == k_Token && "Invalid access!");
1167ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return StringRef(Tok.Data, Tok.Length);
116872e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
1169de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool isRegPair() const {
1170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Kind == k_RegPair && RegIdx.Index <= 30;
1171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
117272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
1173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  unsigned getReg() const override {
1174de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // As a special case until we sort out the definition of div/divu, accept
1175de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // $0/$zero here so that MCK_ZERO works correctly.
117636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Kind == k_RegisterIndex && RegIdx.Index == 0 &&
117736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        RegIdx.Kind & RegKind_GPR)
117836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return getGPR32Reg(); // FIXME: GPR64 too
1179a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
1180de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    llvm_unreachable("Invalid access!");
1181de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return 0;
1182ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
1183ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
1184ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  const MCExpr *getImm() const {
118536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert((Kind == k_Immediate) && "Invalid access!");
1186ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Imm.Val;
1187ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1188ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
118936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int64_t getConstantImm() const {
119036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Val = getImm();
119136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return static_cast<const MCConstantExpr *>(Val)->getValue();
119236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
119336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
119436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MipsOperand *getMemBase() const {
11956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
11966b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Base;
11976b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
11986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
11996b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *getMemOff() const {
12006b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    assert((Kind == k_Memory) && "Invalid access!");
12016b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Mem.Off;
12026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
12036b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
1204c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  int64_t getConstantMemOff() const {
1205c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return static_cast<const MCConstantExpr *>(getMemOff())->getValue();
1206c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1207c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
120837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const SmallVectorImpl<unsigned> &getRegList() const {
120937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert((Kind == k_RegList) && "Invalid access!");
121037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return *(RegList.List);
121137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
121237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned getRegPair() const {
1214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert((Kind == k_RegPair) && "Invalid access!");
1215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return RegIdx.Index;
1216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1218c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand> CreateToken(StringRef Str, SMLoc S,
1219c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                  MipsAsmParser &Parser) {
1220c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<MipsOperand>(k_Token, Parser);
1221ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Data = Str.data();
1222ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->Tok.Length = Str.size();
1223ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->StartLoc = S;
1224ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Op->EndLoc = S;
1225ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Op;
1226ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1227ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
122836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a numeric register (e.g. $1). The exact register remains
122936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// unresolved until an instruction successfully matches
1230c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
123137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createNumericReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1232c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                   SMLoc E, MipsAsmParser &Parser) {
123337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    DEBUG(dbgs() << "createNumericReg(" << Index << ", ...)\n");
123436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_Numeric, RegInfo, S, E, Parser);
1235ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
1236ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
123736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely a GPR.
123836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $gp.
1239c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
124037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createGPRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1241c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               MipsAsmParser &Parser) {
124236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_GPR, RegInfo, S, E, Parser);
1243a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka  }
1244a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
124536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely a FGR.
124636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $f0.
1247c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
124837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createFGRReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1249c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               MipsAsmParser &Parser) {
125036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_FGR, RegInfo, S, E, Parser);
125136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
125236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
125337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// Create a register that is definitely a HWReg.
125437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  /// This is typically only used for named registers such as $hwr_cpunum.
125537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  static std::unique_ptr<MipsOperand>
125637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createHWRegsReg(unsigned Index, const MCRegisterInfo *RegInfo,
125737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                  SMLoc S, SMLoc E, MipsAsmParser &Parser) {
125837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return CreateReg(Index, RegKind_HWRegs, RegInfo, S, E, Parser);
125937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
126037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
126136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an FCC.
126236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $fcc0.
1263c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
126437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createFCCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1265c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               MipsAsmParser &Parser) {
126636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_FCC, RegInfo, S, E, Parser);
126736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
126836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
126936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an ACC.
127036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $ac0.
1271c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
127237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createACCReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S, SMLoc E,
1273c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines               MipsAsmParser &Parser) {
127436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_ACC, RegInfo, S, E, Parser);
127536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
127636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
127736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an MSA128.
127836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $w0.
1279c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
128037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createMSA128Reg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1281c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                  SMLoc E, MipsAsmParser &Parser) {
128236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_MSA128, RegInfo, S, E, Parser);
128336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
128436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
128536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// Create a register that is definitely an MSACtrl.
128636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  /// This is typically only used for named registers such as $msaaccess.
1287c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
128837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  createMSACtrlReg(unsigned Index, const MCRegisterInfo *RegInfo, SMLoc S,
1289c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                   SMLoc E, MipsAsmParser &Parser) {
129036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return CreateReg(Index, RegKind_MSACtrl, RegInfo, S, E, Parser);
129172e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
129272e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
1293c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
1294c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  CreateImm(const MCExpr *Val, SMLoc S, SMLoc E, MipsAsmParser &Parser) {
1295c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<MipsOperand>(k_Immediate, Parser);
129695adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Op->Imm.Val = Val;
129795adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Op->StartLoc = S;
129895adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    Op->EndLoc = E;
129995adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida    return Op;
130095adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida  }
130195adf91f29980e374bf094e15bc3f2764ef9baf4Matheus Almeida
1302c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  static std::unique_ptr<MipsOperand>
1303c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  CreateMem(std::unique_ptr<MipsOperand> Base, const MCExpr *Off, SMLoc S,
1304c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            SMLoc E, MipsAsmParser &Parser) {
1305c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    auto Op = make_unique<MipsOperand>(k_Memory, Parser);
1306c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Op->Mem.Base = Base.release();
13076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->Mem.Off = Off;
13086b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->StartLoc = S;
13096b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Op->EndLoc = E;
13106b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return Op;
13116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
13126b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
131337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  static std::unique_ptr<MipsOperand>
131437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CreateRegList(SmallVectorImpl<unsigned> &Regs, SMLoc StartLoc, SMLoc EndLoc,
131537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                MipsAsmParser &Parser) {
131637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert (Regs.size() > 0 && "Empty list not allowed");
131737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
131837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    auto Op = make_unique<MipsOperand>(k_RegList, Parser);
1319ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Op->RegList.List = new SmallVector<unsigned, 10>(Regs.begin(), Regs.end());
132037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Op->StartLoc = StartLoc;
132137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Op->EndLoc = EndLoc;
132237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Op;
132337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
132437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  static std::unique_ptr<MipsOperand> CreateRegPair(const MipsOperand &MOP,
1326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                    SMLoc S, SMLoc E,
1327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                    MipsAsmParser &Parser) {
1328ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    auto Op = make_unique<MipsOperand>(k_RegPair, Parser);
1329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Op->RegIdx.Index = MOP.RegIdx.Index;
1330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Op->RegIdx.RegInfo = MOP.RegIdx.RegInfo;
1331de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Op->RegIdx.Kind = MOP.RegIdx.Kind;
1332ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Op->StartLoc = S;
1333ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Op->EndLoc = E;
1334ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return Op;
1335ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1336ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
133736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isGPRAsmReg() const {
133836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_GPR && RegIdx.Index <= 31;
133990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic  }
134037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool isMM16AsmReg() const {
134137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!(isRegIdx() && RegIdx.Kind))
134237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
134337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return ((RegIdx.Index >= 2 && RegIdx.Index <= 7)
134437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            || RegIdx.Index == 16 || RegIdx.Index == 17);
134537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
1346ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isMM16AsmRegZero() const {
1347ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!(isRegIdx() && RegIdx.Kind))
1348ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
1349ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return (RegIdx.Index == 0 ||
1350ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            (RegIdx.Index >= 2 && RegIdx.Index <= 7) ||
1351ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            RegIdx.Index == 17);
1352ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1353ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  bool isMM16AsmRegMoveP() const {
1354ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!(isRegIdx() && RegIdx.Kind))
1355ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
1356ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return (RegIdx.Index == 0 || (RegIdx.Index >= 2 && RegIdx.Index <= 3) ||
1357ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      (RegIdx.Index >= 16 && RegIdx.Index <= 20));
1358ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
135936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isFGRAsmReg() const {
136036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AFGR64 is $0-$15 but we handle this in getAFGR64()
136136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_FGR && RegIdx.Index <= 31;
1362a1fe9ef62e18dcb30cdee62a2fad82d05791d359Akira Hatanaka  }
136336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isHWRegsAsmReg() const {
136436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_HWRegs && RegIdx.Index <= 31;
136588373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka  }
136636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isCCRAsmReg() const {
136736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_CCR && RegIdx.Index <= 31;
136888373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka  }
136936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isFCCAsmReg() const {
1370c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (!(isRegIdx() && RegIdx.Kind & RegKind_FCC))
1371c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
1372c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (!AsmParser.hasEightFccRegisters())
1373c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return RegIdx.Index == 0;
1374c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return RegIdx.Index <= 7;
137542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
137636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isACCAsmReg() const {
137736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_ACC && RegIdx.Index <= 3;
137842d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
1379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool isCOP0AsmReg() const {
1380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return isRegIdx() && RegIdx.Kind & RegKind_COP0 && RegIdx.Index <= 31;
1381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
138236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isCOP2AsmReg() const {
138336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_COP2 && RegIdx.Index <= 31;
138442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
1385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  bool isCOP3AsmReg() const {
1386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_COP3 && RegIdx.Index <= 31;
1387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
138836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isMSA128AsmReg() const {
138936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_MSA128 && RegIdx.Index <= 31;
139042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
139136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool isMSACtrlAsmReg() const {
139236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return isRegIdx() && RegIdx.Kind & RegKind_MSACtrl && RegIdx.Index <= 7;
1393006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  }
1394006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
1395ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getStartLoc - Get the location of the first token of this operand.
1396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getStartLoc() const override { return StartLoc; }
1397ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  /// getEndLoc - Get the location of the last token of this operand.
1398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  SMLoc getEndLoc() const override { return EndLoc; }
1399ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
1400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  virtual ~MipsOperand() {
1401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    switch (Kind) {
1402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Immediate:
1403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
1404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Memory:
1405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      delete Mem.Base;
1406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
140737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case k_RegList:
140837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      delete RegList.List;
1409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_RegisterIndex:
1410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    case k_Token:
1411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case k_RegPair:
1412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
1413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
1414dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
1415dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
1416dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  void print(raw_ostream &OS) const override {
141736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Kind) {
141836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Immediate:
141936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Imm<";
14206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      OS << *Imm.Val;
142136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ">";
142236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
142336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Memory:
142436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "Mem<";
142536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Mem.Base->print(OS);
142636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ", ";
14276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      OS << *Mem.Off;
142836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << ">";
142936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
143036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_RegisterIndex:
143136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << "RegIdx<" << RegIdx.Index << ":" << RegIdx.Kind << ">";
143236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
143336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case k_Token:
143436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      OS << Tok.Data;
143536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
143637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case k_RegList:
143737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      OS << "RegList< ";
143837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      for (auto Reg : (*RegList.List))
143937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        OS << Reg << " ";
144037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      OS <<  ">";
144137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
1442ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case k_RegPair:
1443ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      OS << "RegPair<" << RegIdx.Index << "," << RegIdx.Index + 1 << ">";
1444ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
144536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
144672e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka  }
144786924b4182537745659f2660244f3402c1e1ca4dJack Carter}; // class MipsOperand
14482263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic} // namespace
144972e9b6aeb48d9496bac9db8b02c88a618b464588Akira Hatanaka
145025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carternamespace llvm {
145125df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterextern const MCInstrDesc MipsInsts[];
145225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
145325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterstatic const MCInstrDesc &getInstDesc(unsigned Opcode) {
145425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  return MipsInsts[Opcode];
145525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter}
145625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
145737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic bool hasShortDelaySlot(unsigned Opcode) {
145837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  switch (Opcode) {
145937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case Mips::JALS_MM:
146037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case Mips::JALRS_MM:
146137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case Mips::JALRS16_MM:
146237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case Mips::BGEZALS_MM:
146337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case Mips::BLTZALS_MM:
146437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return true;
146537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
146637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
146737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
146837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
146937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic const MCSymbol *getSingleMCSymbol(const MCExpr *Expr) {
1471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (const MCSymbolRefExpr *SRExpr = dyn_cast<MCSymbolRefExpr>(Expr)) {
1472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return &SRExpr->getSymbol();
1473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr)) {
1476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MCSymbol *LHSSym = getSingleMCSymbol(BExpr->getLHS());
1477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MCSymbol *RHSSym = getSingleMCSymbol(BExpr->getRHS());
1478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (LHSSym)
1480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return LHSSym;
1481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RHSSym)
1483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return RHSSym;
1484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return nullptr;
1486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return getSingleMCSymbol(UExpr->getSubExpr());
1490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return nullptr;
1492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic unsigned countMCSymbolRefExpr(const MCExpr *Expr) {
1495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isa<MCSymbolRefExpr>(Expr))
1496f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return 1;
1497f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (const MCBinaryExpr *BExpr = dyn_cast<MCBinaryExpr>(Expr))
1499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return countMCSymbolRefExpr(BExpr->getLHS()) +
1500f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           countMCSymbolRefExpr(BExpr->getRHS());
1501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1502f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (const MCUnaryExpr *UExpr = dyn_cast<MCUnaryExpr>(Expr))
1503f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return countMCSymbolRefExpr(UExpr->getSubExpr());
1504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return 0;
1506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
1507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
150825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carterbool MipsAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
1509de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       MCStreamer &Out,
1510de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       const MCSubtargetInfo *STI) {
1511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
151225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
1513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool ExpandedJalSym = false;
151436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
151525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  Inst.setLoc(IDLoc);
151636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
151736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (MCID.isBranch() || MCID.isCall()) {
151836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const unsigned Opcode = Inst.getOpcode();
151936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    MCOperand Offset;
152036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
152136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    switch (Opcode) {
152236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    default:
152336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
1524ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case Mips::BBIT0:
1525ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case Mips::BBIT032:
1526ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case Mips::BBIT1:
1527ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case Mips::BBIT132:
1528ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      assert(hasCnMips() && "instruction only valid for octeon cpus");
1529ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Fall through
1530ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
153136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BEQ:
153236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BNE:
153336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BEQ_MM:
153436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BNE_MM:
153536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
153636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Offset = Inst.getOperand(2);
153736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Offset.isImm())
153836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break; // We'll deal with this situation later on when applying fixups.
1539c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
154036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch target out of range");
1541c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (OffsetToAlignment(Offset.getImm(),
1542c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                            1LL << (inMicroMipsMode() ? 1 : 2)))
154336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch to misaligned address");
154436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
154536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZ:
154636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGTZ:
154736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLEZ:
154836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZ:
154936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZAL:
155036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZAL:
155136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1F:
155236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1T:
155336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZ_MM:
155436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGTZ_MM:
155536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLEZ_MM:
155636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZ_MM:
155736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BGEZAL_MM:
155836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BLTZAL_MM:
155936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1F_MM:
156036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    case Mips::BC1T_MM:
1561de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case Mips::BC1EQZC_MMR6:
1562de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case Mips::BC1NEZC_MMR6:
1563de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case Mips::BC2EQZC_MMR6:
1564de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    case Mips::BC2NEZC_MMR6:
156536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
156636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Offset = Inst.getOperand(1);
156736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (!Offset.isImm())
156836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break; // We'll deal with this situation later on when applying fixups.
1569c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (!isIntN(inMicroMipsMode() ? 17 : 18, Offset.getImm()))
157036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch target out of range");
1571c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (OffsetToAlignment(Offset.getImm(),
1572c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                            1LL << (inMicroMipsMode() ? 1 : 2)))
157336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return Error(IDLoc, "branch to misaligned address");
157436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
1575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case Mips::BEQZ16_MM:
1576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BEQZC16_MMR6:
1577ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case Mips::BNEZ16_MM:
1578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BNEZC16_MMR6:
1579ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      assert(MCID.getNumOperands() == 2 && "unexpected number of operands");
1580ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Offset = Inst.getOperand(1);
1581ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (!Offset.isImm())
1582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break; // We'll deal with this situation later on when applying fixups.
1583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!isInt<8>(Offset.getImm()))
1584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return Error(IDLoc, "branch target out of range");
1585ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (OffsetToAlignment(Offset.getImm(), 2LL))
1586ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return Error(IDLoc, "branch to misaligned address");
1587ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      break;
158836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
158936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
159036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
1591c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // SSNOP is deprecated on MIPS32r6/MIPS64r6
1592c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // We still accept it but it is a normal nop.
1593c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (hasMips32r6() && Inst.getOpcode() == Mips::SSNOP) {
1594c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    std::string ISA = hasMips64r6() ? "MIPS64r6" : "MIPS32r6";
1595c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Warning(IDLoc, "ssnop is deprecated for " + ISA + " and is equivalent to a "
1596c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                      "nop instruction");
1597c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
1598c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
1599ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (hasCnMips()) {
1600ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const unsigned Opcode = Inst.getOpcode();
1601ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    MCOperand Opnd;
1602ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    int Imm;
1603ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1604ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    switch (Opcode) {
1605ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      default:
1606ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1607ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1608ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::BBIT0:
1609ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::BBIT032:
1610ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::BBIT1:
1611ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::BBIT132:
1612ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1613ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        // The offset is handled above
1614ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Opnd = Inst.getOperand(1);
1615ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Imm = Opnd.getImm();
1618ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (Imm < 0 || Imm > (Opcode == Mips::BBIT0 ||
1619ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                              Opcode == Mips::BBIT1 ? 63 : 31))
1620ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1621ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (Imm > 31) {
1622ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Inst.setOpcode(Opcode == Mips::BBIT0 ? Mips::BBIT032
1623ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                               : Mips::BBIT132);
1624ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          Inst.getOperand(1).setImm(Imm - 32);
1625ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1626ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1627ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1628ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::SEQi:
1629ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::SNEi:
1630ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        assert(MCID.getNumOperands() == 3 && "unexpected number of operands");
1631ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Opnd = Inst.getOperand(2);
1632ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1633ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1634ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Imm = Opnd.getImm();
1635ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!isInt<10>(Imm))
1636ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1637ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1638ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
1639ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
1640ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // This expansion is not in a function called by tryExpandInstruction()
1642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // because the pseudo-instruction doesn't have a distinct opcode.
1643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if ((Inst.getOpcode() == Mips::JAL || Inst.getOpcode() == Mips::JAL_MM) &&
1644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      inPicMode()) {
1645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    warnIfNoMacro(IDLoc);
1646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MCExpr *JalExpr = Inst.getOperand(0).getExpr();
1648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // We can do this expansion if there's only 1 symbol in the argument
1650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // expression.
1651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (countMCSymbolRefExpr(JalExpr) > 1)
1652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return Error(IDLoc, "jal doesn't support multiple symbols in PIC mode");
1653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: This is checking the expression can be handled by the later stages
1655de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //        of the assembler. We ought to leave it to those later stages.
1656f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MCSymbol *JalSym = getSingleMCSymbol(JalExpr);
1657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: Add support for label+offset operands (currently causes an error).
1659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: Add support for forward-declared local symbols.
1660f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: Add expansion for when the LargeGOT option is enabled.
1661f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (JalSym->isInSection() || JalSym->isTemporary()) {
1662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (isABI_O32()) {
1663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // If it's a local symbol and the O32 ABI is being used, we expand to:
1664f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //  lw $25, 0($gp)
1665f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //    R_(MICRO)MIPS_GOT16  label
1666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //  addiu $25, $25, 0
1667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //    R_(MICRO)MIPS_LO16   label
1668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //  jalr  $25
1669de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        const MCExpr *Got16RelocExpr =
1670de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            MipsMCExpr::create(MipsMCExpr::MEK_GOT, JalExpr, getContext());
1671de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        const MCExpr *Lo16RelocExpr =
1672de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            MipsMCExpr::create(MipsMCExpr::MEK_LO, JalExpr, getContext());
1673de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1674de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRX(Mips::LW, Mips::T9, Mips::GP,
1675de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     MCOperand::createExpr(Got16RelocExpr), IDLoc, STI);
1676de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRX(Mips::ADDiu, Mips::T9, Mips::T9,
1677de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     MCOperand::createExpr(Lo16RelocExpr), IDLoc, STI);
1678f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else if (isABI_N32() || isABI_N64()) {
1679f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // If it's a local symbol and the N32/N64 ABIs are being used,
1680f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        // we expand to:
1681f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //  lw/ld $25, 0($gp)
1682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //    R_(MICRO)MIPS_GOT_DISP  label
1683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        //  jalr  $25
1684de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        const MCExpr *GotDispRelocExpr =
1685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            MipsMCExpr::create(MipsMCExpr::MEK_GOT_DISP, JalExpr, getContext());
1686f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1687de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9,
1688de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     Mips::GP, MCOperand::createExpr(GotDispRelocExpr), IDLoc,
1689de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                     STI);
1690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
1691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else {
1692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If it's an external/weak symbol, we expand to:
1693f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //  lw/ld    $25, 0($gp)
1694f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //    R_(MICRO)MIPS_CALL16  label
1695f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //  jalr  $25
1696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      const MCExpr *Call16RelocExpr =
1697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, JalExpr, getContext());
1698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(ABI.ArePtrs64bit() ? Mips::LD : Mips::LW, Mips::T9, Mips::GP,
1700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(Call16RelocExpr), IDLoc, STI);
1701f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
1702f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1703f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    MCInst JalrInst;
1704f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsCpRestoreSet && inMicroMipsMode())
1705f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.setOpcode(Mips::JALRS_MM);
1706f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
1707f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
1708f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    JalrInst.addOperand(MCOperand::createReg(Mips::RA));
1709f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    JalrInst.addOperand(MCOperand::createReg(Mips::T9));
1710f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1711f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: Add an R_(MICRO)MIPS_JALR relocation after the JALR.
1712f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // This relocation is supposed to be an optimization hint for the linker
1713f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // and is not necessary for correctness.
1714f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1715f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Inst = JalrInst;
1716f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ExpandedJalSym = true;
1717f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
1718f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
171925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  if (MCID.mayLoad() || MCID.mayStore()) {
172025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    // Check the offset of memory operand, if it is a symbol
172186924b4182537745659f2660244f3402c1e1ca4dJack Carter    // reference or immediate we may have to expand instructions.
172286924b4182537745659f2660244f3402c1e1ca4dJack Carter    for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
172325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      const MCOperandInfo &OpInfo = MCID.OpInfo[i];
17242263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
17252263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic          (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
172625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        MCOperand &Op = Inst.getOperand(i);
172725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        if (Op.isImm()) {
172825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          int MemOffset = Op.getImm();
172925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          if (MemOffset < -32768 || MemOffset > 32767) {
173086924b4182537745659f2660244f3402c1e1ca4dJack Carter            // Offset can't exceed 16bit value.
1731de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), true);
173225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            return false;
173325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
173425df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        } else if (Op.isExpr()) {
173525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          const MCExpr *Expr = Op.getExpr();
173686924b4182537745659f2660244f3402c1e1ca4dJack Carter          if (Expr->getKind() == MCExpr::SymbolRef) {
173725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            const MCSymbolRefExpr *SR =
17382263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic                static_cast<const MCSymbolRefExpr *>(Expr);
173925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            if (SR->getKind() == MCSymbolRefExpr::VK_None) {
174086924b4182537745659f2660244f3402c1e1ca4dJack Carter              // Expand symbol.
1741de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
174225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter              return false;
174325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter            }
17448afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter          } else if (!isEvaluated(Expr)) {
1745de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            expandMemInst(Inst, IDLoc, Out, STI, MCID.mayLoad(), false);
17468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter            return false;
174725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter          }
174825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter        }
174925df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      }
175086924b4182537745659f2660244f3402c1e1ca4dJack Carter    } // for
17512263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  }   // if load/store
175225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
175337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (inMicroMipsMode()) {
1754ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (MCID.mayLoad()) {
1755ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // Try to create 16-bit GP relative load instruction.
1756ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      for (unsigned i = 0; i < MCID.getNumOperands(); i++) {
1757ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        const MCOperandInfo &OpInfo = MCID.OpInfo[i];
1758ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if ((OpInfo.OperandType == MCOI::OPERAND_MEMORY) ||
1759ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            (OpInfo.OperandType == MCOI::OPERAND_UNKNOWN)) {
1760ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          MCOperand &Op = Inst.getOperand(i);
1761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          if (Op.isImm()) {
1762ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            int MemOffset = Op.getImm();
1763ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            MCOperand &DstReg = Inst.getOperand(0);
1764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            MCOperand &BaseReg = Inst.getOperand(1);
1765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar            if (isInt<9>(MemOffset) && (MemOffset % 4 == 0) &&
1766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                getContext().getRegisterInfo()->getRegClass(
1767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                  Mips::GPRMM16RegClassID).contains(DstReg.getReg()) &&
1768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                (BaseReg.getReg() == Mips::GP ||
1769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                BaseReg.getReg() == Mips::GP_64)) {
1770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1771de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              TOut.emitRRI(Mips::LWGP_MM, DstReg.getReg(), Mips::GP, MemOffset,
1772de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                           IDLoc, STI);
1773ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines              return false;
1774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines            }
1775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          }
1776ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        }
1777ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      } // for
1778ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }   // if load
1779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
1780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // TODO: Handle this with the AsmOperandClass.PredicateMethod.
1781ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
178237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MCOperand Opnd;
178337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int Imm;
178437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
178537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (Inst.getOpcode()) {
178637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      default:
178737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
178837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case Mips::ADDIUSP_MM:
178937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Opnd = Inst.getOperand(0);
179037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!Opnd.isImm())
179137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "expected immediate operand kind");
179237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Imm = Opnd.getImm();
179337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (Imm < -1032 || Imm > 1028 || (Imm < 8 && Imm > -12) ||
179437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            Imm % 4 != 0)
179537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "immediate operand value out of range");
179637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
179737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case Mips::SLL16_MM:
179837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case Mips::SRL16_MM:
179937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Opnd = Inst.getOperand(2);
180037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!Opnd.isImm())
180137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "expected immediate operand kind");
180237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Imm = Opnd.getImm();
180337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (Imm < 1 || Imm > 8)
180437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "immediate operand value out of range");
180537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
180637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case Mips::LI16_MM:
180737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Opnd = Inst.getOperand(1);
180837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!Opnd.isImm())
180937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "expected immediate operand kind");
181037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Imm = Opnd.getImm();
181137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (Imm < -1 || Imm > 126)
181237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "immediate operand value out of range");
181337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
181437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case Mips::ADDIUR2_MM:
181537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Opnd = Inst.getOperand(2);
181637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!Opnd.isImm())
181737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "expected immediate operand kind");
181837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Imm = Opnd.getImm();
181937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!(Imm == 1 || Imm == -1 ||
182037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              ((Imm % 4 == 0) && Imm < 28 && Imm > 0)))
182137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "immediate operand value out of range");
182237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
182337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      case Mips::ANDI16_MM:
182437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Opnd = Inst.getOperand(2);
182537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!Opnd.isImm())
182637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "expected immediate operand kind");
182737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Imm = Opnd.getImm();
182837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (!(Imm == 128 || (Imm >= 1 && Imm <= 4) || Imm == 7 || Imm == 8 ||
182937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              Imm == 15 || Imm == 16 || Imm == 31 || Imm == 32 || Imm == 63 ||
183037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              Imm == 64 || Imm == 255 || Imm == 32768 || Imm == 65535))
183137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          return Error(IDLoc, "immediate operand value out of range");
183237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        break;
1833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::LBU16_MM:
1834ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Opnd = Inst.getOperand(2);
1835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1836ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1837ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Imm = Opnd.getImm();
1838ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (Imm < -1 || Imm > 14)
1839ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1840ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1841ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::SB16_MM:
1842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      case Mips::SB16_MMR6:
1843ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Opnd = Inst.getOperand(2);
1844ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1845ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1846ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Imm = Opnd.getImm();
1847ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (Imm < 0 || Imm > 15)
1848ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::LHU16_MM:
1851ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::SH16_MM:
1852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      case Mips::SH16_MMR6:
1853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Opnd = Inst.getOperand(2);
1854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1856ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Imm = Opnd.getImm();
1857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (Imm < 0 || Imm > 30 || (Imm % 2 != 0))
1858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1859ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1860ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::LW16_MM:
1861ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::SW16_MM:
1862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      case Mips::SW16_MMR6:
1863ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Opnd = Inst.getOperand(2);
1864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1865ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1866ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Imm = Opnd.getImm();
1867ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (Imm < 0 || Imm > 60 || (Imm % 4 != 0))
1868ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1869ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
1870ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      case Mips::ADDIUPC_MM:
1871ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        MCOperand Opnd = Inst.getOperand(1);
1872ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        if (!Opnd.isImm())
1873ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "expected immediate operand kind");
1874ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        int Imm = Opnd.getImm();
1875f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if ((Imm % 4 != 0) || !isInt<25>(Imm))
1876ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          return Error(IDLoc, "immediate operand value out of range");
1877ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        break;
187837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
187937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
188037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
1881de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool FillDelaySlot =
1882de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder();
1883de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (FillDelaySlot)
1884de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitDirectiveSetNoReorder();
1885de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
1886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MacroExpanderResultTy ExpandResult =
1887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      tryExpandInstruction(Inst, IDLoc, Out, STI);
1888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (ExpandResult) {
1889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MER_NotAMacro:
1890de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Out.EmitInstruction(Inst, *STI);
1891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
1892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MER_Success:
1893f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
1894f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case MER_Fail:
1895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
1896f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
189725df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
1898de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // We know we emitted an instruction on the MER_NotAMacro or MER_Success path.
1899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // If we're in microMIPS mode then we must also set EF_MIPS_MICROMIPS.
1900de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (inMicroMipsMode())
1901de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.setUsesMicroMips();
1902de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
19036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // If this instruction has a delay slot and .set reorder is active,
19046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // emit a NOP after it.
1905de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (FillDelaySlot) {
1906de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc, STI);
1907de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitDirectiveSetReorder();
1908de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
19096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
1910f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if ((Inst.getOpcode() == Mips::JalOneReg ||
1911f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar       Inst.getOpcode() == Mips::JalTwoReg || ExpandedJalSym) &&
1912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      isPicAndNotNxxAbi()) {
1913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsCpRestoreSet) {
1914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // We need a NOP between the JALR and the LW:
1915f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If .set reorder has been used, we've already emitted a NOP.
1916f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If .set noreorder has been used, we need to emit a NOP at this point.
1917f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!AssemblerOptions.back()->isReorder())
1918de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitEmptyDelaySlot(hasShortDelaySlot(Inst.getOpcode()), IDLoc,
1919de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                STI);
192025df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
1921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Load the $gp from the stack.
1922de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitGPRestore(CpRestoreOffset, IDLoc, STI);
1923f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else
1924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Warning(IDLoc, "no .cprestore used in PIC mode");
19259d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
1926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
19289d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
19292490dc650895149423bb59538dc03ca352222702Jack Carter
1930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga NainarMipsAsmParser::MacroExpanderResultTy
1931de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarMipsAsmParser::tryExpandInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
1932de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                    const MCSubtargetInfo *STI) {
193386924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (Inst.getOpcode()) {
1934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  default:
1935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return MER_NotAMacro;
19364c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  case Mips::LoadImm32:
1937de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandLoadImm(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
19384c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  case Mips::LoadImm64:
1939de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandLoadImm(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
19404c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  case Mips::LoadAddrImm32:
1941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::LoadAddrImm64:
1942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert((Inst.getOperand(1).isImm() || Inst.getOperand(1).isExpr()) &&
1944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           "expected immediate operand kind");
1945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return expandLoadAddress(Inst.getOperand(0).getReg(), Mips::NoRegister,
1947f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             Inst.getOperand(1),
1948f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             Inst.getOpcode() == Mips::LoadAddrImm32, IDLoc,
1949de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                             Out, STI)
1950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               ? MER_Fail
1951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               : MER_Success;
19524c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  case Mips::LoadAddrReg32:
1953f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::LoadAddrReg64:
1954f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(Inst.getOperand(0).isReg() && "expected register operand kind");
1955f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert(Inst.getOperand(1).isReg() && "expected register operand kind");
1956f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    assert((Inst.getOperand(2).isImm() || Inst.getOperand(2).isExpr()) &&
1957f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar           "expected immediate operand kind");
1958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
1959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return expandLoadAddress(Inst.getOperand(0).getReg(),
1960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             Inst.getOperand(1).getReg(), Inst.getOperand(2),
1961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                             Inst.getOpcode() == Mips::LoadAddrReg32, IDLoc,
1962de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                             Out, STI)
1963f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               ? MER_Fail
1964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               : MER_Success;
1965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::B_MM_Pseudo:
1966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::B_MMR6_Pseudo:
1967de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandUncondBranchMMPseudo(Inst, IDLoc, Out, STI) ? MER_Fail
1968de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                             : MER_Success;
1969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::SWM_MM:
1970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::LWM_MM:
1971de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandLoadStoreMultiple(Inst, IDLoc, Out, STI) ? MER_Fail
1972de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                          : MER_Success;
1973ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::JalOneReg:
1974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::JalTwoReg:
1975de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandJalWithRegs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
19766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case Mips::BneImm:
19776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  case Mips::BeqImm:
1978de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandBranchImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
1979f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLT:
1980f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLE:
1981f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGE:
1982f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGT:
1983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTU:
1984f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEU:
1985f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEU:
1986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTU:
1987f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTL:
1988f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEL:
1989f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEL:
1990f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTL:
1991f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTUL:
1992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEUL:
1993f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEUL:
1994f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTUL:
1995f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTImmMacro:
1996f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEImmMacro:
1997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEImmMacro:
1998f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTImmMacro:
1999f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTUImmMacro:
2000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEUImmMacro:
2001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEUImmMacro:
2002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTUImmMacro:
2003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTLImmMacro:
2004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLELImmMacro:
2005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGELImmMacro:
2006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTLImmMacro:
2007f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTULImmMacro:
2008f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEULImmMacro:
2009f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEULImmMacro:
2010f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTULImmMacro:
2011de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandCondBranches(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2012f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::SDivMacro:
2013de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandDiv(Inst, IDLoc, Out, STI, false, true) ? MER_Fail
2014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                         : MER_Success;
2015f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::DSDivMacro:
2016de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandDiv(Inst, IDLoc, Out, STI, true, true) ? MER_Fail
2017de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                        : MER_Success;
2018f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::UDivMacro:
2019de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandDiv(Inst, IDLoc, Out, STI, false, false) ? MER_Fail
2020de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                          : MER_Success;
2021f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::DUDivMacro:
2022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandDiv(Inst, IDLoc, Out, STI, true, false) ? MER_Fail
2023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                         : MER_Success;
2024de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::PseudoTRUNC_W_S:
2025de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandTrunc(Inst, false, false, IDLoc, Out, STI) ? MER_Fail
2026de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                            : MER_Success;
2027de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::PseudoTRUNC_W_D32:
2028de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandTrunc(Inst, true, false, IDLoc, Out, STI) ? MER_Fail
2029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                           : MER_Success;
2030de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::PseudoTRUNC_W_D:
2031de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandTrunc(Inst, true, true, IDLoc, Out, STI) ? MER_Fail
2032de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                          : MER_Success;
2033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::Ulh:
2034de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandUlh(Inst, true, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2035f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::Ulhu:
2036de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandUlh(Inst, false, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::Ulw:
2038de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandUlw(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::NORImm:
2040de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ADDi:
2042f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ADDiu:
2043f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::SLTi:
2044f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::SLTiu:
2045f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2046f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2047f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      int64_t ImmValue = Inst.getOperand(2).getImm();
2048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (isInt<16>(ImmValue))
2049f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return MER_NotAMacro;
2050de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                         : MER_Success;
2052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2053f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return MER_NotAMacro;
2054f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ANDi:
2055f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ORi:
2056f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::XORi:
2057f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if ((Inst.getNumOperands() == 3) && Inst.getOperand(0).isReg() &&
2058f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Inst.getOperand(1).isReg() && Inst.getOperand(2).isImm()) {
2059f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      int64_t ImmValue = Inst.getOperand(2).getImm();
2060f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (isUInt<16>(ImmValue))
2061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return MER_NotAMacro;
2062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return expandAliasImmediate(Inst, IDLoc, Out, STI) ? MER_Fail
2063de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                         : MER_Success;
2064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2065f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return MER_NotAMacro;
2066f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ROL:
2067f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ROR:
2068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2069f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::ROLImm:
2070f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::RORImm:
2071de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2072f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::DROL:
2073f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::DROR:
2074de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandDRotation(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2075f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::DROLImm:
2076f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::DRORImm:
2077de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandDRotationImm(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
2078de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::ABSMacro:
2079de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return expandAbs(Inst, IDLoc, Out, STI) ? MER_Fail : MER_Success;
208086924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
20819d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
20822490dc650895149423bb59538dc03ca352222702Jack Carter
2083ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesbool MipsAsmParser::expandJalWithRegs(MCInst &Inst, SMLoc IDLoc,
2084de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      MCStreamer &Out,
2085de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      const MCSubtargetInfo *STI) {
2086de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2087de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2088ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Create a JALR instruction which is going to replace the pseudo-JAL.
2089ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MCInst JalrInst;
2090ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  JalrInst.setLoc(IDLoc);
2091ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const MCOperand FirstRegOp = Inst.getOperand(0);
2092ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const unsigned Opcode = Inst.getOpcode();
2093ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2094ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Opcode == Mips::JalOneReg) {
2095ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // jal $rs => jalr $rs
2096f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsCpRestoreSet && inMicroMipsMode()) {
2097f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.setOpcode(Mips::JALRS16_MM);
2098f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.addOperand(FirstRegOp);
2099f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else if (inMicroMipsMode()) {
2100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.setOpcode(hasMips32r6() ? Mips::JALRC16_MMR6 : Mips::JALR16_MM);
2101ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      JalrInst.addOperand(FirstRegOp);
2102ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
2103ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      JalrInst.setOpcode(Mips::JALR);
21046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      JalrInst.addOperand(MCOperand::createReg(Mips::RA));
2105ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      JalrInst.addOperand(FirstRegOp);
2106ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
2107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Opcode == Mips::JalTwoReg) {
2108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // jal $rd, $rs => jalr $rd, $rs
2109f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsCpRestoreSet && inMicroMipsMode())
2110f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.setOpcode(Mips::JALRS_MM);
2111f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
2112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      JalrInst.setOpcode(inMicroMipsMode() ? Mips::JALR_MM : Mips::JALR);
2113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    JalrInst.addOperand(FirstRegOp);
2114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    const MCOperand SecondRegOp = Inst.getOperand(1);
2115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    JalrInst.addOperand(SecondRegOp);
2116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
2117de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Out.EmitInstruction(JalrInst, *STI);
2118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2119f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If .set reorder is active and branch instruction has a delay slot,
2120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // emit a NOP after it.
2121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCInstrDesc &MCID = getInstDesc(JalrInst.getOpcode());
2122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitEmptyDelaySlot(hasShortDelaySlot(JalrInst.getOpcode()), IDLoc,
2124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                            STI);
2125ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return false;
2127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
2128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2129f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Can the value be represented by a unsigned N-bit value and a shift left?
2130f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainartemplate <unsigned N> static bool isShiftedUIntAtAnyPosition(uint64_t x) {
2131f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned BitNum = findFirstSet(x);
2132f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2133f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return (x == x >> BitNum << BitNum) && isUInt<N>(x >> BitNum);
2134f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2135f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2136f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// Load (or add) an immediate into a register.
2137f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///
2138f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// @param ImmValue     The immediate to load.
2139f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// @param DstReg       The register that will hold the immediate.
2140f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// @param SrcReg       A register to add to the immediate or Mips::NoRegister
2141f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///                     for a simple initialization.
2142f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// @param Is32BitImm   Is ImmValue 32-bit or 64-bit?
2143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// @param IsAddress    True if the immediate represents an address. False if it
2144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///                     is an integer.
2145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar/// @param IDLoc        Location of the immediate in the source file.
21466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool MipsAsmParser::loadImmediate(int64_t ImmValue, unsigned DstReg,
2147f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                  unsigned SrcReg, bool Is32BitImm,
2148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                  bool IsAddress, SMLoc IDLoc, MCStreamer &Out,
2149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                  const MCSubtargetInfo *STI) {
2150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
21526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!Is32BitImm && !isGP64bit()) {
21536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Error(IDLoc, "instruction requires a 64-bit architecture");
21546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return true;
21556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
21566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Is32BitImm) {
2158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
2159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Sign extend up to 64-bit so that the predicates match the hardware
2160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // behaviour. In particular, isInt<16>(0xffff8000) and similar should be
2161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // true.
2162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ImmValue = SignExtend64<32>(ImmValue);
2163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else {
2164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Error(IDLoc, "instruction requires a 32-bit immediate");
2165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ZeroReg = IsAddress ? ABI.GetNullPtr() : ABI.GetZeroReg();
2170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned AdduOp = !Is32BitImm ? Mips::DADDu : Mips::ADDu;
2171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
21726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  bool UseSrcReg = false;
21736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (SrcReg != Mips::NoRegister)
21746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    UseSrcReg = true;
21756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TmpReg = DstReg;
2177de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (UseSrcReg &&
2178de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // At this point we need AT to perform the expansions and we exit if it is
2180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // not available.
2181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned ATReg = getATReg(IDLoc);
2182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
2183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    TmpReg = ATReg;
2185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
21869d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter
2187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isInt<16>(ImmValue)) {
21886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!UseSrcReg)
2189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SrcReg = ZeroReg;
2190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // This doesn't quite follow the usual ABI expectations for N32 but matches
2192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // traditional assembler behaviour. N32 would normally use addiu for both
2193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // integers and addresses.
2194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsAddress && !Is32BitImm) {
2195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::DADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::ADDiu, DstReg, SrcReg, ImmValue, IDLoc, STI);
2200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isUInt<16>(ImmValue)) {
2204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned TmpReg = DstReg;
2205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SrcReg == DstReg) {
2206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      TmpReg = getATReg(IDLoc);
2207f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!TmpReg)
2208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
2209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, ImmValue, IDLoc, STI);
2212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (UseSrcReg)
2213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(ABI.GetPtrAdduOp(), DstReg, TmpReg, SrcReg, IDLoc, STI);
2214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isInt<32>(ImmValue) || isUInt<32>(ImmValue)) {
22186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    warnIfNoMacro(IDLoc);
22196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
22206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint16_t Bits31To16 = (ImmValue >> 16) & 0xffff;
22216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint16_t Bits15To0 = ImmValue & 0xffff;
22226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
22236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!Is32BitImm && !isInt<32>(ImmValue)) {
2224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Traditional behaviour seems to special case this particular value. It's
2225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // not clear why other masks are handled differently.
2226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ImmValue == 0xffffffff) {
2227de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRI(Mips::LUi, TmpReg, 0xffff, IDLoc, STI);
2228de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRI(Mips::DSRL32, TmpReg, TmpReg, 0, IDLoc, STI);
2229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (UseSrcReg)
2230de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
2232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
2233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Expand to an ORi instead of a LUi to avoid sign-extending into the
22356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      // upper 32 bits.
2236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits31To16, IDLoc, STI);
2237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, 16, IDLoc, STI);
2238f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Bits15To0)
2239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
2240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (UseSrcReg)
2241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
22436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
22446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2245de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRI(Mips::LUi, TmpReg, Bits31To16, IDLoc, STI);
2246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Bits15To0)
2247de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, Bits15To0, IDLoc, STI);
22486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (UseSrcReg)
2249de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2250f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2251f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
22526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isShiftedUIntAtAnyPosition<16>(ImmValue)) {
22546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (Is32BitImm) {
22556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Error(IDLoc, "instruction requires a 32-bit immediate");
2256c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return true;
2257c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
22586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Traditionally, these immediates are shifted as little as possible and as
2260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // such we align the most significant bit to bit 15 of our temporary.
2261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned FirstSet = findFirstSet((uint64_t)ImmValue);
2262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned LastSet = findLastSet((uint64_t)ImmValue);
2263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned ShiftAmount = FirstSet - (15 - (LastSet - FirstSet));
2264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint16_t Bits = (ImmValue >> ShiftAmount) & 0xffff;
2265de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::ORi, TmpReg, ZeroReg, Bits, IDLoc, STI);
2266de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::DSLL, TmpReg, TmpReg, ShiftAmount, IDLoc, STI);
22676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
22686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (UseSrcReg)
2269de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
22706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2273c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
2274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  warnIfNoMacro(IDLoc);
22756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The remaining case is packed with a sequence of dsll and ori with zeros
2277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // being omitted and any neighbouring dsll's being coalesced.
2278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The highest 32-bit's are equivalent to a 32-bit immediate load.
22796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Load bits 32-63 of ImmValue into bits 0-31 of the temporary register.
2281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (loadImmediate(ImmValue >> 32, TmpReg, Mips::NoRegister, true, false,
2282de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                    IDLoc, Out, STI))
2283f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Shift and accumulate into the register. If a 16-bit chunk is zero, then
2286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // skip it and defer the shift to the next chunk.
2287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ShiftCarriedForwards = 16;
2288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  for (int BitNum = 16; BitNum >= 0; BitNum -= 16) {
2289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint16_t ImmChunk = (ImmValue >> BitNum) & 0xffff;
2290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ImmChunk != 0) {
2292de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::ORi, TmpReg, TmpReg, ImmChunk, IDLoc, STI);
2294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ShiftCarriedForwards = 0;
22956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    }
22966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ShiftCarriedForwards += 16;
22989d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  }
2299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  ShiftCarriedForwards -= 16;
2300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Finish any remaining shifts left by trailing zeros.
2302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (ShiftCarriedForwards)
2303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitDSLL(TmpReg, TmpReg, ShiftCarriedForwards, IDLoc, STI);
2304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (UseSrcReg)
2306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(AdduOp, DstReg, TmpReg, SrcReg, IDLoc, STI);
2307f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2308c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return false;
23099d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter}
23102490dc650895149423bb59538dc03ca352222702Jack Carter
23116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool MipsAsmParser::expandLoadImm(MCInst &Inst, bool Is32BitImm, SMLoc IDLoc,
2312de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                  MCStreamer &Out, const MCSubtargetInfo *STI) {
23136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCOperand &ImmOp = Inst.getOperand(1);
23146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(ImmOp.isImm() && "expected immediate operand kind");
23156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const MCOperand &DstRegOp = Inst.getOperand(0);
23166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  assert(DstRegOp.isReg() && "expected register operand kind");
23176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
23186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (loadImmediate(ImmOp.getImm(), DstRegOp.getReg(), Mips::NoRegister,
2319de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                    Is32BitImm, false, IDLoc, Out, STI))
23206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return true;
23216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
23226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return false;
23236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
23246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::expandLoadAddress(unsigned DstReg, unsigned BaseReg,
2326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                      const MCOperand &Offset,
2327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                      bool Is32BitAddress, SMLoc IDLoc,
2328de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      MCStreamer &Out,
2329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      const MCSubtargetInfo *STI) {
2330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // la can't produce a usable address when addresses are 64-bit.
2331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Is32BitAddress && ABI.ArePtrs64bit()) {
2332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: Demote this to a warning and continue as if we had 'dla' instead.
2333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //        We currently can't do this because we depend on the equality
2334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //        operator and N64 can end up with a GPR32/GPR64 mismatch.
2335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Error(IDLoc, "la used to load 64-bit address");
2336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Continue as if we had 'dla' instead.
2337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Is32BitAddress = false;
2338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // dla requires 64-bit addresses.
2341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!Is32BitAddress && !hasMips3()) {
2342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Error(IDLoc, "instruction requires a 64-bit architecture");
2343f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
234437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
23456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!Offset.isImm())
2347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return loadAndAddSymbolAddress(Offset.getExpr(), DstReg, BaseReg,
2348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                   Is32BitAddress, IDLoc, Out, STI);
2349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ABI.ArePtrs64bit()) {
2351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Continue as if we had 'la' whether we had 'la' or 'dla'.
2352de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    Is32BitAddress = true;
2353de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
23546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return loadImmediate(Offset.getImm(), DstReg, BaseReg, Is32BitAddress, true,
2356de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       IDLoc, Out, STI);
23572f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter}
23582f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
2359de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::loadAndAddSymbolAddress(const MCExpr *SymExpr,
2360de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                            unsigned DstReg, unsigned SrcReg,
2361de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                            bool Is32BitSym, SMLoc IDLoc,
2362de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                            MCStreamer &Out,
2363de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                            const MCSubtargetInfo *STI) {
2364de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2365de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool UseSrcReg = SrcReg != Mips::NoRegister;
2366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  warnIfNoMacro(IDLoc);
23676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2368de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (inPicMode() && ABI.IsO32()) {
2369de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    MCValue Res;
2370de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!SymExpr->evaluateAsRelocatable(Res, nullptr, nullptr)) {
2371de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Error(IDLoc, "expected relocatable expression");
2372de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return true;
2373de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Res.getSymB() != nullptr) {
2375de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Error(IDLoc, "expected relocatable expression with only one symbol");
2376de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return true;
2377de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2378de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2379de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The case where the result register is $25 is somewhat special. If the
2380de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // symbol in the final relocation is external and not modified with a
2381de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // constant then we must use R_MIPS_CALL16 instead of R_MIPS_GOT16.
2382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if ((DstReg == Mips::T9 || DstReg == Mips::T9_64) && !UseSrcReg &&
2383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Res.getConstant() == 0 && !Res.getSymA()->getSymbol().isInSection() &&
2384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        !Res.getSymA()->getSymbol().isTemporary()) {
2385de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      const MCExpr *CallExpr =
2386de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          MipsMCExpr::create(MipsMCExpr::MEK_GOT_CALL, SymExpr, getContext());
2387de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::LW, DstReg, ABI.GetGlobalPtr(),
2388de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(CallExpr), IDLoc, STI);
2389de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return false;
2390de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
23916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2392de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The remaining cases are:
2393de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //   External GOT: lw $tmp, %got(symbol+offset)($gp)
2394de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //                >addiu $tmp, $tmp, %lo(offset)
2395de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //                >addiu $rd, $tmp, $rs
2396de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //   Local GOT:    lw $tmp, %got(symbol+offset)($gp)
2397de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //                 addiu $tmp, $tmp, %lo(symbol+offset)($gp)
2398de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    //                >addiu $rd, $tmp, $rs
2399de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // The addiu's marked with a '>' may be omitted if they are redundant. If
2400de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // this happens then the last instruction must use $rd as the result
2401de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // register.
2402de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const MipsMCExpr *GotExpr =
2403de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        MipsMCExpr::create(MipsMCExpr::MEK_GOT, SymExpr, getContext());
2404de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const MCExpr *LoExpr = nullptr;
2405de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Res.getSymA()->getSymbol().isInSection() ||
2406de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        Res.getSymA()->getSymbol().isTemporary())
2407de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      LoExpr = MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
2408de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    else if (Res.getConstant() != 0) {
2409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // External symbols fully resolve the symbol with just the %got(symbol)
2410de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // but we must still account for any offset to the symbol for expressions
2411de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // like symbol+8.
2412de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      LoExpr = MCConstantExpr::create(Res.getConstant(), getContext());
2413de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2414de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2415de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned TmpReg = DstReg;
2416de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (UseSrcReg &&
2417de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2418de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                               SrcReg)) {
2419de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // If $rs is the same as $rd, we need to use AT.
2420de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // If it is not available we exit.
2421de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      unsigned ATReg = getATReg(IDLoc);
2422de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      if (!ATReg)
2423de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        return true;
2424de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TmpReg = ATReg;
2425de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2426de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2427de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRX(Mips::LW, TmpReg, ABI.GetGlobalPtr(),
2428de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 MCOperand::createExpr(GotExpr), IDLoc, STI);
2429de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2430de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (LoExpr)
2431de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2432de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   IDLoc, STI);
2433de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2434de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (UseSrcReg)
2435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2436de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2437de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
2438de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
2439de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2440de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MipsMCExpr *HiExpr =
2441de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MipsMCExpr::create(MipsMCExpr::MEK_HI, SymExpr, getContext());
2442de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MipsMCExpr *LoExpr =
2443de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MipsMCExpr::create(MipsMCExpr::MEK_LO, SymExpr, getContext());
24446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // This is the 64-bit symbol address expansion.
2446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (ABI.ArePtrs64bit() && isGP64bit()) {
2447f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // We always need AT for the 64-bit expansion.
2448f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If it is not available we exit.
2449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned ATReg = getATReg(IDLoc);
2450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
2451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
24522f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter
2453de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const MipsMCExpr *HighestExpr =
2454de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        MipsMCExpr::create(MipsMCExpr::MEK_HIGHEST, SymExpr, getContext());
2455de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    const MipsMCExpr *HigherExpr =
2456de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        MipsMCExpr::create(MipsMCExpr::MEK_HIGHER, SymExpr, getContext());
2457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2458de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (UseSrcReg &&
2459de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg,
2460de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                               SrcReg)) {
2461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If $rs is the same as $rd:
2462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // (d)la $rd, sym($rd) => lui    $at, %highest(sym)
2463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //                        daddiu $at, $at, %higher(sym)
2464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //                        dsll   $at, $at, 16
2465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //                        daddiu $at, $at, %hi(sym)
2466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //                        dsll   $at, $at, 16
2467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //                        daddiu $at, $at, %lo(sym)
2468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //                        daddu  $rd, $at, $rd
2469de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HighestExpr), IDLoc,
2470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  STI);
2471de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg,
2472de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(HigherExpr), IDLoc, STI);
2473de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2474de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(HiExpr),
2475de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   IDLoc, STI);
2476de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::DSLL, ATReg, ATReg, 16, IDLoc, STI);
2477de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2478de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   IDLoc, STI);
2479de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::DADDu, DstReg, ATReg, SrcReg, IDLoc, STI);
2480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
24836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // (d)la $rd, sym/sym($rs) => lui    $rd, %highest(sym)
2486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //                            lui    $at, %hi(sym)
2487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //                            daddiu $rd, $rd, %higher(sym)
2488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //                            daddiu $at, $at, %lo(sym)
2489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //                            dsll32 $rd, $rd, 0
2490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //                            daddu  $rd, $rd, $at
2491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    //                            (daddu  $rd, $rd, $rs)
2492de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRX(Mips::LUi, DstReg, MCOperand::createExpr(HighestExpr), IDLoc,
2493de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                STI);
2494de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRX(Mips::LUi, ATReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2495de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRX(Mips::DADDiu, DstReg, DstReg,
2496de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 MCOperand::createExpr(HigherExpr), IDLoc, STI);
2497de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRX(Mips::DADDiu, ATReg, ATReg, MCOperand::createExpr(LoExpr),
2498de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 IDLoc, STI);
2499de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::DSLL32, DstReg, DstReg, 0, IDLoc, STI);
2500de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::DADDu, DstReg, DstReg, ATReg, IDLoc, STI);
2501f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (UseSrcReg)
2502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::DADDu, DstReg, DstReg, SrcReg, IDLoc, STI);
25036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
2504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
250637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // And now, the 32-bit symbol address expansion:
2508f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If $rs is the same as $rd:
2509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // (d)la $rd, sym($rd)     => lui   $at, %hi(sym)
2510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //                            ori   $at, $at, %lo(sym)
2511f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //                            addu  $rd, $at, $rd
2512f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Otherwise, if the $rs is different from $rd or if $rs isn't specified:
2513f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // (d)la $rd, sym/sym($rs) => lui   $rd, %hi(sym)
2514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //                            ori   $rd, $rd, %lo(sym)
2515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //                            (addu $rd, $rd, $rs)
2516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TmpReg = DstReg;
2517de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (UseSrcReg &&
2518de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, SrcReg)) {
2519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If $rs is the same as $rd, we need to use AT.
2520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If it is not available we exit.
2521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned ATReg = getATReg(IDLoc);
2522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
2523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    TmpReg = ATReg;
252537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
2526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2527de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRX(Mips::LUi, TmpReg, MCOperand::createExpr(HiExpr), IDLoc, STI);
2528de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRX(Mips::ADDiu, TmpReg, TmpReg, MCOperand::createExpr(LoExpr),
2529de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               IDLoc, STI);
2530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (UseSrcReg)
2532de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::ADDu, DstReg, TmpReg, SrcReg, IDLoc, STI);
2533f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  else
2534de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    assert(
2535de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        getContext().getRegisterInfo()->isSuperOrSubRegisterEq(DstReg, TmpReg));
2536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
253837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
253937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
2540de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandUncondBranchMMPseudo(MCInst &Inst, SMLoc IDLoc,
2541de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                               MCStreamer &Out,
2542de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                               const MCSubtargetInfo *STI) {
2543de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2544de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2545ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  assert(getInstDesc(Inst.getOpcode()).getNumOperands() == 1 &&
2546ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines         "unexpected number of operands");
2547ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MCOperand Offset = Inst.getOperand(0);
2549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Offset.isExpr()) {
2550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Inst.clear();
2551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Inst.setOpcode(Mips::BEQ_MM);
25526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(Mips::ZERO));
25536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createReg(Mips::ZERO));
25546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Inst.addOperand(MCOperand::createExpr(Offset.getExpr()));
2555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
2556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    assert(Offset.isImm() && "expected immediate operand kind");
2557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (isInt<11>(Offset.getImm())) {
2558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // If offset fits into 11 bits then this instruction becomes microMIPS
2559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // 16-bit unconditional branch instruction.
2560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (inMicroMipsMode())
2561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        Inst.setOpcode(hasMips32r6() ? Mips::BC16_MMR6 : Mips::B16_MM);
2562ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    } else {
2563f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!isInt<17>(Offset.getImm()))
2564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Error(IDLoc, "branch target out of range");
2565ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (OffsetToAlignment(Offset.getImm(), 1LL << 1))
2566ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        Error(IDLoc, "branch to misaligned address");
2567ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Inst.clear();
2568ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Inst.setOpcode(Mips::BEQ_MM);
25696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createReg(Mips::ZERO));
25706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createReg(Mips::ZERO));
25716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      Inst.addOperand(MCOperand::createImm(Offset.getImm()));
2572ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
2573ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
2574de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Out.EmitInstruction(Inst, *STI);
2575ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2576f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If .set reorder is active and branch instruction has a delay slot,
2577f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // emit a NOP after it.
2578f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCInstrDesc &MCID = getInstDesc(Inst.getOpcode());
2579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (MCID.hasDelaySlot() && AssemblerOptions.back()->isReorder())
2580de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitEmptyDelaySlot(true, IDLoc, STI);
25814c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
2582ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return false;
2583ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
2584ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
2585de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandBranchImm(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                    const MCSubtargetInfo *STI) {
2587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &DstRegOp = Inst.getOperand(0);
2589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(DstRegOp.isReg() && "expected register operand kind");
2590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &ImmOp = Inst.getOperand(1);
2592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(ImmOp.isImm() && "expected immediate operand kind");
2593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &MemOffsetOp = Inst.getOperand(2);
2595de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert((MemOffsetOp.isImm() || MemOffsetOp.isExpr()) &&
2596de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar         "expected immediate or expression operand");
2597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned OpCode = 0;
2599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch(Inst.getOpcode()) {
2600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BneImm:
2601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      OpCode = Mips::BNE;
2602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BeqImm:
2604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      OpCode = Mips::BEQ;
2605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2606f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
2607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("Unknown immediate branch pseudo-instruction.");
2608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t ImmValue = ImmOp.getImm();
2612f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (ImmValue == 0)
2613de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRX(OpCode, DstRegOp.getReg(), Mips::ZERO, MemOffsetOp, IDLoc,
2614de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 STI);
2615f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  else {
2616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    warnIfNoMacro(IDLoc);
2617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned ATReg = getATReg(IDLoc);
2619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
2620f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2622f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (loadImmediate(ImmValue, ATReg, Mips::NoRegister, !isGP64bit(), true,
2623de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      IDLoc, Out, STI))
2624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2626de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRX(OpCode, DstRegOp.getReg(), ATReg, MemOffsetOp, IDLoc, STI);
2627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
2629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2631de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid MipsAsmParser::expandMemInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2632de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                  const MCSubtargetInfo *STI, bool IsLoad,
2633de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                  bool IsImmOpnd) {
2634de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IsLoad) {
2635de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    expandLoadInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2636de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
2637de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
2638de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  expandStoreInst(Inst, IDLoc, Out, STI, IsImmOpnd);
2639de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
2640de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2641de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid MipsAsmParser::expandLoadInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2642de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                   const MCSubtargetInfo *STI, bool IsImmOpnd) {
2643de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2644de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2645de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned DstReg = Inst.getOperand(0).getReg();
2646de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned BaseReg = Inst.getOperand(1).getReg();
2647de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCInstrDesc &Desc = getInstDesc(Inst.getOpcode());
2649de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  int16_t DstRegClass = Desc.OpInfo[0].RegClass;
2650de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned DstRegClassID =
2651de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      getContext().getRegisterInfo()->getRegClass(DstRegClass).getID();
2652de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  bool IsGPR = (DstRegClassID == Mips::GPR32RegClassID) ||
2653de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               (DstRegClassID == Mips::GPR64RegClassID);
2654de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2655de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IsImmOpnd) {
2656de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    // Try to use DstReg as the temporary.
2657de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (IsGPR && (BaseReg != DstReg)) {
2658de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2659de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                 Inst.getOperand(2).getImm(), DstReg, IDLoc,
2660de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                 STI);
2661de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return;
2662de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    }
2663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2664f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // At this point we need AT to perform the expansions and we exit if it is
2665f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // not available.
2666de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned ATReg = getATReg(IDLoc);
2667de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!ATReg)
2668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return;
2669de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2670de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitLoadWithImmOffset(Inst.getOpcode(), DstReg, BaseReg,
2671de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                               Inst.getOperand(2).getImm(), ATReg, IDLoc, STI);
2672de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
2673f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2674f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2675de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2676de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCOperand LoOperand = MCOperand::createExpr(
2677de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2678de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCOperand HiOperand = MCOperand::createExpr(
2679de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2680de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2681de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // Try to use DstReg as the temporary.
2682de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IsGPR && (BaseReg != DstReg)) {
2683de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2684de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                               LoOperand, DstReg, IDLoc, STI);
2685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
2686de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
2687de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2688de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // At this point we need AT to perform the expansions and we exit if it is
2689de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // not available.
2690de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned ATReg = getATReg(IDLoc);
2691de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ATReg)
2692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
2693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2694de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitLoadWithSymOffset(Inst.getOpcode(), DstReg, BaseReg, HiOperand,
2695de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                             LoOperand, ATReg, IDLoc, STI);
2696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarvoid MipsAsmParser::expandStoreInst(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
2699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                    const MCSubtargetInfo *STI,
2700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                    bool IsImmOpnd) {
2701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2703de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned SrcReg = Inst.getOperand(0).getReg();
2704de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned BaseReg = Inst.getOperand(1).getReg();
2705de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2706de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IsImmOpnd) {
2707de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitStoreWithImmOffset(Inst.getOpcode(), SrcReg, BaseReg,
2708de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                Inst.getOperand(2).getImm(),
2709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                [&]() { return getATReg(IDLoc); }, IDLoc, STI);
2710de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
2711de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
2712de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2713de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned ATReg = getATReg(IDLoc);
2714de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!ATReg)
2715de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return;
2716de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2717de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MCExpr *ExprOffset = Inst.getOperand(2).getExpr();
2718de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCOperand LoOperand = MCOperand::createExpr(
2719de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MipsMCExpr::create(MipsMCExpr::MEK_LO, ExprOffset, getContext()));
2720de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCOperand HiOperand = MCOperand::createExpr(
2721de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      MipsMCExpr::create(MipsMCExpr::MEK_HI, ExprOffset, getContext()));
2722de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitStoreWithSymOffset(Inst.getOpcode(), SrcReg, BaseReg, HiOperand,
2723de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              LoOperand, ATReg, IDLoc, STI);
2724de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
2725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
2726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandLoadStoreMultiple(MCInst &Inst, SMLoc IDLoc,
2727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                            MCStreamer &Out,
2728de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                            const MCSubtargetInfo *STI) {
2729f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned OpNum = Inst.getNumOperands();
2730f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned Opcode = Inst.getOpcode();
2731f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM32_MM : Mips::LWM32_MM;
2732f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2733f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert (Inst.getOperand(OpNum - 1).isImm() &&
2734f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Inst.getOperand(OpNum - 2).isReg() &&
2735f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Inst.getOperand(OpNum - 3).isReg() && "Invalid instruction operand.");
2736f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2737f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (OpNum < 8 && Inst.getOperand(OpNum - 1).getImm() <= 60 &&
2738f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Inst.getOperand(OpNum - 1).getImm() >= 0 &&
2739f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      (Inst.getOperand(OpNum - 2).getReg() == Mips::SP ||
2740f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar       Inst.getOperand(OpNum - 2).getReg() == Mips::SP_64) &&
2741f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      (Inst.getOperand(OpNum - 3).getReg() == Mips::RA ||
2742f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar       Inst.getOperand(OpNum - 3).getReg() == Mips::RA_64)) {
2743f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // It can be implemented as SWM16 or LWM16 instruction.
2744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (inMicroMipsMode() && hasMips32r6())
2745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MMR6 : Mips::LWM16_MMR6;
2746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
2747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      NewOpcode = Opcode == Mips::SWM_MM ? Mips::SWM16_MM : Mips::LWM16_MM;
2748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Inst.setOpcode(NewOpcode);
2751de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Out.EmitInstruction(Inst, *STI);
2752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
2753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
2754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2755f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::expandCondBranches(MCInst &Inst, SMLoc IDLoc,
2756de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       MCStreamer &Out,
2757de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       const MCSubtargetInfo *STI) {
2758de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
2759f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool EmittedNoMacroWarning = false;
2760f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned PseudoOpcode = Inst.getOpcode();
2761f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SrcReg = Inst.getOperand(0).getReg();
2762f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &TrgOp = Inst.getOperand(1);
2763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCExpr *OffsetExpr = Inst.getOperand(2).getExpr();
2764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ZeroSrcOpcode, ZeroTrgOpcode;
2766f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool ReverseOrderSLT, IsUnsigned, IsLikely, AcceptsEquality;
2767f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2768f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TrgReg;
2769f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (TrgOp.isReg())
2770f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    TrgReg = TrgOp.getReg();
2771f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  else if (TrgOp.isImm()) {
2772f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    warnIfNoMacro(IDLoc);
2773f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    EmittedNoMacroWarning = true;
2774f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2775f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    TrgReg = getATReg(IDLoc);
2776f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!TrgReg)
2777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    switch(PseudoOpcode) {
2780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
2781f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("unknown opcode for branch pseudo-instruction");
2782f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLTImmMacro:
2783f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLT;
2784f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2785f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLEImmMacro:
2786f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLE;
2787f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2788f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGEImmMacro:
2789f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGE;
2790f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2791f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGTImmMacro:
2792f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGT;
2793f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2794f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLTUImmMacro:
2795f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLTU;
2796f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2797f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLEUImmMacro:
2798f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLEU;
2799f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2800f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGEUImmMacro:
2801f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGEU;
2802f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2803f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGTUImmMacro:
2804f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGTU;
2805f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2806f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLTLImmMacro:
2807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLTL;
2808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLELImmMacro:
2810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLEL;
2811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2812f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGELImmMacro:
2813f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGEL;
2814f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGTLImmMacro:
2816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGTL;
2817f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2818f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLTULImmMacro:
2819f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLTUL;
2820f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2821f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BLEULImmMacro:
2822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BLEUL;
2823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGEULImmMacro:
2825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGEUL;
2826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::BGTULImmMacro:
2828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      PseudoOpcode = Mips::BGTUL;
2829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
2830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (loadImmediate(TrgOp.getImm(), TrgReg, Mips::NoRegister, !isGP64bit(),
2833de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      false, IDLoc, Out, STI))
2834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
2835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  switch (PseudoOpcode) {
2838f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLT:
2839f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTU:
2840f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTL:
2841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLTUL:
2842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AcceptsEquality = false;
2843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ReverseOrderSLT = false;
2844f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsUnsigned = ((PseudoOpcode == Mips::BLTU) || (PseudoOpcode == Mips::BLTUL));
2845f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsLikely = ((PseudoOpcode == Mips::BLTL) || (PseudoOpcode == Mips::BLTUL));
2846f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroSrcOpcode = Mips::BGTZ;
2847f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroTrgOpcode = Mips::BLTZ;
2848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
2849f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLE:
2850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEU:
2851f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEL:
2852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BLEUL:
2853f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AcceptsEquality = true;
2854f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ReverseOrderSLT = true;
2855f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsUnsigned = ((PseudoOpcode == Mips::BLEU) || (PseudoOpcode == Mips::BLEUL));
2856f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsLikely = ((PseudoOpcode == Mips::BLEL) || (PseudoOpcode == Mips::BLEUL));
2857f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroSrcOpcode = Mips::BGEZ;
2858f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroTrgOpcode = Mips::BLEZ;
2859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
2860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGE:
2861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEU:
2862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEL:
2863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGEUL:
2864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AcceptsEquality = true;
2865f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ReverseOrderSLT = false;
2866f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsUnsigned = ((PseudoOpcode == Mips::BGEU) || (PseudoOpcode == Mips::BGEUL));
2867f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsLikely = ((PseudoOpcode == Mips::BGEL) || (PseudoOpcode == Mips::BGEUL));
2868f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroSrcOpcode = Mips::BLEZ;
2869f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroTrgOpcode = Mips::BGEZ;
2870f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
2871f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGT:
2872f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTU:
2873f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTL:
2874f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Mips::BGTUL:
2875f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    AcceptsEquality = false;
2876f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ReverseOrderSLT = true;
2877f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsUnsigned = ((PseudoOpcode == Mips::BGTU) || (PseudoOpcode == Mips::BGTUL));
2878f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsLikely = ((PseudoOpcode == Mips::BGTL) || (PseudoOpcode == Mips::BGTUL));
2879f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroSrcOpcode = Mips::BLTZ;
2880f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroTrgOpcode = Mips::BGTZ;
2881f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    break;
2882f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  default:
2883f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    llvm_unreachable("unknown opcode for branch pseudo-instruction");
2884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool IsTrgRegZero = (TrgReg == Mips::ZERO);
2887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool IsSrcRegZero = (SrcReg == Mips::ZERO);
2888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (IsSrcRegZero && IsTrgRegZero) {
2889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // FIXME: All of these Opcode-specific if's are needed for compatibility
2890f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // with GAS' behaviour. However, they may not generate the most efficient
2891f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // code in some circumstances.
2892f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (PseudoOpcode == Mips::BLT) {
2893de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRX(Mips::BLTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2894de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  IDLoc, STI);
2895f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2896f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2897f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (PseudoOpcode == Mips::BLE) {
2898de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRX(Mips::BLEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  IDLoc, STI);
2900f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Warning(IDLoc, "branch is always taken");
2901f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2902f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2903f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (PseudoOpcode == Mips::BGE) {
2904de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRX(Mips::BGEZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2905de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  IDLoc, STI);
2906f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Warning(IDLoc, "branch is always taken");
2907f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2908f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2909f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (PseudoOpcode == Mips::BGT) {
2910de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRX(Mips::BGTZ, Mips::ZERO, MCOperand::createExpr(OffsetExpr),
2911de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                  IDLoc, STI);
2912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (PseudoOpcode == Mips::BGTU) {
2915de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::BNE, Mips::ZERO, Mips::ZERO,
2916de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2917f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2918f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (AcceptsEquality) {
2920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If both registers are $0 and the pseudo-branch accepts equality, it
2921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // will always be taken, so we emit an unconditional branch.
2922de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2923de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Warning(IDLoc, "branch is always taken");
2925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If both registers are $0 and the pseudo-branch does not accept
2928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // equality, it will never be taken, so we don't have to emit anything.
2929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (IsSrcRegZero || IsTrgRegZero) {
2932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if ((IsSrcRegZero && PseudoOpcode == Mips::BGTU) ||
2933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        (IsTrgRegZero && PseudoOpcode == Mips::BLTU)) {
2934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If the $rs is $0 and the pseudo-branch is BGTU (0 > x) or
2935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // if the $rt is $0 and the pseudo-branch is BLTU (x < 0),
2936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // the pseudo-branch will never be taken, so we don't emit anything.
2937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // This only applies to unsigned pseudo-branches.
2938f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2939f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2940f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if ((IsSrcRegZero && PseudoOpcode == Mips::BLEU) ||
2941f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        (IsTrgRegZero && PseudoOpcode == Mips::BGEU)) {
2942f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If the $rs is $0 and the pseudo-branch is BLEU (0 <= x) or
2943f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // if the $rt is $0 and the pseudo-branch is BGEU (x >= 0),
2944f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // the pseudo-branch will always be taken, so we emit an unconditional
2945f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // branch.
2946f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // This only applies to unsigned pseudo-branches.
2947de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(Mips::BEQ, Mips::ZERO, Mips::ZERO,
2948de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2949f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Warning(IDLoc, "branch is always taken");
2950f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2951f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2952f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsUnsigned) {
2953f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If the $rs is $0 and the pseudo-branch is BLTU (0 < x) or
2954f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // if the $rt is $0 and the pseudo-branch is BGTU (x > 0),
2955f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // the pseudo-branch will be taken only when the non-zero register is
2956f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // different from 0, so we emit a BNEZ.
2957f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //
2958f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // If the $rs is $0 and the pseudo-branch is BGEU (0 >= x) or
2959f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // if the $rt is $0 and the pseudo-branch is BLEU (x <= 0),
2960f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // the pseudo-branch will be taken only when the non-zero register is
2961f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // equal to 0, so we emit a BEQZ.
2962f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      //
2963f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // Because only BLEU and BGEU branch on equality, we can use the
2964f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      // AcceptsEquality variable to decide when to emit the BEQZ.
2965de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRX(AcceptsEquality ? Mips::BEQ : Mips::BNE,
2966de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   IsSrcRegZero ? TrgReg : SrcReg, Mips::ZERO,
2967de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
2969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
2970f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If we have a signed pseudo-branch and one of the registers is $0,
2971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // we can use an appropriate compare-to-zero branch. We select which one
2972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // to use in the switch statement above.
2973de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRX(IsSrcRegZero ? ZeroSrcOpcode : ZeroTrgOpcode,
2974de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                IsSrcRegZero ? TrgReg : SrcReg,
2975de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                MCOperand::createExpr(OffsetExpr), IDLoc, STI);
2976f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
2977f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
2978f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2979f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If neither the SrcReg nor the TrgReg are $0, we need AT to perform the
2980f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // expansions. If it is not available, we return.
2981f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATRegNum = getATReg(IDLoc);
2982f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!ATRegNum)
2983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
2984f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2985f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!EmittedNoMacroWarning)
2986f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    warnIfNoMacro(IDLoc);
2987f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
2988f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // SLT fits well with 2 of our 4 pseudo-branches:
2989f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //   BLT, where $rs < $rt, translates into "slt $at, $rs, $rt" and
2990f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //   BGT, where $rs > $rt, translates into "slt $at, $rt, $rs".
2991f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If the result of the SLT is 1, we branch, and if it's 0, we don't.
2992f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // This is accomplished by using a BNEZ with the result of the SLT.
2993f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //
2994f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The other 2 pseudo-branches are opposites of the above 2 (BGE with BLT
2995f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // and BLE with BGT), so we change the BNEZ into a a BEQZ.
2996f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Because only BGE and BLE branch on equality, we can use the
2997f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // AcceptsEquality variable to decide when to emit the BEQZ.
2998f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Note that the order of the SLT arguments doesn't change between
2999f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // opposites.
3000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  //
3001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // The same applies to the unsigned variants, except that SLTu is used
3002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // instead of SLT.
3003de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRR(IsUnsigned ? Mips::SLTu : Mips::SLT, ATRegNum,
3004de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               ReverseOrderSLT ? TrgReg : SrcReg,
3005de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               ReverseOrderSLT ? SrcReg : TrgReg, IDLoc, STI);
3006de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3007de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRX(IsLikely ? (AcceptsEquality ? Mips::BEQL : Mips::BNEL)
3008de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                        : (AcceptsEquality ? Mips::BEQ : Mips::BNE),
3009de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               ATRegNum, Mips::ZERO, MCOperand::createExpr(OffsetExpr), IDLoc,
3010de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               STI);
3011f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
3012f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3013f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3014de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandDiv(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3015de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              const MCSubtargetInfo *STI, const bool IsMips64,
3016de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              const bool Signed) {
3017de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3018f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3019f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  warnIfNoMacro(IDLoc);
3020f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3021de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MCOperand &RdRegOp = Inst.getOperand(0);
3022de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(RdRegOp.isReg() && "expected register operand kind");
3023de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned RdReg = RdRegOp.getReg();
3024de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3025de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MCOperand &RsRegOp = Inst.getOperand(1);
3026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(RsRegOp.isReg() && "expected register operand kind");
3027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned RsReg = RsRegOp.getReg();
3028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3029de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const MCOperand &RtRegOp = Inst.getOperand(2);
3030f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(RtRegOp.isReg() && "expected register operand kind");
3031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned RtReg = RtRegOp.getReg();
3032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DivOp;
3033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ZeroReg;
3034f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3035f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (IsMips64) {
3036f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DivOp = Signed ? Mips::DSDIV : Mips::DUDIV;
3037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroReg = Mips::ZERO_64;
3038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else {
3039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DivOp = Signed ? Mips::SDIV : Mips::UDIV;
3040f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ZeroReg = Mips::ZERO;
3041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3042f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3043f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool UseTraps = useTraps();
3044f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3045f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RsReg == Mips::ZERO || RsReg == Mips::ZERO_64) {
3046f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)
3047f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Warning(IDLoc, "dividing zero by zero");
3048f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (IsMips64) {
3049f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Signed && (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64)) {
3050f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        if (UseTraps) {
3051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3052f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          return false;
3053f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        }
3054f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3056f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
3057f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3058f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else {
3059de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3060f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3061f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3062f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3063f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3064f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (RtReg == Mips::ZERO || RtReg == Mips::ZERO_64) {
3065f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Warning(IDLoc, "division by zero");
3066f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Signed) {
3067f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (UseTraps) {
3068de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar        TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3069f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return false;
3070f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3071f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3072de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3073f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3074f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3075f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3076f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3077f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // FIXME: The values for these two BranchTarget variables may be different in
3078f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // micromips. These magic numbers need to be removed.
3079f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned BranchTargetNoTraps;
3080f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned BranchTarget;
3081f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3082f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (UseTraps) {
3083f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BranchTarget = IsMips64 ? 12 : 8;
3084de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::TEQ, RtReg, ZeroReg, 0x7, IDLoc, STI);
3085f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else {
3086f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BranchTarget = IsMips64 ? 20 : 16;
3087f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    BranchTargetNoTraps = 8;
3088f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Branch to the li instruction.
3089de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::BNE, RtReg, ZeroReg, BranchTargetNoTraps, IDLoc, STI);
3090f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3091f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3092de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRR(DivOp, RsReg, RtReg, IDLoc, STI);
3093f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3094f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!UseTraps)
3095de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitII(Mips::BREAK, 0x7, 0, IDLoc, STI);
3096f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3097f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!Signed) {
3098de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3099f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3100f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3101f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3102f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = getATReg(IDLoc);
3103f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!ATReg)
3104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
3105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3106de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, -1, IDLoc, STI);
3107f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (IsMips64) {
3108f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Branch to the mflo instruction.
3109de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3110de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::ADDiu, ATReg, ZeroReg, 1, IDLoc, STI);
3111de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::DSLL32, ATReg, ATReg, 0x1f, IDLoc, STI);
3112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else {
3113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Branch to the mflo instruction.
3114de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::BNE, RtReg, ATReg, BranchTarget, IDLoc, STI);
3115de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRI(Mips::LUi, ATReg, (uint16_t)0x8000, IDLoc, STI);
3116f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3118f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (UseTraps)
3119de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::TEQ, RsReg, ATReg, 0x6, IDLoc, STI);
3120f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  else {
3121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Branch to the mflo instruction.
3122de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::BNE, RsReg, ATReg, BranchTargetNoTraps, IDLoc, STI);
3123de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::SLL, ZeroReg, ZeroReg, 0, IDLoc, STI);
3124de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitII(Mips::BREAK, 0x6, 0, IDLoc, STI);
3125de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
3126de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitR(Mips::MFLO, RdReg, IDLoc, STI);
3127de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return false;
3128de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
3129de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3130de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandTrunc(MCInst &Inst, bool IsDouble, bool Is64FPU,
3131de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                SMLoc IDLoc, MCStreamer &Out,
3132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                const MCSubtargetInfo *STI) {
3133de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3134de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3135de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(Inst.getNumOperands() == 3 && "Invalid operand count");
3136de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(Inst.getOperand(0).isReg() && Inst.getOperand(1).isReg() &&
3137de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar         Inst.getOperand(2).isReg() && "Invalid instruction operand.");
3138de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3139de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned FirstReg = Inst.getOperand(0).getReg();
3140de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned SecondReg = Inst.getOperand(1).getReg();
3141de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned ThirdReg = Inst.getOperand(2).getReg();
3142de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3143de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (hasMips1() && !hasMips2()) {
3144de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    unsigned ATReg = getATReg(IDLoc);
3145de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (!ATReg)
3146de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return true;
3147de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3148de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRR(Mips::CFC1, ThirdReg, Mips::RA, IDLoc, STI);
3149de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitNop(IDLoc, STI);
3150de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::ORi, ATReg, ThirdReg, 0x3, IDLoc, STI);
3151de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(Mips::XORi, ATReg, ATReg, 0x2, IDLoc, STI);
3152de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRR(Mips::CTC1, Mips::RA, ATReg, IDLoc, STI);
3153de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitNop(IDLoc, STI);
3154de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRR(IsDouble ? (Is64FPU ? Mips::CVT_W_D64 : Mips::CVT_W_D32)
3155de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                         : Mips::CVT_W_S,
3156de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                FirstReg, SecondReg, IDLoc, STI);
3157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRR(Mips::CTC1, Mips::RA, ThirdReg, IDLoc, STI);
3158de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitNop(IDLoc, STI);
3159de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
3160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3161de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3162de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRR(IsDouble ? (Is64FPU ? Mips::TRUNC_W_D64 : Mips::TRUNC_W_D32)
3163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                       : Mips::TRUNC_W_S,
3164de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar              FirstReg, SecondReg, IDLoc, STI);
3165de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
3167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::expandUlh(MCInst &Inst, bool Signed, SMLoc IDLoc,
3170de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              MCStreamer &Out, const MCSubtargetInfo *STI) {
3171de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3172de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips32r6() || hasMips64r6()) {
3174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  warnIfNoMacro(IDLoc);
3179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &DstRegOp = Inst.getOperand(0);
3181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(DstRegOp.isReg() && "expected register operand kind");
3182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3183f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &SrcRegOp = Inst.getOperand(1);
3184f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(SrcRegOp.isReg() && "expected register operand kind");
3185f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3186f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3187f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3188f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3189f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DstReg = DstRegOp.getReg();
3190f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SrcReg = SrcRegOp.getReg();
3191f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t OffsetValue = OffsetImmOp.getImm();
3192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3193f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // NOTE: We always need AT for ULHU, as it is always used as the source
3194f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // register for one of the LBu's.
3195f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = getATReg(IDLoc);
3196f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!ATReg)
3197f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
3198f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3199f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // When the value of offset+1 does not fit in 16 bits, we have to load the
3200f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // offset in AT, (D)ADDu the original source register (if there was one), and
3201f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // then use AT as the source register for the 2 generated LBu's.
3202f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool LoadedOffsetInAT = false;
3203f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!isInt<16>(OffsetValue + 1) || !isInt<16>(OffsetValue)) {
3204f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LoadedOffsetInAT = true;
3205f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3206f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      true, IDLoc, Out, STI))
3208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3209f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3211f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // because it will make our output more similar to GAS'. For example,
3212f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // instead of just an "ori $1, $9, 32768".
3214f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // NOTE: If there is no source register specified in the ULHU, the parser
3215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // will interpret it as $0.
3216f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI);
3218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3219f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3220f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FirstLbuDstReg = LoadedOffsetInAT ? DstReg : ATReg;
3221f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SecondLbuDstReg = LoadedOffsetInAT ? ATReg : DstReg;
3222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned LbuSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3223f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t FirstLbuOffset = 0, SecondLbuOffset = 0;
3225f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isLittle()) {
3226f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    FirstLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3227f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SecondLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3228f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else {
3229f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    FirstLbuOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3230f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SecondLbuOffset = LoadedOffsetInAT ? 1 : (OffsetValue + 1);
3231f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3233f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SllReg = LoadedOffsetInAT ? DstReg : ATReg;
3234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3235de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRI(Signed ? Mips::LB : Mips::LBu, FirstLbuDstReg, LbuSrcReg,
3236de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               FirstLbuOffset, IDLoc, STI);
3237f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3238de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRI(Mips::LBu, SecondLbuDstReg, LbuSrcReg, SecondLbuOffset, IDLoc,
3239de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               STI);
3240f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3241de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRI(Mips::SLL, SllReg, SllReg, 8, IDLoc, STI);
3242f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3243de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRR(Mips::OR, DstReg, DstReg, ATReg, IDLoc, STI);
3244f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3245f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
3246f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3247f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3248de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandUlw(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3249de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              const MCSubtargetInfo *STI) {
3250de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3251de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
3252f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips32r6() || hasMips64r6()) {
3253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Error(IDLoc, "instruction not supported on mips32r6 or mips64r6");
3254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &DstRegOp = Inst.getOperand(0);
3258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(DstRegOp.isReg() && "expected register operand kind");
3259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &SrcRegOp = Inst.getOperand(1);
3261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(SrcRegOp.isReg() && "expected register operand kind");
3262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3263f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCOperand &OffsetImmOp = Inst.getOperand(2);
3264f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert(OffsetImmOp.isImm() && "expected immediate operand kind");
3265f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SrcReg = SrcRegOp.getReg();
3267f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t OffsetValue = OffsetImmOp.getImm();
3268f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = 0;
3269f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // When the value of offset+3 does not fit in 16 bits, we have to load the
3271f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // offset in AT, (D)ADDu the original source register (if there was one), and
3272f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // then use AT as the source register for the generated LWL and LWR.
3273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool LoadedOffsetInAT = false;
3274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!isInt<16>(OffsetValue + 3) || !isInt<16>(OffsetValue)) {
3275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ATReg = getATReg(IDLoc);
3276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
3277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LoadedOffsetInAT = true;
3279f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3280f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    warnIfNoMacro(IDLoc);
3281f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3282f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (loadImmediate(OffsetValue, ATReg, Mips::NoRegister, !ABI.ArePtrs64bit(),
3283de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                      true, IDLoc, Out, STI))
3284f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3285f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3286f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // NOTE: We do this (D)ADDu here instead of doing it in loadImmediate()
3287f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // because it will make our output more similar to GAS'. For example,
3288f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // generating an "ori $1, $zero, 32768" followed by an "addu $1, $1, $9",
3289f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // instead of just an "ori $1, $9, 32768".
3290f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // NOTE: If there is no source register specified in the ULW, the parser
3291f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // will interpret it as $0.
3292f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (SrcReg != Mips::ZERO && SrcReg != Mips::ZERO_64)
3293de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitAddu(ATReg, ATReg, SrcReg, ABI.ArePtrs64bit(), STI);
3294f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3295f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FinalSrcReg = LoadedOffsetInAT ? ATReg : SrcReg;
3297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t LeftLoadOffset = 0, RightLoadOffset  = 0;
3298f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (isLittle()) {
3299f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LeftLoadOffset = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3300f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RightLoadOffset  = LoadedOffsetInAT ? 0 : OffsetValue;
3301f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else {
3302f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    LeftLoadOffset = LoadedOffsetInAT ? 0 : OffsetValue;
3303f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    RightLoadOffset  = LoadedOffsetInAT ? 3 : (OffsetValue + 3);
3304f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3305f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRI(Mips::LWL, DstRegOp.getReg(), FinalSrcReg, LeftLoadOffset, IDLoc,
3307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               STI);
3308f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3309de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRI(Mips::LWR, DstRegOp.getReg(), FinalSrcReg, RightLoadOffset,
3310de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar               IDLoc, STI);
3311f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3312f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
3313f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3314f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3315f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::expandAliasImmediate(MCInst &Inst, SMLoc IDLoc,
3316de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                         MCStreamer &Out,
3317de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                         const MCSubtargetInfo *STI) {
3318de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3320f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert (Inst.getNumOperands() == 3 && "Invalid operand count");
3321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  assert (Inst.getOperand(0).isReg() &&
3322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Inst.getOperand(1).isReg() &&
3323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          Inst.getOperand(2).isImm() && "Invalid instruction operand.");
3324f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = Mips::NoRegister;
3326f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FinalDstReg = Mips::NoRegister;
3327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DstReg = Inst.getOperand(0).getReg();
3328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SrcReg = Inst.getOperand(1).getReg();
3329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t ImmValue = Inst.getOperand(2).getImm();
3330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3331f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool Is32Bit = isInt<32>(ImmValue) || isUInt<32>(ImmValue);
3332f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3333f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FinalOpcode = Inst.getOpcode();
3334f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3335f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (DstReg == SrcReg) {
3336f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ATReg = getATReg(Inst.getLoc());
3337f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
3338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    FinalDstReg = DstReg;
3340f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    DstReg = ATReg;
3341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3342f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!loadImmediate(ImmValue, DstReg, Mips::NoRegister, Is32Bit, false, Inst.getLoc(), Out, STI)) {
3344f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    switch (FinalOpcode) {
3345f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
3346f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("unimplemented expansion");
3347f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::ADDi):
3348f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::ADD;
3349f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3350f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::ADDiu):
3351f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::ADDu;
3352f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3353f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::ANDi):
3354f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::AND;
3355f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3356f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::NORImm):
3357f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::NOR;
3358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3359f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::ORi):
3360f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::OR;
3361f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3362f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::SLTi):
3363f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::SLT;
3364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3365f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::SLTiu):
3366f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::SLTu;
3367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case (Mips::XORi):
3369f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::XOR;
3370f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3371f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3372f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3373f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (FinalDstReg == Mips::NoRegister)
3374de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(FinalOpcode, DstReg, DstReg, SrcReg, IDLoc, STI);
3375f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else
3376de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(FinalOpcode, FinalDstReg, FinalDstReg, DstReg, IDLoc, STI);
3377f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3378f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3379f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
3380f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3381f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3382de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3383de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                   const MCSubtargetInfo *STI) {
3384de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3385f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = Mips::NoRegister;
3386f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DReg = Inst.getOperand(0).getReg();
3387f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SReg = Inst.getOperand(1).getReg();
3388f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TReg = Inst.getOperand(2).getReg();
3389f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TmpReg = DReg;
3390f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3391f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FirstShift = Mips::NOP;
3392f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SecondShift = Mips::NOP;
3393f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3394f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips32r2()) {
3395f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3396f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (DReg == SReg) {
3397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      TmpReg = getATReg(Inst.getLoc());
3398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!TmpReg)
3399f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
3400f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3401f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3402f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::ROL) {
3403de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::SUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3404de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::ROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3405f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3406f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3407f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3408f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::ROR) {
3409de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::ROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
3414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips32()) {
3417f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3418f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    switch (Inst.getOpcode()) {
3419f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
3420f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("unexpected instruction opcode");
3421f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::ROL:
3422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FirstShift = Mips::SRLV;
3423f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SecondShift = Mips::SLLV;
3424f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3425f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::ROR:
3426f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FirstShift = Mips::SLLV;
3427f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SecondShift = Mips::SRLV;
3428f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3429f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3430f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3431f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ATReg = getATReg(Inst.getLoc());
3432f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
3433f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3435de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::SUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3436de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3437de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3438de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3439f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3440f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3441f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3442f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3443f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
3444f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3445f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3446f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::expandRotationImm(MCInst &Inst, SMLoc IDLoc,
3447de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      MCStreamer &Out,
3448de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                      const MCSubtargetInfo *STI) {
3449de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = Mips::NoRegister;
3451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DReg = Inst.getOperand(0).getReg();
3452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SReg = Inst.getOperand(1).getReg();
3453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t ImmValue = Inst.getOperand(2).getImm();
3454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FirstShift = Mips::NOP;
3456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SecondShift = Mips::NOP;
3457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips32r2()) {
3459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::ROLImm) {
3461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t MaxShift = 32;
3462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      uint64_t ShiftValue = ImmValue;
3463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ImmValue != 0)
3464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        ShiftValue = MaxShift - ImmValue;
3465de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::ROTR, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::RORImm) {
3470de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::ROTR, DReg, SReg, ImmValue, Inst.getLoc(), STI);
3471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
3475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips32()) {
3478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ImmValue == 0) {
3480de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::SRL, DReg, SReg, 0, Inst.getLoc(), STI);
3481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    switch (Inst.getOpcode()) {
3485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
3486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("unexpected instruction opcode");
3487f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::ROLImm:
3488f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FirstShift = Mips::SLL;
3489f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SecondShift = Mips::SRL;
3490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::RORImm:
3492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FirstShift = Mips::SRL;
3493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SecondShift = Mips::SLL;
3494f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3495f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3496f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3497f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ATReg = getATReg(Inst.getLoc());
3498f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
3499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3500f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3501de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue, Inst.getLoc(), STI);
3502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(SecondShift, DReg, SReg, 32 - ImmValue, Inst.getLoc(), STI);
3503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3504f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3505f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3506f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3507f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3508f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
3509f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3511de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandDRotation(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3512de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                    const MCSubtargetInfo *STI) {
3513de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3514f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = Mips::NoRegister;
3515f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DReg = Inst.getOperand(0).getReg();
3516f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SReg = Inst.getOperand(1).getReg();
3517f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TReg = Inst.getOperand(2).getReg();
3518f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned TmpReg = DReg;
3519f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3520f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FirstShift = Mips::NOP;
3521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SecondShift = Mips::NOP;
3522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips64r2()) {
3524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (TmpReg == SReg) {
3526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      TmpReg = getATReg(Inst.getLoc());
3527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (!TmpReg)
3528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        return true;
3529f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3530f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3531f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::DROL) {
3532de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::DSUBu, TmpReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3533de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::DROTRV, DReg, SReg, TmpReg, Inst.getLoc(), STI);
3534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3535f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3536f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3537f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::DROR) {
3538de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRR(Mips::DROTRV, DReg, SReg, TReg, Inst.getLoc(), STI);
3539f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
3540f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
35416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3542f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return true;
3543f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
35446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3545f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips64()) {
35466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3547f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    switch (Inst.getOpcode()) {
35486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    default:
3549f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("unexpected instruction opcode");
3550f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::DROL:
3551f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FirstShift = Mips::DSRLV;
3552f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SecondShift = Mips::DSLLV;
35536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      break;
3554f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::DROR:
3555f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FirstShift = Mips::DSLLV;
3556f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      SecondShift = Mips::DSRLV;
3557f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3558f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
35596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ATReg = getATReg(Inst.getLoc());
35616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!ATReg)
35626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return true;
35636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3564de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::DSUBu, ATReg, Mips::ZERO, TReg, Inst.getLoc(), STI);
3565de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(FirstShift, ATReg, SReg, ATReg, Inst.getLoc(), STI);
3566de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(SecondShift, DReg, SReg, TReg, Inst.getLoc(), STI);
3567de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
35686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
35706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
3571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
35736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
35746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3575f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::expandDRotationImm(MCInst &Inst, SMLoc IDLoc,
3576de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       MCStreamer &Out,
3577de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                       const MCSubtargetInfo *STI) {
3578de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3579f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned ATReg = Mips::NoRegister;
3580f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned DReg = Inst.getOperand(0).getReg();
3581f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SReg = Inst.getOperand(1).getReg();
3582f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t ImmValue = Inst.getOperand(2).getImm() % 64;
3583f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3584f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned FirstShift = Mips::NOP;
3585f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned SecondShift = Mips::NOP;
3586f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3587f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCInst TmpInst;
3588f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3589f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips64r2()) {
3590f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3591f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    unsigned FinalOpcode = Mips::NOP;
3592f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ImmValue == 0)
3593f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::DROTR;
3594f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if (ImmValue % 32 == 0)
3595f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      FinalOpcode = Mips::DROTR32;
3596f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    else if ((ImmValue >= 1) && (ImmValue <= 32)) {
3597f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Inst.getOpcode() == Mips::DROLImm)
3598f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FinalOpcode = Mips::DROTR32;
3599f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else
3600f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FinalOpcode = Mips::DROTR;
3601f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else if (ImmValue >= 33) {
3602f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Inst.getOpcode() == Mips::DROLImm)
3603f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FinalOpcode = Mips::DROTR;
3604f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      else
3605f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FinalOpcode = Mips::DROTR32;
360625df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
3607f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    uint64_t ShiftValue = ImmValue % 32;
3609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Inst.getOpcode() == Mips::DROLImm)
3610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ShiftValue = (32 - ImmValue % 32) % 32;
3611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3612de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(FinalOpcode, DReg, SReg, ShiftValue, Inst.getLoc(), STI);
3613f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3614f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
361525df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  }
3616f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3617f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (hasMips64()) {
3618f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3619f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ImmValue == 0) {
3620de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      TOut.emitRRI(Mips::DSRL, DReg, SReg, 0, Inst.getLoc(), STI);
3621f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
362225df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter    }
362325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter
3624f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    switch (Inst.getOpcode()) {
3625f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    default:
3626f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      llvm_unreachable("unexpected instruction opcode");
3627f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::DROLImm:
3628f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((ImmValue >= 1) && (ImmValue <= 31)) {
3629f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FirstShift = Mips::DSLL;
3630f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SecondShift = Mips::DSRL32;
3631f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3632f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ImmValue == 32) {
3633f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FirstShift = Mips::DSLL32;
3634f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SecondShift = Mips::DSRL32;
3635f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3636f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((ImmValue >= 33) && (ImmValue <= 63)) {
3637f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FirstShift = Mips::DSLL32;
3638f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SecondShift = Mips::DSRL;
3639f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3640f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3641f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    case Mips::DRORImm:
3642f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((ImmValue >= 1) && (ImmValue <= 31)) {
3643f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FirstShift = Mips::DSRL;
3644f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SecondShift = Mips::DSLL32;
3645f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3646f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ImmValue == 32) {
3647f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FirstShift = Mips::DSRL32;
3648f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SecondShift = Mips::DSLL32;
3649f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3650f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((ImmValue >= 33) && (ImmValue <= 63)) {
3651f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        FirstShift = Mips::DSRL32;
3652f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        SecondShift = Mips::DSLL;
3653f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
3654f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      break;
3655f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
3656ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3657f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ATReg = getATReg(Inst.getLoc());
3658f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (!ATReg)
3659f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return true;
3660ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3661de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(FirstShift, ATReg, SReg, ImmValue % 32, Inst.getLoc(), STI);
3662de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRI(SecondShift, DReg, SReg, (32 - ImmValue % 32) % 32,
3663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 Inst.getLoc(), STI);
3664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::OR, DReg, DReg, ATReg, Inst.getLoc(), STI);
3665ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3666f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
3667f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return true;
3670ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
3671ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3672de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::expandAbs(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out,
3673de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                              const MCSubtargetInfo *STI) {
3674de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsTargetStreamer &TOut = getTargetStreamer();
3675de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned FirstRegOp = Inst.getOperand(0).getReg();
3676de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  unsigned SecondRegOp = Inst.getOperand(1).getReg();
36774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
3678de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRI(Mips::BGEZ, SecondRegOp, 8, IDLoc, STI);
3679de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (FirstRegOp != SecondRegOp)
3680de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitRRR(Mips::ADDu, FirstRegOp, SecondRegOp, Mips::ZERO, IDLoc, STI);
3681de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else
3682de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    TOut.emitEmptyDelaySlot(false, IDLoc, STI);
3683de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  TOut.emitRRR(Mips::SUB, FirstRegOp, Mips::ZERO, SecondRegOp, IDLoc, STI);
3684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3685de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return false;
36866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
36876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
3688c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesunsigned MipsAsmParser::checkTargetMatchPredicate(MCInst &Inst) {
3689de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  switch (Inst.getOpcode()) {
3690c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // As described by the Mips32r2 spec, the registers Rd and Rs for
3691c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // jalr.hb must be different.
3692de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // It also applies for registers Rt and Rs of microMIPSr6 jalrc.hb instruction
3693de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // and registers Rd and Base for microMIPS lwp instruction
3694de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::JALR_HB:
3695de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::JALRC_HB_MMR6:
3696de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::JALRC_MMR6:
3697de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
3698de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Match_RequiresDifferentSrcAndDst;
3699de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Match_Success;
3700de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::LWP_MM:
3701de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::LWP_MMR6:
3702de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Inst.getOperand(0).getReg() == Inst.getOperand(2).getReg())
3703de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Match_RequiresDifferentSrcAndDst;
3704de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Match_Success;
3705de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // As described the MIPSR6 spec, the compact branches that compare registers
3706de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // must:
3707de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // a) Not use the zero register.
3708de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // b) Not use the same register twice.
3709de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // c) rs < rt for bnec, beqc.
3710de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  //    NB: For this case, the encoding will swap the operands as their
3711de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  //    ordering doesn't matter. GAS performs this transformation  too.
3712de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  //    Hence, that constraint does not have to be enforced.
3713de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  //
3714de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // The compact branches that branch iff the signed addition of two registers
3715de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // would overflow must have rs >= rt. That can be handled like beqc/bnec with
3716de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // operand swapping. They do not have restriction of using the zero register.
3717de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BLEZC:
3718de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BGEZC:
3719de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BGTZC:
3720de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BLTZC:
3721de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BEQZC:
3722de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BNEZC:
3723de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Inst.getOperand(0).getReg() == Mips::ZERO)
3724de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Match_RequiresNoZeroRegister;
3725de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Match_Success;
3726de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BGEC:
3727de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BLTC:
3728de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BGEUC:
3729de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BLTUC:
3730de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BEQC:
3731de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Mips::BNEC:
3732de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Inst.getOperand(0).getReg() == Mips::ZERO)
3733de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Match_RequiresNoZeroRegister;
3734de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Inst.getOperand(1).getReg() == Mips::ZERO)
3735de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Match_RequiresNoZeroRegister;
3736de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (Inst.getOperand(0).getReg() == Inst.getOperand(1).getReg())
3737de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      return Match_RequiresDifferentOperands;
3738de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Match_Success;
3739de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  default:
3740de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Match_Success;
3741de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
3742c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
3743c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
3744f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic SMLoc RefineErrorLoc(const SMLoc Loc, const OperandVector &Operands,
3745f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                            uint64_t ErrorInfo) {
3746f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (ErrorInfo != ~0ULL && ErrorInfo < Operands.size()) {
3747f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SMLoc ErrorLoc = Operands[ErrorInfo]->getStartLoc();
3748f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ErrorLoc == SMLoc())
3749f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return Loc;
3750f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return ErrorLoc;
3751f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
3752f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return Loc;
3753f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
3754f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
3755c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
3756c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                            OperandVector &Operands,
3757c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                            MCStreamer &Out,
375837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                            uint64_t &ErrorInfo,
3759c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                            bool MatchingInlineAsm) {
3760c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
3761ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  MCInst Inst;
37622263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  unsigned MatchResult =
37632263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      MatchInstructionImpl(Operands, Inst, ErrorInfo, MatchingInlineAsm);
3764ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3765ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (MatchResult) {
3766ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_Success: {
3767de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    if (processInstruction(Inst, IDLoc, Out, STI))
376825df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter      return true;
3769ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
3770ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
3771ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MissingFeature:
3772ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(IDLoc, "instruction requires a CPU feature not currently enabled");
3773ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
3774ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_InvalidOperand: {
3775ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc ErrorLoc = IDLoc;
377637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ErrorInfo != ~0ULL) {
3777ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      if (ErrorInfo >= Operands.size())
3778ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(IDLoc, "too few operands for instruction");
3779ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3780f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      ErrorLoc = Operands[ErrorInfo]->getStartLoc();
378186924b4182537745659f2660244f3402c1e1ca4dJack Carter      if (ErrorLoc == SMLoc())
378286924b4182537745659f2660244f3402c1e1ca4dJack Carter        ErrorLoc = IDLoc;
3783ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
3784ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
3785ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(ErrorLoc, "invalid operand for instruction");
3786ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
3787ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case Match_MnemonicFail:
3788ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(IDLoc, "invalid instruction");
3789c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case Match_RequiresDifferentSrcAndDst:
3790c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return Error(IDLoc, "source and destination must be different");
3791de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_RequiresDifferentOperands:
3792de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(IDLoc, "registers must be different");
3793de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_RequiresNoZeroRegister:
3794de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(IDLoc, "invalid operand ($zero) for instruction");
3795f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_Immz:
3796f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo), "expected '0'");
3797f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm1_0:
3798f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3799f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 1-bit unsigned immediate");
3800f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm2_0:
3801f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3802f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 2-bit unsigned immediate");
3803f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm2_1:
3804f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3805f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected immediate in range 1 .. 4");
3806f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm3_0:
3807f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3808f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 3-bit unsigned immediate");
3809f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm4_0:
3810f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3811f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 4-bit unsigned immediate");
3812de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm4_0:
3813de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3814de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 4-bit signed immediate");
3815f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm5_0:
3816f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3817f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 5-bit unsigned immediate");
3818de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm5_0:
3819de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3820de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 5-bit signed immediate");
3821f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm5_1:
3822f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3823f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected immediate in range 1 .. 32");
3824f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm5_32:
3825f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3826f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected immediate in range 32 .. 63");
3827f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm5_33:
3828f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3829f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected immediate in range 33 .. 64");
3830f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm5_0_Report_UImm6:
3831f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // This is used on UImm5 operands that have a corresponding UImm5_32
3832f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // operand to avoid confusing the user.
3833f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3834f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 6-bit unsigned immediate");
3835f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm5_Lsl2:
3836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected both 7-bit unsigned immediate and multiple of 4");
3838de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImmRange2_64:
3839de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3840de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected immediate in range 2 .. 64");
3841f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm6_0:
3842f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3843f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 6-bit unsigned immediate");
3844de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImm6_Lsl2:
3845de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3846de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected both 8-bit unsigned immediate and multiple of 4");
3847de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm6_0:
3848f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3849f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 6-bit signed immediate");
3850f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm7_0:
3851f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3852f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 7-bit unsigned immediate");
3853de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImm7_N1:
3854de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3855de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected immediate in range -1 .. 126");
3856de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm7_Lsl2:
3857de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3858de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected both 9-bit signed immediate and multiple of 4");
3859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm8_0:
3860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 8-bit unsigned immediate");
3862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  case Match_UImm10_0:
3863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 "expected 10-bit unsigned immediate");
3865de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm10_0:
3866de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3867de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 10-bit signed immediate");
3868de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm11_0:
3869de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3870de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 11-bit signed immediate");
3871de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImm16:
3872de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImm16_Relaxed:
3873de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3874de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 16-bit unsigned immediate");
3875de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm16:
3876de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm16_Relaxed:
3877de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3878de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 16-bit signed immediate");
3879de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImm20_0:
3880de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3881de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 20-bit unsigned immediate");
3882de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_UImm26_0:
3883de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3884de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 26-bit unsigned immediate");
3885de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm32:
3886de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_SImm32_Relaxed:
3887de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3888de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected 32-bit signed immediate");
3889de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm9:
3890de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3891de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 9-bit signed offset");
3892de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm10:
3893de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3894de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 10-bit signed offset");
3895de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm10Lsl1:
3896de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3897de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 11-bit signed offset and multiple of 2");
3898de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm10Lsl2:
3899de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3900de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 12-bit signed offset and multiple of 4");
3901de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm10Lsl3:
3902de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3903de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 13-bit signed offset and multiple of 8");
3904de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm11:
3905de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3906de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 11-bit signed offset");
3907de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm12:
3908de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3909de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 12-bit signed offset");
3910de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  case Match_MemSImm16:
3911de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return Error(RefineErrorLoc(IDLoc, Operands, ErrorInfo),
3912de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                 "expected memory with 16-bit signed offset");
3913ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
3914ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
3915ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  llvm_unreachable("Implement any new match types added!");
3916fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
3917fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
39186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid MipsAsmParser::warnIfRegIndexIsAT(unsigned RegIndex, SMLoc Loc) {
39196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (RegIndex != 0 && AssemblerOptions.back()->getATRegIndex() == RegIndex)
39206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Warning(Loc, "used $at (currently $" + Twine(RegIndex) +
39216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                     ") without \".set noat\"");
39226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
39236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
39246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid MipsAsmParser::warnIfNoMacro(SMLoc Loc) {
39256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!AssemblerOptions.back()->isMacro())
39266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    Warning(Loc, "macro instruction expanded into multiple instructions");
392736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
392836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
392937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesvoid
393037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::printWarningWithFixIt(const Twine &Msg, const Twine &FixMsg,
393137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                     SMRange Range, bool ShowColors) {
393237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getSourceManager().PrintMessage(Range.Start, SourceMgr::DK_Warning, Msg,
393337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  Range, SMFixIt(Range, FixMsg),
393437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  ShowColors);
393537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
393637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
393799e98551bf8719764f9345ce856118f3f1a9c441Jack Carterint MipsAsmParser::matchCPURegisterName(StringRef Name) {
39382263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  int CC;
393999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
39402263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  CC = StringSwitch<unsigned>(Name)
39412263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("zero", 0)
394236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           .Case("at", 1)
39432263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a0", 4)
39442263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a1", 5)
39452263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a2", 6)
39462263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("a3", 7)
39472263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("v0", 2)
39482263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("v1", 3)
39492263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s0", 16)
39502263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s1", 17)
39512263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s2", 18)
39522263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s3", 19)
39532263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s4", 20)
39542263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s5", 21)
39552263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s6", 22)
39562263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("s7", 23)
39572263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("k0", 26)
39582263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("k1", 27)
395936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           .Case("gp", 28)
39602263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("sp", 29)
39612263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("fp", 30)
396236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines           .Case("s8", 30)
39632263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("ra", 31)
39642263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t0", 8)
39652263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t1", 9)
39662263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t2", 10)
39672263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t3", 11)
39682263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t4", 12)
39692263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t5", 13)
39702263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t6", 14)
39712263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t7", 15)
39722263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t8", 24)
39732263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("t9", 25)
39742263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Default(-1);
397599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
397637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!(isABI_N32() || isABI_N64()))
397737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return CC;
397837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
397937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (12 <= CC && CC <= 15) {
398037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Name is one of t4-t7
398137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    AsmToken RegTok = getLexer().peekTok();
398237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SMRange RegRange = RegTok.getLocRange();
398337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
398437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef FixedName = StringSwitch<StringRef>(Name)
398537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              .Case("t4", "t0")
398637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              .Case("t5", "t1")
398737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              .Case("t6", "t2")
398837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              .Case("t7", "t3")
398937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              .Default("");
399037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    assert(FixedName != "" &&  "Register name is not one of t4-t7.");
399137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
399237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    printWarningWithFixIt("register names $t4-$t7 are only available in O32.",
399337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                          "Did you mean $" + FixedName + "?", RegRange);
399437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
399537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
399637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Although SGI documentation just cuts out t0-t3 for n32/n64,
399737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // GNU pushes the values of t0-t3 to override the o32/o64 values for t4-t7
399837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // We are supporting both cases, so for t0-t3 we'll just push them to t4-t7.
399937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (8 <= CC && CC <= 11)
400037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CC += 4;
400137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
400237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (CC == -1)
400337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CC = StringSwitch<unsigned>(Name)
400437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Case("a4", 8)
400537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Case("a5", 9)
400637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Case("a6", 10)
400737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Case("a7", 11)
400837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Case("kt0", 26)
400937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Case("kt1", 27)
401037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines             .Default(-1);
401136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
401237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return CC;
401337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
401437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
401537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesint MipsAsmParser::matchHWRegsRegisterName(StringRef Name) {
401637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  int CC;
401737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
401837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CC = StringSwitch<unsigned>(Name)
401937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            .Case("hwr_cpunum", 0)
402037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            .Case("hwr_synci_step", 1)
402137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            .Case("hwr_cc", 2)
402237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            .Case("hwr_ccres", 3)
402337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            .Case("hwr_ulr", 29)
402437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            .Default(-1);
4025572e1bd109518f80b54d229de10699c4603944c3David Chisnall
402699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter  return CC;
402799e98551bf8719764f9345ce856118f3f1a9c441Jack Carter}
402886924b4182537745659f2660244f3402c1e1ca4dJack Carter
4029bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchFPURegisterName(StringRef Name) {
4030ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
4031f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  if (Name[0] == 'f') {
4032f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    StringRef NumString = Name.substr(1);
4033f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter    unsigned IntVal;
403486924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (NumString.getAsInteger(10, IntVal))
40352263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      return -1;     // This is not an integer.
4036bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (IntVal > 31) // Maximum index for fpu register.
4037f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter      return -1;
4038bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return IntVal;
4039bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  }
4040bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  return -1;
4041bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic}
4042f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter
4043bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchFCCRegisterName(StringRef Name) {
4044bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic
4045bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (Name.startswith("fcc")) {
4046bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    StringRef NumString = Name.substr(3);
4047bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    unsigned IntVal;
4048bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (NumString.getAsInteger(10, IntVal))
40492263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      return -1;    // This is not an integer.
4050bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (IntVal > 7) // There are only 8 fcc registers.
4051bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic      return -1;
4052bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return IntVal;
4053f740d6e328bd10904b079e1ce6583f436d6c9817Jack Carter  }
4054ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return -1;
4055ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
405686924b4182537745659f2660244f3402c1e1ca4dJack Carter
4057bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medicint MipsAsmParser::matchACRegisterName(StringRef Name) {
4058bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic
4059899ee589f5182a35495f068ae15b5f2b5ff4ef8aAkira Hatanaka  if (Name.startswith("ac")) {
4060899ee589f5182a35495f068ae15b5f2b5ff4ef8aAkira Hatanaka    StringRef NumString = Name.substr(2);
4061bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    unsigned IntVal;
4062bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (NumString.getAsInteger(10, IntVal))
40632263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic      return -1;    // This is not an integer.
4064bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    if (IntVal > 3) // There are only 3 acc registers.
4065bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic      return -1;
4066bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return IntVal;
4067bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  }
4068bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  return -1;
4069bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic}
40707231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
407142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carterint MipsAsmParser::matchMSA128RegisterName(StringRef Name) {
407242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  unsigned IntVal;
407342d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
407442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  if (Name.front() != 'w' || Name.drop_front(1).getAsInteger(10, IntVal))
407542d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter    return -1;
407642d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
407742d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  if (IntVal > 31)
407842d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter    return -1;
407942d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
408042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  return IntVal;
408142d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter}
408242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
4083006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeidaint MipsAsmParser::matchMSA128CtrlRegisterName(StringRef Name) {
4084006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  int CC;
4085006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
4086006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  CC = StringSwitch<unsigned>(Name)
40872263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msair", 0)
40882263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msacsr", 1)
40892263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msaaccess", 2)
40902263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msasave", 3)
40912263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msamodify", 4)
40922263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msarequest", 5)
40932263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msamap", 6)
40942263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Case("msaunmap", 7)
40952263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic           .Default(-1);
4096006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
4097006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida  return CC;
4098006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida}
4099006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
41000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarunsigned MipsAsmParser::getATReg(SMLoc Loc) {
41016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  unsigned ATIndex = AssemblerOptions.back()->getATRegIndex();
41020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (ATIndex == 0) {
4103c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    reportParseError(Loc,
410437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                     "pseudo-instruction requires $at, which is not available");
41050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return 0;
41060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
41070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  unsigned AT = getReg(
41080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar      (isGP64bit()) ? Mips::GPR64RegClassID : Mips::GPR32RegClassID, ATIndex);
410936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return AT;
411036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
411130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
411286924b4182537745659f2660244f3402c1e1ca4dJack Carterunsigned MipsAsmParser::getReg(int RC, int RegNo) {
411399cb622041a0839c7dfcf0263c5102a305a0fdb5Bill Wendling  return *(getContext().getRegisterInfo()->getRegClass(RC).begin() + RegNo);
4114ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
4115ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
411637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseOperand(OperandVector &Operands, StringRef Mnemonic) {
411737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
411837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DEBUG(dbgs() << "parseOperand\n");
411936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
41209d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // Check if the current operand has a custom associated parser, if so, try to
41219d577c861414c28967d77c2a1edf64b68efdeaeeJack Carter  // custom parse the operand, or fallback to the general approach.
4122ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  OperandMatchResultTy ResTy = MatchOperandParserImpl(Operands, Mnemonic);
4123ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_Success)
4124ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
4125ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // If there wasn't a custom match, try the generic matcher below. Otherwise,
4126ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // there was a match, but an error occurred, in which case, just return that
4127ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // the operand parsing failed.
4128ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (ResTy == MatchOperand_ParseFail)
4129ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
4130ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
413136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << ".. Generic Parser\n");
413236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4133ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  switch (getLexer().getKind()) {
4134ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  default:
4135ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    Error(Parser.getTok().getLoc(), "unexpected token in operand");
4136ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return true;
4137ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Dollar: {
413886924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Parse the register.
4139ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc S = Parser.getTok().getLoc();
4140ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
414136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Almost all registers have been parsed by custom parsers. There is only
414236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // one exception to this. $zero (and it's alias $0) will reach this point
414336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // for div, divu, and similar instructions because it is not an operand
414436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // to the instruction definition but an explicit register. Special case
414536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // this situation for now.
414637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (parseAnyRegister(Operands) != MatchOperand_NoMatch)
4147ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return false;
414836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
414986924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Maybe it is a symbol reference.
4150ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    StringRef Identifier;
4151cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    if (Parser.parseIdentifier(Identifier))
4152ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return true;
4153ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
4154ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
41556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSymbol *Sym = getContext().getOrCreateSymbol("$" + Identifier);
415686924b4182537745659f2660244f3402c1e1ca4dJack Carter    // Otherwise create a symbol reference.
41572263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    const MCExpr *Res =
41586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar        MCSymbolRefExpr::create(Sym, MCSymbolRefExpr::VK_None, getContext());
4159ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
416036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateImm(Res, S, E, *this));
4161ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return false;
4162ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
41632263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  // Else drop to expression parsing.
4164ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::LParen:
4165ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Minus:
4166ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Plus:
4167ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::Integer:
4168c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case AsmToken::Tilde:
4169ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  case AsmToken::String: {
417036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. generic integer\n");
417137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    OperandMatchResultTy ResTy = parseImm(Operands);
417236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy != MatchOperand_Success;
4173ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
41746b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Percent: {
417586924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is a symbol reference or constant expression.
41766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    const MCExpr *IdVal;
417786924b4182537745659f2660244f3402c1e1ca4dJack Carter    SMLoc S = Parser.getTok().getLoc(); // Start location of the operand.
4178ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    if (parseRelocOperand(IdVal))
41796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
41806b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4181ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4182ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
418336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
41846b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return false;
418530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // case AsmToken::Percent
418630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } // switch(getLexer().getKind())
4187fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
4188fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
4189fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
41902263a2ca72e21206d45a69532004a0b17881e733Vladimir Medicconst MCExpr *MipsAsmParser::evaluateRelocExpr(const MCExpr *Expr,
41918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                               StringRef RelocStr) {
4192de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (RelocStr == "hi(%neg(%gp_rel")
4193de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return MipsMCExpr::createGpOff(MipsMCExpr::MEK_HI, Expr, getContext());
4194de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  else if (RelocStr == "lo(%neg(%gp_rel")
4195de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return MipsMCExpr::createGpOff(MipsMCExpr::MEK_LO, Expr, getContext());
4196de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
4197de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsMCExpr::MipsExprKind Kind =
4198de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      StringSwitch<MipsMCExpr::MipsExprKind>(RelocStr)
4199de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("call16", MipsMCExpr::MEK_GOT_CALL)
4200de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("call_hi", MipsMCExpr::MEK_CALL_HI16)
4201de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("call_lo", MipsMCExpr::MEK_CALL_LO16)
4202de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("dtprel_hi", MipsMCExpr::MEK_DTPREL_HI)
4203de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("dtprel_lo", MipsMCExpr::MEK_DTPREL_LO)
4204de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("got", MipsMCExpr::MEK_GOT)
4205de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("got_disp", MipsMCExpr::MEK_GOT_DISP)
4206de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("got_hi", MipsMCExpr::MEK_GOT_HI16)
4207de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("got_lo", MipsMCExpr::MEK_GOT_LO16)
4208de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("got_ofst", MipsMCExpr::MEK_GOT_OFST)
4209de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("got_page", MipsMCExpr::MEK_GOT_PAGE)
4210de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("gottprel", MipsMCExpr::MEK_GOTTPREL)
4211de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("gp_rel", MipsMCExpr::MEK_GPREL)
4212de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("hi", MipsMCExpr::MEK_HI)
4213de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("higher", MipsMCExpr::MEK_HIGHER)
4214de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("highest", MipsMCExpr::MEK_HIGHEST)
4215de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("lo", MipsMCExpr::MEK_LO)
4216de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("neg", MipsMCExpr::MEK_NEG)
4217de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("pcrel_hi", MipsMCExpr::MEK_PCREL_HI16)
4218de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("pcrel_lo", MipsMCExpr::MEK_PCREL_LO16)
4219de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("tlsgd", MipsMCExpr::MEK_TLSGD)
4220de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("tlsldm", MipsMCExpr::MEK_TLSLDM)
4221de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("tprel_hi", MipsMCExpr::MEK_TPREL_HI)
4222de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("tprel_lo", MipsMCExpr::MEK_TPREL_LO)
4223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Default(MipsMCExpr::MEK_None);
4224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
4225de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  assert(Kind != MipsMCExpr::MEK_None);
4226de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return MipsMCExpr::create(Kind, Expr, getContext());
42278afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
42288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
42298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::isEvaluated(const MCExpr *Expr) {
42308afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
42318afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  switch (Expr->getKind()) {
42328afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Constant:
42338afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return true;
42348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::SymbolRef:
42358afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return (cast<MCSymbolRefExpr>(Expr)->getKind() != MCSymbolRefExpr::VK_None);
42368afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Binary:
42378afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(Expr)) {
42388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (!isEvaluated(BE->getLHS()))
42398afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return false;
42408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return isEvaluated(BE->getRHS());
42418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    }
42428afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case MCExpr::Unary:
42438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    return isEvaluated(cast<MCUnaryExpr>(Expr)->getSubExpr());
424436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MCExpr::Target:
424536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
42468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
42478afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
42488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter}
42496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
425086924b4182537745659f2660244f3402c1e1ca4dJack Carterbool MipsAsmParser::parseRelocOperand(const MCExpr *&Res) {
425137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
42522263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  Parser.Lex();                          // Eat the % token.
425386924b4182537745659f2660244f3402c1e1ca4dJack Carter  const AsmToken &Tok = Parser.getTok(); // Get next token, operation.
42546b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (Tok.isNot(AsmToken::Identifier))
42556b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
42566b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
42570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  std::string Str = Tok.getIdentifier();
42586b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
425986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the identifier.
426086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Now make an expression from the rest of the operand.
42616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  const MCExpr *IdVal;
4262ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc EndLoc;
42636b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
42646b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  if (getLexer().getKind() == AsmToken::LParen) {
42656b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    while (1) {
426686924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the '(' token.
42676b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      if (getLexer().getKind() == AsmToken::Percent) {
426886924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the % token.
42696b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        const AsmToken &nextTok = Parser.getTok();
42706b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (nextTok.isNot(AsmToken::Identifier))
42716b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
427238539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += "(%";
427338539ebc2b55d2decec2322efd3360bf61f31da1Benjamin Kramer        Str += nextTok.getIdentifier();
427486924b4182537745659f2660244f3402c1e1ca4dJack Carter        Parser.Lex(); // Eat the identifier.
42756b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        if (getLexer().getKind() != AsmToken::LParen)
42766b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter          return true;
42776b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      } else
42786b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter        break;
42796b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    }
428086924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (getParser().parseParenExpression(IdVal, EndLoc))
42816b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter      return true;
42826b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4283ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    while (getLexer().getKind() == AsmToken::RParen)
428486924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the ')' token.
42856b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
42866b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  } else
428786924b4182537745659f2660244f3402c1e1ca4dJack Carter    return true; // Parenthesis must follow the relocation operand.
42886b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
428986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Res = evaluateRelocExpr(IdVal, Str);
42908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return false;
42916b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
42926b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4293ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carterbool MipsAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc,
4294ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter                                  SMLoc &EndLoc) {
4295c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Operands;
429637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OperandMatchResultTy ResTy = parseAnyRegister(Operands);
429736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy == MatchOperand_Success) {
429836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    assert(Operands.size() == 1);
4299c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    MipsOperand &Operand = static_cast<MipsOperand &>(*Operands.front());
430036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StartLoc = Operand.getStartLoc();
430136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    EndLoc = Operand.getEndLoc();
430236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
430336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AFAIK, we only support numeric registers and named GPR's in CFI
430436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // directives.
430536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // Don't worry about eating tokens before failing. Using an unrecognised
430636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // register is a parse error.
430736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Operand.isGPRAsmReg()) {
430836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Resolve to GPR32 or GPR64 appropriately.
4309c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      RegNo = isGP64bit() ? Operand.getGPR64Reg() : Operand.getGPR32Reg();
431036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
431136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
431236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return (RegNo == (unsigned)-1);
431336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
431436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
431536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  assert(Operands.size() == 0);
43162263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  return (RegNo == (unsigned)-1);
4317ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
4318ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
43198afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carterbool MipsAsmParser::parseMemOffset(const MCExpr *&Res, bool isParenExpr) {
432037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
4321ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
43228afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool Result = true;
4323f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  unsigned NumOfLParen = 0;
43248afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
4325f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  while (getLexer().getKind() == AsmToken::LParen) {
43268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
4327f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    ++NumOfLParen;
4328f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
4329ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
433086924b4182537745659f2660244f3402c1e1ca4dJack Carter  switch (getLexer().getKind()) {
43316b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  default:
43326b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return true;
433325df6a93f3324bd30f44dcb95fd17aff0a92d438Jack Carter  case AsmToken::Identifier:
43348afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  case AsmToken::LParen:
43356b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Integer:
43366b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Minus:
43376b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  case AsmToken::Plus:
43388afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (isParenExpr)
4339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      Result = getParser().parseParenExprOfDepth(NumOfLParen, Res, S);
43408afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else
43418afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Result = (getParser().parseExpression(Res));
434286924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().getKind() == AsmToken::RParen)
43438afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Parser.Lex();
434486924b4182537745659f2660244f3402c1e1ca4dJack Carter    break;
4345ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  case AsmToken::Percent:
43468afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Result = parseRelocOperand(Res);
43476b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
43488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  return Result;
43496b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter}
43506b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4351c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMipsAsmParser::OperandMatchResultTy
4352c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMipsAsmParser::parseMemOperand(OperandVector &Operands) {
435337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
435436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "parseMemOperand\n");
4355dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  const MCExpr *IdVal = nullptr;
4356ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc S;
43578afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  bool isParenExpr = false;
4358bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  MipsAsmParser::OperandMatchResultTy Res = MatchOperand_NoMatch;
435986924b4182537745659f2660244f3402c1e1ca4dJack Carter  // First operand is the offset.
4360ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  S = Parser.getTok().getLoc();
43616b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
43628afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() == AsmToken::LParen) {
43638afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    Parser.Lex();
43648afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    isParenExpr = true;
43658afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
43666b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
43678afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (getLexer().getKind() != AsmToken::Dollar) {
436886924b4182537745659f2660244f3402c1e1ca4dJack Carter    if (parseMemOffset(IdVal, isParenExpr))
43698afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
43708afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
437186924b4182537745659f2660244f3402c1e1ca4dJack Carter    const AsmToken &Tok = Parser.getTok(); // Get the next token.
43728afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    if (Tok.isNot(AsmToken::LParen)) {
4373c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      MipsOperand &Mnemonic = static_cast<MipsOperand &>(*Operands[0]);
4374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (Mnemonic.getToken() == "la" || Mnemonic.getToken() == "dla") {
43752263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic        SMLoc E =
43762263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
437736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
43788afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
43798afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
43808afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      if (Tok.is(AsmToken::EndOfStatement)) {
43812263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic        SMLoc E =
43822263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic            SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
43838afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
438486924b4182537745659f2660244f3402c1e1ca4dJack Carter        // Zero register assumed, add a memory operand with ZERO as its base.
4385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        // "Base" will be managed by k_Memory.
438637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        auto Base = MipsOperand::createGPRReg(0, getContext().getRegisterInfo(),
4387c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                              S, E, *this);
4388c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        Operands.push_back(
4389c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines            MipsOperand::CreateMem(std::move(Base), IdVal, S, E, *this));
43908afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter        return MatchOperand_Success;
43918afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      }
43928afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      Error(Parser.getTok().getLoc(), "'(' expected");
43938afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter      return MatchOperand_ParseFail;
43942f68b311a1b0efb3cafeca3780f5c3d09a762a50Jack Carter    }
43956b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
439686924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Eat the '(' token.
43978afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
43986b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
439937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Res = parseAnyRegister(Operands);
4400bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (Res != MatchOperand_Success)
4401bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic    return Res;
44026b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4403bd980e5569d085ab73e351ec9fca8b698e06d44fVladimir Medic  if (Parser.getTok().isNot(AsmToken::RParen)) {
44046b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    Error(Parser.getTok().getLoc(), "')' expected");
44056b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter    return MatchOperand_ParseFail;
44066b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  }
44076b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4408ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4409ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
441086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Eat the ')' token.
44116b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
4412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!IdVal)
44136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    IdVal = MCConstantExpr::create(0, getContext());
44146b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter
441586924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Replace the register operand with the memory operand.
4416c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  std::unique_ptr<MipsOperand> op(
4417c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      static_cast<MipsOperand *>(Operands.back().release()));
441886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Remove the register from the operands.
4419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // "op" will be managed by k_Memory.
44206b96c3f71fce6b0a7c380dfc3b7ebf22c40e804bJack Carter  Operands.pop_back();
442186924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Add the memory operand.
44228afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  if (const MCBinaryExpr *BE = dyn_cast<MCBinaryExpr>(IdVal)) {
44238afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    int64_t Imm;
44246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (IdVal->evaluateAsAbsolute(Imm))
44256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      IdVal = MCConstantExpr::create(Imm, getContext());
44268afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter    else if (BE->getLHS()->getKind() != MCExpr::SymbolRef)
44276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      IdVal = MCBinaryExpr::create(BE->getOpcode(), BE->getRHS(), BE->getLHS(),
44288afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter                                   getContext());
44298afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  }
44308afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter
4431c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Operands.push_back(MipsOperand::CreateMem(std::move(op), IdVal, S, E, *this));
4432ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return MatchOperand_Success;
4433ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter}
4434ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
4435c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::searchSymbolAlias(OperandVector &Operands) {
443637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
44376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSymbol *Sym = getContext().lookupSymbol(Parser.getTok().getIdentifier());
443836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Sym) {
443936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SMLoc S = Parser.getTok().getLoc();
444036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    const MCExpr *Expr;
444136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Sym->isVariable())
444236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Expr = Sym->getVariableValue();
444336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    else
4444a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka      return false;
444536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Expr->getKind() == MCExpr::SymbolRef) {
444636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
444737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      StringRef DefSymbol = Ref->getSymbol().getName();
444836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (DefSymbol.startswith("$")) {
444936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        OperandMatchResultTy ResTy =
445037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            matchAnyRegisterNameWithoutDollar(Operands, DefSymbol.substr(1), S);
445136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        if (ResTy == MatchOperand_Success) {
445236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          Parser.Lex();
445336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return true;
445436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        } else if (ResTy == MatchOperand_ParseFail)
445536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          llvm_unreachable("Should never ParseFail");
445636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return false;
445736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      }
445836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
4459a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka  }
446036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
4461a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka}
4462a796d90c0ed7ebd5d58fced43c60afc2e9bf6225Akira Hatanaka
4463ec3199f675b17b12fd779df557c6bff25aa4e862Jack CarterMipsAsmParser::OperandMatchResultTy
446437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::matchAnyRegisterNameWithoutDollar(OperandVector &Operands,
4465c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                 StringRef Identifier,
4466c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                                 SMLoc S) {
446736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  int Index = matchCPURegisterName(Identifier);
446836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
446937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createGPRReg(
447037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
447137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return MatchOperand_Success;
447237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
447337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
447437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Index = matchHWRegsRegisterName(Identifier);
447537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Index != -1) {
447637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createHWRegsReg(
447736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
4478ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter    return MatchOperand_Success;
4479ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter  }
448045ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
448136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchFPURegisterName(Identifier);
448236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
448337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createFGRReg(
448436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
448536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
448645ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  }
448745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
448836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchFCCRegisterName(Identifier);
448936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
449037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createFCCReg(
449136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
449236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
449342d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter  }
449442d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
449536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchACRegisterName(Identifier);
449636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
449737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createACCReg(
449836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
449945ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida    return MatchOperand_Success;
450036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
450145ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
450236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchMSA128RegisterName(Identifier);
450336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
450437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createMSA128Reg(
450536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
450645ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida    return MatchOperand_Success;
450745ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  }
450845ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
450936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Index = matchMSA128CtrlRegisterName(Identifier);
451036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Index != -1) {
451137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createMSACtrlReg(
451236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Index, getContext().getRegisterInfo(), S, getLexer().getLoc(), *this));
451336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
451445ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida  }
451545ecbfc8e58923131068dced0cf89348ac61208fMatheus Almeida
451636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_NoMatch;
45177231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic}
45187231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir Medic
45197231625f75b4da1c87deb833cd9cad6c5ee95d95Vladimir MedicMipsAsmParser::OperandMatchResultTy
452037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::matchAnyRegisterWithoutDollar(OperandVector &Operands, SMLoc S) {
452137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
452236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  auto Token = Parser.getLexer().peekTok(false);
452336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
452436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Token.is(AsmToken::Identifier)) {
452536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. identifier\n");
452636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    StringRef Identifier = Token.getIdentifier();
452736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OperandMatchResultTy ResTy =
452837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        matchAnyRegisterNameWithoutDollar(Operands, Identifier, S);
452936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
453036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Token.is(AsmToken::Integer)) {
453136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. integer\n");
453237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Operands.push_back(MipsOperand::createNumericReg(
453336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        Token.getIntVal(), getContext().getRegisterInfo(), S, Token.getLoc(),
453436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        *this));
453536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_Success;
453636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
453790b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
453836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << Parser.getTok().getKind() << "\n");
453990b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
454036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_NoMatch;
454190b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic}
454290b1086b93708149ed7a3749e2eeccea264a037dVladimir Medic
4543c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMipsAsmParser::OperandMatchResultTy
454437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::parseAnyRegister(OperandVector &Operands) {
454537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
454637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DEBUG(dbgs() << "parseAnyRegister\n");
454788373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
454836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  auto Token = Parser.getTok();
454988373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
455036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc S = Token.getLoc();
455188373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
455236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Token.isNot(AsmToken::Dollar)) {
455336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. !$ -> try sym aliasing\n");
455436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Token.is(AsmToken::Identifier)) {
455536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (searchSymbolAlias(Operands))
455636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return MatchOperand_Success;
455736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
455836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    DEBUG(dbgs() << ".. !symalias -> NoMatch\n");
455988373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka    return MatchOperand_NoMatch;
456036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
456136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << ".. $\n");
456288373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
456337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OperandMatchResultTy ResTy = matchAnyRegisterWithoutDollar(Operands, S);
456436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy == MatchOperand_Success) {
456536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // $
456636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex(); // identifier
456736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
456836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return ResTy;
456988373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka}
457088373c29fe9d0b498ed21c3d29129f31806d7ec8Akira Hatanaka
4571e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir MedicMipsAsmParser::OperandMatchResultTy
457237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::parseImm(OperandVector &Operands) {
457337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
457436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (getLexer().getKind()) {
457536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
4576e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic    return MatchOperand_NoMatch;
457736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::LParen:
457836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Minus:
457936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Plus:
458036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::Integer:
4581c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  case AsmToken::Tilde:
458236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case AsmToken::String:
458336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
458436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
4585e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic
458636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *IdVal;
4587e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic  SMLoc S = Parser.getTok().getLoc();
458836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getParser().parseExpression(IdVal))
458936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_ParseFail;
4590e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic
459136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
459236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(MipsOperand::CreateImm(IdVal, S, E, *this));
4593e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic  return MatchOperand_Success;
4594e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic}
4595e925f7dbbf497412cd0cc3f67b9b96fed0cc3712Vladimir Medic
4596c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMipsAsmParser::OperandMatchResultTy
459737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::parseJumpTarget(OperandVector &Operands) {
459837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
459937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DEBUG(dbgs() << "parseJumpTarget\n");
460042d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
460136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  SMLoc S = getLexer().getLoc();
460242d9ca629934d0c20ac19949399ce4faa9a7bbb3Jack Carter
460336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Integers and expressions are acceptable
460437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OperandMatchResultTy ResTy = parseImm(Operands);
460536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy != MatchOperand_NoMatch)
460636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
4607006cff8d7b60ddf632f8642f01693dace7827d8bMatheus Almeida
460836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Registers are a valid target and have priority over symbols.
460937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ResTy = parseAnyRegister(Operands);
461036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (ResTy != MatchOperand_NoMatch)
461136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return ResTy;
4612c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
461336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *Expr = nullptr;
461436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.parseExpression(Expr)) {
461536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // We have no way of knowing if a symbol was consumed so we must ParseFail
461636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return MatchOperand_ParseFail;
4617c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  }
461836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(
461936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      MipsOperand::CreateImm(Expr, S, getLexer().getLoc(), *this));
462036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return MatchOperand_Success;
4621ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter}
4622ec3199f675b17b12fd779df557c6bff25aa4e862Jack Carter
4623d59ad8a8013fd76177fb61c741562af3024d34cdVladimir MedicMipsAsmParser::OperandMatchResultTy
4624c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen HinesMipsAsmParser::parseInvNum(OperandVector &Operands) {
462537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
4626d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  const MCExpr *IdVal;
4627d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  // If the first token is '$' we may have register operand.
4628d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  if (Parser.getTok().is(AsmToken::Dollar))
4629d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic    return MatchOperand_NoMatch;
4630d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  SMLoc S = Parser.getTok().getLoc();
4631d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  if (getParser().parseExpression(IdVal))
4632d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic    return MatchOperand_ParseFail;
4633d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(IdVal);
46342263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  assert(MCE && "Unexpected MCExpr type.");
4635d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  int64_t Val = MCE->getValue();
4636d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
4637d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  Operands.push_back(MipsOperand::CreateImm(
46386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      MCConstantExpr::create(0 - Val, getContext()), S, E, *this));
4639d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic  return MatchOperand_Success;
4640d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic}
4641d59ad8a8013fd76177fb61c741562af3024d34cdVladimir Medic
464295adf91f29980e374bf094e15bc3f2764ef9baf4Matheus AlmeidaMipsAsmParser::OperandMatchResultTy
464337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesMipsAsmParser::parseRegisterList(OperandVector &Operands) {
464437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
464537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<unsigned, 10> Regs;
464637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned RegNo;
464737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned PrevReg = Mips::NoRegister;
464837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool RegRange = false;
464937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
465037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
465137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Parser.getTok().isNot(AsmToken::Dollar))
465237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return MatchOperand_ParseFail;
465337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
465437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SMLoc S = Parser.getTok().getLoc();
465537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  while (parseAnyRegister(TmpOperands) == MatchOperand_Success) {
465637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SMLoc E = getLexer().getLoc();
465737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MipsOperand &Reg = static_cast<MipsOperand &>(*TmpOperands.back());
465837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    RegNo = isGP64bit() ? Reg.getGPR64Reg() : Reg.getGPR32Reg();
465937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (RegRange) {
466037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // Remove last register operand because registers from register range
466137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // should be inserted first.
4662f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((isGP64bit() && RegNo == Mips::RA_64) ||
4663f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          (!isGP64bit() && RegNo == Mips::RA)) {
466437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Regs.push_back(RegNo);
466537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      } else {
466637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        unsigned TmpReg = PrevReg + 1;
466737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        while (TmpReg <= RegNo) {
4668f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          if ((((TmpReg < Mips::S0) || (TmpReg > Mips::S7)) && !isGP64bit()) ||
4669f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar              (((TmpReg < Mips::S0_64) || (TmpReg > Mips::S7_64)) &&
4670f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar               isGP64bit())) {
467137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            Error(E, "invalid register operand");
467237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            return MatchOperand_ParseFail;
467337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          }
467437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
467537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          PrevReg = TmpReg;
467637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          Regs.push_back(TmpReg++);
467737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        }
467837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
467937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
468037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      RegRange = false;
468137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    } else {
4682f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if ((PrevReg == Mips::NoRegister) &&
4683f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          ((isGP64bit() && (RegNo != Mips::S0_64) && (RegNo != Mips::RA_64)) ||
4684f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar          (!isGP64bit() && (RegNo != Mips::S0) && (RegNo != Mips::RA)))) {
468537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Error(E, "$16 or $31 expected");
468637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MatchOperand_ParseFail;
4687f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else if (!(((RegNo == Mips::FP || RegNo == Mips::RA ||
4688f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    (RegNo >= Mips::S0 && RegNo <= Mips::S7)) &&
4689f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    !isGP64bit()) ||
4690f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                   ((RegNo == Mips::FP_64 || RegNo == Mips::RA_64 ||
4691f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    (RegNo >= Mips::S0_64 && RegNo <= Mips::S7_64)) &&
4692f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                    isGP64bit()))) {
469337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Error(E, "invalid register operand");
469437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MatchOperand_ParseFail;
469537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      } else if ((PrevReg != Mips::NoRegister) && (RegNo != PrevReg + 1) &&
4696f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                 ((RegNo != Mips::FP && RegNo != Mips::RA && !isGP64bit()) ||
4697f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                  (RegNo != Mips::FP_64 && RegNo != Mips::RA_64 &&
4698f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                   isGP64bit()))) {
469937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Error(E, "consecutive register numbers expected");
470037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MatchOperand_ParseFail;
470137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
470237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
470337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Regs.push_back(RegNo);
470437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
470537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
470637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.getTok().is(AsmToken::Minus))
470737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      RegRange = true;
470837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
470937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!Parser.getTok().isNot(AsmToken::Minus) &&
471037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        !Parser.getTok().isNot(AsmToken::Comma)) {
471137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Error(E, "',' or '-' expected");
471237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MatchOperand_ParseFail;
471337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
471437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
471537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Lex(); // Consume comma or minus
471637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.getTok().isNot(AsmToken::Dollar))
471737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
471837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
471937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    PrevReg = RegNo;
472037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
472137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
472237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SMLoc E = Parser.getTok().getLoc();
472337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
472437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  parseMemOperand(Operands);
472537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return MatchOperand_Success;
472637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
472737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4728ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMipsAsmParser::OperandMatchResultTy
4729ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMipsAsmParser::parseRegisterPair(OperandVector &Operands) {
4730ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MCAsmParser &Parser = getParser();
4731ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4732ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SMLoc S = Parser.getTok().getLoc();
4733ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (parseAnyRegister(Operands) != MatchOperand_Success)
4734ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MatchOperand_ParseFail;
4735ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4736ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SMLoc E = Parser.getTok().getLoc();
4737de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MipsOperand Op = static_cast<MipsOperand &>(*Operands.back());
4738de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
4739ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Operands.pop_back();
4740de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  Operands.push_back(MipsOperand::CreateRegPair(Op, S, E, *this));
4741ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return MatchOperand_Success;
4742ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
4743ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4744ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMipsAsmParser::OperandMatchResultTy
4745ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesMipsAsmParser::parseMovePRegPair(OperandVector &Operands) {
4746ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MCAsmParser &Parser = getParser();
4747ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 8> TmpOperands;
4748ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SmallVector<unsigned, 10> Regs;
4749ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4750ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Parser.getTok().isNot(AsmToken::Dollar))
4751ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MatchOperand_ParseFail;
4752ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4753ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SMLoc S = Parser.getTok().getLoc();
4754ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4755ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4756ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MatchOperand_ParseFail;
4757ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4758ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  MipsOperand *Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4759ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4760ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Regs.push_back(RegNo);
4761ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4762ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  SMLoc E = Parser.getTok().getLoc();
4763ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Parser.getTok().isNot(AsmToken::Comma)) {
4764ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    Error(E, "',' expected");
4765ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MatchOperand_ParseFail;
4766ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
4767ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4768ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Remove comma.
4769ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex();
4770ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4771ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (parseAnyRegister(TmpOperands) != MatchOperand_Success)
4772ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return MatchOperand_ParseFail;
4773ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4774ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Reg = &static_cast<MipsOperand &>(*TmpOperands.back());
4775ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  RegNo = isGP64bit() ? Reg->getGPR64Reg() : Reg->getGPR32Reg();
4776ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Regs.push_back(RegNo);
4777ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4778ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Operands.push_back(MipsOperand::CreateRegList(Regs, S, E, *this));
4779ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4780ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return MatchOperand_Success;
4781ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
4782ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
478336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Sometimes (i.e. load/stores) the operand may be followed immediately by
478436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// either this.
478536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '(', register, ')'
478636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handle it before we iterate so we don't get tripped up by the lack of
478736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a comma.
478837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseParenSuffix(StringRef Name, OperandVector &Operands) {
478937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
479036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().is(AsmToken::LParen)) {
479136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
479236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken("(", getLexer().getLoc(), *this));
479336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
479437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (parseOperand(Operands, Name)) {
479536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
479636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
479736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token in argument list");
479836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
479936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::RParen)) {
480036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
480136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
480236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token, expected ')'");
480336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
480436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
480536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken(")", getLexer().getLoc(), *this));
480636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
480736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
480836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
480936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
481036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
481136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Sometimes (i.e. in MSA) the operand may be followed immediately by
481236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// either one of these.
481336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '[', register, ']'
481436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// ::= '[', integer, ']'
481536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// handle it before we iterate so we don't get tripped up by the lack of
481636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// a comma.
481737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseBracketSuffix(StringRef Name,
4818c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                       OperandVector &Operands) {
481937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
482036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().is(AsmToken::LBrac)) {
482136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
482236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken("[", getLexer().getLoc(), *this));
482336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
482437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (parseOperand(Operands, Name)) {
482536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
482636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
482736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token in argument list");
482836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
482936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::RBrac)) {
483036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      SMLoc Loc = getLexer().getLoc();
483136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
483236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return Error(Loc, "unexpected token, expected ']'");
483336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
483436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Operands.push_back(
483536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        MipsOperand::CreateToken("]", getLexer().getLoc(), *this));
483636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
483736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
483836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
483936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
484036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
4841c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
4842c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                     SMLoc NameLoc, OperandVector &Operands) {
484337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
484436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  DEBUG(dbgs() << "ParseInstruction\n");
484537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
484637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // We have reached first instruction, module directive are now forbidden.
484737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().forbidModuleDirective();
484837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
4849fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic  // Check if we have valid mnemonic
4850f63ef914b67593e4b20a0b85e889380c20b41f55Craig Topper  if (!mnemonicIsValid(Name, 0)) {
4851fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic    Parser.eatToEndOfStatement();
485237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Error(NameLoc, "unknown instruction");
4853fce9279ac0265fd5ea637dd30253bad26f4273daVladimir Medic  }
4854088483627720acb58c96951b7b634f67312c7272Vladimir Medic  // First operand in MCInst is instruction mnemonic.
485536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Operands.push_back(MipsOperand::CreateToken(Name, NameLoc, *this));
4856ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
4857ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  // Read the remaining operands.
4858ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4859ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    // Read the first operand.
486037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (parseOperand(Operands, Name)) {
4861ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      SMLoc Loc = getLexer().getLoc();
4862cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      Parser.eatToEndOfStatement();
4863ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      return Error(Loc, "unexpected token in argument list");
4864ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
486537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getLexer().is(AsmToken::LBrac) && parseBracketSuffix(Name, Operands))
486636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      return true;
486736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    // AFAIK, parenthesis suffixes are never on the first operand
4868ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
486986924b4182537745659f2660244f3402c1e1ca4dJack Carter    while (getLexer().is(AsmToken::Comma)) {
487086924b4182537745659f2660244f3402c1e1ca4dJack Carter      Parser.Lex(); // Eat the comma.
4871ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      // Parse and remember the operand.
487237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (parseOperand(Operands, Name)) {
4873ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        SMLoc Loc = getLexer().getLoc();
4874cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach        Parser.eatToEndOfStatement();
4875ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter        return Error(Loc, "unexpected token in argument list");
4876ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter      }
487736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Parse bracket and parenthesis suffixes before we iterate
487836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      if (getLexer().is(AsmToken::LBrac)) {
487937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (parseBracketSuffix(Name, Operands))
488036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          return true;
488136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      } else if (getLexer().is(AsmToken::LParen) &&
488237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                 parseParenSuffix(Name, Operands))
488336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        return true;
4884ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    }
4885ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
4886ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4887ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    SMLoc Loc = getLexer().getLoc();
4888cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
4889ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter    return Error(Loc, "unexpected token in argument list");
4890ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  }
489186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
4892ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter  return false;
4893fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
4894fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
4895de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// FIXME: Given that these have the same name, these should both be
4896de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar// consistent on affecting the Parser.
4897c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::reportParseError(Twine ErrorMsg) {
489837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
489986924b4182537745659f2660244f3402c1e1ca4dJack Carter  SMLoc Loc = getLexer().getLoc();
490086924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.eatToEndOfStatement();
490186924b4182537745659f2660244f3402c1e1ca4dJack Carter  return Error(Loc, ErrorMsg);
490230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
490330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4904c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::reportParseError(SMLoc Loc, Twine ErrorMsg) {
4905dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return Error(Loc, ErrorMsg);
4906dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
4907dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
490830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoAtDirective() {
490937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
491086924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Line should look like: ".set noat".
4911ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4912ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Set the $at register to $0.
49136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  AssemblerOptions.back()->setATRegIndex(0);
4914ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4915ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex(); // Eat "noat".
4916ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
491786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
491830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
491937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
492030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
492130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
4922ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4923ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  getTargetStreamer().emitDirectiveSetNoAt();
492486924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
492530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
492630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
492786924b4182537745659f2660244f3402c1e1ca4dJack Carter
492830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetAtDirective() {
4929ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Line can be: ".set at", which sets $at to $1
4930ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  //          or  ".set at=$reg", which sets $at to $reg.
493137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
4932ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex(); // Eat "at".
4933ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
493430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().is(AsmToken::EndOfStatement)) {
4935ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // No register was specified, so we set $at to $1.
49366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    AssemblerOptions.back()->setATRegIndex(1);
4937ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4938ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    getTargetStreamer().emitDirectiveSetAt();
493986924b4182537745659f2660244f3402c1e1ca4dJack Carter    Parser.Lex(); // Consume the EndOfStatement.
494030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
4941ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
4942ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4943ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (getLexer().isNot(AsmToken::Equal)) {
4944ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("unexpected token, expected equals sign");
4945ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
4946ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
4947ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex(); // Eat "=".
4948ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4949ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (getLexer().isNot(AsmToken::Dollar)) {
4950ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (getLexer().is(AsmToken::EndOfStatement)) {
4951ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      reportParseError("no register specified");
495230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter      return false;
495399e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    } else {
4954ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      reportParseError("unexpected token, expected dollar sign '$'");
495599e98551bf8719764f9345ce856118f3f1a9c441Jack Carter      return false;
495699e98551bf8719764f9345ce856118f3f1a9c441Jack Carter    }
4957ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
4958ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex(); // Eat "$".
495999e98551bf8719764f9345ce856118f3f1a9c441Jack Carter
4960ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Find out what "reg" is.
4961ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  unsigned AtRegNo;
4962ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const AsmToken &Reg = Parser.getTok();
4963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Reg.is(AsmToken::Identifier)) {
4964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    AtRegNo = matchCPURegisterName(Reg.getIdentifier());
4965ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Reg.is(AsmToken::Integer)) {
4966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    AtRegNo = Reg.getIntVal();
4967ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
4968ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("unexpected token, expected identifier or integer");
4969ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
4970ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
497130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
4972ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // Check if $reg is a valid register. If it is, set $at to $reg.
49736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!AssemblerOptions.back()->setATRegIndex(AtRegNo)) {
4974ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("invalid register");
497530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
4976ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
4977ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex(); // Eat "reg".
4978ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4979ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  // If this is not the end of the statement, report an error.
4980ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
4981ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("unexpected token, expected end of statement");
498230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
498330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
4984ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4985ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  getTargetStreamer().emitDirectiveSetAtWithArg(AtRegNo);
4986ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
4987ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  Parser.Lex(); // Consume the EndOfStatement.
4988ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  return false;
498930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
499030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
499130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetReorderDirective() {
499237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
499330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
499486924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
499530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
499637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
499730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
499830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
499937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.back()->setReorder();
500036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getTargetStreamer().emitDirectiveSetReorder();
500186924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
500230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
500330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
500430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
500530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoReorderDirective() {
500637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
500786924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex();
500886924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
500986924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
501037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
501130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
501286924b4182537745659f2660244f3402c1e1ca4dJack Carter  }
501337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.back()->setNoReorder();
501436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getTargetStreamer().emitDirectiveSetNoReorder();
501586924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
501686924b4182537745659f2660244f3402c1e1ca4dJack Carter  return false;
501730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
501830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
501930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetMacroDirective() {
502037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
502130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
502286924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
502330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
502437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
502530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
502630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
502737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.back()->setMacro();
50286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveSetMacro();
502986924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
503030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
503130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
503230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
503330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseSetNoMacroDirective() {
503437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
503530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  Parser.Lex();
503686924b4182537745659f2660244f3402c1e1ca4dJack Carter  // If this is not the end of the statement, report an error.
503730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
503837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
503930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
504030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
504137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (AssemblerOptions.back()->isReorder()) {
504230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    reportParseError("`noreorder' must be set before `nomacro'");
504330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
504430116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
504537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.back()->setNoMacro();
50466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveSetNoMacro();
504786924b4182537745659f2660244f3402c1e1ca4dJack Carter  Parser.Lex(); // Consume the EndOfStatement.
504830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return false;
504930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
5050c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
505137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetMsaDirective() {
505237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
505337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex();
505437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
505537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If this is not the end of the statement, report an error.
505637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
505737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected end of statement");
505837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
505937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  setFeatureBits(Mips::FeatureMSA, "msa");
506037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetMsa();
506137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
506237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
506337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
506437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetNoMsaDirective() {
506537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
506636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex();
506737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
506837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If this is not the end of the statement, report an error.
506937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
507037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected end of statement");
507137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
507237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  clearFeatureBits(Mips::FeatureMSA, "msa");
507337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetNoMsa();
507437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
507537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
507637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
507737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetNoDspDirective() {
507837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
507937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex(); // Eat "nodsp".
508037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
508136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // If this is not the end of the statement, report an error.
508236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
508337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
508436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
508536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
508637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
508737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  clearFeatureBits(Mips::FeatureDSP, "dsp");
508837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetNoDsp();
508937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
509037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
509137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
509237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetMips16Directive() {
509337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
509437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex(); // Eat "mips16".
509537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
509637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If this is not the end of the statement, report an error.
509737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
509837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
509937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
510037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
510137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
510237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  setFeatureBits(Mips::FeatureMips16, "mips16");
510337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetMips16();
510437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex(); // Consume the EndOfStatement.
510537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
510637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
510737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
510837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetNoMips16Directive() {
510937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
511037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex(); // Eat "nomips16".
511137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
511237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If this is not the end of the statement, report an error.
511337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
511437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
511537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
511637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
511737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
511837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  clearFeatureBits(Mips::FeatureMips16, "mips16");
511937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetNoMips16();
512036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Consume the EndOfStatement.
512136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
512236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
512336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5124c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::parseSetFpDirective() {
512537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5126c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsABIFlagsSection::FpABIKind FpAbiVal;
5127c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  // Line can be: .set fp=32
5128c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  //              .set fp=xx
5129c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  //              .set fp=64
5130c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Parser.Lex(); // Eat fp token
5131c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  AsmToken Tok = Parser.getTok();
5132c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Tok.isNot(AsmToken::Equal)) {
513337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected equals sign '='");
5134c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5135c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5136c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Parser.Lex(); // Eat '=' token.
5137c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Tok = Parser.getTok();
5138c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5139c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!parseFpABIValue(FpAbiVal, ".set"))
5140c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5141c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5142c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
514337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
5144c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5145c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5146c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  getTargetStreamer().emitDirectiveSetFp(FpAbiVal);
5147c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Parser.Lex(); // Consume the EndOfStatement.
5148c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return false;
5149c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
5150c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5151f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::parseSetOddSPRegDirective() {
5152f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCAsmParser &Parser = getParser();
5153f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5154f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Parser.Lex(); // Eat "oddspreg".
5155f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5156f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reportParseError("unexpected token, expected end of statement");
5157f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
5158f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5159f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5160f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  clearFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5161f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveSetOddSPReg();
5162f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
5163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
5164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::parseSetNoOddSPRegDirective() {
5166f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCAsmParser &Parser = getParser();
5167f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5168f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Parser.Lex(); // Eat "nooddspreg".
5169f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reportParseError("unexpected token, expected end of statement");
5171f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
5172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5174f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  setFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5175f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveSetNoOddSPReg();
5176f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
5177f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
5178f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
517937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetPopDirective() {
518037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
518137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  SMLoc Loc = getLexer().getLoc();
518237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
518337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex();
518437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
518537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected end of statement");
518637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
518737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Always keep an element on the options "stack" to prevent the user
518837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // from changing the initial options. This is how we remember them.
518937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (AssemblerOptions.size() == 2)
519037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError(Loc, ".set pop with no .set push");
519137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
5192f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo &STI = copySTI();
519337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.pop_back();
51946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  setAvailableFeatures(
51956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ComputeAvailableFeatures(AssemblerOptions.back()->getFeatures()));
51966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  STI.setFeatureBits(AssemblerOptions.back()->getFeatures());
519737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
519837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetPop();
519937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
520037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
520137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
520237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetPushDirective() {
520337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
520437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex();
520537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
520637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected end of statement");
520737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
520837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Create a copy of the current assembler options environment and push it.
520937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.push_back(
521037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines              make_unique<MipsAssemblerOptions>(AssemblerOptions.back().get()));
521137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
521237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetPush();
521337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
521437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
521537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
52166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool MipsAsmParser::parseSetSoftFloatDirective() {
52176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCAsmParser &Parser = getParser();
52186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Parser.Lex();
52196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement))
52206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return reportParseError("unexpected token, expected end of statement");
52216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
52226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  setFeatureBits(Mips::FeatureSoftFloat, "soft-float");
52236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveSetSoftFloat();
52246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return false;
52256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
52266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
52276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool MipsAsmParser::parseSetHardFloatDirective() {
52286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCAsmParser &Parser = getParser();
52296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  Parser.Lex();
52306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement))
52316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return reportParseError("unexpected token, expected end of statement");
52326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
52336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  clearFeatureBits(Mips::FeatureSoftFloat, "soft-float");
52346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveSetHardFloat();
52356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return false;
52366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
52376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
5238c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carterbool MipsAsmParser::parseSetAssignment() {
5239c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  StringRef Name;
5240c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  const MCExpr *Value;
524137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5242c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
5243c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (Parser.parseIdentifier(Name))
5244c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    reportParseError("expected identifier after .set");
5245c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
5246c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  if (getLexer().isNot(AsmToken::Comma))
524737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected comma");
52488afc8b7e63d5ce2d027e92934d16b19e5ba2db59Jack Carter  Lex(); // Eat comma
5249c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
525036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Parser.parseExpression(Value))
5251c57905ef4dfc7a8b573efbf8e0a1f9580d98bfe8Jack Carter    return reportParseError("expected valid expression after comma");
5252c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
52536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  MCSymbol *Sym = getContext().getOrCreateSymbol(Name);
5254c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  Sym->setVariableValue(Value);
5255c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter
5256c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  return false;
5257c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter}
525886924b4182537745659f2660244f3402c1e1ca4dJack Carter
525937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetMips0Directive() {
526037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
526137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex();
526237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
526337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected end of statement");
526437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
526537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Reset assembler options to their initial values.
5266f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCSubtargetInfo &STI = copySTI();
52676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  setAvailableFeatures(
52686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      ComputeAvailableFeatures(AssemblerOptions.front()->getFeatures()));
52696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  STI.setFeatureBits(AssemblerOptions.front()->getFeatures());
527037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  AssemblerOptions.back()->setFeatures(AssemblerOptions.front()->getFeatures());
527137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
527237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetMips0();
527337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
527437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
527537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
527637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseSetArchDirective() {
527737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
527837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex();
527937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::Equal))
528037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected equals sign");
528137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
528237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Parser.Lex();
528337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef Arch;
528437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Parser.parseIdentifier(Arch))
528537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("expected arch identifier");
528637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
528737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  StringRef ArchFeatureName =
528837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      StringSwitch<StringRef>(Arch)
528937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips1", "mips1")
529037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips2", "mips2")
529137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips3", "mips3")
529237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips4", "mips4")
529337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips5", "mips5")
529437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips32", "mips32")
529537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips32r2", "mips32r2")
5296ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          .Case("mips32r3", "mips32r3")
5297ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          .Case("mips32r5", "mips32r5")
529837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips32r6", "mips32r6")
529937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips64", "mips64")
530037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips64r2", "mips64r2")
5301ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          .Case("mips64r3", "mips64r3")
5302ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines          .Case("mips64r5", "mips64r5")
530337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("mips64r6", "mips64r6")
5304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          .Case("octeon", "cnmips")
530537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Case("r4000", "mips3") // This is an implementation of Mips3.
530637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          .Default("");
530737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
530837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (ArchFeatureName.empty())
530937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unsupported architecture");
531037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
531137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  selectArch(ArchFeatureName);
531237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveSetArch(Arch);
531337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return false;
531437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
531537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
531636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseSetFeature(uint64_t Feature) {
531737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
531836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex();
531936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
532037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return reportParseError("unexpected token, expected end of statement");
532136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5322dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  switch (Feature) {
5323dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  default:
5324dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    llvm_unreachable("Unimplemented feature");
5325dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureDSP:
5326dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    setFeatureBits(Mips::FeatureDSP, "dsp");
5327dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetDsp();
532836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
5329dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMicroMips:
5330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    setFeatureBits(Mips::FeatureMicroMips, "micromips");
5331dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMicroMips();
533236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
533337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips1:
533437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips1");
533537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips1();
533637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
533737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips2:
533837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips2");
533937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips2();
534037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
534137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips3:
534237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips3");
534337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips3();
534437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
534537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips4:
534637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips4");
534737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips4();
534837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
534937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips5:
535037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips5");
535137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips5();
535237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
535337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips32:
535437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips32");
535537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips32();
535636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
5357dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips32r2:
535837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips32r2");
5359dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips32R2();
536036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
5361ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::FeatureMips32r3:
5362ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    selectArch("mips32r3");
5363ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    getTargetStreamer().emitDirectiveSetMips32R3();
5364ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
5365ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::FeatureMips32r5:
5366ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    selectArch("mips32r5");
5367ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    getTargetStreamer().emitDirectiveSetMips32R5();
5368ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
536937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips32r6:
537037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips32r6");
537137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips32R6();
537237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
5373dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips64:
537437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips64");
5375dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips64();
537636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
5377dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  case Mips::FeatureMips64r2:
537837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips64r2");
5379dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    getTargetStreamer().emitDirectiveSetMips64R2();
538036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
5381ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::FeatureMips64r3:
5382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    selectArch("mips64r3");
5383ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    getTargetStreamer().emitDirectiveSetMips64R3();
5384ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
5385ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  case Mips::FeatureMips64r5:
5386ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    selectArch("mips64r5");
5387ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    getTargetStreamer().emitDirectiveSetMips64R5();
5388ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    break;
538937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case Mips::FeatureMips64r6:
539037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    selectArch("mips64r6");
539137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveSetMips64R6();
539237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
539336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
539436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
539536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
539636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
539736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::eatComma(StringRef ErrorStr) {
539837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
539936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::Comma)) {
540036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    SMLoc Loc = getLexer().getLoc();
540136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.eatToEndOfStatement();
540236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return Error(Loc, ErrorStr);
540336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
540436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Parser.Lex(); // Eat the comma.
540636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return true;
540736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
540836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5409f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// Used to determine if .cpload, .cprestore, and .cpsetup have any effect.
5410f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// In this class, it is only used for .cprestore.
5411f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// FIXME: Only keep track of IsPicEnabled in one place, instead of in both
5412f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar// MipsTargetELFStreamer and MipsAsmParser.
5413f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::isPicAndNotNxxAbi() {
5414f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return inPicMode() && !(isABI_N32() || isABI_N64());
5415f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
5416f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
541737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesbool MipsAsmParser::parseDirectiveCpLoad(SMLoc Loc) {
541837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (AssemblerOptions.back()->isReorder())
541937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Warning(Loc, ".cpload should be inside a noreorder section");
5420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
542137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (inMips16Mode()) {
542237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError(".cpload is not supported in Mips16 mode");
542337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
542437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
5425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5426c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> Reg;
542737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OperandMatchResultTy ResTy = parseAnyRegister(Reg);
5428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
5429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    reportParseError("expected register containing function address");
5430dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
5431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
5432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5433c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsOperand &RegOpnd = static_cast<MipsOperand &>(*Reg[0]);
5434c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!RegOpnd.isGPRAsmReg()) {
5435c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    reportParseError(RegOpnd.getStartLoc(), "invalid register");
5436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
5437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
5438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
543937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // If this is not the end of the statement, report an error.
544037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
544137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
544237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
544337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
544437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
544537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  getTargetStreamer().emitDirectiveCpLoad(RegOpnd.getGPR32Reg());
5446dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
5447dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
5448dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5449f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::parseDirectiveCpRestore(SMLoc Loc) {
5450f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  MCAsmParser &Parser = getParser();
5451f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5452f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Note that .cprestore is ignored if used with the N32 and N64 ABIs or if it
5453f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // is used in non-PIC mode.
5454f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5455f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (inMips16Mode()) {
5456f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reportParseError(".cprestore is not supported in Mips16 mode");
5457f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
5458f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5459f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5460f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Get the stack offset value.
5461f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  const MCExpr *StackOffset;
5462f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  int64_t StackOffsetVal;
5463f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (Parser.parseExpression(StackOffset)) {
5464f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reportParseError("expected stack offset value");
5465f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
5466f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5467f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5468f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (!StackOffset->evaluateAsAbsolute(StackOffsetVal)) {
5469f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reportParseError("stack offset is not an absolute expression");
5470f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
5471f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5472f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5473f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (StackOffsetVal < 0) {
5474f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Warning(Loc, ".cprestore with negative stack offset has no effect");
5475f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsCpRestoreSet = false;
5476f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else {
5477f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsCpRestoreSet = true;
5478f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    CpRestoreOffset = StackOffsetVal;
5479f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5480f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5481f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If this is not the end of the statement, report an error.
5482f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5483f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    reportParseError("unexpected token, expected end of statement");
5484f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false;
5485f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  }
5486f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5487de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (!getTargetStreamer().emitDirectiveCpRestore(
5488de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar          CpRestoreOffset, [&]() { return getATReg(Loc); }, Loc, STI))
5489de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return true;
5490f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  Parser.Lex(); // Consume the EndOfStatement.
5491f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
5492f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
5493f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
549436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveCPSetup() {
549537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
549636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned FuncReg;
549736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  unsigned Save;
549836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  bool SaveIsReg = true;
549936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5500c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
550137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
5502c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (ResTy == MatchOperand_NoMatch) {
5503c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    reportParseError("expected register containing function address");
5504c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5505c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5506c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5507c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsOperand &FuncRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5508c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!FuncRegOpnd.isGPRAsmReg()) {
5509c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    reportParseError(FuncRegOpnd.getStartLoc(), "invalid register");
5510c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Parser.eatToEndOfStatement();
5511c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5512c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5513c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5514c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  FuncReg = FuncRegOpnd.getGPR32Reg();
5515c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  TmpReg.clear();
551636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
551737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!eatComma("unexpected token, expected comma"))
551836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
551936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
552037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  ResTy = parseAnyRegister(TmpReg);
5521c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (ResTy == MatchOperand_NoMatch) {
5522f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    const MCExpr *OffsetExpr;
5523f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    int64_t OffsetVal;
5524f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SMLoc ExprLoc = getLexer().getLoc();
5525f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5526f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (Parser.parseExpression(OffsetExpr) ||
5527f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        !OffsetExpr->evaluateAsAbsolute(OffsetVal)) {
5528f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      reportParseError(ExprLoc, "expected save register or stack offset");
5529c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      Parser.eatToEndOfStatement();
5530c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
5531c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
5532f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5533f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    Save = OffsetVal;
5534f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    SaveIsReg = false;
5535c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else {
5536c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    MipsOperand &SaveOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
5537c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (!SaveOpnd.isGPRAsmReg()) {
5538c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      reportParseError(SaveOpnd.getStartLoc(), "invalid register");
5539c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      Parser.eatToEndOfStatement();
5540c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
5541c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
5542c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Save = SaveOpnd.getGPR32Reg();
5543c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
554436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
554537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!eatComma("unexpected token, expected comma"))
554636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
554736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5548ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const MCExpr *Expr;
5549ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Parser.parseExpression(Expr)) {
5550ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("expected expression");
5551ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
5552ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
555336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5554ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Expr->getKind() != MCExpr::SymbolRef) {
5555ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("expected symbol");
5556ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
5557ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
5558ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  const MCSymbolRefExpr *Ref = static_cast<const MCSymbolRefExpr *>(Expr);
5559ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
5560f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  CpSaveLocation = Save;
5561f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  CpSaveLocationIsRegister = SaveIsReg;
5562f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5563ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  getTargetStreamer().emitDirectiveCpsetup(FuncReg, Save, Ref->getSymbol(),
5564ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                           SaveIsReg);
5565dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return false;
5566dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
556736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
5568f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarbool MipsAsmParser::parseDirectiveCPReturn() {
5569f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveCpreturn(CpSaveLocation,
5570f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar                                            CpSaveLocationIsRegister);
5571f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  return false;
5572f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar}
5573f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5574dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool MipsAsmParser::parseDirectiveNaN() {
557537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const AsmToken &Tok = Parser.getTok();
5578dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
5579dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Tok.getString() == "2008") {
5580dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex();
5581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      getTargetStreamer().emitDirectiveNaN2008();
5582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
5583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (Tok.getString() == "legacy") {
5584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Parser.Lex();
5585dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      getTargetStreamer().emitDirectiveNaNLegacy();
5586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return false;
5587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
5588dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
5589dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // If we don't recognize the option passed to the .nan
5590dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // directive (e.g. no option or unknown option), emit an error.
5591dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  reportParseError("invalid option in .nan directive");
559236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
559336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
559436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
559530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carterbool MipsAsmParser::parseDirectiveSet() {
559637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
559786924b4182537745659f2660244f3402c1e1ca4dJack Carter  // Get the next token.
559830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  const AsmToken &Tok = Parser.getTok();
559930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
560030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  if (Tok.getString() == "noat") {
560130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoAtDirective();
560230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "at") {
560330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetAtDirective();
560437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "arch") {
560537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetArchDirective();
5606c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  } else if (Tok.getString() == "fp") {
5607c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return parseSetFpDirective();
5608f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else if (Tok.getString() == "oddspreg") {
5609f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return parseSetOddSPRegDirective();
5610f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else if (Tok.getString() == "nooddspreg") {
5611f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return parseSetNoOddSPRegDirective();
561237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "pop") {
561337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetPopDirective();
561437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "push") {
561537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetPushDirective();
561630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "reorder") {
561730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetReorderDirective();
561830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "noreorder") {
561930116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoReorderDirective();
562030116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "macro") {
562130116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetMacroDirective();
562230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomacro") {
562330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return parseSetNoMacroDirective();
562436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips16") {
562537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetMips16Directive();
562630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomips16") {
562736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return parseSetNoMips16Directive();
562830116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  } else if (Tok.getString() == "nomicromips") {
5629de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    clearFeatureBits(Mips::FeatureMicroMips, "micromips");
563036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveSetNoMicroMips();
5631cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach    Parser.eatToEndOfStatement();
563230116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter    return false;
563336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "micromips") {
5634dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMicroMips);
563537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips0") {
563637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetMips0Directive();
563737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips1") {
563837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips1);
563937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips2") {
564037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips2);
564137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips3") {
564237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips3);
564337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips4") {
564437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips4);
564537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips5") {
564637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips5);
564737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips32") {
564837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips32);
564936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips32r2") {
5650dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMips32r2);
5651ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Tok.getString() == "mips32r3") {
5652ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return parseSetFeature(Mips::FeatureMips32r3);
5653ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Tok.getString() == "mips32r5") {
5654ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return parseSetFeature(Mips::FeatureMips32r5);
565537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips32r6") {
565637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips32r6);
565736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips64") {
5658dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMips64);
565936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "mips64r2") {
5660dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureMips64r2);
5661ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Tok.getString() == "mips64r3") {
5662ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return parseSetFeature(Mips::FeatureMips64r3);
5663ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Tok.getString() == "mips64r5") {
5664ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return parseSetFeature(Mips::FeatureMips64r5);
566537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "mips64r6") {
566637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetFeature(Mips::FeatureMips64r6);
566736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  } else if (Tok.getString() == "dsp") {
5668dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseSetFeature(Mips::FeatureDSP);
566937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "nodsp") {
567037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetNoDspDirective();
567137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "msa") {
567237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetMsaDirective();
567337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else if (Tok.getString() == "nomsa") {
567437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return parseSetNoMsaDirective();
56756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (Tok.getString() == "softfloat") {
56766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return parseSetSoftFloatDirective();
56776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (Tok.getString() == "hardfloat") {
56786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return parseSetHardFloatDirective();
5679c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter  } else {
568086924b4182537745659f2660244f3402c1e1ca4dJack Carter    // It is just an identifier, look for an assignment.
5681c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    parseSetAssignment();
5682c91b5e197bb41ccb2f9f78b6176e61c848df9e15Jack Carter    return false;
568330116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  }
5684801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
568530116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter  return true;
568630116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter}
568730116cd2e24a4a2b6c2771ef2665d655de93b984Jack Carter
568836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// parseDataDirective
5689801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter///  ::= .word [ expression (, expression)* ]
569036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDataDirective(unsigned Size, SMLoc L) {
569137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5692801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5693801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    for (;;) {
5694801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      const MCExpr *Value;
5695cb2ae3d98e3bb36e5813f8f69b00d39efd026dcdJim Grosbach      if (getParser().parseExpression(Value))
5696801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        return true;
5697801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
5698801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      getParser().getStreamer().EmitValue(Value, Size);
5699801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
5700801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().is(AsmToken::EndOfStatement))
5701801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter        break;
5702801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
5703801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      if (getLexer().isNot(AsmToken::Comma))
570437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return Error(L, "unexpected token, expected comma");
5705801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter      Parser.Lex();
5706801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    }
5707801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
5708801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
5709801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  Parser.Lex();
5710801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  return false;
5711801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter}
5712801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
57132263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic/// parseDirectiveGpWord
57142263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic///  ::= .gpword local_sym
57152263a2ca72e21206d45a69532004a0b17881e733Vladimir Medicbool MipsAsmParser::parseDirectiveGpWord() {
571637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
57172263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  const MCExpr *Value;
57182263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  // EmitGPRel32Value requires an expression, so we are using base class
57192263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  // method to evaluate the expression.
57202263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  if (getParser().parseExpression(Value))
57212263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    return true;
57222263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  getParser().getStreamer().EmitGPRel32Value(Value);
57232263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic
5724c0fad4d9fdb1aebe029bcb54311fad7059b1a9e5Vladimir Medic  if (getLexer().isNot(AsmToken::EndOfStatement))
572537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Error(getLexer().getLoc(),
572637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                "unexpected token, expected end of statement");
5727c0fad4d9fdb1aebe029bcb54311fad7059b1a9e5Vladimir Medic  Parser.Lex(); // Eat EndOfStatement token.
57282263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic  return false;
57292263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic}
57302263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic
573136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// parseDirectiveGpDWord
573236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines///  ::= .gpdword local_sym
573336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveGpDWord() {
573437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
573536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  const MCExpr *Value;
573636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // EmitGPRel64Value requires an expression, so we are using base class
573736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // method to evaluate the expression.
573836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getParser().parseExpression(Value))
573936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return true;
574036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  getParser().getStreamer().EmitGPRel64Value(Value);
574136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
574236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement))
574337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Error(getLexer().getLoc(),
574437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                "unexpected token, expected end of statement");
574536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.Lex(); // Eat EndOfStatement token.
574636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
574736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
5748acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
574936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::parseDirectiveOption() {
575037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
575136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Get the option token.
575236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  AsmToken Tok = Parser.getTok();
575336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // At the moment only identifiers are supported.
575436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Tok.isNot(AsmToken::Identifier)) {
575537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Error(Parser.getTok().getLoc(), "unexpected token, expected identifier");
575636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.eatToEndOfStatement();
575736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
575836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
575936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
576036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  StringRef Option = Tok.getIdentifier();
576136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
576236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Option == "pic0") {
5763f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // MipsAsmParser needs to know if the current PIC mode changes.
5764f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsPicEnabled = false;
5765f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
576636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveOptionPic0();
576736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
576836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
576936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Error(Parser.getTok().getLoc(),
577037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "unexpected token, expected end of statement");
577136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
577236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
577336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
577436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
577536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
577636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (Option == "pic2") {
5777f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // MipsAsmParser needs to know if the current PIC mode changes.
5778f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsPicEnabled = true;
5779f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
578036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveOptionPic2();
578136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    Parser.Lex();
578236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
578336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Error(Parser.getTok().getLoc(),
578437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "unexpected token, expected end of statement");
578536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
578636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
578736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
578836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
578936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
579036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  // Unknown option.
579137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Warning(Parser.getTok().getLoc(),
579237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          "unknown option, expected 'pic0' or 'pic2'");
579336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Parser.eatToEndOfStatement();
579436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  return false;
579536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
579636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
57970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar/// parseInsnDirective
57980c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar///  ::= .insn
57990c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarbool MipsAsmParser::parseInsnDirective() {
58000c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // If this is not the end of the statement, report an error.
58010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
58020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    reportParseError("unexpected token, expected end of statement");
58030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar    return false;
58040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  }
58050c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
58060c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // The actual label marking happens in
58070c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  // MipsELFStreamer::createPendingLabelRelocs().
58080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveInsn();
58090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
58100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  getParser().Lex(); // Eat EndOfStatement token.
58110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar  return false;
58120c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar}
58130c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
5814de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar/// parseSSectionDirective
5815de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar///  ::= .sbss
5816de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar///  ::= .sdata
5817de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool MipsAsmParser::parseSSectionDirective(StringRef Section, unsigned Type) {
5818de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // If this is not the end of the statement, report an error.
5819de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
5820de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    reportParseError("unexpected token, expected end of statement");
5821de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
5822de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
5823de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5824de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  MCSection *ELFSection = getContext().getELFSection(
5825de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      Section, Type, ELF::SHF_WRITE | ELF::SHF_ALLOC | ELF::SHF_MIPS_GPREL);
5826de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  getParser().getStreamer().SwitchSection(ELFSection);
5827de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5828de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  getParser().Lex(); // Eat EndOfStatement token.
5829de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  return false;
5830de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar}
5831de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
5832c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// parseDirectiveModule
5833c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines///  ::= .module oddspreg
5834c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines///  ::= .module nooddspreg
5835c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines///  ::= .module fp=value
5836f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///  ::= .module softfloat
5837f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar///  ::= .module hardfloat
5838c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::parseDirectiveModule() {
583937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5840c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MCAsmLexer &Lexer = getLexer();
5841c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  SMLoc L = Lexer.getLoc();
5842c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
584337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!getTargetStreamer().isModuleDirectiveAllowed()) {
5844c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    // TODO : get a better message.
5845c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    reportParseError(".module directive must appear before any code");
5846c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5847c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5848c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  StringRef Option;
5850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Parser.parseIdentifier(Option)) {
5851ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    reportParseError("expected .module option identifier");
5852ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false;
5853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
5854c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Option == "oddspreg") {
5856f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    clearModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5857f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5858f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Synchronize the abiflags information with the FeatureBits information we
5859f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // changed above.
5860f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().updateABIInfo(*this);
5861f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5862f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If printing assembly, use the recently updated abiflags information.
5863f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5864f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // emitted at the end).
5865f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().emitDirectiveModuleOddSPReg();
5866c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5867ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If this is not the end of the statement, report an error.
5868ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5869ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      reportParseError("unexpected token, expected end of statement");
5870c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
5871ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
5872c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5873ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false; // parseDirectiveModule has finished successfully.
5874ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Option == "nooddspreg") {
5875ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (!isABI_O32()) {
5876ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      Error(L, "'.module nooddspreg' requires the O32 ABI");
5877ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return false;
5878ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
5879c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5880f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setModuleFeatureBits(Mips::FeatureNoOddSPReg, "nooddspreg");
5881f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5882f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Synchronize the abiflags information with the FeatureBits information we
5883f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // changed above.
5884f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().updateABIInfo(*this);
5885f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5886f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If printing assembly, use the recently updated abiflags information.
5887f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5888f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // emitted at the end).
5889f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().emitDirectiveModuleOddSPReg();
5890c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5891ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    // If this is not the end of the statement, report an error.
5892ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5893ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      reportParseError("unexpected token, expected end of statement");
5894c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
5895c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
5896c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5897ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return false; // parseDirectiveModule has finished successfully.
5898ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else if (Option == "fp") {
5899ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return parseDirectiveModuleFP();
5900f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else if (Option == "softfloat") {
5901f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    setModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5902f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5903f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Synchronize the ABI Flags information with the FeatureBits information we
5904f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // updated above.
5905f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().updateABIInfo(*this);
5906f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5907f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If printing assembly, use the recently updated ABI Flags information.
5908f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5909f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // emitted later).
5910f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().emitDirectiveModuleSoftFloat();
5911f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5912f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If this is not the end of the statement, report an error.
5913f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5914f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      reportParseError("unexpected token, expected end of statement");
5915f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
5916f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
5917f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5918f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false; // parseDirectiveModule has finished successfully.
5919f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  } else if (Option == "hardfloat") {
5920f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    clearModuleFeatureBits(Mips::FeatureSoftFloat, "soft-float");
5921f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5922f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // Synchronize the ABI Flags information with the FeatureBits information we
5923f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // updated above.
5924f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().updateABIInfo(*this);
5925f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5926f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If printing assembly, use the recently updated ABI Flags information.
5927f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5928f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // emitted later).
5929f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    getTargetStreamer().emitDirectiveModuleHardFloat();
5930f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5931f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    // If this is not the end of the statement, report an error.
5932f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (getLexer().isNot(AsmToken::EndOfStatement)) {
5933f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      reportParseError("unexpected token, expected end of statement");
5934f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      return false;
5935f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
5936f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5937f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    return false; // parseDirectiveModule has finished successfully.
5938ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  } else {
5939c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return Error(L, "'" + Twine(Option) + "' is not a valid .module option.");
5940c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5941c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
5942c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5943c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines/// parseDirectiveModuleFP
5944c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines///  ::= =32
5945c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines///  ::= =xx
5946c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines///  ::= =64
5947c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::parseDirectiveModuleFP() {
594837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5949c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MCAsmLexer &Lexer = getLexer();
5950c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5951c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Lexer.isNot(AsmToken::Equal)) {
595237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected equals sign '='");
5953c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5954c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5955c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Parser.Lex(); // Eat '=' token.
5956c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5957c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MipsABIFlagsSection::FpABIKind FpABI;
5958c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (!parseFpABIValue(FpABI, ".module"))
5959c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5960c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5961c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (getLexer().isNot(AsmToken::EndOfStatement)) {
596237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    reportParseError("unexpected token, expected end of statement");
5963c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return false;
5964c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
5965c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5966f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // Synchronize the abiflags information with the FeatureBits information we
5967f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // changed above.
5968f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  getTargetStreamer().updateABIInfo(*this);
5969f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5970f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If printing assembly, use the recently updated abiflags information.
5971f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // If generating ELF, don't do anything (the .MIPS.abiflags section gets
5972f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  // emitted at the end).
5973f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  getTargetStreamer().emitDirectiveModuleFP();
5974f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar
5975c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  Parser.Lex(); // Consume the EndOfStatement.
5976c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return false;
5977c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
5978c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5979c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hinesbool MipsAsmParser::parseFpABIValue(MipsABIFlagsSection::FpABIKind &FpABI,
5980c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines                                    StringRef Directive) {
598137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
5982c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  MCAsmLexer &Lexer = getLexer();
5983f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar  bool ModuleLevelOptions = Directive == ".module";
5984c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5985c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Lexer.is(AsmToken::Identifier)) {
5986c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    StringRef Value = Parser.getTok().getString();
5987c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Parser.Lex();
5988c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5989c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Value != "xx") {
5990c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      reportParseError("unsupported value, expected 'xx', '32' or '64'");
5991c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
5992c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
5993c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5994c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (!isABI_O32()) {
5995c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      reportParseError("'" + Directive + " fp=xx' requires the O32 ABI");
5996c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
5997c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
5998c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
5999c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    FpABI = MipsABIFlagsSection::FpABIKind::XX;
6000f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    if (ModuleLevelOptions) {
6001f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      setModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6002f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6003f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else {
6004f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      setFeatureBits(Mips::FeatureFPXX, "fpxx");
6005f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6006f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
6007c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return true;
6008c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
6009c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
6010c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  if (Lexer.is(AsmToken::Integer)) {
6011c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    unsigned Value = Parser.getTok().getIntVal();
6012c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    Parser.Lex();
6013c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
6014c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Value != 32 && Value != 64) {
6015c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      reportParseError("unsupported value, expected 'xx', '32' or '64'");
6016c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      return false;
6017c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    }
6018c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
6019c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    if (Value == 32) {
6020c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      if (!isABI_O32()) {
6021c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        reportParseError("'" + Directive + " fp=32' requires the O32 ABI");
6022c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines        return false;
6023c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      }
6024c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
6025c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      FpABI = MipsABIFlagsSection::FpABIKind::S32;
6026f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ModuleLevelOptions) {
6027f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6028f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        clearModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6029f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
6030f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6031f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        clearFeatureBits(Mips::FeatureFP64Bit, "fp64");
6032f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
6033f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    } else {
6034c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines      FpABI = MipsABIFlagsSection::FpABIKind::S64;
6035f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      if (ModuleLevelOptions) {
6036f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        clearModuleFeatureBits(Mips::FeatureFPXX, "fpxx");
6037f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        setModuleFeatureBits(Mips::FeatureFP64Bit, "fp64");
6038f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      } else {
6039f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        clearFeatureBits(Mips::FeatureFPXX, "fpxx");
6040f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar        setFeatureBits(Mips::FeatureFP64Bit, "fp64");
6041f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar      }
6042f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    }
6043c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
6044c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines    return true;
6045c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  }
6046c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
6047c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines  return false;
6048c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines}
6049c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines
605036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesbool MipsAsmParser::ParseDirective(AsmToken DirectiveID) {
6051de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // This returns false if this function recognizes the directive
6052de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // regardless of whether it is successfully handles or reports an
6053de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // error. Otherwise it returns true to give the generic parser a
6054de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  // chance at recognizing it.
6055de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
605637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  MCAsmParser &Parser = getParser();
6057801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  StringRef IDVal = DirectiveID.getString();
6058801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
6059de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".cpload") {
6060de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveCpLoad(DirectiveID.getLoc());
6061de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6062de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6063de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".cprestore") {
6064de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveCpRestore(DirectiveID.getLoc());
6065de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6066de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
606736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".dword") {
606836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    parseDataDirective(8, DirectiveID.getLoc());
606936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
607036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
607186924b4182537745659f2660244f3402c1e1ca4dJack Carter  if (IDVal == ".ent") {
607237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SymbolName;
607337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
607437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.parseIdentifier(SymbolName)) {
607537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected identifier after .ent");
607637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
607737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
607837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
607937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // There's an undocumented extension that allows an integer to
608037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // follow the name of the procedure which AFAICS is ignored by GAS.
608137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Example: .ent foo,2
608237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
608337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (getLexer().isNot(AsmToken::Comma)) {
608437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // Even though we accept this undocumented extension for compatibility
608537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // reasons, the additional integer argument does not actually change
608637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // the behaviour of the '.ent' directive, so we would like to discourage
608737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // its use. We do this by not referring to the extended version in
608837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // error messages which are not directly related to its use.
608937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reportParseError("unexpected token, expected end of statement");
609037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
609137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
609237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Parser.Lex(); // Eat the comma.
609337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      const MCExpr *DummyNumber;
609437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      int64_t DummyNumberVal;
609537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // If the user was explicitly trying to use the extended version,
609637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      // we still give helpful extension-related error messages.
609737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (Parser.parseExpression(DummyNumber)) {
609837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reportParseError("expected number after comma");
609937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
610037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
61016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      if (!DummyNumber->evaluateAsAbsolute(DummyNumberVal)) {
610237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        reportParseError("expected an absolute expression after comma");
610337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return false;
610437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
610537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
610637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
610737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this is not the end of the statement, report an error.
610837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
610937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected end of statement");
611037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
611137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
611237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
61136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    MCSymbol *Sym = getContext().getOrCreateSymbol(SymbolName);
611437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
611537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveEnt(*Sym);
611637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CurrentFn = Sym;
6117f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsCpRestoreSet = false;
6118acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
6119acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
6120acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
6121801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".end") {
612237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    StringRef SymbolName;
612337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
612437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.parseIdentifier(SymbolName)) {
612537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected identifier after .end");
612637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
612737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
612837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
612937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
613037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected end of statement");
613137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
613237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
613337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
613437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (CurrentFn == nullptr) {
613537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError(".end used without .ent");
613637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
613737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
613837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
613937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if ((SymbolName != CurrentFn->getName())) {
614037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError(".end symbol does not match .ent symbol");
614137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
614237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
614337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
614437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitDirectiveEnd(SymbolName);
614537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    CurrentFn = nullptr;
6146f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsCpRestoreSet = false;
6147acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
6148acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
6149acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
6150801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".frame") {
615137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // .frame $stack_reg, frame_size_in_bytes, $return_reg
615237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    SmallVector<std::unique_ptr<MCParsedAsmOperand>, 1> TmpReg;
615337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    OperandMatchResultTy ResTy = parseAnyRegister(TmpReg);
615437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
615537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected stack register");
615637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
615737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
615837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
615937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MipsOperand &StackRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
616037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!StackRegOpnd.isGPRAsmReg()) {
616137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError(StackRegOpnd.getStartLoc(),
616237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       "expected general purpose register");
616337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
616437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
616537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    unsigned StackReg = StackRegOpnd.getGPR32Reg();
616637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
616737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.getTok().is(AsmToken::Comma))
616837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Parser.Lex();
616937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
617037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected comma");
617137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
617237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
617337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
617437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Parse the frame size.
617537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const MCExpr *FrameSize;
617637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int64_t FrameSizeVal;
617737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
617837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.parseExpression(FrameSize)) {
617937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected frame size value");
618037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
618137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
618237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
61836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!FrameSize->evaluateAsAbsolute(FrameSizeVal)) {
618437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("frame size not an absolute expression");
618537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
618637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
618737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
618837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.getTok().is(AsmToken::Comma))
618937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Parser.Lex();
619037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
619137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected comma");
619237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
619337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
619437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
619537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Parse the return register.
619637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    TmpReg.clear();
619737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    ResTy = parseAnyRegister(TmpReg);
619837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (ResTy == MatchOperand_NoMatch || ResTy == MatchOperand_ParseFail) {
619937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected return register");
620037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
620137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
620237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
620337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    MipsOperand &ReturnRegOpnd = static_cast<MipsOperand &>(*TmpReg[0]);
620437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!ReturnRegOpnd.isGPRAsmReg()) {
620537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError(ReturnRegOpnd.getStartLoc(),
620637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                       "expected general purpose register");
620737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
620837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
620937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
621037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this is not the end of the statement, report an error.
621137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
621237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected end of statement");
621337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
621437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
621537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
621637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    getTargetStreamer().emitFrame(StackReg, FrameSizeVal,
621737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                  ReturnRegOpnd.getGPR32Reg());
6218f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar    IsCpRestoreSet = false;
6219acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
6220acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
6221acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
6222801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".set") {
6223de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveSet();
6224de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6225acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
6226acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
622737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (IDVal == ".mask" || IDVal == ".fmask") {
622837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // .mask bitmask, frame_offset
622937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // bitmask: One bit for each register used.
623037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // frame_offset: Offset from Canonical Frame Address ($sp on entry) where
623137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //               first register is expected to be saved.
623237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Examples:
623337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //   .mask 0x80000000, -4
623437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //   .fmask 0x80000000, -4
623537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    //
6236acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
623737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Parse the bitmask
623837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const MCExpr *BitMask;
623937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int64_t BitMaskVal;
624037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
624137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.parseExpression(BitMask)) {
624237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected bitmask value");
624337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
624437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
624537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
62466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!BitMask->evaluateAsAbsolute(BitMaskVal)) {
624737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("bitmask not an absolute expression");
624837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
624937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
625037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
625137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.getTok().is(AsmToken::Comma))
625237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Parser.Lex();
625337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else {
625437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected comma");
625537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
625637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
625737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
625837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Parse the frame_offset
625937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    const MCExpr *FrameOffset;
626037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    int64_t FrameOffsetVal;
626137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
626237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Parser.parseExpression(FrameOffset)) {
626337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("expected frame offset value");
626437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
626537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
626637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
62676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (!FrameOffset->evaluateAsAbsolute(FrameOffsetVal)) {
626837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("frame offset not an absolute expression");
626937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
627037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
627137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
627237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // If this is not the end of the statement, report an error.
627337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (getLexer().isNot(AsmToken::EndOfStatement)) {
627437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      reportParseError("unexpected token, expected end of statement");
627537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return false;
627637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
627737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
627837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (IDVal == ".mask")
627937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      getTargetStreamer().emitMask(BitMaskVal, FrameOffsetVal);
628037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    else
628137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      getTargetStreamer().emitFMask(BitMaskVal, FrameOffsetVal);
6282acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
6283acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
6284acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
6285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (IDVal == ".nan")
6286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return parseDirectiveNaN();
6287dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
6288801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".gpword") {
62892263a2ca72e21206d45a69532004a0b17881e733Vladimir Medic    parseDirectiveGpWord();
6290acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter    return false;
6291acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter  }
6292acbea45573078631e116c2aa91e57d3a9cb2dde1Jack Carter
629336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".gpdword") {
629436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    parseDirectiveGpDWord();
629536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
629636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
629736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
6298801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  if (IDVal == ".word") {
629936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    parseDataDirective(4, DirectiveID.getLoc());
6300801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter    return false;
6301801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter  }
6302801c5838830d190a6b0d8e462bd43805f66ba50fJack Carter
6303de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".hword") {
6304de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDataDirective(2, DirectiveID.getLoc());
6305de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6306de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6307de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar
6308de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".option") {
6309de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveOption();
6310de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6311de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
631236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
631336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if (IDVal == ".abicalls") {
631436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    getTargetStreamer().emitDirectiveAbiCalls();
631536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    if (Parser.getTok().isNot(AsmToken::EndOfStatement)) {
631637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Error(Parser.getTok().getLoc(),
631737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            "unexpected token, expected end of statement");
631836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      // Clear line
631936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      Parser.eatToEndOfStatement();
632036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
632136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    return false;
632236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
6323a87a147ee7bb9adb4caea631ff0ba7e66bb9b0b5Bill Wendling
6324de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".cpsetup") {
6325de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveCPSetup();
6326de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6327de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6328de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".cpreturn") {
6329de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveCPReturn();
6330de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6331de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6332de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".module") {
6333de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseDirectiveModule();
6334de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6335de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6336de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".llvm_internal_mips_reallow_module_directive") {
6337de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseInternalDirectiveReallowModule();
6338de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6339de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6340de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".insn") {
6341de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseInsnDirective();
6342de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6343de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6344de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".sbss") {
6345de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseSSectionDirective(IDVal, ELF::SHT_NOBITS);
6346de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6347de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
6348de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  if (IDVal == ".sdata") {
6349de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    parseSSectionDirective(IDVal, ELF::SHT_PROGBITS);
6350de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    return false;
6351de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  }
63520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar
6353fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  return true;
6354fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
6355fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola
63564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarbool MipsAsmParser::parseInternalDirectiveReallowModule() {
63574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  // If this is not the end of the statement, report an error.
63584c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  if (getLexer().isNot(AsmToken::EndOfStatement)) {
63594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    reportParseError("unexpected token, expected end of statement");
63604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar    return false;
63614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  }
63624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
63634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  getTargetStreamer().reallowModuleDirective();
63644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
63654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  getParser().Lex(); // Eat EndOfStatement token.
63664c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar  return false;
63674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar}
63684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar
6369fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindolaextern "C" void LLVMInitializeMipsAsmParser() {
6370fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> X(TheMipsTarget);
6371fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> Y(TheMipselTarget);
6372fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> A(TheMips64Target);
6373fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola  RegisterMCAsmParser<MipsAsmParser> B(TheMips64elTarget);
6374fddf80459747198d2ee33974c90f6137ea29cbd8Rafael Espindola}
6375ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter
6376ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_REGISTER_MATCHER
6377ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#define GET_MATCHER_IMPLEMENTATION
6378ec65be84cd630d53233e7a37f0ef9d2303ac5153Jack Carter#include "MipsGenAsmMatcher.inc"
6379