131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- ARMDisassembler.cpp - Disassembler for ARM/Thumb ISA --------------===//
2b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen//
3b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen//                     The LLVM Compiler Infrastructure
4b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen//
5b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen// This file is distributed under the University of Illinois Open Source
6b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen// License. See LICENSE.TXT for details.
7b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen//
8b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen//===----------------------------------------------------------------------===//
9b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
10d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCDisassembler.h"
118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "MCTargetDesc/ARMAddressingModes.h"
128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "MCTargetDesc/ARMBaseInfo.h"
13d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMMCExpr.h"
148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "llvm/MC/MCContext.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h"
16fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/MC/MCFixedLenDisassembler.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInst.h"
18d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInstrDesc.h"
1975e3b7fb8fdf069b6f9f1e1db9634ca5701cbe96Dylan Noblesmith#include "llvm/MC/MCSubtargetInfo.h"
20b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#include "llvm/Support/Debug.h"
21b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#include "llvm/Support/ErrorHandling.h"
22fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/LEB128.h"
233e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
24b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#include "llvm/Support/raw_ostream.h"
25f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton#include <vector>
26b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
27c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloyusing namespace llvm;
28c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "arm-disassembler"
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
31a6804444e874b27aee5921d4c6049df573c5e249Owen Andersontypedef MCDisassembler::DecodeStatus DecodeStatus;
32a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson
33a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonnamespace {
34f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  // Handles the condition code status of instructions in IT blocks
35f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  class ITStatus
36f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  {
37f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    public:
38f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Returns the condition code for instruction in IT block
39f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      unsigned getITCC() {
40f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        unsigned CC = ARMCC::AL;
41f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        if (instrInITBlock())
42f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          CC = ITStates.back();
43f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        return CC;
44f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
45f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
46f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Advances the IT block state to the next T or E
47f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      void advanceITState() {
48f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        ITStates.pop_back();
49f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
50f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
51f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Returns true if the current instruction is in an IT block
52f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      bool instrInITBlock() {
53f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        return !ITStates.empty();
54f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
55f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
56f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Returns true if current instruction is the last instruction in an IT block
57f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      bool instrLastInITBlock() {
58f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        return ITStates.size() == 1;
59f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
60f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
61f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Called when decoding an IT instruction. Sets the IT state for the following
62f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // instructions that for the IT block. Firstcond and Mask correspond to the
63f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // fields in the IT instruction encoding.
64f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      void setITState(char Firstcond, char Mask) {
65f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        // (3 - the number of trailing zeros) is the number of then / else.
664d2f077df1b46a126b5595d983f233ec896b757eRichard Barton        unsigned CondBit0 = Firstcond & 1;
67c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer        unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
68f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
69f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        assert(NumTZ <= 3 && "Invalid IT mask!");
70f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        // push condition codes onto the stack the correct order for the pops
71f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
72f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          bool T = ((Mask >> Pos) & 1) == CondBit0;
73f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          if (T)
74f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton            ITStates.push_back(CCBits);
75f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          else
76f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton            ITStates.push_back(CCBits ^ 1);
77f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        }
78f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        ITStates.push_back(CCBits);
79f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
80f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
81f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    private:
82f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      std::vector<unsigned char> ITStates;
83f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  };
84f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton}
85f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
86f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Bartonnamespace {
8737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// ARM disassembler for all ARM platforms.
88a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonclass ARMDisassembler : public MCDisassembler {
89a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonpublic:
90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ARMDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MCDisassembler(STI, Ctx) {
92a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  }
93a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
942c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  ~ARMDisassembler() override {}
95a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              ArrayRef<uint8_t> Bytes, uint64_t Address,
9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              raw_ostream &VStream,
9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              raw_ostream &CStream) const override;
100a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson};
101a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines/// Thumb disassembler for all Thumb platforms.
103a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonclass ThumbDisassembler : public MCDisassembler {
104a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonpublic:
105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ThumbDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) :
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MCDisassembler(STI, Ctx) {
107a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  }
108a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
1092c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  ~ThumbDisassembler() override {}
110a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
11137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
11237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              ArrayRef<uint8_t> Bytes, uint64_t Address,
11337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              raw_ostream &VStream,
11437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                              raw_ostream &CStream) const override;
115a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
116a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonprivate:
117f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  mutable ITStatus ITBlock;
118d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson  DecodeStatus AddThumbPredicate(MCInst&) const;
119a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  void UpdateThumbVFPPredicate(MCInst&) const;
120a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson};
121a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson}
122a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
123a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
124c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  switch (In) {
125c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    case MCDisassembler::Success:
126c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      // Out stays the same.
127c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return true;
128c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    case MCDisassembler::SoftFail:
129c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      Out = In;
130c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return true;
131c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    case MCDisassembler::Fail:
132c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      Out = In;
133c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return false;
134c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  }
1354d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  llvm_unreachable("Invalid DecodeStatus!");
136c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy}
13783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
138a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy
1398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Forward declare these because the autogenerated code will reference them.
1408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Definitions are further down.
141c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
143c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
144c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                               unsigned RegNo, uint64_t Address,
145c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                               const void *Decoder);
146f86e436fb95670ed110818fefa403f21ae104639Mihai Popastatic DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
147f86e436fb95670ed110818fefa403f21ae104639Mihai Popa                                               unsigned RegNo, uint64_t Address,
148f86e436fb95670ed110818fefa403f21ae104639Mihai Popa                                               const void *Decoder);
149c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
151c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
153c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
1553862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuvillestatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
1563862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville                                   uint64_t Address, const void *Decoder);
157c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
159c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
1608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
161c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
163c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
164c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                unsigned RegNo,
165c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                uint64_t Address,
166c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                const void *Decoder);
167c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
1688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
169c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
17028f08c93e75d291695ea89b9004145103292e85bJim Grosbach                                   uint64_t Address, const void *Decoder);
171c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
172c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                               unsigned RegNo, uint64_t Address,
173c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                               const void *Decoder);
1748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
175c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
177c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
179c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
181c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
183c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
1858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
186c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
1878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
188c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
1898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
190c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
191c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                  unsigned Insn,
192c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                  uint64_t Address,
193c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                  const void *Decoder);
194c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
1958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
196c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
1978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
198c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
1998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
200c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
2018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
2028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
203c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
2048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                                  unsigned Insn,
2058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                                  uint64_t Adddress,
2068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                                  const void *Decoder);
207c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2089e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                               uint64_t Address, const void *Decoder);
209c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2109e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                               uint64_t Address, const void *Decoder);
211c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
213c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
21435008c2f8dcfe55960fe4efea3a26e526d437ad6Owen Anderson                               uint64_t Address, const void *Decoder);
2152c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainarstatic DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
2162c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                               uint64_t Address, const void *Decoder);
2172c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainarstatic DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
2182c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                               uint64_t Address, const void *Decoder);
219c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2206153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson                               uint64_t Address, const void *Decoder);
221c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
223c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
225c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
2272a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderbystatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2282a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                               uint64_t Address, const void *Decoder);
229c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
2308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
231c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
233aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
2348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
235aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
23630a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
237aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
23830a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
239aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
24030a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
241aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
24230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
243c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
2448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
245c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
2468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
247c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
2488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
249c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
2508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
251c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
2528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
253c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
2548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
255c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
2568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
257c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
2588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
259c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
2608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
261c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
2628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
263c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
2648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
265c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
2668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
267c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
2688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
269c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
2708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
271c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
272c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson                               uint64_t Address, const void *Decoder);
2734e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuvillestatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
2744e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville                               uint64_t Address, const void *Decoder);
275c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
27626d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson                               uint64_t Address, const void *Decoder);
27737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Insn,
27837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               uint64_t Address, const void *Decoder);
279c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
2803f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson                               uint64_t Address, const void *Decoder);
281c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
282cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson                               uint64_t Address, const void *Decoder);
283c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
2849ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                               uint64_t Address, const void *Decoder);
285c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
2869ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                               uint64_t Address, const void *Decoder);
287c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
2887cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                               uint64_t Address, const void *Decoder);
289c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
2907cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                               uint64_t Address, const void *Decoder);
291c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
2927a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
293c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
2947a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
295c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
2967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
297c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
2987a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
299c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
3007a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
301c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
3027a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
303c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
3047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
305c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
3067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
307c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
308357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                               uint64_t Address, const void *Decoder);
309c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
310357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                               uint64_t Address, const void *Decoder);
311c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
312cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson                               uint64_t Address, const void *Decoder);
313c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
314b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder);
315c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
316b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder);
317b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
3188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
319c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
3208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
321c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
3228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
323c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
3248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
325c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
3268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
327c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
3288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
329c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
3308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
331c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
3328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
333c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
3348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
335c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
3368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
337c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
3388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
339ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
340ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
341ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
342ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
343ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
344ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
345ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
346ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
347c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
3488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
349c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
3508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
351c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
352b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                               uint64_t Address, const void *Decoder);
353c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
3548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
355c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
3568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
357c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
3588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
359c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
3608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
361c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
3628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
36346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuvillestatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
36446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville                                uint64_t Address, const void *Decoder);
365c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
3668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
367c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
3688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
369c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
3707f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach                                uint64_t Address, const void *Decoder);
371c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
3728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
373c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
3748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
375c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
3768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
377c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
3788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
379c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
380f44082091c5517a3275c57a8b58e36987c8227f0Owen Anderson                                uint64_t Address, const void *Decoder);
381c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
382a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                               uint64_t Address, const void *Decoder);
383c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
384a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                               uint64_t Address, const void *Decoder);
385c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
38608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson                                uint64_t Address, const void *Decoder);
387c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
388a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson                                uint64_t Address, const void *Decoder);
389c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
3900afa0094afdfe589f407feb76948f273b414b278Owen Anderson                                uint64_t Address, const void *Decoder);
3910afa0094afdfe589f407feb76948f273b414b278Owen Anderson
392c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
393b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga                                uint64_t Address, const void *Decoder);
394fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Barangastatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
395fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga                                uint64_t Address, const void *Decoder);
3968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "ARMGenDisassemblerTables.inc"
3979899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan
398dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic MCDisassembler *createARMDisassembler(const Target &T,
399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             const MCSubtargetInfo &STI,
400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                             MCContext &Ctx) {
401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return new ARMDisassembler(STI, Ctx);
4028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
4038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic MCDisassembler *createThumbDisassembler(const Target &T,
405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               const MCSubtargetInfo &STI,
406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                               MCContext &Ctx) {
407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return new ThumbDisassembler(STI, Ctx);
4088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
4098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
410ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines// Post-decoding checks
411ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic DecodeStatus checkDecodedInstruction(MCInst &MI, uint64_t &Size,
412ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            uint64_t Address, raw_ostream &OS,
413ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            raw_ostream &CS,
414ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            uint32_t Insn,
415ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines                                            DecodeStatus Result)
416ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines{
417ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  switch (MI.getOpcode()) {
418ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    case ARM::HVC: {
419ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // HVC is undefined if condition = 0xf otherwise upredictable
420ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      // if condition != 0xe
421ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      uint32_t Cond = (Insn >> 28) & 0xF;
422ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (Cond == 0xF)
423ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return MCDisassembler::Fail;
424ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      if (Cond != 0xE)
425ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines        return MCDisassembler::SoftFail;
426ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines      return Result;
427ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    }
428ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    default: return Result;
429ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  }
430ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines}
431ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines
432a6804444e874b27aee5921d4c6049df573c5e249Owen AndersonDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
43337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             ArrayRef<uint8_t> Bytes,
43437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             uint64_t Address, raw_ostream &OS,
43537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                             raw_ostream &CS) const {
43637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CommentStream = &CS;
4378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
438a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy  assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
43937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "Asked to disassemble an ARM instruction but Subtarget is in Thumb "
44037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines         "mode!");
441a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy
4428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // We want to read exactly 4 bytes of data.
44337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Bytes.size() < 4) {
44486ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer    Size = 0;
445c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
44686ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  }
4478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Encoded as a small-endian 32-bit word in the stream.
44937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Insn =
45037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      (Bytes[3] << 24) | (Bytes[2] << 16) | (Bytes[1] << 8) | (Bytes[0] << 0);
4518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Calling the auto-generated decoder function.
45337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DecodeStatus Result =
45437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableARM32, MI, Insn, Address, this, STI);
45537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
4568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
457ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines    return checkDecodedInstruction(MI, Size, Address, OS, CS, Insn, Result);
458b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
459b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
4608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // VFP and NEON instructions, similarly, are shared between ARM
4618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // and Thumb modes.
4628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
46337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = decodeInstruction(DecoderTableVFP32, MI, Insn, Address, this, STI);
46437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
4658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
46637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
4678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
4688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
47037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = decodeInstruction(DecoderTableVFPV832, MI, Insn, Address, this, STI);
47137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
4724ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly    Size = 4;
47337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
4744ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  }
4754ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly
4764ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  MI.clear();
47737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
47837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableNEONData32, MI, Insn, Address, this, STI);
47937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
4808533ebad6f6e407215497ca50771f323058f5576Owen Anderson    Size = 4;
4818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // Add a fake predicate operand, because we share these instruction
4828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // definitions with Thumb2 where these instructions are predicable.
483a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!DecodePredicateOperand(MI, 0xE, Address, this))
484a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
48537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
4868533ebad6f6e407215497ca50771f323058f5576Owen Anderson  }
4878533ebad6f6e407215497ca50771f323058f5576Owen Anderson
4888533ebad6f6e407215497ca50771f323058f5576Owen Anderson  MI.clear();
48937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, Insn, Address,
490fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             this, STI);
49137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
4928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
4938533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // Add a fake predicate operand, because we share these instruction
4948533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // definitions with Thumb2 where these instructions are predicable.
495a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!DecodePredicateOperand(MI, 0xE, Address, this))
496a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
49737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
4988533ebad6f6e407215497ca50771f323058f5576Owen Anderson  }
4998533ebad6f6e407215497ca50771f323058f5576Owen Anderson
5008533ebad6f6e407215497ca50771f323058f5576Owen Anderson  MI.clear();
50137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
50237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableNEONDup32, MI, Insn, Address, this, STI);
50337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
5048533ebad6f6e407215497ca50771f323058f5576Owen Anderson    Size = 4;
5058533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // Add a fake predicate operand, because we share these instruction
5068533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // definitions with Thumb2 where these instructions are predicable.
507a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!DecodePredicateOperand(MI, 0xE, Address, this))
508a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
50937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
5108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
5118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
51337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
51437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTablev8NEON32, MI, Insn, Address, this, STI);
51537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
51619c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    Size = 4;
51737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
51819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  }
5198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
52019c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  MI.clear();
52137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
52237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTablev8Crypto32, MI, Insn, Address, this, STI);
52337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
5245df37dab763ce377095389c4ea1cff88db369954Amara Emerson    Size = 4;
52537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
5265df37dab763ce377095389c4ea1cff88db369954Amara Emerson  }
5275df37dab763ce377095389c4ea1cff88db369954Amara Emerson
5285df37dab763ce377095389c4ea1cff88db369954Amara Emerson  MI.clear();
52986ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  Size = 0;
530c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Fail;
5318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
5328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonnamespace llvm {
5341a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
5368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5379e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
5389e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// immediate Value in the MCInst.  The immediate Value has had any PC
5399e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// adjustment made by the caller.  If the instruction is a branch instruction
5409e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// then isBranch is true, else false.  If the getOpInfo() function was set as
5419e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// part of the setupForSymbolicDisassembly() call then that function is called
5429e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// to get any symbolic information at the Address for this instruction.  If
5439e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// that returns non-zero then the symbolic information it returns is used to
5449e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// create an MCExpr and that is added as an operand to the MCInst.  If
5459e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// getOpInfo() returns zero and isBranch is true then a symbol look up for
5469e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// Value is done and if a symbol is found an MCExpr is created with that, else
5479e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// an MCExpr with Value is created.  This function returns true if it adds an
5489e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// operand to the MCInst and false otherwise.
5499e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderbystatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
5509e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                     bool isBranch, uint64_t InstSize,
5519e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                     MCInst &MI, const void *Decoder) {
5529e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
5532c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  // FIXME: Does it make sense for value to be negative?
5542c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch,
5552c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha                                       /* Offset */ 0, InstSize);
5569e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
5579e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
5589e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
5599e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// referenced by a load instruction with the base register that is the Pc.
5609e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// These can often be values in a literal pool near the Address of the
5619e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// instruction.  The Address of the instruction and its immediate Value are
5629e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// used as a possible literal pool entry.  The SymbolLookUp call back will
563c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru/// return the name of a symbol referenced by the literal pool's entry if
5649e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// the referenced address is that of a symbol.  Or it will return a pointer to
5659e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// a literal 'C' string if the referenced address of the literal pool's entry
5669e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// is an address into a section with 'C' string literals.
5679e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderbystatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
568b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                            const void *Decoder) {
5699e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
5702c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  Dis->tryAddingPcLoadReferenceComment(Value, Address);
5719e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
5729e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
5738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Thumb1 instructions don't have explicit S bits.  Rather, they
5748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// implicitly set CPSR.  Since it's not represented in the encoding, the
5758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// auto-generated decoder won't inject the CPSR operand.  We need to fix
5768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// that as a post-pass.
5778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) {
5788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
5790aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
5808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MCInst::iterator I = MI.begin();
5810aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  for (unsigned i = 0; i < NumOps; ++i, ++I) {
5820aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    if (I == MI.end()) break;
5838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
5840aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson      if (i > 0 && OpInfo[i-1].isPredicate()) continue;
5858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
5868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      return;
587b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen    }
588b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
589b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
5900aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
5918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
5928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Most Thumb instructions don't have explicit predicates in the
5948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// encoding, but rather get their predicates from IT context.  We need
5958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// to fix up the predicate operands using this context information as a
5968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// post-pass.
597d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen AndersonMCDisassembler::DecodeStatus
598d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen AndersonThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
59951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  MCDisassembler::DecodeStatus S = Success;
60051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson
6018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // A few instructions actually have predicates encoded in them.  Don't
6028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // try to overwrite it if we're seeing one of those.
6038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (MI.getOpcode()) {
6048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::tBcc:
6058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2Bcc:
606d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    case ARM::tCBZ:
607d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    case ARM::tCBNZ:
6089f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::tCPS:
6099f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::t2CPS3p:
6109f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::t2CPS2p:
6119f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::t2CPS1p:
612d9346fbb06d64266c2fe46edef7a15cb9af7e7e8Owen Anderson    case ARM::tMOVSr:
613c18e940c5a1c050701594ee2b356cd40249505a3Owen Anderson    case ARM::tSETEND:
614441462f9328cc7fb86af74c9568a7f70b7bd1fbcOwen Anderson      // Some instructions (mostly conditional branches) are not
615441462f9328cc7fb86af74c9568a7f70b7bd1fbcOwen Anderson      // allowed in IT blocks.
616f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      if (ITBlock.instrInITBlock())
61751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        S = SoftFail;
61851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      else
61951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        return Success;
62051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      break;
62151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    case ARM::tB:
62251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    case ARM::t2B:
62304c7877894492d6e8aa45567988cd7de100589d8Owen Anderson    case ARM::t2TBB:
62404c7877894492d6e8aa45567988cd7de100589d8Owen Anderson    case ARM::t2TBH:
62551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      // Some instructions (mostly unconditional branches) can
62651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      // only appears at the end of, or outside of, an IT.
627f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
62851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        S = SoftFail;
629d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson      break;
630b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen    default:
6318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
632b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
633b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
6348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // If we're in an IT block, base the predicate on that.  Otherwise,
6358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // assume a predicate of AL.
6368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned CC;
637f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  CC = ITBlock.getITCC();
638f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  if (CC == 0xF)
6398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    CC = ARMCC::AL;
640f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  if (ITBlock.instrInITBlock())
641f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    ITBlock.advanceITState();
6428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
6438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
6440aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
6458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MCInst::iterator I = MI.begin();
6460aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  for (unsigned i = 0; i < NumOps; ++i, ++I) {
6470aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    if (I == MI.end()) break;
6488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (OpInfo[i].isPredicate()) {
6498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      I = MI.insert(I, MCOperand::CreateImm(CC));
6508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ++I;
6518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      if (CC == ARMCC::AL)
6528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        MI.insert(I, MCOperand::CreateReg(0));
6538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      else
6548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
65551f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      return S;
656b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen    }
6578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
658b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
6590aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  I = MI.insert(I, MCOperand::CreateImm(CC));
6600aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  ++I;
6618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (CC == ARMCC::AL)
6620aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    MI.insert(I, MCOperand::CreateReg(0));
6638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
6640aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
665d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson
66651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  return S;
6678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
6688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
6698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Thumb VFP instructions are a special case.  Because we share their
6708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// encodings between ARM and Thumb modes, and they are predicable in ARM
6718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// mode, the auto-generated decoder will give them an (incorrect)
6728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// predicate operand.  We need to rewrite these operands based on the IT
6738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// context as a post-pass.
6748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
6758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned CC;
676f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  CC = ITBlock.getITCC();
677f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  if (ITBlock.instrInITBlock())
678f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    ITBlock.advanceITState();
6798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
6808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
6818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MCInst::iterator I = MI.begin();
68212a1e3bbcbd4e8f740c8304379001d1e6731561cOwen Anderson  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
68312a1e3bbcbd4e8f740c8304379001d1e6731561cOwen Anderson  for (unsigned i = 0; i < NumOps; ++i, ++I) {
6848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (OpInfo[i].isPredicate() ) {
6858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      I->setImm(CC);
6868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ++I;
6878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      if (CC == ARMCC::AL)
6888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        I->setReg(0);
6898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      else
6908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        I->setReg(ARM::CPSR);
6918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      return;
692eca915fb5242442756a80bad7f285cb54d7b8ea4Johnny Chen    }
6938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
6948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
6958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
696a6804444e874b27aee5921d4c6049df573c5e249Owen AndersonDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
69737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                               ArrayRef<uint8_t> Bytes,
698c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                               uint64_t Address,
69937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                               raw_ostream &OS,
70037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                               raw_ostream &CS) const {
70137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  CommentStream = &CS;
7028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
703a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy  assert((STI.getFeatureBits() & ARM::ModeThumb) &&
704a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy         "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
705a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy
7068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // We want to read exactly 2 bytes of data.
70737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Bytes.size() < 2) {
70886ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer    Size = 0;
709c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
71086ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  }
711eca915fb5242442756a80bad7f285cb54d7b8ea4Johnny Chen
71237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint16_t Insn16 = (Bytes[1] << 8) | Bytes[0];
71337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DecodeStatus Result =
71437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableThumb16, MI, Insn16, Address, this, STI);
71537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
7168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 2;
71737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Check(Result, AddThumbPredicate(MI));
71837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
71916280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson  }
72016280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson
72116280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson  MI.clear();
72237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result = decodeInstruction(DecoderTableThumbSBit16, MI, Insn16, Address, this,
72337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                             STI);
72437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result) {
72516280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson    Size = 2;
726f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    bool InITBlock = ITBlock.instrInITBlock();
72737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Check(Result, AddThumbPredicate(MI));
7288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    AddThumb1SBit(MI, InITBlock);
72937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
7308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
73337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
73437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableThumb216, MI, Insn16, Address, this, STI);
73537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
7368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 2;
7377011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson
7387011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson    // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
7397011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson    // the Thumb predicate.
740f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
74137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Result = MCDisassembler::SoftFail;
7427011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson
74337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Check(Result, AddThumbPredicate(MI));
7448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // If we find an IT instruction, we need to parse its condition
7468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // code and mask operands so that we can apply them correctly
7478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // to the subsequent instructions.
7488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (MI.getOpcode() == ARM::t2IT) {
74934626acf7fb042c3a831e2f7dfb653ea79c7adecOwen Anderson
750f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      unsigned Firstcond = MI.getOperand(0).getImm();
751eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson      unsigned Mask = MI.getOperand(1).getImm();
752f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      ITBlock.setITState(Firstcond, Mask);
753eca915fb5242442756a80bad7f285cb54d7b8ea4Johnny Chen    }
754b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
75537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
7568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // We want to read exactly 4 bytes of data.
75937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Bytes.size() < 4) {
76086ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer    Size = 0;
761c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
76286ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  }
7638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
76437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t Insn32 =
76537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      (Bytes[3] << 8) | (Bytes[2] << 0) | (Bytes[1] << 24) | (Bytes[0] << 16);
7668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
76737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
76837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableThumb32, MI, Insn32, Address, this, STI);
76937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
7708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
771f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    bool InITBlock = ITBlock.instrInITBlock();
77237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Check(Result, AddThumbPredicate(MI));
7738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    AddThumb1SBit(MI, InITBlock);
77437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
7758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
77837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
77937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableThumb232, MI, Insn32, Address, this, STI);
78037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
7818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
78237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Check(Result, AddThumbPredicate(MI));
78337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
7848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
78637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
787ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    MI.clear();
78837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result =
78937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        decodeInstruction(DecoderTableVFP32, MI, Insn32, Address, this, STI);
79037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Result != MCDisassembler::Fail) {
791ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      Size = 4;
792ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      UpdateThumbVFPPredicate(MI);
79337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return Result;
794ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    }
7958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
796b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
7974ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  MI.clear();
79837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result =
79937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      decodeInstruction(DecoderTableVFPV832, MI, Insn32, Address, this, STI);
80037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (Result != MCDisassembler::Fail) {
8014ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly    Size = 4;
80237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return Result;
8034ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  }
8044ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly
80537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (fieldFromInstruction(Insn32, 28, 4) == 0xE) {
806ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    MI.clear();
80737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = decodeInstruction(DecoderTableNEONDup32, MI, Insn32, Address, this,
80837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                               STI);
80937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Result != MCDisassembler::Fail) {
810ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      Size = 4;
81137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Check(Result, AddThumbPredicate(MI));
81237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return Result;
813ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    }
814ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson  }
815ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson
81637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (fieldFromInstruction(Insn32, 24, 8) == 0xF9) {
817ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    MI.clear();
81837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t NEONLdStInsn = Insn32;
819ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    NEONLdStInsn &= 0xF0FFFFFF;
820ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    NEONLdStInsn |= 0x04000000;
82137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
822fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                               Address, this, STI);
82337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Result != MCDisassembler::Fail) {
824ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson      Size = 4;
82537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Check(Result, AddThumbPredicate(MI));
82637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return Result;
827ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    }
828ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson  }
829ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson
83037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (fieldFromInstruction(Insn32, 24, 4) == 0xF) {
831ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    MI.clear();
83237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t NEONDataInsn = Insn32;
8338533ebad6f6e407215497ca50771f323058f5576Owen Anderson    NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
8348533ebad6f6e407215497ca50771f323058f5576Owen Anderson    NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
8358533ebad6f6e407215497ca50771f323058f5576Owen Anderson    NEONDataInsn |= 0x12000000; // Set bits 28 and 25
83637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
837fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                               Address, this, STI);
83837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Result != MCDisassembler::Fail) {
8398533ebad6f6e407215497ca50771f323058f5576Owen Anderson      Size = 4;
84037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Check(Result, AddThumbPredicate(MI));
84137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return Result;
8428533ebad6f6e407215497ca50771f323058f5576Owen Anderson    }
8438533ebad6f6e407215497ca50771f323058f5576Owen Anderson
8443f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    MI.clear();
84537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t NEONCryptoInsn = Insn32;
8463f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    NEONCryptoInsn &= 0xF0FFFFFF; // Clear bits 27-24
8473f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    NEONCryptoInsn |= (NEONCryptoInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
8483f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    NEONCryptoInsn |= 0x12000000; // Set bits 28 and 25
84937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = decodeInstruction(DecoderTablev8Crypto32, MI, NEONCryptoInsn,
8503f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov                               Address, this, STI);
85137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Result != MCDisassembler::Fail) {
8523f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov      Size = 4;
85337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return Result;
8543f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    }
8555df37dab763ce377095389c4ea1cff88db369954Amara Emerson
8563f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    MI.clear();
85737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    uint32_t NEONv8Insn = Insn32;
8583f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
85937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    Result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
8603f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov                               this, STI);
86137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Result != MCDisassembler::Fail) {
8623f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov      Size = 4;
86337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return Result;
8643f04b5068619ca0411521c9871f4bfc6b04f951fArtyom Skrobov    }
86519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  }
86619c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly
86719c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  MI.clear();
86886ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  Size = 0;
869c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Fail;
870b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
871b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
872b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
8738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonextern "C" void LLVMInitializeARMDisassembler() {
87436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetRegistry::RegisterMCDisassembler(TheARMLETarget,
8758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                         createARMDisassembler);
87636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetRegistry::RegisterMCDisassembler(TheARMBETarget,
87736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         createARMDisassembler);
87836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetRegistry::RegisterMCDisassembler(TheThumbLETarget,
87936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines                                         createThumbDisassembler);
88036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  TargetRegistry::RegisterMCDisassembler(TheThumbBETarget,
8818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                         createThumbDisassembler);
8828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
883b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
884b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t GPRDecoderTable[] = {
8858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R0, ARM::R1, ARM::R2, ARM::R3,
8868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R4, ARM::R5, ARM::R6, ARM::R7,
8878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R8, ARM::R9, ARM::R10, ARM::R11,
8888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R12, ARM::SP, ARM::LR, ARM::PC
8898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
8908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
891c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
8928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
8938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 15)
894c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
895b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
8968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = GPRDecoderTable[RegNo];
8978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
898c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
8998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
9008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
901a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
902c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
903c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
9045c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  DecodeStatus S = MCDisassembler::Success;
9055c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga
9065c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  if (RegNo == 15)
9075c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga    S = MCDisassembler::SoftFail;
9085c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga
9095c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
9105c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga
9115c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  return S;
91251c9805c4bcca635bc6a854e4a246ebd4258f512Owen Anderson}
91351c9805c4bcca635bc6a854e4a246ebd4258f512Owen Anderson
914f86e436fb95670ed110818fefa403f21ae104639Mihai Popastatic DecodeStatus
915f86e436fb95670ed110818fefa403f21ae104639Mihai PopaDecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
916f86e436fb95670ed110818fefa403f21ae104639Mihai Popa                               uint64_t Address, const void *Decoder) {
917f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  DecodeStatus S = MCDisassembler::Success;
918f86e436fb95670ed110818fefa403f21ae104639Mihai Popa
919f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  if (RegNo == 15)
920f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  {
921f86e436fb95670ed110818fefa403f21ae104639Mihai Popa    Inst.addOperand(MCOperand::CreateReg(ARM::APSR_NZCV));
922f86e436fb95670ed110818fefa403f21ae104639Mihai Popa    return MCDisassembler::Success;
923f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  }
924f86e436fb95670ed110818fefa403f21ae104639Mihai Popa
925f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
926f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  return S;
927f86e436fb95670ed110818fefa403f21ae104639Mihai Popa}
928f86e436fb95670ed110818fefa403f21ae104639Mihai Popa
929c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
9318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 7)
932c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
9338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
9348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
9358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
9363862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuvillestatic const uint16_t GPRPairDecoderTable[] = {
9373862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
9383862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
9393862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville};
9403862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9413862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuvillestatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
9423862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
9433862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
9443862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9453862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (RegNo > 13)
9463862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville    return MCDisassembler::Fail;
9473862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9483862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if ((RegNo & 1) || RegNo == 0xe)
9493862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville     S = MCDisassembler::SoftFail;
9503862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9513862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
9523862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  Inst.addOperand(MCOperand::CreateReg(RegisterPair));
9533862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  return S;
9543862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville}
9553862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
956c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
9588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = 0;
9598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (RegNo) {
9608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
9618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R0;
9628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
9648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R1;
9658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
9678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R2;
9688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
9708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R3;
9718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 9:
9738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R9;
9748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 12:
9768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R12;
9778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
979c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
9808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
981b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
9828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
983c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
9848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
9858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
986c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
98807c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
98907c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  if (RegNo == 13 || RegNo == 15)
99007c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville    S = MCDisassembler::SoftFail;
99107c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
99207c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  return S;
9938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
994bd3327654b5708f1ba92aff3ab25b1bbf5034797Kevin Enderby
995b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t SPRDecoderTable[] = {
9968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
9978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
9988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
9998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S12, ARM::S13, ARM::S14, ARM::S15,
10008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S16, ARM::S17, ARM::S18, ARM::S19,
10018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S20, ARM::S21, ARM::S22, ARM::S23,
10028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S24, ARM::S25, ARM::S26, ARM::S27,
10038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S28, ARM::S29, ARM::S30, ARM::S31
10048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
10058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1006c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
10078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
10088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 31)
1009c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
1010b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
10118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = SPRDecoderTable[RegNo];
10128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
1013c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
1014b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1015b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1016b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t DPRDecoderTable[] = {
10178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
10188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
10198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
10208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D12, ARM::D13, ARM::D14, ARM::D15,
10218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D16, ARM::D17, ARM::D18, ARM::D19,
10228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D20, ARM::D21, ARM::D22, ARM::D23,
10238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D24, ARM::D25, ARM::D26, ARM::D27,
10248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D28, ARM::D29, ARM::D30, ARM::D31
10258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
10268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1027c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
10288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
102937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
103037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          .getFeatureBits();
103137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasD16 = featureBits & ARM::FeatureD16;
103237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
103337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (RegNo > 31 || (hasD16 && RegNo > 15))
1034c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
1035b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
10368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = DPRDecoderTable[RegNo];
10378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
1038c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
10398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
10408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1041c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
10428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
10438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 7)
1044c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
10468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
1047b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1048a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
1049c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
1050c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                            uint64_t Address, const void *Decoder) {
10518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 15)
1052c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
10548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
1055b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1056b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t QPRDecoderTable[] = {
10578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
10588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
10598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
10608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
10618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
1062af5b0e851e42d7de1247c4084ba75a76c4497ca6Johnny Chen
1063bd3327654b5708f1ba92aff3ab25b1bbf5034797Kevin Enderby
1064c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
10658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
1066bac932e9c3c4305a3c73598f3d0dc55de53d4c68Mihai Popa  if (RegNo > 31 || (RegNo & 1) != 0)
1067c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  RegNo >>= 1;
1069b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
10708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = QPRDecoderTable[RegNo];
10718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
1072c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
1073b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1074b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1075b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t DPairDecoderTable[] = {
107628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
107728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
107828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
107928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
108028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
108128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q15
108228f08c93e75d291695ea89b9004145103292e85bJim Grosbach};
108328f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1084c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
108528f08c93e75d291695ea89b9004145103292e85bJim Grosbach                                   uint64_t Address, const void *Decoder) {
108628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  if (RegNo > 30)
108728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    return MCDisassembler::Fail;
108828f08c93e75d291695ea89b9004145103292e85bJim Grosbach
108928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  unsigned Register = DPairDecoderTable[RegNo];
109028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  Inst.addOperand(MCOperand::CreateReg(Register));
109128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  return MCDisassembler::Success;
109228f08c93e75d291695ea89b9004145103292e85bJim Grosbach}
109328f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1094b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t DPairSpacedDecoderTable[] = {
1095c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1096c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1097c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1098c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1099c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1100c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1101c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1102c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D28_D30, ARM::D29_D31
1103c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach};
1104c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1105c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1106c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                                                   unsigned RegNo,
1107c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                                                   uint64_t Address,
1108c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                                                   const void *Decoder) {
1109c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  if (RegNo > 29)
1110c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    return MCDisassembler::Fail;
1111c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1112c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  unsigned Register = DPairSpacedDecoderTable[RegNo];
1113c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(Register));
1114c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  return MCDisassembler::Success;
1115c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach}
1116c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1117c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
11188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
1119c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Val == 0xF) return MCDisassembler::Fail;
1120bd9091c18d85d6649763165c4951d7b5ff2e31a9Owen Anderson  // AL predicate is not allowed on Thumb1 branches.
1121bd9091c18d85d6649763165c4951d7b5ff2e31a9Owen Anderson  if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
1122c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
11238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
11248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Val == ARMCC::AL) {
11258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
11268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else
11278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1128c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
1129b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1130b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1131c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
11328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
11338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Val)
11348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
11358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
11368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
1137c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
11388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
11396bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen
1140c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
11418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
1142a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
11438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1144fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1145fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Val, 5, 2);
1146fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 7, 5);
11478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Register-immediate
1149a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1150a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
11518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
11538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (type) {
11548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
11558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsl;
11568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
11588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsr;
11598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
11618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::asr;
11628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
11648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::ror;
11658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11666bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen  }
11678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Shift == ARM_AM::ror && imm == 0)
11698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Shift = ARM_AM::rrx;
11708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Op = Shift | (imm << 3);
11728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Op));
11738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
117483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
11758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
11768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1177c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
11788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
1179a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
11808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1181fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1182fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Val, 5, 2);
1183fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rs = fieldFromInstruction(Val, 8, 4);
11848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Register-register
1186a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1187a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1188a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1189a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
11908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
11928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (type) {
11938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
11948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsl;
11958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
11978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsr;
11988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
12008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::asr;
12018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
12028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
12038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::ror;
12048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
12056bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen  }
12066bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen
12078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Shift));
12086bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen
120983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1210b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1211b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1212c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
12138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1214a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
121583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
121601b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  bool NeedDisjointWriteback = false;
121701b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  unsigned WritebackReg = 0;
1218921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson  switch (Inst.getOpcode()) {
121901b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  default:
122001b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover    break;
122101b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::LDMIA_UPD:
122201b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::LDMDB_UPD:
122301b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::LDMIB_UPD:
122401b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::LDMDA_UPD:
122501b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::t2LDMIA_UPD:
122601b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::t2LDMDB_UPD:
122701b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::t2STMIA_UPD:
122801b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover  case ARM::t2STMDB_UPD:
122901b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover    NeedDisjointWriteback = true;
123001b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover    WritebackReg = Inst.getOperand(0).getReg();
123101b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover    break;
1232921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson  }
1233921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson
123426d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson  // Empty register lists are not allowed.
12354dc8bdf87d402ad8c91d9a72777d9576c5461e40Benjamin Kramer  if (Val == 0) return MCDisassembler::Fail;
12368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  for (unsigned i = 0; i < 16; ++i) {
1237ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson    if (Val & (1 << i)) {
1238a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1239a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
1240921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      // Writeback not allowed if Rn is in the target list.
124101b0e94bb731310e72f66977e4b57cd3f3280ba4Tim Northover      if (NeedDisjointWriteback && WritebackReg == Inst.end()[-1].getReg())
1242921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson        Check(S, MCDisassembler::SoftFail);
1243ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson    }
1244b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
12458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
124683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1247b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1248b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1249c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
12508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1251a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
125283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1253fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1254fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned regs = fieldFromInstruction(Val, 0, 8);
12558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1256242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  // In case of unpredictable encoding, tweak the operands.
1257242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  if (regs == 0 || (Vd + regs) > 32) {
1258242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = Vd + regs > 32 ? 32 - Vd : regs;
1259242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = std::max( 1u, regs);
1260242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    S = MCDisassembler::SoftFail;
1261242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  }
1262242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover
1263a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1264a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1265ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  for (unsigned i = 0; i < (regs - 1); ++i) {
1266a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1267a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
1268ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
12698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
127083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1271b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1272b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1273c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
12748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1275a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
127683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1277fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1278242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  unsigned regs = fieldFromInstruction(Val, 1, 7);
1279b422d0b65e15435b6aef4a92f5663db9ec6659d4Silviu Baranga
1280242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  // In case of unpredictable encoding, tweak the operands.
1281242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1282242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = Vd + regs > 32 ? 32 - Vd : regs;
1283242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = std::max( 1u, regs);
1284242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = std::min(16u, regs);
1285242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    S = MCDisassembler::SoftFail;
1286242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  }
12878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1288a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1289a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
1290ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  for (unsigned i = 0; i < (regs - 1); ++i) {
1291a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1292a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
1293ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
12948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
129583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1296b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1297b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1298c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
12998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                      uint64_t Address, const void *Decoder) {
130010cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // This operand encodes a mask of contiguous zeros between a specified MSB
130110cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
130210cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // the mask of all bits LSB-and-lower, and then xor them to create
1303c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach  // the mask of that's all ones on [msb, lsb].  Finally we not it to
130410cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // create the final mask.
1305fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned msb = fieldFromInstruction(Val, 5, 5);
1306fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned lsb = fieldFromInstruction(Val, 0, 5);
130789db0f690c3238544e59ea3bf2b7a0d6bc8a6544Owen Anderson
1308cb775519279cd1471c490eb5bf4e3ce663fcdc7dOwen Anderson  DecodeStatus S = MCDisassembler::Success;
13091c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby  if (lsb > msb) {
13101c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    Check(S, MCDisassembler::SoftFail);
13111c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    // The check above will cause the warning for the "potentially undefined
13121c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    // instruction encoding" but we can't build a bad MCOperand value here
13131c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    // with a lsb > msb or else printing the MCInst will cause a crash.
13141c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    lsb = msb;
13151c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby  }
1316cb775519279cd1471c490eb5bf4e3ce663fcdc7dOwen Anderson
13178b22778431cdeb112366ed5dc6283b3a7af19018Owen Anderson  uint32_t msb_mask = 0xFFFFFFFF;
13188b22778431cdeb112366ed5dc6283b3a7af19018Owen Anderson  if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
13198b22778431cdeb112366ed5dc6283b3a7af19018Owen Anderson  uint32_t lsb_mask = (1U << lsb) - 1;
132089db0f690c3238544e59ea3bf2b7a0d6bc8a6544Owen Anderson
13218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
1322cb775519279cd1471c490eb5bf4e3ce663fcdc7dOwen Anderson  return S;
1323b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1324b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1325c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
13268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
1327a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
132883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1329fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1330fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned CRd = fieldFromInstruction(Insn, 12, 4);
1331fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned coproc = fieldFromInstruction(Insn, 8, 4);
1332fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 8);
1333fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1334fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Insn, 23, 1);
13358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
13368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
13378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OFFSET:
13388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_PRE:
13398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_POST:
13408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OPTION:
13418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OFFSET:
13428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_PRE:
13438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_POST:
13448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OPTION:
13458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OFFSET:
13468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_PRE:
13478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_POST:
13488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OPTION:
13498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OFFSET:
13508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_PRE:
13518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_POST:
13528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OPTION:
13538a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_OFFSET:
13548a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_PRE:
13558a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_POST:
13568a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_OPTION:
13578a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_OFFSET:
13588a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_PRE:
13598a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_POST:
13608a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_OPTION:
13618a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_OFFSET:
13628a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_PRE:
13638a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_POST:
13648a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_OPTION:
13658a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_OFFSET:
13668a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_PRE:
13678a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_POST:
13688a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_OPTION:
13698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      if (coproc == 0xA || coproc == 0xB)
1370c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail;
13718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
13728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
13738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
13748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
13758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1376fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
1377fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov                                                          .getFeatureBits();
1378fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov  if ((featureBits & ARM::HasV8Ops) && (coproc != 14))
1379fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov    return MCDisassembler::Fail;
1380fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov
13818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(coproc));
13828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(CRd));
1383a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1384a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
13858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
13868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
1387c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2_OFFSET:
1388c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2L_OFFSET:
1389c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2_PRE:
1390c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2L_PRE:
1391c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2_OFFSET:
1392c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2L_OFFSET:
1393c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2_PRE:
1394c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2L_PRE:
1395c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2_OFFSET:
1396c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2L_OFFSET:
1397c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2_PRE:
1398c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2L_PRE:
1399c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2_OFFSET:
1400c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2L_OFFSET:
1401c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2_PRE:
1402c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2L_PRE:
1403c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC_OFFSET:
1404c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDCL_OFFSET:
1405c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC_PRE:
1406c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDCL_PRE:
1407c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC_OFFSET:
1408c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STCL_OFFSET:
1409c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC_PRE:
1410c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STCL_PRE:
1411c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC_OFFSET:
1412c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDCL_OFFSET:
1413c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC_PRE:
1414c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDCL_PRE:
1415c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC_OFFSET:
1416c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STCL_OFFSET:
1417c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC_PRE:
1418c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STCL_PRE:
141981b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach      imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
142081b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach      Inst.addOperand(MCOperand::CreateImm(imm));
142181b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach      break;
142281b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDC2_POST:
142381b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDC2L_POST:
142481b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STC2_POST:
142581b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STC2L_POST:
142681b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDC2_POST:
142781b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDC2L_POST:
142881b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::STC2_POST:
142981b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::STC2L_POST:
143081b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDC_POST:
143181b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDCL_POST:
143281b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STC_POST:
143381b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STCL_POST:
143481b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDC_POST:
143581b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDCL_POST:
1436c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC_POST:
1437c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STCL_POST:
14388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      imm |= U << 8;
1439c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      // fall through.
14408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
1441c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      // The 'option' variant doesn't encode 'U' in the immediate since
1442c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      // the immediate is unsigned [0,255].
1443c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(imm));
14448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
14468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
14488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OFFSET:
14498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_PRE:
14508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_POST:
14518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OPTION:
14528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OFFSET:
14538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_PRE:
14548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_POST:
14558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OPTION:
14568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OFFSET:
14578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_PRE:
14588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_POST:
14598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OPTION:
14608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OFFSET:
14618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_PRE:
14628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_POST:
14638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OPTION:
1464a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1465a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
14668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
14688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
14708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
147183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
14729899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan}
14739899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan
1474a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
1475c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
1476c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                              uint64_t Address, const void *Decoder) {
1477a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
147883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1479fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1480fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1481fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1482fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
1483fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1484fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned reg = fieldFromInstruction(Insn, 25, 1);
1485fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
1486fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
14878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // On stores, the writeback operand precedes Rt.
14898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
14908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STR_POST_IMM:
14918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STR_POST_REG:
1492508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::STRB_POST_IMM:
1493508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::STRB_POST_REG:
1494342ebd5f380637d965504dcc350f9d0d79bbe599Jim Grosbach    case ARM::STRT_POST_REG:
1495342ebd5f380637d965504dcc350f9d0d79bbe599Jim Grosbach    case ARM::STRT_POST_IMM:
149610348e70d567fb61f6c762d99e91e215c720ebd1Jim Grosbach    case ARM::STRBT_POST_REG:
149710348e70d567fb61f6c762d99e91e215c720ebd1Jim Grosbach    case ARM::STRBT_POST_IMM:
1498a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1499a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
15008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
15028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
15048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1505a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1506a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
15078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
15088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // On loads, the writeback operand comes after Rt.
15098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
15108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDR_POST_IMM:
15118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDR_POST_REG:
1512508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::LDRB_POST_IMM:
1513508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::LDRB_POST_REG:
15148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRBT_POST_REG:
15158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRBT_POST_IMM:
151659999264e6cfc7f5d59c9a92c8cd9baaa53434f4Jim Grosbach    case ARM::LDRT_POST_REG:
151759999264e6cfc7f5d59c9a92c8cd9baaa53434f4Jim Grosbach    case ARM::LDRT_POST_IMM:
1518a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1519a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
15208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
15228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
15248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1525a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1526a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
15278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
15288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM_AM::AddrOpc Op = ARM_AM::add;
1529fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  if (!fieldFromInstruction(Insn, 23, 1))
15308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Op = ARM_AM::sub;
15318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
15328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  bool writeback = (P == 0) || (W == 1);
15338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned idx_mode = 0;
15348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (P && writeback)
15358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    idx_mode = ARMII::IndexModePre;
15368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else if (!P && writeback)
15378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    idx_mode = ARMII::IndexModePost;
15388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1539a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (writeback && (Rn == 15 || Rn == Rt))
1540a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    S = MCDisassembler::SoftFail; // UNPREDICTABLE
154171156a6e00d3dc4c531a421a76b3b6ee0ae7d0abOwen Anderson
15428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (reg) {
1543a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1544a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
15458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1546fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    switch( fieldFromInstruction(Insn, 5, 2)) {
15478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 0:
15488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::lsl;
15498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 1:
15518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::lsr;
15528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 2:
15548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::asr;
15558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 3:
15578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::ror;
15588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      default:
1560c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail;
15618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
1562fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned amt = fieldFromInstruction(Insn, 7, 5);
156393c7c449a1351542fa5a275587187154dbedb8e0Tim Northover    if (Opc == ARM_AM::ror && amt == 0)
156493c7c449a1351542fa5a275587187154dbedb8e0Tim Northover      Opc = ARM_AM::rrx;
15658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
15668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
15678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imm));
15688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
15698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
15708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
15718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(tmp));
15728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
15738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1574a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1575a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
15768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
157783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
15788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
15798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1580c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
15818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
1582a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
158383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1584fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 13, 4);
1585fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val,  0, 4);
1586fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Val, 5, 2);
1587fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 7, 5);
1588fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Val, 12, 1);
15898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
159051157d22348fdbd4b7975877d5b58e53a6d5d3a2Owen Anderson  ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
15918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (type) {
15928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
15938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::lsl;
15948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
15968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::lsr;
15978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
15998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::asr;
16008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
16018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
16028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::ror;
16038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
16048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
16058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
160693c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  if (ShOp == ARM_AM::ror && imm == 0)
160793c7c449a1351542fa5a275587187154dbedb8e0Tim Northover    ShOp = ARM_AM::rrx;
160893c7c449a1351542fa5a275587187154dbedb8e0Tim Northover
1609a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1610a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1611a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1612a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
16138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned shift;
16148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (U)
16158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
16168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
16178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
16188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(shift));
16198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
162083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
16218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
16228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1623a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
1624c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
1625c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
1626a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
162783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1628fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1629fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1630fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1631fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Insn, 22, 1);
1632fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 8, 4);
1633fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
1634fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1635fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
1636fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
16376fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga  unsigned Rt2 = Rt + 1;
16388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
16398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  bool writeback = (W == 1) | (P == 0);
1640c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson
1641c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson  // For {LD,ST}RD, Rt must be even, else undefined.
1642c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson  switch (Inst.getOpcode()) {
1643c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::STRD:
1644c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::STRD_PRE:
1645c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::STRD_POST:
1646c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::LDRD:
1647c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::LDRD_PRE:
1648c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::LDRD_POST:
16496fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt & 0x1) S = MCDisassembler::SoftFail;
16506fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16516fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    default:
16526fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16536fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga  }
16546fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga  switch (Inst.getOpcode()) {
16556fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRD:
16566fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRD_PRE:
16576fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRD_POST:
16586fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (P == 0 && W == 1)
16596fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16606fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga
16616fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
16626fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16636fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rm == 15)
16646fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16656fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt2 == 15)
16666fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
1667fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (!type && fieldFromInstruction(Insn, 8, 4))
16686fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16696fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16706fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRH:
16716fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRH_PRE:
16726fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRH_POST:
16736fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt == 15)
16746fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16756fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (writeback && (Rn == 15 || Rn == Rt))
16766fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16776fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && Rm == 15)
16786fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16796fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16806fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRD:
16816fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRD_PRE:
16826fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRD_POST:
16836fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rn == 15){
16846fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        if (Rt2 == 15)
16856fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga          S = MCDisassembler::SoftFail;
16866fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        break;
16876fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      }
16886fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (P == 0 && W == 1)
16896fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16906fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
16916fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16926fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && writeback && Rn == 15)
16936fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16946fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (writeback && (Rn == Rt || Rn == Rt2))
16956fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16966fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16976fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRH:
16986fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRH_PRE:
16996fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRH_POST:
17006fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rn == 15){
17016fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        if (Rt == 15)
17026fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga          S = MCDisassembler::SoftFail;
17036fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        break;
17046fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      }
17056fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt == 15)
17066fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
17076fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && Rm == 15)
17086fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
17096fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && writeback && (Rn == 15 || Rn == Rt))
17106fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
17116fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
17126fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSH:
17136fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSH_PRE:
17146fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSH_POST:
17156fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSB:
17166fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSB_PRE:
17176fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSB_POST:
17186fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rn == 15){
17196fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        if (Rt == 15)
17206fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga          S = MCDisassembler::SoftFail;
17216fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        break;
17226fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      }
17236fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && (Rt == 15 || (writeback && Rn == Rt)))
17246fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
17256fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && (Rt == 15 || Rm == 15))
17266fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
17276fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && writeback && (Rn == 15 || Rn == Rt))
17286fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
1729c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson      break;
1730a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    default:
1731a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      break;
1732c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson  }
1733c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson
17348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (writeback) { // Writeback
17358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (P)
17368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      U |= ARMII::IndexModePre << 9;
17378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    else
17388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      U |= ARMII::IndexModePost << 9;
17398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
17408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // On stores, the writeback operand precedes Rt.
17418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
17428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD:
17438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_PRE:
17448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_POST:
174579628e92e1f903d50340d4cd3d1ea8c5fff63a87Owen Anderson    case ARM::STRH:
174679628e92e1f903d50340d4cd3d1ea8c5fff63a87Owen Anderson    case ARM::STRH_PRE:
174779628e92e1f903d50340d4cd3d1ea8c5fff63a87Owen Anderson    case ARM::STRH_POST:
1748a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1749a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
17508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
17528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
17548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1756a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1757a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
17588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
17598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD:
17608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_PRE:
17618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_POST:
17628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD:
17638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_PRE:
17648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_POST:
1765a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
1766a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
17678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
17698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
17728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (writeback) {
17738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // On loads, the writeback operand comes after Rt.
17748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
17758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD:
17768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_PRE:
17778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_POST:
17780d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRH:
17790d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRH_PRE:
17800d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRH_POST:
17810d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSH:
17820d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSH_PRE:
17830d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSH_POST:
17840d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSB:
17850d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSB_PRE:
17860d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSB_POST:
17878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRHTr:
17888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRSBTr:
1789a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1790a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
17918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
17938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
17958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1797a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1798a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
17998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
18008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (type) {
18018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
18028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
18038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
1804a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1805a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
18068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(U));
18078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
18088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1809a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1810a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
18118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
181283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
18138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
18148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1815c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
18168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1817a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
181883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1819fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1820fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mode = fieldFromInstruction(Insn, 23, 2);
18218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
18228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (mode) {
18238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
18248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::da;
18258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
18268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
18278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::ia;
18288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
18298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
18308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::db;
18318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
18328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
18338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::ib;
18348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
18358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
18368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
18378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(mode));
1838a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1839a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
18408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
184183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
18428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
18438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
184446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuvillestatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
184546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville                               uint64_t Address, const void *Decoder) {
184646e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
184746e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
184846e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
184946e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
185046e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
185146e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned pred = fieldFromInstruction(Insn, 28, 4);
185246e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
185346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (pred == 0xF)
185446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
185546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
185646e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
185746e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
185846e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
185946e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
186046e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
186146e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
186246e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
186346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
186446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  return S;
186546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville}
186646e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
1867c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
18688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  unsigned Insn,
18698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
1870a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
187183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1872fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1873fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1874fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned reglist = fieldFromInstruction(Insn, 0, 16);
18758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
18768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xF) {
1877ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville    // Ambiguous with RFE and SRS
18788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
1879846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDA:
18808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDA);
18818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1882846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDA_UPD:
18838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDA_UPD);
18848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1885846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDB:
18868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDB);
18878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1888846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDB_UPD:
18898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDB_UPD);
18908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1891846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIA:
18928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIA);
18938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1894846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIA_UPD:
18958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIA_UPD);
18968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1897846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIB:
18988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIB);
18998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1900846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIB_UPD:
19018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIB_UPD);
19028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1903846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDA:
1904846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDA);
1905846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1906846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDA_UPD:
1907846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDA_UPD);
1908846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1909846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDB:
1910846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDB);
1911846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1912846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDB_UPD:
1913846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDB_UPD);
1914846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1915846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIA:
1916846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIA);
1917846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1918846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIA_UPD:
1919846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIA_UPD);
1920846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1921846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIB:
1922846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIB);
1923846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1924846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIB_UPD:
1925846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIB_UPD);
1926846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1927846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      default:
1928ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville        return MCDisassembler::Fail;
19298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
1930846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson
1931846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson    // For stores (which become SRS's, the only operand is the mode.
1932fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    if (fieldFromInstruction(Insn, 20, 1) == 0) {
1933ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville      // Check SRS encoding constraints
1934ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville      if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
1935ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville            fieldFromInstruction(Insn, 20, 1) == 0))
1936ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville        return MCDisassembler::Fail;
1937ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville
1938846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      Inst.addOperand(
1939fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach          MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4)));
1940846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      return S;
1941846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson    }
1942846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson
19438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
19448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
19458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1946a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1947a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1948a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1949a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail; // Tied
1950a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1951a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1952a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
1953a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
19548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
195583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
19568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
19578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1958c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
19598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1960fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imod = fieldFromInstruction(Insn, 18, 2);
1961fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned M = fieldFromInstruction(Insn, 17, 1);
1962fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned iflags = fieldFromInstruction(Insn, 6, 3);
1963fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mode = fieldFromInstruction(Insn, 0, 5);
19648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1965a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
196614090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson
196746e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  // This decoder is called from multiple location that do not check
196846e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  // the full encoding is valid before they do.
196946e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (fieldFromInstruction(Insn, 5, 1) != 0 ||
197046e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville      fieldFromInstruction(Insn, 16, 1) != 0 ||
197146e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville      fieldFromInstruction(Insn, 20, 8) != 0x10)
197246e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
197346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
197435008c2f8dcfe55960fe4efea3a26e526d437ad6Owen Anderson  // imod == '01' --> UNPREDICTABLE
197514090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
197614090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  // return failure here.  The '01' imod value is unprintable, so there's
197714090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  // nothing useful we could do even if we returned UNPREDICTABLE.
197835008c2f8dcfe55960fe4efea3a26e526d437ad6Owen Anderson
1979c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (imod == 1) return MCDisassembler::Fail;
198014090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson
198114090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  if (imod && M) {
19828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::CPS3p);
19838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
19848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
19858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
198614090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  } else if (imod && !M) {
19878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::CPS2p);
19888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
19898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
1990c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (mode) S = MCDisassembler::SoftFail;
199114090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  } else if (!imod && M) {
19928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::CPS1p);
19938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
1994c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (iflags) S = MCDisassembler::SoftFail;
19951dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson  } else {
199614090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson    // imod == '00' && M == '0' --> UNPREDICTABLE
19971dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson    Inst.setOpcode(ARM::CPS1p);
19981dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
1999c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
20001dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson  }
20018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
200214090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  return S;
20038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
20048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2005c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
20066153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson                                 uint64_t Address, const void *Decoder) {
2007fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imod = fieldFromInstruction(Insn, 9, 2);
2008fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned M = fieldFromInstruction(Insn, 8, 1);
2009fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned iflags = fieldFromInstruction(Insn, 5, 3);
2010fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mode = fieldFromInstruction(Insn, 0, 5);
20116153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
2012a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
20136153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
20146153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // imod == '01' --> UNPREDICTABLE
20156153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
20166153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // return failure here.  The '01' imod value is unprintable, so there's
20176153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // nothing useful we could do even if we returned UNPREDICTABLE.
20186153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
2019c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (imod == 1) return MCDisassembler::Fail;
20206153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
20216153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  if (imod && M) {
20226153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.setOpcode(ARM::t2CPS3p);
20236153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
20246153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
20256153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
20266153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  } else if (imod && !M) {
20276153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.setOpcode(ARM::t2CPS2p);
20286153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
20296153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
2030c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (mode) S = MCDisassembler::SoftFail;
20316153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  } else if (!imod && M) {
20326153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.setOpcode(ARM::t2CPS1p);
20336153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
2034c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (iflags) S = MCDisassembler::SoftFail;
20356153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  } else {
20361ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    // imod == '00' && M == '0' --> this is a HINT instruction
20371ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    int imm = fieldFromInstruction(Insn, 0, 8);
20381ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    // HINT are defined only for immediate in [0..4]
20391ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    if(imm > 4) return MCDisassembler::Fail;
20401ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    Inst.setOpcode(ARM::t2HINT);
20411ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    Inst.addOperand(MCOperand::CreateImm(imm));
20426153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  }
20436153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
20446153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  return S;
20456153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson}
20466153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
2047c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
20489e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                 uint64_t Address, const void *Decoder) {
20499e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  DecodeStatus S = MCDisassembler::Success;
20509e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2051fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 8, 4);
20529e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  unsigned imm = 0;
20539e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2054fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
2055fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
2056fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2057fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
20589e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20599e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (Inst.getOpcode() == ARM::t2MOVTi16)
20609e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
20619e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby      return MCDisassembler::Fail;
20629e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
20639e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    return MCDisassembler::Fail;
20649e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20659e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
20669e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm));
20679e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20689e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  return S;
20699e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
20709e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2071c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
20729e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                 uint64_t Address, const void *Decoder) {
20739e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  DecodeStatus S = MCDisassembler::Success;
20749e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2075fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
20779e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  unsigned imm = 0;
20789e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
2080fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
20819e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20829e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (Inst.getOpcode() == ARM::MOVTi16)
20834521019c6fd23680c583abe086067fc1c569bad1Tim Northover    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
20849e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby      return MCDisassembler::Fail;
20854521019c6fd23680c583abe086067fc1c569bad1Tim Northover
20864521019c6fd23680c583abe086067fc1c569bad1Tim Northover  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
20879e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    return MCDisassembler::Fail;
20889e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20899e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
20909e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm));
20919e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20929e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
20939e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    return MCDisassembler::Fail;
20949e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20959e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  return S;
20969e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
20976153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
2098c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
20998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
2100a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
210183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 16, 4);
2103fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 0, 4);
2104fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 8, 4);
2105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Ra = fieldFromInstruction(Insn, 12, 4);
2106fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
21078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xF)
21098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
21108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2111a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2112a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2113a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2114a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2115a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2116a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2117a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
2118a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2120a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2121a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21221fb6673bc2f0a404f4f914bf381c627402ac7c6bOwen Anderson
212383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
21248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
21258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21262c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainarstatic DecodeStatus DecodeTSTInstruction(MCInst &Inst, unsigned Insn,
21272c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                                  uint64_t Address, const void *Decoder) {
21282c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  DecodeStatus S = MCDisassembler::Success;
21292c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21302c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  unsigned Pred = fieldFromInstruction(Insn, 28, 4);
21312c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
21322c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
21332c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21342c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if (Pred == 0xF)
21352c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    return DecodeSETPANInstruction(Inst, Insn, Address, Decoder);
21362c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21372c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
21382c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    return MCDisassembler::Fail;
21392c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
21402c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    return MCDisassembler::Fail;
21412c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if (!Check(S, DecodePredicateOperand(Inst, Pred, Address, Decoder)))
21422c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    return MCDisassembler::Fail;
21432c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21442c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  return S;
21452c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar}
21462c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21472c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainarstatic DecodeStatus DecodeSETPANInstruction(MCInst &Inst, unsigned Insn,
21482c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar                                  uint64_t Address, const void *Decoder) {
21492c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  DecodeStatus S = MCDisassembler::Success;
21502c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21512c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  unsigned Imm = fieldFromInstruction(Insn, 9, 1);
21522c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21532c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
21542c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  uint64_t FeatureBits = Dis->getSubtargetInfo().getFeatureBits();
21552c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if ((FeatureBits & ARM::HasV8_1aOps) == 0 ||
21562c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      (FeatureBits & ARM::HasV8Ops) == 0 )
21572c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    return MCDisassembler::Fail;
21582c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21592c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  // Decoder can be called from DecodeTST, which does not check the full
21602c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  // encoding is valid.
21612c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if (fieldFromInstruction(Insn, 20,12) != 0xf11 ||
21622c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      fieldFromInstruction(Insn, 4,4) != 0)
21632c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    return MCDisassembler::Fail;
21642c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  if (fieldFromInstruction(Insn, 10,10) != 0 ||
21652c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar      fieldFromInstruction(Insn, 0,4) != 0)
21662c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar    S = MCDisassembler::SoftFail;
21672c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21682c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  Inst.setOpcode(ARM::SETPAN);
21692c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  Inst.addOperand(MCOperand::CreateImm(Imm));
21702c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
21712c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar  return S;
21722c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar}
21732c3e0051c31c3f5b2328b447eadf1cf9c4427442Pirama Arumuga Nainar
2174c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
21758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                           uint64_t Address, const void *Decoder) {
2176a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
217783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2178fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned add = fieldFromInstruction(Val, 12, 1);
2179fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 12);
2180fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 13, 4);
21818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2182a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2183a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (!add) imm *= -1;
21868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (imm == 0 && !add) imm = INT32_MIN;
21878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
21889e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (Rn == 15)
21899e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
21908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
219183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
21928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
21938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2194c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
21958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
2196a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
219783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2198fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 9, 4);
2199fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Val, 8, 1);
2200fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 8);
22018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2202a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2203a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
22048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
22058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (U)
22068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
22078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
22088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
22098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
221083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
22118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
22128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2213c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
22148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
22158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
22168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
22178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2218a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
22192a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin EnderbyDecodeT2BInstruction(MCInst &Inst, unsigned Insn,
22202a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                     uint64_t Address, const void *Decoder) {
2221445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  DecodeStatus Status = MCDisassembler::Success;
2222445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby
2223445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // Note the J1 and J2 values are from the encoded instruction.  So here
2224445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // change them to I1 and I2 values via as documented:
2225445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // I1 = NOT(J1 EOR S);
2226445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // I2 = NOT(J2 EOR S);
2227445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // and build the imm32 with one trailing zero as documented:
2228445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2229445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned S = fieldFromInstruction(Insn, 26, 1);
2230445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned J1 = fieldFromInstruction(Insn, 13, 1);
2231445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned J2 = fieldFromInstruction(Insn, 11, 1);
2232445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned I1 = !(J1 ^ S);
2233445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned I2 = !(J2 ^ S);
2234445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
2235445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
2236445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
22378117ac555d06b23f61ddd06aa54d3dfa3e5b8e56Amaury de la Vieuville  int imm32 = SignExtend32<25>(tmp << 1);
2238445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
22392a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 4, Inst, Decoder))
2240445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm32));
2241445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby
2242445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  return Status;
22432a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby}
22442a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby
22452a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderbystatic DecodeStatus
2246c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2247c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
2248a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
224983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2250fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2251fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
22528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
22538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xF) {
22548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::BLXi);
2255fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    imm |= fieldFromInstruction(Insn, 24, 1) << 1;
2256b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2257b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                  true, 4, Inst, Decoder))
2258793b811c5057365d847b7f9ae326358e76facfe2Benjamin Kramer    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
225983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return S;
22608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
22618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2262b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2263b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                true, 4, Inst, Decoder))
22649e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2265a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2266a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
22678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
226883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
22698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
22708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
22718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2272c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
22738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
2274a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
227583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2276fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
2277fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Val, 4, 2);
22788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2279a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2280a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
22818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (!align)
22828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(0));
22838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
22848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(4 << align));
22858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
228683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
22878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
22888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2289c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
22908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
2291a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
229283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2293fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2294fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2295fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2296fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2297fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2298fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
22998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
23008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // First output register
230128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  switch (Inst.getOpcode()) {
2302c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2303c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2304c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2305c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2306c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2307c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2308c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2309c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2310c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
231128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
231228f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
231328f08c93e75d291695ea89b9004145103292e85bJim Grosbach    break;
2314c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b16:
2315c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b32:
2316c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b8:
2317c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b16wb_fixed:
2318c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b16wb_register:
2319c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b32wb_fixed:
2320c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b32wb_register:
2321c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b8wb_fixed:
2322c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b8wb_register:
2323c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2324c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      return MCDisassembler::Fail;
2325c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    break;
232628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  default:
232728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
232828f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
232928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
23308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
23318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Second output register
23328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
23338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8:
23348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16:
23358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32:
23368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8_UPD:
23378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16_UPD:
23388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32_UPD:
23398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8:
23408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16:
23418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32:
23428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
23438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
23448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
2345a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2346a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8:
23498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16:
23508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32:
23518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8_UPD:
23528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16_UPD:
23538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32_UPD:
23548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8:
23558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16:
23568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32:
23578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
23588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
23598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2360a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2361a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
23638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
23658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
23668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Third output register
23678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch(Inst.getOpcode()) {
23688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8:
23698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16:
23708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32:
23718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8_UPD:
23728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16_UPD:
23738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32_UPD:
23748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8:
23758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16:
23768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32:
23778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
23788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
23798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
2380a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2381a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8:
23848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16:
23858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32:
23868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8_UPD:
23878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16_UPD:
23888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32_UPD:
23898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8:
23908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16:
23918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32:
23928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
23938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
23948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2395a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2396a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
23998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
24018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
24028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Fourth output register
24038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
24048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8:
24058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16:
24068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32:
24078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
24088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
24098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
2410a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2411a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
24128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8:
24148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16:
24158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32:
24168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
24178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
24188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2419a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2420a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
24218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
24238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
24258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
24268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Writeback operand
24278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
242810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d8wb_fixed:
242910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d16wb_fixed:
243010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d32wb_fixed:
243110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d64wb_fixed:
243210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d8wb_register:
243310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d16wb_register:
243410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d32wb_register:
243510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d64wb_register:
243610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q8wb_fixed:
243710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q16wb_fixed:
243810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q32wb_fixed:
243910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q64wb_fixed:
244010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q8wb_register:
244110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q16wb_register:
244210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q32wb_register:
244310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q64wb_register:
24445921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d8Twb_fixed:
24455921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d8Twb_register:
24465921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d16Twb_fixed:
24475921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d16Twb_register:
24485921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d32Twb_fixed:
24495921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d32Twb_register:
24505921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d64Twb_fixed:
24515921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d64Twb_register:
2452399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d8Qwb_fixed:
2453399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d8Qwb_register:
2454399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d16Qwb_fixed:
2455399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d16Qwb_register:
2456399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d32Qwb_fixed:
2457399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d32Qwb_register:
2458399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d64Qwb_fixed:
2459399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d64Qwb_register:
2460a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d8wb_fixed:
2461a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d16wb_fixed:
2462a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d32wb_fixed:
2463a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8wb_fixed:
2464a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16wb_fixed:
2465a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32wb_fixed:
2466a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d8wb_register:
2467a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d16wb_register:
2468a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d32wb_register:
2469a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8wb_register:
2470a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16wb_register:
2471a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32wb_register:
2472a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b8wb_fixed:
2473a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b16wb_fixed:
2474a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b32wb_fixed:
2475a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b8wb_register:
2476a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b16wb_register:
2477a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b32wb_register:
2478a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby      Inst.addOperand(MCOperand::CreateImm(0));
2479a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby      break;
24808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8_UPD:
24818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16_UPD:
24828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32_UPD:
24838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8_UPD:
24848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16_UPD:
24858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32_UPD:
24868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
24878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
24888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
24898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
24908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
24918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2492a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2493a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
24948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
24968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
24988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
24998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Base (register+alignment)
2500a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2501a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
25028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
25038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Offset (register)
250410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  switch (Inst.getOpcode()) {
250510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  default:
250610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // The below have been updated to have explicit am6offset split
250710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // between fixed and register offset. For those instructions not
250810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // yet updated, we need to add an additional reg0 operand for the
250910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // fixed variant.
251010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    //
251110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // The fixed offset encodes as Rm == 0xd, so we check for that.
251210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    if (Rm == 0xd) {
251310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
251410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach      break;
251510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    }
251610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // Fall through to handle the register offset variant.
251710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d8wb_fixed:
251810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d16wb_fixed:
251910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d32wb_fixed:
252010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d64wb_fixed:
252104b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d8Twb_fixed:
252204b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d16Twb_fixed:
252304b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d32Twb_fixed:
252404b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d64Twb_fixed:
2525fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d8Qwb_fixed:
2526fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d16Qwb_fixed:
2527fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d32Qwb_fixed:
2528fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d64Qwb_fixed:
252910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d8wb_register:
253010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d16wb_register:
253110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d32wb_register:
253210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d64wb_register:
253310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q8wb_fixed:
253410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q16wb_fixed:
253510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q32wb_fixed:
253610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q64wb_fixed:
253710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q8wb_register:
253810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q16wb_register:
253910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q32wb_register:
254010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q64wb_register:
254110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
254210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // variant encodes Rm == 0xf. Anything else is a register offset post-
254310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // increment and we need to add the register operand to the instruction.
254410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    if (Rm != 0xD && Rm != 0xF &&
254510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach        !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2546a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
254710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    break;
2548a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2d8wb_fixed:
2549a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2d16wb_fixed:
2550a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2d32wb_fixed:
2551a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2b8wb_fixed:
2552a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2b16wb_fixed:
2553a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2b32wb_fixed:
2554a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2q8wb_fixed:
2555a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2q16wb_fixed:
2556a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2q32wb_fixed:
2557a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby    break;
2558ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
25598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
256083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
25618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
25628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2563aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
2564aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
256530a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned type = fieldFromInstruction(Insn, 8, 4);
256630a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned align = fieldFromInstruction(Insn, 4, 2);
2567aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 6 && (align & 2)) return MCDisassembler::Fail;
2568aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 7 && (align & 2)) return MCDisassembler::Fail;
2569aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 10 && align == 3) return MCDisassembler::Fail;
2570aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville
2571aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2572aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2573aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
257430a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
257530a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2576aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
2577aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
257830a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned size = fieldFromInstruction(Insn, 6, 2);
2579aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (size == 3) return MCDisassembler::Fail;
258030a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
258130a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned type = fieldFromInstruction(Insn, 8, 4);
258230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned align = fieldFromInstruction(Insn, 4, 2);
2583aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 8 && align == 3) return MCDisassembler::Fail;
2584aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 9 && align == 3) return MCDisassembler::Fail;
2585aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville
2586aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2587aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2588aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
258930a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
259030a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2591aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
2592aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
259330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned size = fieldFromInstruction(Insn, 6, 2);
2594aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (size == 3) return MCDisassembler::Fail;
259530a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
259630a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned align = fieldFromInstruction(Insn, 4, 2);
2597aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (align & 2) return MCDisassembler::Fail;
259830a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2599aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2600aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2601aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
260230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
260330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2604aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
2605aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
260630a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned size = fieldFromInstruction(Insn, 6, 2);
2607aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (size == 3) return MCDisassembler::Fail;
260830a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2609aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2610aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2611aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
261230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
261330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2614c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
26158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
2616a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
261783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2618fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2619fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2620fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2621fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2622fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2623fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
26248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
26258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Writeback Operand
26268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
26274334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d8wb_fixed:
26284334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d16wb_fixed:
26294334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d32wb_fixed:
26304334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d64wb_fixed:
26314334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d8wb_register:
26324334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d16wb_register:
26334334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d32wb_register:
26344334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d64wb_register:
26354334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q8wb_fixed:
26364334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q16wb_fixed:
26374334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q32wb_fixed:
26384334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q64wb_fixed:
26394334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q8wb_register:
26404334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q16wb_register:
26414334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q32wb_register:
26424334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q64wb_register:
2643d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d8Twb_fixed:
2644d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d16Twb_fixed:
2645d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d32Twb_fixed:
2646d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d64Twb_fixed:
2647d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d8Twb_register:
2648d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d16Twb_register:
2649d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d32Twb_register:
2650d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d64Twb_register:
26514c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d8Qwb_fixed:
26524c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d16Qwb_fixed:
26534c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d32Qwb_fixed:
26544c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d64Qwb_fixed:
26554c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d8Qwb_register:
26564c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d16Qwb_register:
26574c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d32Qwb_register:
26584c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d64Qwb_register:
2659bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d8wb_fixed:
2660bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d16wb_fixed:
2661bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d32wb_fixed:
2662bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d8wb_register:
2663bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d16wb_register:
2664bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d32wb_register:
2665bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q8wb_fixed:
2666bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q16wb_fixed:
2667bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q32wb_fixed:
2668bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q8wb_register:
2669bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q16wb_register:
2670bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q32wb_register:
2671bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b8wb_fixed:
2672bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b16wb_fixed:
2673bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b32wb_fixed:
2674bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b8wb_register:
2675bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b16wb_register:
2676bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b32wb_register:
2677b318cc16c9e959adb96294b3aa4940e74f68dde3Kevin Enderby      if (Rm == 0xF)
2678b318cc16c9e959adb96294b3aa4940e74f68dde3Kevin Enderby        return MCDisassembler::Fail;
2679f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby      Inst.addOperand(MCOperand::CreateImm(0));
2680f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby      break;
26818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8_UPD:
26828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16_UPD:
26838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32_UPD:
26848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8_UPD:
26858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16_UPD:
26868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32_UPD:
26878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
26888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
26898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
26908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
26918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
26928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2693a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2694a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
26958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
26968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
26978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
26988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
26998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
27008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Base (register+alignment)
2701a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2702a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
27038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
27048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Offset (register)
270560cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson  switch (Inst.getOpcode()) {
270660cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    default:
270760cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      if (Rm == 0xD)
270860cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson        Inst.addOperand(MCOperand::CreateReg(0));
270960cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      else if (Rm != 0xF) {
271060cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson        if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
271160cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson          return MCDisassembler::Fail;
271260cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      }
271360cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      break;
271460cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d8wb_fixed:
271560cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d16wb_fixed:
271660cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d32wb_fixed:
271760cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d64wb_fixed:
271860cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q8wb_fixed:
271960cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q16wb_fixed:
272060cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q32wb_fixed:
272160cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q64wb_fixed:
2722f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d8Twb_fixed:
2723f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d16Twb_fixed:
2724f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d32Twb_fixed:
2725f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d64Twb_fixed:
2726f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d8Qwb_fixed:
2727f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d16Qwb_fixed:
2728f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d32Qwb_fixed:
2729f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d64Qwb_fixed:
2730f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2d8wb_fixed:
2731f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2d16wb_fixed:
2732f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2d32wb_fixed:
2733f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2q8wb_fixed:
2734f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2q16wb_fixed:
2735f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2q32wb_fixed:
2736f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2b8wb_fixed:
2737f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2b16wb_fixed:
2738f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2b32wb_fixed:
273960cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      break;
2740ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
27418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
274260cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson
27438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // First input register
274428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  switch (Inst.getOpcode()) {
274528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q16:
274628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q32:
274728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64:
274828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q8:
274928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q16wb_fixed:
275028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q16wb_register:
275128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q32wb_fixed:
275228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q32wb_register:
275328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64wb_fixed:
275428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64wb_register:
275528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q8wb_fixed:
275628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q8wb_register:
275728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d16:
275828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d32:
275928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d8:
276028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d16wb_fixed:
276128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d16wb_register:
276228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d32wb_fixed:
276328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d32wb_register:
276428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d8wb_fixed:
276528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d8wb_register:
276628f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
276728f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
276828f08c93e75d291695ea89b9004145103292e85bJim Grosbach    break;
2769c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b16:
2770c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b32:
2771c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b8:
2772c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b16wb_fixed:
2773c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b16wb_register:
2774c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b32wb_fixed:
2775c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b32wb_register:
2776c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b8wb_fixed:
2777c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b8wb_register:
2778c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2779c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      return MCDisassembler::Fail;
2780c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    break;
278128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  default:
278228f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
278328f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
278428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
27858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
27868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Second input register
27878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
27888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8:
27898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16:
27908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32:
27918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8_UPD:
27928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16_UPD:
27938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32_UPD:
27948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8:
27958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16:
27968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32:
27978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
27988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
27998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
2800a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2801a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
28028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8:
28048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16:
28058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32:
28068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8_UPD:
28078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16_UPD:
28088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32_UPD:
28098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8:
28108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16:
28118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32:
28128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
28138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
28148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2815a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2816a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
28178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
28198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
28218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
28228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Third input register
28238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
28248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8:
28258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16:
28268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32:
28278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8_UPD:
28288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16_UPD:
28298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32_UPD:
28308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8:
28318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16:
28328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32:
28338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
28348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
28358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
2836a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2837a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
28388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8:
28408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16:
28418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32:
28428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8_UPD:
28438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16_UPD:
28448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32_UPD:
28458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8:
28468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16:
28478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32:
28488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
28498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
28508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2851a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2852a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
28538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
28558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
28578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
28588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Fourth input register
28598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
28608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8:
28618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16:
28628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32:
28638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
28648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
28658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
2866a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2867a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
28688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8:
28708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16:
28718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32:
28728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
28738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
28748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2875a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2876a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
28778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
28798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
28808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
28818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
288283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
28838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
28848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2885c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
28868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
2887a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
288883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2889fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2890fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2891fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2892fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2893fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Insn, 4, 1);
2894fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 6, 2);
28958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
289624b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover  if (size == 0 && align == 1)
289724b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover    return MCDisassembler::Fail;
28988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  align *= (1 << size);
28998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2900c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  switch (Inst.getOpcode()) {
2901c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
2902c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
2903c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
2904c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
2905c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2906c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2907c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
2908c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  default:
2909c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2910c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2911c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
2912c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  }
2913f1c8e3e70e222365b84f4cb7e87396ee85820711Owen Anderson  if (Rm != 0xF) {
2914a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2915a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2916ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
29178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2918a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2919a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
29208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
29218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2922096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2923096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  // variant encodes Rm == 0xf. Anything else is a register offset post-
2924096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  // increment and we need to add the register operand to the instruction.
2925096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  if (Rm != 0xD && Rm != 0xF &&
2926096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach      !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2927096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    return MCDisassembler::Fail;
29288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
292983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
29308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
29318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2932c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
29338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
2934a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
293583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2936fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2937fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2938fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2939fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2940fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Insn, 4, 1);
2941fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
29428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  align *= 2*size;
29438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2944c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  switch (Inst.getOpcode()) {
2945c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
2946c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
2947c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
2948c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
2949c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2950c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2951c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
29524d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
29534d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
29544d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
29554d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
29564d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
29574d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach      return MCDisassembler::Fail;
29584d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    break;
2959c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  default:
2960c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2961c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2962c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
2963c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  }
2964158c8a49c23d01297e7913c03c1fdb0760aee3a8Kevin Enderby
2965158c8a49c23d01297e7913c03c1fdb0760aee3a8Kevin Enderby  if (Rm != 0xF)
2966158c8a49c23d01297e7913c03c1fdb0760aee3a8Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(0));
29678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2968a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2969a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
29708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
29718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2972c5a2a33938182ccc5a1a94f7e1e2b3fdaff6a8b1Kevin Enderby  if (Rm != 0xD && Rm != 0xF) {
2973a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2974a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2975ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
29768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
297783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
29788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
29798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2980c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
29818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
2982a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
298383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2984fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2985fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2986fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2987fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2988fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
29898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2990a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2991a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2992a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2993a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2994a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2995a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2996f1c8e3e70e222365b84f4cb7e87396ee85820711Owen Anderson  if (Rm != 0xF) {
2997a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2998a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2999ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3001a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3002a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
30038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(0));
30048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Rm == 0xD)
30068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
3007ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  else if (Rm != 0xF) {
3008a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3009a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
3010ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
301283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
30138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3015c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Insn,
30168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
3017a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
301883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3019fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3020fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3021fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3022fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3023fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 6, 2);
3024fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
3025fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Insn, 4, 1);
30268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (size == 0x3) {
302824b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover    if (align == 0)
302924b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover      return MCDisassembler::Fail;
30308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    align = 16;
30318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
30328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (size == 2) {
30338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      align *= 8;
30348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    } else {
30358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      size = 1 << size;
30368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      align *= 4*size;
30378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
30388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
30398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3040a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3041a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3042a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
3043a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3044a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
3045a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3046a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
3047a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3048f1c8e3e70e222365b84f4cb7e87396ee85820711Owen Anderson  if (Rm != 0xF) {
3049a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3050a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
3051ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3053a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3054a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
30558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
30568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Rm == 0xD)
30588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
3059ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  else if (Rm != 0xF) {
3060a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3061a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
3062ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
306483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
30658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3067a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
3068c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn,
3069c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                            uint64_t Address, const void *Decoder) {
3070a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
307183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3072fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3073fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3074fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 4);
3075fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 3) << 4;
3076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 24, 1) << 7;
3077fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 8, 4) << 8;
3078fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 5, 1) << 12;
3079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Q = fieldFromInstruction(Insn, 6, 1);
30808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3081ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  if (Q) {
3082a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3083a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3084ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  } else {
3085a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3086a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3087ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
30908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
30928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv4i16:
30938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv2i32:
30948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv4i16:
30958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv2i32:
3096a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3097a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
30988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
30998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv8i16:
31008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv4i32:
31018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv8i16:
31028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv4i32:
3103a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3104a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
31058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
31068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
31078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
31088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
31098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
311083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3113c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
31148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                        uint64_t Address, const void *Decoder) {
3115a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
311683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3117fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3118fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3119fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3120fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3121fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 18, 2);
31228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3123a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3124a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3125a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3126a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
31278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(8 << size));
31288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
312983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3132c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
31338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
31348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(8 - Val));
3135c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3138c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
31398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
31408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(16 - Val));
3141c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3144c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
31458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
31468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(32 - Val));
3147c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3150c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
31518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
31528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(64 - Val));
3153c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3156c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
31578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
3158a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
315983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3160fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3161fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3162fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3163fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
3164fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3165fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3166fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned op = fieldFromInstruction(Insn, 6, 1);
31678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3168a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3169a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3170ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  if (op) {
3171a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3172a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail; // Writeback
3173ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
31748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
317528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  switch (Inst.getOpcode()) {
317628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VTBL2:
317728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VTBX2:
317828f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
317928f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
318028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    break;
318128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  default:
318228f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
318328f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
318428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
31858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3186a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3187a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
31888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
318983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3192c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
31938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                     uint64_t Address, const void *Decoder) {
3194a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
319583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3196fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned dst = fieldFromInstruction(Insn, 8, 3);
3197fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 8);
31988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3199a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
3200a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
32018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
320296425c846494c1c20a4c931f4783571295ab170cOwen Anderson  switch(Inst.getOpcode()) {
32031af7f7291d0689e2d58f900c9b5ecaddec56caa1Owen Anderson    default:
3204c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
320596425c846494c1c20a4c931f4783571295ab170cOwen Anderson    case ARM::tADR:
32069f7e8319947c65d9aef2a0f0984557c3b3a20656Owen Anderson      break; // tADR does not explicitly represent the PC as an operand.
320796425c846494c1c20a4c931f4783571295ab170cOwen Anderson    case ARM::tADDrSPi:
320896425c846494c1c20a4c931f4783571295ab170cOwen Anderson      Inst.addOperand(MCOperand::CreateReg(ARM::SP));
320996425c846494c1c20a4c931f4783571295ab170cOwen Anderson      break;
321096425c846494c1c20a4c931f4783571295ab170cOwen Anderson  }
32118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
32128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
321383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
32148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3216c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
32178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
32182a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
32192a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 2, Inst, Decoder))
32202a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
3221c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
32228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3224c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
32258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
32263610a15c3581dee713820f72d8ffe2e2a632b057Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
32272a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 4, Inst, Decoder))
32282a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
3229c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
32308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3232c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
32338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
3234ce888351106a72825e2a107cb08d7130f3dce0eeGordon Keiser  if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
32352a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 2, Inst, Decoder))
3236ce888351106a72825e2a107cb08d7130f3dce0eeGordon Keiser    Inst.addOperand(MCOperand::CreateImm(Val << 1));
3237c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
32388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3240c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
32418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
3242a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
324383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3244fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3245fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 3, 3);
32468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3247a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3248a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3249a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3250a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
32518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
325283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
32538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3255c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
32568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
3257a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
325883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3259fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3260fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 3, 5);
32618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3262a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3263a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
32648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
32658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
326683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
32678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3269c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
32708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
32719e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  unsigned imm = Val << 2;
32729e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
32739e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  Inst.addOperand(MCOperand::CreateImm(imm));
32749e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
32758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3276c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
32778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3279c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
32808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
32818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3282b113ec55e897c85fda606409c1eedec4f89ec53fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
32838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3284c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
32858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3287c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
32888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
3289a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
329083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3291fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 6, 4);
3292fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 2, 4);
3293fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 2);
32948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3295cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  // Thumb stores cannot use PC as dest register.
3296cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  switch (Inst.getOpcode()) {
3297cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHs:
3298cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBs:
3299cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRs:
3300cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    if (Rn == 15)
3301cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville      return MCDisassembler::Fail;
3302cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  default:
3303cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3304cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  }
3305cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville
3306a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3307a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3308a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3309a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
33108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
33118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
331283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
33138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
33148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3315c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
33168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                              uint64_t Address, const void *Decoder) {
3317a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
331883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3319ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3320fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3321ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
332237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
332337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          .getFeatureBits();
332437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasMP = featureBits & ARM::FeatureMP;
332537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasV7Ops = featureBits & ARM::HasV7Ops;
332637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
33270c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rn == 15) {
33288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
33290c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRBs:
33300c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
33310c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33320c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRHs:
33330c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
33340c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33350c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHs:
33360c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
33370c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33380c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSBs:
33390c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
33400c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33410c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRs:
33420c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
33430c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33440c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLDs:
33450c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDpci);
33460c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33470c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLIs:
33480c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLIpci);
33490c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33500c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
33510c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
33528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
33538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3354ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3355ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
33568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
33570c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
33580c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
33590c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHs:
33600c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
33610c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRHs:
33620c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDWs);
33630c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
336437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case ARM::t2LDRSBs:
336537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Inst.setOpcode(ARM::t2PLIs);
33660c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
33670c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33680c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
33690c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
33700c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
3371ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  switch (Inst.getOpcode()) {
3372ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2PLDs:
337337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
3374ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2PLIs:
337537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!hasV7Ops)
337637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MCDisassembler::Fail;
337737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
337837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case ARM::t2PLDWs:
337937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!hasV7Ops || !hasMP)
338037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MCDisassembler::Fail;
3381ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3382ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3383ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3384ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville        return MCDisassembler::Fail;
33858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
33868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3387fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
3388fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
3389fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
3390a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3391a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
33928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
339383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
33948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
33958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3396ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
3397ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3398ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3399ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3400ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3401ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3402ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned U = fieldFromInstruction(Insn, 9, 1);
3403ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3404ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (U << 8);
3405ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (Rn << 9);
340637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned add = fieldFromInstruction(Insn, 9, 1);
340737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
340837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
340937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          .getFeatureBits();
341037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasMP = featureBits & ARM::FeatureMP;
341137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasV7Ops = featureBits & ARM::HasV7Ops;
3412ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3413ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3414ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3415ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRi8:
3416ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3417ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3418ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRBi8:
3419ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3420ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3421ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSBi8:
3422ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
3423ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3424ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRHi8:
3425ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3426ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3427ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSHi8:
3428ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3429ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
34300c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLDi8:
34310c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDpci);
34320c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
34330c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLIi8:
34340c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLIpci);
34350c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
3436ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3437ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3438ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3439ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3440ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3441ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
34420c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
34430c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
34440c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHi8:
34450c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
344637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case ARM::t2LDRHi8:
344737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!add)
344837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        Inst.setOpcode(ARM::t2PLDWi8);
344937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
345037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case ARM::t2LDRSBi8:
345137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Inst.setOpcode(ARM::t2PLIi8);
345237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
34530c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
34540c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
34550c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
34560c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
34570c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
34580c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  switch (Inst.getOpcode()) {
34590c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLDi8:
346037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
34610c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLIi8:
346237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!hasV7Ops)
346337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::Fail;
34640c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    break;
346537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case ARM::t2PLDWi8:
346637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!hasV7Ops || !hasMP)
346737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MCDisassembler::Fail;
346837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
34690c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  default:
34700c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
34710c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
34720c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
34730c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
3474ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3475ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3476ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3477ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3478ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3479ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
3480ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3481ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3482ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3483ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3484ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3485ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3486ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (Rn << 13);
3487ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
348837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
348937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          .getFeatureBits();
349037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasMP = (featureBits & ARM::FeatureMP);
349137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasV7Ops = (featureBits & ARM::HasV7Ops);
349237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
3493ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3494ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3495ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRi12:
3496ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3497ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3498ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRHi12:
3499ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3500ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3501ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSHi12:
3502ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3503ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3504ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRBi12:
3505ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3506ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3507ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSBi12:
3508ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
3509ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
35100c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLDi12:
35110c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDpci);
35120c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
35130c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLIi12:
35140c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLIpci);
35150c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
3516ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3517ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3518ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3519ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3520ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3521ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
35220c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
35230c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
35240c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHi12:
35250c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
35260c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRHi12:
352737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Inst.setOpcode(ARM::t2PLDWi12);
352837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
352937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case ARM::t2LDRSBi12:
353037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      Inst.setOpcode(ARM::t2PLIi12);
35310c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
35320c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
35330c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
35340c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
35350c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
35360c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
35370c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  switch (Inst.getOpcode()) {
35380c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLDi12:
353937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
35400c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLIi12:
354137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!hasV7Ops)
354237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::Fail;
35430c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    break;
354437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  case ARM::t2PLDWi12:
354537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!hasV7Ops || !hasMP)
354637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MCDisassembler::Fail;
354737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
35480c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  default:
35490c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
35500c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
35510c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
35520c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
3553ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
3554ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3555ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3556ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3557ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3558ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
3559ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3560ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3561ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3562ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3563ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3564ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3565ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (Rn << 9);
3566ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3567ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3568ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3569ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRT:
3570ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3571ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3572ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRBT:
3573ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3574ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3575ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRHT:
3576ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3577ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3578ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSBT:
3579ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
3580ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3581ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSHT:
3582ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3583ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3584ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3585ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3586ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3587ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3588ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3589ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3590ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3591ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3592ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3593ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3594ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3595ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3596ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3597ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
3598ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3599ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3600ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3601ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3602ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned U = fieldFromInstruction(Insn, 23, 1);
3603ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  int imm = fieldFromInstruction(Insn, 0, 12);
3604ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
360537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
360637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          .getFeatureBits();
360737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  bool hasV7Ops = (featureBits & ARM::HasV7Ops);
360837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
36090c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
36100c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
36110c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRBpci:
36120c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRHpci:
36130c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2PLDpci);
36140c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        break;
36150c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRSBpci:
36160c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2PLIpci);
36170c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        break;
36180c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRSHpci:
36190c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        return MCDisassembler::Fail;
36200c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      default:
36210c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        break;
36220c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
36230c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
36240c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
36250c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  switch(Inst.getOpcode()) {
36260c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLDpci:
362737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    break;
36280c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLIpci:
362937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (!hasV7Ops)
363037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::Fail;
36310c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    break;
36320c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  default:
3633ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3634ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3635ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3636ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3637ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!U) {
3638ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    // Special case for #-0.
3639ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    if (imm == 0)
3640ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      imm = INT32_MIN;
3641ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    else
3642ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      imm = -imm;
3643ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3644ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  Inst.addOperand(MCOperand::CreateImm(imm));
3645ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3646ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3647ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3648ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3649c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
365010cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                           uint64_t Address, const void *Decoder) {
3651fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu  if (Val == 0)
3652fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    Inst.addOperand(MCOperand::CreateImm(INT32_MIN));
3653fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu  else {
3654fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    int imm = Val & 0xFF;
3655fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu
3656fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    if (!(Val & 0x100)) imm *= -1;
36571144af3c9b4da48cd581156e05b24261c8de366aRichard Smith    Inst.addOperand(MCOperand::CreateImm(imm * 4));
3658fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu  }
36598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3660c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
36618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
36628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3663c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
36648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
3665a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
366683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3667fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 9, 4);
3668fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 9);
36698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3670a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3671a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3672a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
3673a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
36748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
367583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
36768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
36778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3678c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
3679b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                                   uint64_t Address, const void *Decoder) {
3680b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  DecodeStatus S = MCDisassembler::Success;
3681b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3682fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 8, 4);
3683fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 8);
3684b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3685b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
3686b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return MCDisassembler::Fail;
3687b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3688b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(imm));
3689b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3690b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  return S;
3691b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach}
3692b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3693c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
369410cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                         uint64_t Address, const void *Decoder) {
36958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  int imm = Val & 0xFF;
3696705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson  if (Val == 0)
3697705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson    imm = INT32_MIN;
3698705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson  else if (!(Val & 0x100))
3699705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson    imm *= -1;
37008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
37018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3702c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
37038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
37058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3706c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
370710cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                 uint64_t Address, const void *Decoder) {
3708a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
370983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3710fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 9, 4);
3711fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 9);
37128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3713cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  // Thumb stores cannot use PC as dest register.
3714cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  switch (Inst.getOpcode()) {
3715cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRT:
3716cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBT:
3717cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHT:
3718cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRi8:
3719cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHi8:
3720cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBi8:
3721cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    if (Rn == 15)
3722cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville      return MCDisassembler::Fail;
3723cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3724cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  default:
3725cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3726cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  }
3727cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville
37288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Some instructions always use an additive offset.
37298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
37308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRT:
37318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRBT:
37328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRHT:
37338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRSBT:
37348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRSHT:
3735ecd1c557904815e568258fc5420de479589b0a93Owen Anderson    case ARM::t2STRT:
3736ecd1c557904815e568258fc5420de479589b0a93Owen Anderson    case ARM::t2STRBT:
3737ecd1c557904815e568258fc5420de479589b0a93Owen Anderson    case ARM::t2STRHT:
37388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      imm |= 0x100;
37398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
37408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
37418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
37428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
37438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3744a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3745a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3746a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
3747a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
37488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
374983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
37508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3752c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
3753a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson                                    uint64_t Address, const void *Decoder) {
3754a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  DecodeStatus S = MCDisassembler::Success;
3755a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3756fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3757fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3758fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addr = fieldFromInstruction(Insn, 0, 8);
3759fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  addr |= fieldFromInstruction(Insn, 9, 1) << 8;
3760a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  addr |= Rn << 9;
3761fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned load = fieldFromInstruction(Insn, 20, 1);
3762a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3763ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3764ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3765ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDR_PRE:
3766ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDR_POST:
3767ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3768ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3769ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRB_PRE:
3770ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRB_POST:
3771ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3772ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3773ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRH_PRE:
3774ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRH_POST:
3775ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3776ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3777ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSB_PRE:
3778ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSB_POST:
37790c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      if (Rt == 15)
37800c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2PLIpci);
37810c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      else
37820c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2LDRSBpci);
3783ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3784ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSH_PRE:
3785ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSH_POST:
3786ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3787ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3788ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3789ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3790ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3791ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3792ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3793ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3794a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  if (!load) {
3795a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3796a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson      return MCDisassembler::Fail;
3797a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  }
3798a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3799b78821d380b6f9514bd3b56b1c27ba367660228bJoe Abbey  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3800a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    return MCDisassembler::Fail;
3801a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3802a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  if (load) {
3803a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3804a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson      return MCDisassembler::Fail;
3805a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  }
3806a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3807a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
3808a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    return MCDisassembler::Fail;
3809a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3810a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  return S;
3811a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson}
38128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3813c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
381410cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                  uint64_t Address, const void *Decoder) {
3815a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
381683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3817fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 13, 4);
3818fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 12);
38198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3820cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  // Thumb stores cannot use PC as dest register.
3821cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  switch (Inst.getOpcode()) {
3822cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRi12:
3823cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBi12:
3824cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHi12:
3825cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    if (Rn == 15)
3826cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville      return MCDisassembler::Fail;
3827cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  default:
3828cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3829cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  }
3830cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville
3831a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3832a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
38338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
38348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
383583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
38368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
38388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3839c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
384010cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                uint64_t Address, const void *Decoder) {
3841fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 7);
38428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
38438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
38448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
38458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
38468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3847c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
38488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3850c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
385110cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                uint64_t Address, const void *Decoder) {
3852a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
385383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
38548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Inst.getOpcode() == ARM::tADDrSP) {
3855fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
3856fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
38578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3858a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3859a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3860bb32f1d545241ab957f402165cec359d4473c0caJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3861a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3862a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
38638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else if (Inst.getOpcode() == ARM::tADDspr) {
3864fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned Rm = fieldFromInstruction(Insn, 3, 4);
38658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
38668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
38678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3868a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3869a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
38708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
38718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
387283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
38738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3875c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
387610cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                           uint64_t Address, const void *Decoder) {
3877fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
3878fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned flags = fieldFromInstruction(Insn, 0, 3);
38798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
38808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imod));
38818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(flags));
38828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3883c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
38848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3886c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
388710cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                             uint64_t Address, const void *Decoder) {
3888a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
3889fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3890fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned add = fieldFromInstruction(Insn, 4, 1);
38918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3892b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
3893a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
38948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(add));
38958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
389683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
38978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3899c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
390010cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                 uint64_t Address, const void *Decoder) {
3901dd051a0414d0c807388bdc9584b71729b3158571NAKAMURA Takumi  // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
39022d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // Note only one trailing zero not two.  Also the J1 and J2 values are from
39032d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // the encoded instruction.  So here change to I1 and I2 values via:
39042d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I1 = NOT(J1 EOR S);
39052d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I2 = NOT(J2 EOR S);
39062d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // and build the imm32 with two trailing zeros as documented:
3907dd051a0414d0c807388bdc9584b71729b3158571NAKAMURA Takumi  // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
39082d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned S = (Val >> 23) & 1;
39092d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J1 = (Val >> 22) & 1;
39102d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J2 = (Val >> 21) & 1;
39112d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I1 = !(J1 ^ S);
39122d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I2 = !(J2 ^ S);
39132d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
39142d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  int imm32 = SignExtend32<25>(tmp << 1);
39152d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby
391601817c39a9d7ff864d0b5de4941eec93d2f9e3a8Jim Grosbach  if (!tryAddingSymbolicOperand(Address,
39172d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby                                (Address & ~2u) + imm32 + 4,
39189e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                true, 4, Inst, Decoder))
39192d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm32));
3920c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
39218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
39228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3923c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
39248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                              uint64_t Address, const void *Decoder) {
39258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Val == 0xA || Val == 0xB)
3926c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
39278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3928fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov  uint64_t featureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
3929fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov                                                          .getFeatureBits();
3930fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov  if ((featureBits & ARM::HasV8Ops) && !(Val == 14 || Val == 15))
3931fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov    return MCDisassembler::Fail;
3932fa840ba402806d978c18401c6bea1c808607d944Artyom Skrobov
39338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
3934c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
39358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
39368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3937a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
3938c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
39397f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach                       uint64_t Address, const void *Decoder) {
39407f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  DecodeStatus S = MCDisassembler::Success;
39417f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
3942fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3943fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
39447f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
39457f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
39467f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
39477f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return MCDisassembler::Fail;
39487f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
39497f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return MCDisassembler::Fail;
39507f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  return S;
39517f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach}
39527f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
39537f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbachstatic DecodeStatus
3954c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
3955c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
3956a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
395783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3958fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 22, 4);
39598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xE || pred == 0xF) {
3960fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned opc = fieldFromInstruction(Insn, 4, 28);
39618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (opc) {
39628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      default:
3963c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail;
3964b45b11bce1fd79b0973d2df8db295583b5477c62Owen Anderson      case 0xf3bf8f4:
39658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::t2DSB);
39668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
3967b45b11bce1fd79b0973d2df8db295583b5477c62Owen Anderson      case 0xf3bf8f5:
39688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::t2DMB);
39698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
3970b45b11bce1fd79b0973d2df8db295583b5477c62Owen Anderson      case 0xf3bf8f6:
39718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::t2ISB);
39726de3c6f1a926f49cca2fd207ab4eeb6c35e0e068Owen Anderson        break;
39738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
39748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3975fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned imm = fieldFromInstruction(Insn, 0, 4);
3976c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson    return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
39778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
39788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3979fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
3980fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
3981fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
3982fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
3983fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
39848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3985a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
3986a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3987a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3988a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
39898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
399083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
39918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
39928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
39938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Decode a shifted immediate operand.  These basically consist
39948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// of an 8-bit value, and a 4-bit directive that specifies either
39958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// a splat operation or a rotation.
3996c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
39978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                          uint64_t Address, const void *Decoder) {
3998fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned ctrl = fieldFromInstruction(Val, 10, 2);
39998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (ctrl == 0) {
4000fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned byte = fieldFromInstruction(Val, 8, 2);
4001fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned imm = fieldFromInstruction(Val, 0, 8);
40028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (byte) {
40038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 0:
40048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm(imm));
40058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
40068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 1:
40078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
40088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
40098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 2:
40108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
40118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
40128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 3:
40138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
40148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                             (imm << 8)  |  imm));
40158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
40168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
40178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
4018fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
4019fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned rot = fieldFromInstruction(Val, 7, 5);
40208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
40218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imm));
40228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
40238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4024c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
40258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
40268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4027a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
4028c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
4029c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                            uint64_t Address, const void *Decoder){
4030c8f2fcc9a381f1e024656568f2face2f600e0328Richard Barton  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
40312a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 2, Inst, Decoder))
4032c8f2fcc9a381f1e024656568f2face2f600e0328Richard Barton    Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1)));
4033c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
40348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
40358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4036c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
403710cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                       uint64_t Address, const void *Decoder){
40382d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // Val is passed in as S:J1:J2:imm10:imm11
40392d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // Note no trailing zero after imm11.  Also the J1 and J2 values are from
40402d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // the encoded instruction.  So here change to I1 and I2 values via:
40412d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I1 = NOT(J1 EOR S);
40422d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I2 = NOT(J2 EOR S);
40432d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // and build the imm32 with one trailing zero as documented:
4044dd051a0414d0c807388bdc9584b71729b3158571NAKAMURA Takumi  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
40452d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned S = (Val >> 23) & 1;
40462d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J1 = (Val >> 22) & 1;
40472d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J2 = (Val >> 21) & 1;
40482d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I1 = !(J1 ^ S);
40492d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I2 = !(J2 ^ S);
40502d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
40512d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  int imm32 = SignExtend32<25>(tmp << 1);
40522d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby
40532d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
4054b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                true, 4, Inst, Decoder))
40552d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm32));
4056c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
40578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
40588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4059c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
4060c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson                                   uint64_t Address, const void *Decoder) {
4061c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  if (Val & ~0xf)
4062c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
4063c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson
4064c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
4065c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
4066c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson}
4067c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson
40684e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuvillestatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
40694e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville                                        uint64_t Address, const void *Decoder) {
40704e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville  if (Val & ~0xf)
40714e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville    return MCDisassembler::Fail;
40724e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville
40734e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville  Inst.addOperand(MCOperand::CreateImm(Val));
40744e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville  return MCDisassembler::Success;
40754e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville}
40764e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville
4077c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
407826d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson                          uint64_t Address, const void *Decoder) {
407937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  DecodeStatus S = MCDisassembler::Success;
408037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint64_t FeatureBits = ((const MCDisassembler*)Decoder)->getSubtargetInfo()
408137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                                          .getFeatureBits();
408237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (FeatureBits & ARM::FeatureMClass) {
408337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    unsigned ValLow = Val & 0xff;
408437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
408537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // Validate the SYSm value first.
408637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    switch (ValLow) {
408737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  0: // apsr
408837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  1: // iapsr
408937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  2: // eapsr
409037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  3: // xpsr
409137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  5: // ipsr
409237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  6: // epsr
409337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  7: // iepsr
409437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  8: // msp
409537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case  9: // psp
409637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case 16: // primask
409737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case 20: // control
409837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
409937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case 17: // basepri
410037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case 18: // basepri_max
410137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    case 19: // faultmask
410237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!(FeatureBits & ARM::HasV7Ops))
410337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // Values basepri, basepri_max and faultmask are only valid for v7m.
410437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        return MCDisassembler::Fail;
410537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      break;
410637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    default:
410737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::Fail;
410837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
410937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
411037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Inst.getOpcode() == ARM::t2MSR_M) {
411137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      unsigned Mask = fieldFromInstruction(Val, 10, 2);
411237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      if (!(FeatureBits & ARM::HasV7Ops)) {
411337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // The ARMv6-M MSR bits {11-10} can be only 0b10, other values are
411437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // unpredictable.
411537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (Mask != 2)
411637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          S = MCDisassembler::SoftFail;
411737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
411837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      else {
411937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // The ARMv7-M architecture stores an additional 2-bit mask value in
412037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // MSR bits {11-10}. The mask is used only with apsr, iapsr, eapsr and
412137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // xpsr, it has to be 0b10 in other cases. Bit mask{1} indicates if
412237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // the NZCVQ bits should be moved by the instruction. Bit mask{0}
412337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // indicates the move for the GE{3:0} bits, the mask{0} bit can be set
412437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        // only if the processor includes the DSP extension.
412537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        if (Mask == 0 || (Mask != 2 && ValLow > 3) ||
412637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines            (!(FeatureBits & ARM::FeatureDSPThumb2) && (Mask & 1)))
412737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines          S = MCDisassembler::SoftFail;
412837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      }
412937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    }
413037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
413137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    // A/R class
413237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (Val == 0)
413337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::Fail;
413437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
413537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Inst.addOperand(MCOperand::CreateImm(Val));
413637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return S;
413737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
413837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
413937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic DecodeStatus DecodeBankedReg(MCInst &Inst, unsigned Val,
414037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines                                    uint64_t Address, const void *Decoder) {
414137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
414237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned R = fieldFromInstruction(Val, 5, 1);
414337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  unsigned SysM = fieldFromInstruction(Val, 0, 5);
414437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
414537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // The table of encodings for these banked registers comes from B9.2.3 of the
414637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // ARM ARM. There are patterns, but nothing regular enough to make this logic
414737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // neater. So by fiat, these values are UNPREDICTABLE:
414837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!R) {
414937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SysM == 0x7 || SysM == 0xf || SysM == 0x18 || SysM == 0x19 ||
415037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        SysM == 0x1a || SysM == 0x1b)
415137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::SoftFail;
415237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  } else {
415337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    if (SysM != 0xe && SysM != 0x10 && SysM != 0x12 && SysM != 0x14 &&
415437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines        SysM != 0x16 && SysM != 0x1c && SysM != 0x1e)
415537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      return MCDisassembler::SoftFail;
415637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  }
415737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
415826d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
4159c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
416026d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson}
4161cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
4162c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
4163c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                        uint64_t Address, const void *Decoder) {
4164a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
416583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4166fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4167fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4168fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
41693f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
41703862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (Rn == 0xF)
41713862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville    S = MCDisassembler::SoftFail;
41723f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
41733862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4174a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4175a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4176a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4177a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4178a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
41793f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
418083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
41813f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson}
41823f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
4183c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
4184c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                         uint64_t Address, const void *Decoder){
4185a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
418683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4187fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4188fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 0, 4);
4189fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4190fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4191cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
4192d3af696c08923d4d376641b52c3b2cb5baa00487Tim Northover  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
4193a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4194cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
41953862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
41963862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville    S = MCDisassembler::SoftFail;
4197cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
41983862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
4199a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4200a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4201a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4202a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4203a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4204cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
420583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
4206cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson}
4207cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
4208c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
42099ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                            uint64_t Address, const void *Decoder) {
4210a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
42119ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4212fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4213fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4214fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4215fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4216fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4217fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
42189ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4219c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
42209ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4221a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4222a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4223a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4224a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4225a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4226a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4227a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4228a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42299ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
42309ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return S;
42319ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
42329ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4233c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
42349ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                            uint64_t Address, const void *Decoder) {
4235a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
42369ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4237fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4238fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4239fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4240fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4241fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4242fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4243fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
42449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4245c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4246c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rm == 0xF) S = MCDisassembler::SoftFail;
42479ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4248a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4249a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4250a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4251a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4252a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4253a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4254a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4255a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42569ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
42579ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return S;
42589ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
42599ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
42609ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4261c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
42627cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                            uint64_t Address, const void *Decoder) {
4263a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
426483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4265fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4266fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4267fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4268fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4269fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4270fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4271cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
4272c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
42737cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4274a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4275a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4276a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4277a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4278a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4279a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4280a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4281a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42827cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
428383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
42847cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson}
42857cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4286c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
42877cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                            uint64_t Address, const void *Decoder) {
4288a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
428983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4290fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4291fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4292fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4293fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4294fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4295fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
42967cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4297c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
42987cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4299a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4300a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4301a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4302a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4303a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4304a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4305a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4306a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
43077cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
430883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
43097cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson}
43107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4311c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
43127a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4313a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
431483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4315fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4316fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4317fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4318fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4319fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
43207a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
43217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
43227a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
43237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
43247a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4325c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
43267a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4327fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4328c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4329fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
43307a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43317a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4332fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4333c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4334fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4335fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
43367a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
43377a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43387a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4339fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
4340c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4341fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4342eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4343eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4344eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0 :
4345eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4346eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4347eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4; break;
4348eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4349eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4350eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4351eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      break;
43527a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
43537a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4354a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4355a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
43567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4357a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4358a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
43597a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4360a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4361a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
43627a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
43632cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4364c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4365a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4366a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4367c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
43682cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
43697a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
43707a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4371a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4372a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
43737a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
43747a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
437583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
43767a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
43777a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4378c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
43797a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4380a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
438183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4382fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4383fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4384fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4385fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4386fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
43877a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
43887a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
43897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
43907a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
43917a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4392c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
43937a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4394fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4395c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4396fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
43977a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43987a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4399fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4400c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4401fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4402fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
44037a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
44047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44057a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4406fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
4407c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4408fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4409eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4410eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4411eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0:
4412eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4413eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4414eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4; break;
4415eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4416eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4417eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4418eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      break;
44197a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
44207a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4422a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4423a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44247a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4425a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4426a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44277a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
44282cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4429c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4430a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4431a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4432c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
44332cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
44347a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
44357a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4436a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4437a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44387a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
44397a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
444083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
44417a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
44427a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44437a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4444c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
44457a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4446a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
444783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4448fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4449fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4450fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4451fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4452fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
44537a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44547a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
44557a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
44567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
44577a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
44587a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4459c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
44607a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4461fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
4462fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
44637a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
44647a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44657a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4466fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4467fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
44687a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4469fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
44707a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
44717a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44727a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4473fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4474c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4475fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4476fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1) != 0)
44777a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4478fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
44797a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
44807a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44817a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
44827a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4483a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4484a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4485a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4486a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44877a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4488a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4489a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
44907a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4491a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4492a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44937a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
44942cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4495c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4496a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4497a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4498c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
44992cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
45007a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
45017a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4502a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4503a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4504a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4505a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
45067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
45077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
450883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
45097a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
45107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4511c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
45127a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4513a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
451483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4515fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4516fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4517fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4518fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4519fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
45207a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
45227a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
45237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
45247a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
45257a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4526c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
45277a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4528fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
4529fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
45307a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
45317a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45327a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4533fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4534fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
45357a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4536fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
45377a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
45387a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45397a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4540fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4541c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4542fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4543fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1) != 0)
45447a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4545fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
45467a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
45477a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45487a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
45497a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45507a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4551a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4552a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
45537a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4554a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4555a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
45567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
45572cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4558c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4559a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4560a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4561c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
45622cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
45637a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
45647a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4565a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4566a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4567a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4568a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
45697a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
45707a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
457183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
45727a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
45737a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45747a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4575c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
45767a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4577a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
457883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4579fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4580fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4581fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4582fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4583fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
45847a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45857a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
45867a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
45877a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
45887a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
45897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4590c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
45917a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4592fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4593c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4594fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
45957a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4597fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4598c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4599fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4600fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
46017a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
46027a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46037a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4604fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 2))
4605c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4606fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4607fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
46087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
46097a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
46117a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4612a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4613a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4614a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4615a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4616a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4617a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
46197a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4620a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4621a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46227a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4623a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4624a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46257a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
4626eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  if (Rm != 0xF) {
4627c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4628a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4629a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4630c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
46312cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
46327a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
46337a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4634a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4635a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4636a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4637a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4638a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4639a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46407a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
46417a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
464283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
46437a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
46447a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4645c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
46467a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4647a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
464883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4649fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4650fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4651fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4652fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4653fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
46547a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
46557a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
46567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
46577a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
46587a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
46597a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4660c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
46617a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4662fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4663c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4664fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
46657a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46667a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4667fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4668c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4669fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4670fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
46717a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
46727a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46737a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4674fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 2))
4675c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4676fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4677fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
46787a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
46797a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46807a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
46817a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
46827a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4683a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4684a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46857a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4686a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4687a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46887a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
46892cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4690c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4691a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4692a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4693c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
46942cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
46957a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
46967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4697a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4698a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4699a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4700a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4701a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4702a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
47037a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
47047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
470583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
47067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
47077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
47087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4709c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
47107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4711a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
471283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4713fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4714fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4715fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4716fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4717fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
47187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
47197a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
47207a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
47217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
47227a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
47237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4724c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
47257a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4726fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
47277a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4728fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
47297a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
47307a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4731fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
47327a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4733fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4734fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
47357a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
47367a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
47377a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4738eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4739eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0:
4740eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4741eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4742eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4743eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4744eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4745eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4746eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4747fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4748fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
47497a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
47507a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
47517a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
47527a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4753a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4754a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4755a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4756a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4757a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4758a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4759a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4760a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
47617a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
47627a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4763a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4764a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
47657a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4766a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4767a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
47687a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
47692cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4770c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4771a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4772a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4773c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
47742cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
47757a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
47767a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4777a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4778a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4779a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4780a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4781a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4782a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4783a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4784a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
47857a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
47867a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
478783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
47887a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
47897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4790c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
47917a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4792a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
479383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4794fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4795fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4796fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4797fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4798fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
47997a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
48007a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
48017a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
48027a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
48037a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
48047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4805c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
48067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4807fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
48087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4809fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
48107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
48117a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4812fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
48137a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4814fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4815fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
48167a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
48177a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
48187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4819eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4820eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0:
4821eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4822eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4823eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4824eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4825eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4826eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4827eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4828fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4829fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
48307a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
48317a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
48327a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
48337a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
48347a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4835a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4836a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
48377a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4838a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4839a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
48407a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
48412cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4842c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4843a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4844a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4845c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
48462cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
48477a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
48487a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4849a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4850a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4851a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4852a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4853a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4854a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4855a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4856a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
48577a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
48587a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
485983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
48607a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
48617a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4862c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
4863357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                                  uint64_t Address, const void *Decoder) {
4864a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
4865fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4866fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4867fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4868fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4869fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4870357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4871357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4872c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
4873357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4874a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4875a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4876a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4877a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4878a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4879a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4880a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4881a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4882a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4883a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4884357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4885357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  return S;
4886357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson}
4887357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4888c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
4889357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                                  uint64_t Address, const void *Decoder) {
4890a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
4891fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4892fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4893fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4894fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4895fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4896357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4897357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4898c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
4899357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4900a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4901a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4902a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4903a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4904a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4905a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4906a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4907a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4908a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4909a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4910357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4911357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  return S;
4912357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson}
49138e1e60b5f8fd9c6233bdb8814ee40887555a0594Owen Anderson
4914c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
4915eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson                             uint64_t Address, const void *Decoder) {
4916a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
4917fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 4, 4);
4918fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mask = fieldFromInstruction(Insn, 0, 4);
4919eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson
4920eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  if (pred == 0xF) {
4921eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson    pred = 0xE;
4922c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
4923e234d02204e0e546c3555e7e894b8521d22a2121Owen Anderson  }
4924e234d02204e0e546c3555e7e894b8521d22a2121Owen Anderson
4925ff08da15cf3d0412ee9cc325fc5a720bcad178f2Amaury de la Vieuville  if (mask == 0x0)
4926ff08da15cf3d0412ee9cc325fc5a720bcad178f2Amaury de la Vieuville    return MCDisassembler::Fail;
4927eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson
4928eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(pred));
4929eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(mask));
4930f44082091c5517a3275c57a8b58e36987c8227f0Owen Anderson  return S;
4931f44082091c5517a3275c57a8b58e36987c8227f0Owen Anderson}
4932a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4933a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachstatic DecodeStatus
4934c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
4935a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                           uint64_t Address, const void *Decoder) {
4936a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  DecodeStatus S = MCDisassembler::Success;
4937a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4938fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4939fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4940fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4941fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4942fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
4943fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Insn, 23, 1);
4944fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
4945a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool writeback = (W == 1) | (P == 0);
4946a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4947a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  addr |= (U << 8) | (Rn << 9);
4948a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4949a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (writeback && (Rn == Rt || Rn == Rt2))
4950a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Check(S, MCDisassembler::SoftFail);
4951a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (Rt == Rt2)
4952a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Check(S, MCDisassembler::SoftFail);
4953a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4954a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt
4955a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4956a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4957a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt2
4958a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4959a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4960a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Writeback operand
4961a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4962a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4963a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
4964a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4965a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4966a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4967a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return S;
4968a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
4969a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4970a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachstatic DecodeStatus
4971c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
4972a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                           uint64_t Address, const void *Decoder) {
4973a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  DecodeStatus S = MCDisassembler::Success;
4974a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4975fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4976fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4977fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4978fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4979fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
4980fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Insn, 23, 1);
4981fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
4982a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool writeback = (W == 1) | (P == 0);
4983a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4984a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  addr |= (U << 8) | (Rn << 9);
4985a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4986a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (writeback && (Rn == Rt || Rn == Rt2))
4987a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Check(S, MCDisassembler::SoftFail);
4988a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4989a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Writeback operand
4990a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4991a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4992a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt
4993a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4994a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4995a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt2
4996a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4997a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4998a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
4999a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
5000a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
5001a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
5002a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return S;
5003a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
500408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
5005c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
500608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson                                uint64_t Address, const void *Decoder) {
5007fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
5008fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
500908fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  if (sign1 != sign2) return MCDisassembler::Fail;
501008fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
5011fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Val = fieldFromInstruction(Insn, 0, 8);
5012fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Val |= fieldFromInstruction(Insn, 12, 3) << 8;
5013fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Val |= fieldFromInstruction(Insn, 26, 1) << 11;
501408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  Val |= sign1 << 12;
501508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val)));
501608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
501708fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  return MCDisassembler::Success;
501808fef885eb39339a47e3be7f0842b1db33683003Owen Anderson}
501908fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
5020c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
50210afa0094afdfe589f407feb76948f273b414b278Owen Anderson                                              uint64_t Address,
50220afa0094afdfe589f407feb76948f273b414b278Owen Anderson                                              const void *Decoder) {
50230afa0094afdfe589f407feb76948f273b414b278Owen Anderson  DecodeStatus S = MCDisassembler::Success;
50240afa0094afdfe589f407feb76948f273b414b278Owen Anderson
50250afa0094afdfe589f407feb76948f273b414b278Owen Anderson  // Shift of "asr #32" is not allowed in Thumb2 mode.
5026ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines  if (Val == 0x20) S = MCDisassembler::Fail;
50270afa0094afdfe589f407feb76948f273b414b278Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
50280afa0094afdfe589f407feb76948f273b414b278Owen Anderson  return S;
50290afa0094afdfe589f407feb76948f273b414b278Owen Anderson}
50300afa0094afdfe589f407feb76948f273b414b278Owen Anderson
5031c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
5032cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson                               uint64_t Address, const void *Decoder) {
5033fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
5034fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
5035fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
5036fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
5037cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson
5038cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (pred == 0xF)
5039cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
5040cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson
5041cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  DecodeStatus S = MCDisassembler::Success;
504235ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga
504335ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga  if (Rt == Rn || Rn == Rt2)
504435ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga    S = MCDisassembler::SoftFail;
504535ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga
5046cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5047cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
5048cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5049cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
5050cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5051cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
5052cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
5053cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
5054cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson
5055cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  return S;
5056cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson}
5057b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5058c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
5059b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder) {
5060fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5061fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5062fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5063fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5064fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 16, 6);
5065fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
50669eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville  unsigned op = fieldFromInstruction(Insn, 5, 1);
5067b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5068b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  DecodeStatus S = MCDisassembler::Success;
5069b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5070b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  // VMOVv2f32 is ambiguous with these decodings.
507122925d93e9c5d6159f24853457c858be5f08af04Owen Anderson  if (!(imm & 0x38) && cmode == 0xF) {
50729eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville    if (op == 1) return MCDisassembler::Fail;
5073b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    Inst.setOpcode(ARM::VMOVv2f32);
5074b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5075b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  }
5076b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5077c64835b0c57913b11abd648b76913390e62af8d6Amaury de la Vieuville  if (!(imm & 0x20)) return MCDisassembler::Fail;
5078b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5079b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
5080b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
5081b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
5082b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
5083b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(64 - imm));
5084b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5085b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  return S;
5086b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson}
5087b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5088c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
5089b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder) {
5090fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
5091fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
5092fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
5093fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
5094fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 16, 6);
5095fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
50969eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville  unsigned op = fieldFromInstruction(Insn, 5, 1);
5097b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5098b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  DecodeStatus S = MCDisassembler::Success;
5099b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5100b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  // VMOVv4f32 is ambiguous with these decodings.
5101b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!(imm & 0x38) && cmode == 0xF) {
51029eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville    if (op == 1) return MCDisassembler::Fail;
5103b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    Inst.setOpcode(ARM::VMOVv4f32);
5104b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
5105b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  }
5106b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5107c64835b0c57913b11abd648b76913390e62af8d6Amaury de la Vieuville  if (!(imm & 0x20)) return MCDisassembler::Fail;
5108b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5109b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
5110b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
5111b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
5112b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
5113b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(64 - imm));
5114b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
5115b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  return S;
5116b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson}
5117b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
5118c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
5119b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga                                uint64_t Address, const void *Decoder) {
5120b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  DecodeStatus S = MCDisassembler::Success;
5121b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
5122fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 16, 4);
5123fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Val, 12, 4);
5124fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
5125fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
5126fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Cond = fieldFromInstruction(Val, 28, 4);
5127b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
5128fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
5129b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    S = MCDisassembler::SoftFail;
5130b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
5131b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5132b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
5133b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
5134b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
5135b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
5136b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
5137b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
5138b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
5139b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
5140b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
5141b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
5142b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  return S;
5143b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga}
5144b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
5145fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Barangastatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
5146fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga                                uint64_t Address, const void *Decoder) {
5147fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5148fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  DecodeStatus S = MCDisassembler::Success;
5149fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5150fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned CRm = fieldFromInstruction(Val, 0, 4);
5151fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned opc1 = fieldFromInstruction(Val, 4, 4);
5152fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned cop = fieldFromInstruction(Val, 8, 4);
5153fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Val, 12, 4);
5154fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
5155fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5156fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if ((cop & ~0x1) == 0xa)
5157fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    return MCDisassembler::Fail;
5158fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5159fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if (Rt == Rt2)
5160fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    S = MCDisassembler::SoftFail;
5161fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5162fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  Inst.addOperand(MCOperand::CreateImm(cop));
5163fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  Inst.addOperand(MCOperand::CreateImm(opc1));
5164fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
5165fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    return MCDisassembler::Fail;
5166fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
5167fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    return MCDisassembler::Fail;
5168fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  Inst.addOperand(MCOperand::CreateImm(CRm));
5169fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5170fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  return S;
5171fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga}
5172fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
5173