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
10b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#define DEBUG_TYPE "arm-disassembler"
11b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
12d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCDisassembler.h"
138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "MCTargetDesc/ARMAddressingModes.h"
148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "MCTargetDesc/ARMBaseInfo.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "MCTargetDesc/ARMMCExpr.h"
168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "llvm/MC/MCContext.h"
17d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCExpr.h"
18fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/MC/MCFixedLenDisassembler.h"
19d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInst.h"
20d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCInstrDesc.h"
2175e3b7fb8fdf069b6f9f1e1db9634ca5701cbe96Dylan Noblesmith#include "llvm/MC/MCSubtargetInfo.h"
22b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#include "llvm/Support/Debug.h"
23b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#include "llvm/Support/ErrorHandling.h"
24fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach#include "llvm/Support/LEB128.h"
25d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/MemoryObject.h"
263e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h"
27b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen#include "llvm/Support/raw_ostream.h"
28f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton#include <vector>
29b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
30c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloyusing namespace llvm;
31c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy
32a6804444e874b27aee5921d4c6049df573c5e249Owen Andersontypedef MCDisassembler::DecodeStatus DecodeStatus;
33a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson
34a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonnamespace {
35f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  // Handles the condition code status of instructions in IT blocks
36f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  class ITStatus
37f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  {
38f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    public:
39f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Returns the condition code for instruction in IT block
40f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      unsigned getITCC() {
41f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        unsigned CC = ARMCC::AL;
42f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        if (instrInITBlock())
43f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          CC = ITStates.back();
44f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        return CC;
45f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
46f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
47f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Advances the IT block state to the next T or E
48f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      void advanceITState() {
49f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        ITStates.pop_back();
50f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
51f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
52f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Returns true if the current instruction is in an IT block
53f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      bool instrInITBlock() {
54f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        return !ITStates.empty();
55f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
56f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
57f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Returns true if current instruction is the last instruction in an IT block
58f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      bool instrLastInITBlock() {
59f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        return ITStates.size() == 1;
60f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
61f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
62f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // Called when decoding an IT instruction. Sets the IT state for the following
63f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // instructions that for the IT block. Firstcond and Mask correspond to the
64f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      // fields in the IT instruction encoding.
65f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      void setITState(char Firstcond, char Mask) {
66f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        // (3 - the number of trailing zeros) is the number of then / else.
674d2f077df1b46a126b5595d983f233ec896b757eRichard Barton        unsigned CondBit0 = Firstcond & 1;
68c6af2432c802d241c8fffbe0371c023e6c58844eMichael J. Spencer        unsigned NumTZ = countTrailingZeros<uint8_t>(Mask);
69f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        unsigned char CCBits = static_cast<unsigned char>(Firstcond & 0xf);
70f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        assert(NumTZ <= 3 && "Invalid IT mask!");
71f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        // push condition codes onto the stack the correct order for the pops
72f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        for (unsigned Pos = NumTZ+1; Pos <= 3; ++Pos) {
73f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          bool T = ((Mask >> Pos) & 1) == CondBit0;
74f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          if (T)
75f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton            ITStates.push_back(CCBits);
76f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton          else
77f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton            ITStates.push_back(CCBits ^ 1);
78f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        }
79f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton        ITStates.push_back(CCBits);
80f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      }
81f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
82f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    private:
83f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      std::vector<unsigned char> ITStates;
84f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  };
85f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton}
86f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton
87f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Bartonnamespace {
88a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson/// ARMDisassembler - ARM disassembler for all ARM platforms.
89a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonclass ARMDisassembler : public MCDisassembler {
90a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonpublic:
91a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  /// Constructor     - Initializes the disassembler.
92a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  ///
93b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  ARMDisassembler(const MCSubtargetInfo &STI) :
94b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    MCDisassembler(STI) {
95a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  }
96a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
97a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  ~ARMDisassembler() {
98a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  }
99a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
100a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  /// getInstruction - See MCDisassembler.
101a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  DecodeStatus getInstruction(MCInst &instr,
102a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson                              uint64_t &size,
103adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff                              const MemoryObject &region,
104a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson                              uint64_t address,
10598c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                              raw_ostream &vStream,
10698c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                              raw_ostream &cStream) const;
107a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson};
108a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
109a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson/// ThumbDisassembler - Thumb disassembler for all Thumb platforms.
110a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonclass ThumbDisassembler : public MCDisassembler {
111a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonpublic:
112a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  /// Constructor     - Initializes the disassembler.
113a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  ///
114b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  ThumbDisassembler(const MCSubtargetInfo &STI) :
115b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy    MCDisassembler(STI) {
116a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  }
117a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
118a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  ~ThumbDisassembler() {
119a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  }
120a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
121a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  /// getInstruction - See MCDisassembler.
122a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  DecodeStatus getInstruction(MCInst &instr,
123a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson                              uint64_t &size,
124adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff                              const MemoryObject &region,
125a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson                              uint64_t address,
12698c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                              raw_ostream &vStream,
12798c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                              raw_ostream &cStream) const;
128a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
129a1c110045a284190955f28b8f308ffb365cc2edaOwen Andersonprivate:
130f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  mutable ITStatus ITBlock;
131d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson  DecodeStatus AddThumbPredicate(MCInst&) const;
132a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson  void UpdateThumbVFPPredicate(MCInst&) const;
133a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson};
134a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson}
135a1c110045a284190955f28b8f308ffb365cc2edaOwen Anderson
136a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic bool Check(DecodeStatus &Out, DecodeStatus In) {
137c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  switch (In) {
138c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    case MCDisassembler::Success:
139c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      // Out stays the same.
140c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return true;
141c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    case MCDisassembler::SoftFail:
142c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      Out = In;
143c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return true;
144c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    case MCDisassembler::Fail:
145c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      Out = In;
146c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return false;
147c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  }
1484d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie  llvm_unreachable("Invalid DecodeStatus!");
149c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy}
15083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
151a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy
1528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Forward declare these because the autogenerated code will reference them.
1538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Definitions are further down.
154c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
156c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeGPRnopcRegisterClass(MCInst &Inst,
157c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                               unsigned RegNo, uint64_t Address,
158c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                               const void *Decoder);
159f86e436fb95670ed110818fefa403f21ae104639Mihai Popastatic DecodeStatus DecodeGPRwithAPSRRegisterClass(MCInst &Inst,
160f86e436fb95670ed110818fefa403f21ae104639Mihai Popa                                               unsigned RegNo, uint64_t Address,
161f86e436fb95670ed110818fefa403f21ae104639Mihai Popa                                               const void *Decoder);
162c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
164c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
166c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
1678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
1683862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuvillestatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
1693862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville                                   uint64_t Address, const void *Decoder);
170c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
1718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
172c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
1738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
174c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
1758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
176c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPR_VFP2RegisterClass(MCInst &Inst,
177c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                unsigned RegNo,
178c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                uint64_t Address,
179c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                const void *Decoder);
180c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
1818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder);
182c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
18328f08c93e75d291695ea89b9004145103292e85bJim Grosbach                                   uint64_t Address, const void *Decoder);
184c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
185c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                               unsigned RegNo, uint64_t Address,
186c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                               const void *Decoder);
1878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
188c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
1898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
190c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
1918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
192c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val,
1938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
194c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
1958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
196c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
1978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
198c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
1998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
2008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
201c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Insn,
2028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
203c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
2048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
205c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode2IdxInstruction(MCInst &Inst,
206c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                  unsigned Insn,
207c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                  uint64_t Address,
208c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                                  const void *Decoder);
209c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Insn,
2108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
211c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode3Instruction(MCInst &Inst,unsigned Insn,
2128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
213c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Insn,
2148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
215c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Insn,
2168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
2178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
218c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst & Inst,
2198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                                  unsigned Insn,
2208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                                  uint64_t Adddress,
2218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                                  const void *Decoder);
222c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
2239e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                               uint64_t Address, const void *Decoder);
224c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
2259e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                               uint64_t Address, const void *Decoder);
226c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
2278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
228c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
22935008c2f8dcfe55960fe4efea3a26e526d437ad6Owen Anderson                               uint64_t Address, const void *Decoder);
230c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
2316153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson                               uint64_t Address, const void *Decoder);
232c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
2338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
234c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
2358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
236c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
2378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
2382a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderbystatic DecodeStatus DecodeT2BInstruction(MCInst &Inst, unsigned Insn,
2392a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                               uint64_t Address, const void *Decoder);
240c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeBranchImmInstruction(MCInst &Inst,unsigned Insn,
2418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
242c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
2438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
244aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Val,
2458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
246aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Val,
24730a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
248aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Val,
24930a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
250aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Val,
25130a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
252aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Val,
25330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa                               uint64_t Address, const void *Decoder);
254c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Val,
2558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
256c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Val,
2578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
258c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Val,
2598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
260c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Val,
2618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
262c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4DupInstruction(MCInst &Inst, unsigned Val,
2638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
264c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeNEONModImmInstruction(MCInst &Inst,unsigned Val,
2658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
266c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Val,
2678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
268c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
2698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
270c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
2718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
272c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
2738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
274c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
2758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
276c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
2778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
278c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
2798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
280c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Insn,
2818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
282c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Insn,
283c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson                               uint64_t Address, const void *Decoder);
2844e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuvillestatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Insn,
2854e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville                               uint64_t Address, const void *Decoder);
286c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Insn,
28726d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson                               uint64_t Address, const void *Decoder);
288c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
2893f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson                               uint64_t Address, const void *Decoder);
290c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
291cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson                               uint64_t Address, const void *Decoder);
292c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
2939ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                               uint64_t Address, const void *Decoder);
294c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
2959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                               uint64_t Address, const void *Decoder);
296c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
2977cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                               uint64_t Address, const void *Decoder);
298c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
2997cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                               uint64_t Address, const void *Decoder);
300c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
3017a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
302c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
3037a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
304c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
3057a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
306c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
3077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
308c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
3097a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
310c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
3117a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
312c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
3137a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
314c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
3157a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                               uint64_t Address, const void *Decoder);
316c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
317357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                               uint64_t Address, const void *Decoder);
318c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
319357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                               uint64_t Address, const void *Decoder);
320c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
321cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson                               uint64_t Address, const void *Decoder);
322c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
323b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder);
324c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
325b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder);
3267c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombetstatic DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address,
3277c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet                                 const void *Decoder);
328b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
3298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
330c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
3318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
332c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
3338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
334c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
3358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
336c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
3378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
338c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
3398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
340c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
3418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
342c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
3438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
344c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
3458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
346c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
3478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
348c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Val,
3498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
350ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
351ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
352ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
353ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
354ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
355ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
356ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
357ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                               uint64_t Address, const void* Decoder);
358c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
3598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
360c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
3618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
362c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
363b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                               uint64_t Address, const void *Decoder);
364c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
3658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
366c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
3678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
368c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Val,
3698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder);
370c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
3718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
372c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
3738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
37446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuvillestatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
37546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville                                uint64_t Address, const void *Decoder);
376c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Insn,
3778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
378c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
3798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
380c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbTableBranch(MCInst &Inst, unsigned Val,
3817f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach                                uint64_t Address, const void *Decoder);
382c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumb2BCCInstruction(MCInst &Inst, unsigned Val,
3838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
384c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
3858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
386c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBCCTargetOperand(MCInst &Inst,unsigned Val,
3878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
388c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
3898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                uint64_t Address, const void *Decoder);
390c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Val,
391f44082091c5517a3275c57a8b58e36987c8227f0Owen Anderson                                uint64_t Address, const void *Decoder);
392c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LDRDPreInstruction(MCInst &Inst,unsigned Insn,
393a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                               uint64_t Address, const void *Decoder);
394c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2STRDPreInstruction(MCInst &Inst,unsigned Insn,
395a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                               uint64_t Address, const void *Decoder);
396c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Adr(MCInst &Inst, unsigned Val,
39708fef885eb39339a47e3be7f0842b1db33683003Owen Anderson                                uint64_t Address, const void *Decoder);
398c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Val,
399a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson                                uint64_t Address, const void *Decoder);
400c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, unsigned Val,
4010afa0094afdfe589f407feb76948f273b414b278Owen Anderson                                uint64_t Address, const void *Decoder);
4020afa0094afdfe589f407feb76948f273b414b278Owen Anderson
403c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
404b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga                                uint64_t Address, const void *Decoder);
405fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Barangastatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
406fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga                                uint64_t Address, const void *Decoder);
4078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson#include "ARMGenDisassemblerTables.inc"
4089899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan
409b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloystatic MCDisassembler *createARMDisassembler(const Target &T, const MCSubtargetInfo &STI) {
410b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  return new ARMDisassembler(STI);
4118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
4128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
413b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloystatic MCDisassembler *createThumbDisassembler(const Target &T, const MCSubtargetInfo &STI) {
414b950585cc5a0d665e9accfe5ce490cd269756f2eJames Molloy  return new ThumbDisassembler(STI);
4158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
4168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
417a6804444e874b27aee5921d4c6049df573c5e249Owen AndersonDecodeStatus ARMDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
418adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff                                             const MemoryObject &Region,
419c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                             uint64_t Address,
42098c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                                             raw_ostream &os,
42198c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                                             raw_ostream &cs) const {
4229e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  CommentStream = &cs;
4239e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
4248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint8_t bytes[4];
4258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
426a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy  assert(!(STI.getFeatureBits() & ARM::ModeThumb) &&
427a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy         "Asked to disassemble an ARM instruction but Subtarget is in Thumb mode!");
428a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy
4298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // We want to read exactly 4 bytes of data.
43049a6a8d8f2994249c81b7914b07015714748a55cBenjamin Kramer  if (Region.readBytes(Address, 4, bytes) == -1) {
43186ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer    Size = 0;
432c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
43386ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  }
4348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Encoded as a small-endian 32-bit word in the stream.
4368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint32_t insn = (bytes[3] << 24) |
4378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                  (bytes[2] << 16) |
4388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                  (bytes[1] <<  8) |
4398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                  (bytes[0] <<  0);
4408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Calling the auto-generated decoder function.
442fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  DecodeStatus result = decodeInstruction(DecoderTableARM32, MI, insn,
443fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                                          Address, this, STI);
444c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
4458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
44683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
447b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
448b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
4498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // VFP and NEON instructions, similarly, are shared between ARM
4508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // and Thumb modes.
4518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
452fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableVFP32, MI, insn, Address, this, STI);
453c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
4548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
45583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
4568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
4578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
4588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
4594ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  result = decodeInstruction(DecoderTableVFPV832, MI, insn, Address, this, STI);
4604ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  if (result != MCDisassembler::Fail) {
4614ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly    Size = 4;
4624ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly    return result;
4634ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  }
4644ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly
4654ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  MI.clear();
466fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableNEONData32, MI, insn, Address,
467fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             this, STI);
468c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
4698533ebad6f6e407215497ca50771f323058f5576Owen Anderson    Size = 4;
4708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // Add a fake predicate operand, because we share these instruction
4718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // definitions with Thumb2 where these instructions are predicable.
472a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!DecodePredicateOperand(MI, 0xE, Address, this))
473a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
47483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
4758533ebad6f6e407215497ca50771f323058f5576Owen Anderson  }
4768533ebad6f6e407215497ca50771f323058f5576Owen Anderson
4778533ebad6f6e407215497ca50771f323058f5576Owen Anderson  MI.clear();
478fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableNEONLoadStore32, MI, insn, Address,
479fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             this, STI);
480c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
4818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
4828533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // Add a fake predicate operand, because we share these instruction
4838533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // definitions with Thumb2 where these instructions are predicable.
484a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!DecodePredicateOperand(MI, 0xE, Address, this))
485a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
48683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
4878533ebad6f6e407215497ca50771f323058f5576Owen Anderson  }
4888533ebad6f6e407215497ca50771f323058f5576Owen Anderson
4898533ebad6f6e407215497ca50771f323058f5576Owen Anderson  MI.clear();
490fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableNEONDup32, MI, insn, Address,
491fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             this, STI);
492c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
4938533ebad6f6e407215497ca50771f323058f5576Owen Anderson    Size = 4;
4948533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // Add a fake predicate operand, because we share these instruction
4958533ebad6f6e407215497ca50771f323058f5576Owen Anderson    // definitions with Thumb2 where these instructions are predicable.
496a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!DecodePredicateOperand(MI, 0xE, Address, this))
497a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
49883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
4998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
5008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
50219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  result = decodeInstruction(DecoderTablev8NEON32, MI, insn, Address,
50319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly                             this, STI);
50419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  if (result != MCDisassembler::Fail) {
50519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    Size = 4;
50619c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    return result;
50719c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  }
5088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
50919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  MI.clear();
51086ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  Size = 0;
511c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Fail;
5128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
5138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonnamespace llvm {
5151a2f9886a2a60dbd41216468a240446bbfed3e76Benjamin Kramerextern const MCInstrDesc ARMInsts[];
5168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
5178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5189e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// tryAddingSymbolicOperand - trys to add a symbolic operand in place of the
5199e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// immediate Value in the MCInst.  The immediate Value has had any PC
5209e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// adjustment made by the caller.  If the instruction is a branch instruction
5219e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// then isBranch is true, else false.  If the getOpInfo() function was set as
5229e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// part of the setupForSymbolicDisassembly() call then that function is called
5239e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// to get any symbolic information at the Address for this instruction.  If
5249e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// that returns non-zero then the symbolic information it returns is used to
5259e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// create an MCExpr and that is added as an operand to the MCInst.  If
5269e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// getOpInfo() returns zero and isBranch is true then a symbol look up for
5279e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// Value is done and if a symbol is found an MCExpr is created with that, else
5289e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// an MCExpr with Value is created.  This function returns true if it adds an
5299e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// operand to the MCInst and false otherwise.
5309e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderbystatic bool tryAddingSymbolicOperand(uint64_t Address, int32_t Value,
5319e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                     bool isBranch, uint64_t InstSize,
5329e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                     MCInst &MI, const void *Decoder) {
5339e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
5342c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  // FIXME: Does it make sense for value to be negative?
5352c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  return Dis->tryAddingSymbolicOperand(MI, (uint32_t)Value, Address, isBranch,
5362c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha                                       /* Offset */ 0, InstSize);
5379e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
5389e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
5399e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// tryAddingPcLoadReferenceComment - trys to add a comment as to what is being
5409e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// referenced by a load instruction with the base register that is the Pc.
5419e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// These can often be values in a literal pool near the Address of the
5429e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// instruction.  The Address of the instruction and its immediate Value are
5439e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// used as a possible literal pool entry.  The SymbolLookUp call back will
544c8e41c591741b3da1077f7000274ad040bef8002Sylvestre Ledru/// return the name of a symbol referenced by the literal pool's entry if
5459e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// the referenced address is that of a symbol.  Or it will return a pointer to
5469e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// a literal 'C' string if the referenced address of the literal pool's entry
5479e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby/// is an address into a section with 'C' string literals.
5489e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderbystatic void tryAddingPcLoadReferenceComment(uint64_t Address, int Value,
549b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                            const void *Decoder) {
5509e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  const MCDisassembler *Dis = static_cast<const MCDisassembler*>(Decoder);
5512c94d0faa0e1c268893d5e04dc77e8a35889db00Ahmed Bougacha  Dis->tryAddingPcLoadReferenceComment(Value, Address);
5529e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
5539e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
5548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Thumb1 instructions don't have explicit S bits.  Rather, they
5558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// implicitly set CPSR.  Since it's not represented in the encoding, the
5568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// auto-generated decoder won't inject the CPSR operand.  We need to fix
5578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// that as a post-pass.
5588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonstatic void AddThumb1SBit(MCInst &MI, bool InITBlock) {
5598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
5600aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
5618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MCInst::iterator I = MI.begin();
5620aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  for (unsigned i = 0; i < NumOps; ++i, ++I) {
5630aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    if (I == MI.end()) break;
5648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (OpInfo[i].isOptionalDef() && OpInfo[i].RegClass == ARM::CCRRegClassID) {
5650aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson      if (i > 0 && OpInfo[i-1].isPredicate()) continue;
5668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
5678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      return;
568b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen    }
569b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
570b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
5710aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  MI.insert(I, MCOperand::CreateReg(InITBlock ? 0 : ARM::CPSR));
5728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
5738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
5748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Most Thumb instructions don't have explicit predicates in the
5758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// encoding, but rather get their predicates from IT context.  We need
5768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// to fix up the predicate operands using this context information as a
5778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// post-pass.
578d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen AndersonMCDisassembler::DecodeStatus
579d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen AndersonThumbDisassembler::AddThumbPredicate(MCInst &MI) const {
58051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  MCDisassembler::DecodeStatus S = Success;
58151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson
5828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // A few instructions actually have predicates encoded in them.  Don't
5838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // try to overwrite it if we're seeing one of those.
5848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (MI.getOpcode()) {
5858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::tBcc:
5868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2Bcc:
587d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    case ARM::tCBZ:
588d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    case ARM::tCBNZ:
5899f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::tCPS:
5909f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::t2CPS3p:
5919f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::t2CPS2p:
5929f666b5f2e4a5e94cd667e5be0c5d513dd64ea67Owen Anderson    case ARM::t2CPS1p:
593d9346fbb06d64266c2fe46edef7a15cb9af7e7e8Owen Anderson    case ARM::tMOVSr:
594c18e940c5a1c050701594ee2b356cd40249505a3Owen Anderson    case ARM::tSETEND:
595441462f9328cc7fb86af74c9568a7f70b7bd1fbcOwen Anderson      // Some instructions (mostly conditional branches) are not
596441462f9328cc7fb86af74c9568a7f70b7bd1fbcOwen Anderson      // allowed in IT blocks.
597f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      if (ITBlock.instrInITBlock())
59851f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        S = SoftFail;
59951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      else
60051f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        return Success;
60151f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      break;
60251f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    case ARM::tB:
60351f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson    case ARM::t2B:
60404c7877894492d6e8aa45567988cd7de100589d8Owen Anderson    case ARM::t2TBB:
60504c7877894492d6e8aa45567988cd7de100589d8Owen Anderson    case ARM::t2TBH:
60651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      // Some instructions (mostly unconditional branches) can
60751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      // only appears at the end of, or outside of, an IT.
608f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      if (ITBlock.instrInITBlock() && !ITBlock.instrLastInITBlock())
60951f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson        S = SoftFail;
610d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson      break;
611b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen    default:
6128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
613b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
614b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
6158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // If we're in an IT block, base the predicate on that.  Otherwise,
6168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // assume a predicate of AL.
6178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned CC;
618f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  CC = ITBlock.getITCC();
619f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  if (CC == 0xF)
6208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    CC = ARMCC::AL;
621f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  if (ITBlock.instrInITBlock())
622f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    ITBlock.advanceITState();
6238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
6248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
6250aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
6268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MCInst::iterator I = MI.begin();
6270aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  for (unsigned i = 0; i < NumOps; ++i, ++I) {
6280aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    if (I == MI.end()) break;
6298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (OpInfo[i].isPredicate()) {
6308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      I = MI.insert(I, MCOperand::CreateImm(CC));
6318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ++I;
6328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      if (CC == ARMCC::AL)
6338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        MI.insert(I, MCOperand::CreateReg(0));
6348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      else
6358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
63651f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson      return S;
637b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen    }
6388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
639b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
6400aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  I = MI.insert(I, MCOperand::CreateImm(CC));
6410aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson  ++I;
6428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (CC == ARMCC::AL)
6430aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    MI.insert(I, MCOperand::CreateReg(0));
6448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
6450aa38ab1fb53c457ce90390aed2659eb085709f0Owen Anderson    MI.insert(I, MCOperand::CreateReg(ARM::CPSR));
646d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson
64751f6a7abf27fc92c3d8904c2334feab8b498e8e9Owen Anderson  return S;
6488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
6498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
6508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Thumb VFP instructions are a special case.  Because we share their
6518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// encodings between ARM and Thumb modes, and they are predicable in ARM
6528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// mode, the auto-generated decoder will give them an (incorrect)
6538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// predicate operand.  We need to rewrite these operands based on the IT
6548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// context as a post-pass.
6558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonvoid ThumbDisassembler::UpdateThumbVFPPredicate(MCInst &MI) const {
6568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned CC;
657f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  CC = ITBlock.getITCC();
658f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton  if (ITBlock.instrInITBlock())
659f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    ITBlock.advanceITState();
6608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
6618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  const MCOperandInfo *OpInfo = ARMInsts[MI.getOpcode()].OpInfo;
6628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MCInst::iterator I = MI.begin();
66312a1e3bbcbd4e8f740c8304379001d1e6731561cOwen Anderson  unsigned short NumOps = ARMInsts[MI.getOpcode()].NumOperands;
66412a1e3bbcbd4e8f740c8304379001d1e6731561cOwen Anderson  for (unsigned i = 0; i < NumOps; ++i, ++I) {
6658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (OpInfo[i].isPredicate() ) {
6668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      I->setImm(CC);
6678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ++I;
6688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      if (CC == ARMCC::AL)
6698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        I->setReg(0);
6708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      else
6718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        I->setReg(ARM::CPSR);
6728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      return;
673eca915fb5242442756a80bad7f285cb54d7b8ea4Johnny Chen    }
6748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
6758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
6768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
677a6804444e874b27aee5921d4c6049df573c5e249Owen AndersonDecodeStatus ThumbDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
678adef06a71458ded0716935a61b3d43d164d4df12Derek Schuff                                               const MemoryObject &Region,
679c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                               uint64_t Address,
68098c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                                               raw_ostream &os,
68198c5ddabca1debf935a07d14d0cbc9732374bdb8Owen Anderson                                               raw_ostream &cs) const {
6829e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  CommentStream = &cs;
6839e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
6848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint8_t bytes[4];
6858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
686a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy  assert((STI.getFeatureBits() & ARM::ModeThumb) &&
687a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy         "Asked to disassemble in Thumb mode but Subtarget is in ARM mode!");
688a5d585685493d85d5cb72b831a68ec747ae55a86James Molloy
6898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // We want to read exactly 2 bytes of data.
69049a6a8d8f2994249c81b7914b07015714748a55cBenjamin Kramer  if (Region.readBytes(Address, 2, bytes) == -1) {
69186ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer    Size = 0;
692c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
69386ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  }
694eca915fb5242442756a80bad7f285cb54d7b8ea4Johnny Chen
6958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint16_t insn16 = (bytes[1] << 8) | bytes[0];
696fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  DecodeStatus result = decodeInstruction(DecoderTableThumb16, MI, insn16,
697fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                                          Address, this, STI);
698c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
6998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 2;
700d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    Check(result, AddThumbPredicate(MI));
70183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
70216280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson  }
70316280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson
70416280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson  MI.clear();
705fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableThumbSBit16, MI, insn16,
706fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             Address, this, STI);
70716280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson  if (result) {
70816280308ac6f20d9da06eafcc19e4a6777f49750Owen Anderson    Size = 2;
709f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    bool InITBlock = ITBlock.instrInITBlock();
710d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    Check(result, AddThumbPredicate(MI));
7118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    AddThumb1SBit(MI, InITBlock);
71283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
7138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
716fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableThumb216, MI, insn16,
717fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             Address, this, STI);
718c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
7198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 2;
7207011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson
7217011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson    // Nested IT blocks are UNPREDICTABLE.  Must be checked before we add
7227011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson    // the Thumb predicate.
723f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    if (MI.getOpcode() == ARM::t2IT && ITBlock.instrInITBlock())
7247011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson      result = MCDisassembler::SoftFail;
7257011eee9b509f3a0f95a75f68787384f31ea3e01Owen Anderson
726d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    Check(result, AddThumbPredicate(MI));
7278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // If we find an IT instruction, we need to parse its condition
7298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // code and mask operands so that we can apply them correctly
7308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // to the subsequent instructions.
7318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (MI.getOpcode() == ARM::t2IT) {
73234626acf7fb042c3a831e2f7dfb653ea79c7adecOwen Anderson
733f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      unsigned Firstcond = MI.getOperand(0).getImm();
734eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson      unsigned Mask = MI.getOperand(1).getImm();
735f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton      ITBlock.setITState(Firstcond, Mask);
736eca915fb5242442756a80bad7f285cb54d7b8ea4Johnny Chen    }
737b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
73883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
7398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // We want to read exactly 4 bytes of data.
74249a6a8d8f2994249c81b7914b07015714748a55cBenjamin Kramer  if (Region.readBytes(Address, 4, bytes) == -1) {
74386ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer    Size = 0;
744c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
74586ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  }
7468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint32_t insn32 = (bytes[3] <<  8) |
7488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                    (bytes[2] <<  0) |
7498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                    (bytes[1] << 24) |
7508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                    (bytes[0] << 16);
7518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
752fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableThumb32, MI, insn32, Address,
753fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             this, STI);
754c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
7558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
756f4478f99dd63503bf0f0e763bc6d684e738bfe3dRichard Barton    bool InITBlock = ITBlock.instrInITBlock();
757d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    Check(result, AddThumbPredicate(MI));
7588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    AddThumb1SBit(MI, InITBlock);
75983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
7608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
7628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  MI.clear();
763fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  result = decodeInstruction(DecoderTableThumb232, MI, insn32, Address,
764fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                             this, STI);
765c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (result != MCDisassembler::Fail) {
7668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Size = 4;
767d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson    Check(result, AddThumbPredicate(MI));
76883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return result;
7698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
7708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
771ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville  if (fieldFromInstruction(insn32, 28, 4) == 0xE) {
772ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    MI.clear();
773ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    result = decodeInstruction(DecoderTableVFP32, MI, insn32, Address, this, STI);
774ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    if (result != MCDisassembler::Fail) {
775ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      Size = 4;
776ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      UpdateThumbVFPPredicate(MI);
777ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      return result;
778ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    }
7798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
780b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
7814ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  MI.clear();
7824ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  result = decodeInstruction(DecoderTableVFPV832, MI, insn32, Address, this, STI);
7834ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  if (result != MCDisassembler::Fail) {
7844ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly    Size = 4;
7854ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly    return result;
7864ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly  }
7874ea250524f77a67102118747dad6ee69f9f3b3aaJoey Gouly
788ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville  if (fieldFromInstruction(insn32, 28, 4) == 0xE) {
789ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    MI.clear();
790ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    result = decodeInstruction(DecoderTableNEONDup32, MI, insn32, Address,
791ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville                               this, STI);
792ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    if (result != MCDisassembler::Fail) {
793ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      Size = 4;
794ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      Check(result, AddThumbPredicate(MI));
795ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville      return result;
796ebc3938ae717d7352de800344c3ad5a1bceb74e5Amaury de la Vieuville    }
797ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson  }
798ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson
799fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  if (fieldFromInstruction(insn32, 24, 8) == 0xF9) {
800ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    MI.clear();
801ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    uint32_t NEONLdStInsn = insn32;
802ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    NEONLdStInsn &= 0xF0FFFFFF;
803ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    NEONLdStInsn |= 0x04000000;
804fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    result = decodeInstruction(DecoderTableNEONLoadStore32, MI, NEONLdStInsn,
805fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                               Address, this, STI);
806c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (result != MCDisassembler::Fail) {
807ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson      Size = 4;
808d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson      Check(result, AddThumbPredicate(MI));
80983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson      return result;
810ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    }
811ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson  }
812ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson
813fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  if (fieldFromInstruction(insn32, 24, 4) == 0xF) {
814ef2865a8eadffd7e346b9bc70c647578010b6afdOwen Anderson    MI.clear();
8158533ebad6f6e407215497ca50771f323058f5576Owen Anderson    uint32_t NEONDataInsn = insn32;
8168533ebad6f6e407215497ca50771f323058f5576Owen Anderson    NEONDataInsn &= 0xF0FFFFFF; // Clear bits 27-24
8178533ebad6f6e407215497ca50771f323058f5576Owen Anderson    NEONDataInsn |= (NEONDataInsn & 0x10000000) >> 4; // Move bit 28 to bit 24
8188533ebad6f6e407215497ca50771f323058f5576Owen Anderson    NEONDataInsn |= 0x12000000; // Set bits 28 and 25
819fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    result = decodeInstruction(DecoderTableNEONData32, MI, NEONDataInsn,
820fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach                               Address, this, STI);
821c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (result != MCDisassembler::Fail) {
8228533ebad6f6e407215497ca50771f323058f5576Owen Anderson      Size = 4;
823d2fc31b3f75700dc89305cb161f3bca7f1a39befOwen Anderson      Check(result, AddThumbPredicate(MI));
82483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson      return result;
8258533ebad6f6e407215497ca50771f323058f5576Owen Anderson    }
8268533ebad6f6e407215497ca50771f323058f5576Owen Anderson  }
8278533ebad6f6e407215497ca50771f323058f5576Owen Anderson
82819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  MI.clear();
82919c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  uint32_t NEONv8Insn = insn32;
83019c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  NEONv8Insn &= 0xF3FFFFFF; // Clear bits 27-26
83119c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  result = decodeInstruction(DecoderTablev8NEON32, MI, NEONv8Insn, Address,
83219c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly                             this, STI);
83319c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  if (result != MCDisassembler::Fail) {
83419c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    Size = 4;
83519c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly    return result;
83619c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  }
83719c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly
83819c14abf1c4ccebfa7d07bdd6ea8462a15c0b749Joey Gouly  MI.clear();
83986ce852a15f0c66601dcaf55644d8c4ec268906fBenjamin Kramer  Size = 0;
840c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Fail;
841b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
842b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
843b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
8448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Andersonextern "C" void LLVMInitializeARMDisassembler() {
8458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  TargetRegistry::RegisterMCDisassembler(TheARMTarget,
8468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                         createARMDisassembler);
8478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  TargetRegistry::RegisterMCDisassembler(TheThumbTarget,
8488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                         createThumbDisassembler);
8498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
850b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
851b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t GPRDecoderTable[] = {
8528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R0, ARM::R1, ARM::R2, ARM::R3,
8538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R4, ARM::R5, ARM::R6, ARM::R7,
8548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R8, ARM::R9, ARM::R10, ARM::R11,
8558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM::R12, ARM::SP, ARM::LR, ARM::PC
8568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
8578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
858c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
8598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
8608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 15)
861c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
862b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
8638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = GPRDecoderTable[RegNo];
8648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
865c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
8668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
8678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
868a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
869c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeGPRnopcRegisterClass(MCInst &Inst, unsigned RegNo,
870c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
8715c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  DecodeStatus S = MCDisassembler::Success;
8725c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga
8735c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  if (RegNo == 15)
8745c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga    S = MCDisassembler::SoftFail;
8755c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga
8765c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
8775c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga
8785c062ad92672f22e61a4b20a9954af3db3b72bd6Silviu Baranga  return S;
87951c9805c4bcca635bc6a854e4a246ebd4258f512Owen Anderson}
88051c9805c4bcca635bc6a854e4a246ebd4258f512Owen Anderson
881f86e436fb95670ed110818fefa403f21ae104639Mihai Popastatic DecodeStatus
882f86e436fb95670ed110818fefa403f21ae104639Mihai PopaDecodeGPRwithAPSRRegisterClass(MCInst &Inst, unsigned RegNo,
883f86e436fb95670ed110818fefa403f21ae104639Mihai Popa                               uint64_t Address, const void *Decoder) {
884f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  DecodeStatus S = MCDisassembler::Success;
885f86e436fb95670ed110818fefa403f21ae104639Mihai Popa
886f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  if (RegNo == 15)
887f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  {
888f86e436fb95670ed110818fefa403f21ae104639Mihai Popa    Inst.addOperand(MCOperand::CreateReg(ARM::APSR_NZCV));
889f86e436fb95670ed110818fefa403f21ae104639Mihai Popa    return MCDisassembler::Success;
890f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  }
891f86e436fb95670ed110818fefa403f21ae104639Mihai Popa
892f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
893f86e436fb95670ed110818fefa403f21ae104639Mihai Popa  return S;
894f86e436fb95670ed110818fefa403f21ae104639Mihai Popa}
895f86e436fb95670ed110818fefa403f21ae104639Mihai Popa
896c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetGPRRegisterClass(MCInst &Inst, unsigned RegNo,
8978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
8988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 7)
899c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
9008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder);
9018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
9028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
9033862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuvillestatic const uint16_t GPRPairDecoderTable[] = {
9043862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  ARM::R0_R1, ARM::R2_R3,   ARM::R4_R5,  ARM::R6_R7,
9053862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  ARM::R8_R9, ARM::R10_R11, ARM::R12_SP
9063862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville};
9073862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9083862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuvillestatic DecodeStatus DecodeGPRPairRegisterClass(MCInst &Inst, unsigned RegNo,
9093862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
9103862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
9113862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9123862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (RegNo > 13)
9133862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville    return MCDisassembler::Fail;
9143862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9153862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if ((RegNo & 1) || RegNo == 0xe)
9163862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville     S = MCDisassembler::SoftFail;
9173862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
9183862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  unsigned RegisterPair = GPRPairDecoderTable[RegNo/2];
9193862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  Inst.addOperand(MCOperand::CreateReg(RegisterPair));
9203862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  return S;
9213862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville}
9223862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville
923c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodetcGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
9258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = 0;
9268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (RegNo) {
9278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
9288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R0;
9298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
9318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R1;
9328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
9348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R2;
9358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
9378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R3;
9388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 9:
9408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R9;
9418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 12:
9438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Register = ARM::R12;
9448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
9458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
946c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
9478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
948b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
9498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
950c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
9518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
9528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
953c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecoderGPRRegisterClass(MCInst &Inst, unsigned RegNo,
9548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
95507c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
95607c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  if (RegNo == 13 || RegNo == 15)
95707c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville    S = MCDisassembler::SoftFail;
95807c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  Check(S, DecodeGPRRegisterClass(Inst, RegNo, Address, Decoder));
95907c3e159d8fffc8b16bcd52cc395a78007c62910Amaury de la Vieuville  return S;
9608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
961bd3327654b5708f1ba92aff3ab25b1bbf5034797Kevin Enderby
962b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t SPRDecoderTable[] = {
9638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::S0,  ARM::S1,  ARM::S2,  ARM::S3,
9648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::S4,  ARM::S5,  ARM::S6,  ARM::S7,
9658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::S8,  ARM::S9, ARM::S10, ARM::S11,
9668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S12, ARM::S13, ARM::S14, ARM::S15,
9678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S16, ARM::S17, ARM::S18, ARM::S19,
9688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S20, ARM::S21, ARM::S22, ARM::S23,
9698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S24, ARM::S25, ARM::S26, ARM::S27,
9708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::S28, ARM::S29, ARM::S30, ARM::S31
9718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
9728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
973c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegisterClass(MCInst &Inst, unsigned RegNo,
9748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
9758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 31)
976c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
977b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
9788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = SPRDecoderTable[RegNo];
9798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
980c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
981b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
982b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
983b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t DPRDecoderTable[] = {
9848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::D0,  ARM::D1,  ARM::D2,  ARM::D3,
9858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::D4,  ARM::D5,  ARM::D6,  ARM::D7,
9868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::D8,  ARM::D9, ARM::D10, ARM::D11,
9878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D12, ARM::D13, ARM::D14, ARM::D15,
9888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D16, ARM::D17, ARM::D18, ARM::D19,
9898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D20, ARM::D21, ARM::D22, ARM::D23,
9908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D24, ARM::D25, ARM::D26, ARM::D27,
9918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::D28, ARM::D29, ARM::D30, ARM::D31
9928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
9938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
994c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegisterClass(MCInst &Inst, unsigned RegNo,
9958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
9968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 31)
997c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
998b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
9998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = DPRDecoderTable[RegNo];
10008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
1001c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
10028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
10038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1004c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPR_8RegisterClass(MCInst &Inst, unsigned RegNo,
10058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
10068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 7)
1007c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
10098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
1010b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1011a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
1012c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeDPR_VFP2RegisterClass(MCInst &Inst, unsigned RegNo,
1013c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                            uint64_t Address, const void *Decoder) {
10148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (RegNo > 15)
1015c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeDPRRegisterClass(Inst, RegNo, Address, Decoder);
10178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
1018b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1019b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t QPRDecoderTable[] = {
10208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::Q0,  ARM::Q1,  ARM::Q2,  ARM::Q3,
10218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::Q4,  ARM::Q5,  ARM::Q6,  ARM::Q7,
10228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson     ARM::Q8,  ARM::Q9, ARM::Q10, ARM::Q11,
10238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM::Q12, ARM::Q13, ARM::Q14, ARM::Q15
10248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson};
1025af5b0e851e42d7de1247c4084ba75a76c4497ca6Johnny Chen
1026bd3327654b5708f1ba92aff3ab25b1bbf5034797Kevin Enderby
1027c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeQPRRegisterClass(MCInst &Inst, unsigned RegNo,
10288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
1029bac932e9c3c4305a3c73598f3d0dc55de53d4c68Mihai Popa  if (RegNo > 31 || (RegNo & 1) != 0)
1030c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  RegNo >>= 1;
1032b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
10338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Register = QPRDecoderTable[RegNo];
10348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(Register));
1035c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
1036b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1037b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1038b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t DPairDecoderTable[] = {
103928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q0,  ARM::D1_D2,   ARM::Q1,  ARM::D3_D4,   ARM::Q2,  ARM::D5_D6,
104028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q3,  ARM::D7_D8,   ARM::Q4,  ARM::D9_D10,  ARM::Q5,  ARM::D11_D12,
104128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q6,  ARM::D13_D14, ARM::Q7,  ARM::D15_D16, ARM::Q8,  ARM::D17_D18,
104228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q9,  ARM::D19_D20, ARM::Q10, ARM::D21_D22, ARM::Q11, ARM::D23_D24,
104328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q12, ARM::D25_D26, ARM::Q13, ARM::D27_D28, ARM::Q14, ARM::D29_D30,
104428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  ARM::Q15
104528f08c93e75d291695ea89b9004145103292e85bJim Grosbach};
104628f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1047c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairRegisterClass(MCInst &Inst, unsigned RegNo,
104828f08c93e75d291695ea89b9004145103292e85bJim Grosbach                                   uint64_t Address, const void *Decoder) {
104928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  if (RegNo > 30)
105028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    return MCDisassembler::Fail;
105128f08c93e75d291695ea89b9004145103292e85bJim Grosbach
105228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  unsigned Register = DPairDecoderTable[RegNo];
105328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  Inst.addOperand(MCOperand::CreateReg(Register));
105428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  return MCDisassembler::Success;
105528f08c93e75d291695ea89b9004145103292e85bJim Grosbach}
105628f08c93e75d291695ea89b9004145103292e85bJim Grosbach
1057b78ca423844f19f4a838abb49b4b4fa7ae499707Craig Topperstatic const uint16_t DPairSpacedDecoderTable[] = {
1058c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D0_D2,   ARM::D1_D3,   ARM::D2_D4,   ARM::D3_D5,
1059c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D4_D6,   ARM::D5_D7,   ARM::D6_D8,   ARM::D7_D9,
1060c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D8_D10,  ARM::D9_D11,  ARM::D10_D12, ARM::D11_D13,
1061c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D12_D14, ARM::D13_D15, ARM::D14_D16, ARM::D15_D17,
1062c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D16_D18, ARM::D17_D19, ARM::D18_D20, ARM::D19_D21,
1063c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D20_D22, ARM::D21_D23, ARM::D22_D24, ARM::D23_D25,
1064c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D24_D26, ARM::D25_D27, ARM::D26_D28, ARM::D27_D29,
1065c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  ARM::D28_D30, ARM::D29_D31
1066c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach};
1067c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1068c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPairSpacedRegisterClass(MCInst &Inst,
1069c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                                                   unsigned RegNo,
1070c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                                                   uint64_t Address,
1071c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach                                                   const void *Decoder) {
1072c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  if (RegNo > 29)
1073c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    return MCDisassembler::Fail;
1074c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1075c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  unsigned Register = DPairSpacedDecoderTable[RegNo];
1076c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  Inst.addOperand(MCOperand::CreateReg(Register));
1077c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  return MCDisassembler::Success;
1078c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach}
1079c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach
1080c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePredicateOperand(MCInst &Inst, unsigned Val,
10818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
1082c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Val == 0xF) return MCDisassembler::Fail;
1083bd9091c18d85d6649763165c4951d7b5ff2e31a9Owen Anderson  // AL predicate is not allowed on Thumb1 branches.
1084bd9091c18d85d6649763165c4951d7b5ff2e31a9Owen Anderson  if (Inst.getOpcode() == ARM::tBcc && Val == 0xE)
1085c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
10868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
10878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Val == ARMCC::AL) {
10888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
10898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else
10908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
1091c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
1092b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1093b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1094c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCCOutOperand(MCInst &Inst, unsigned Val,
10958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
10968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Val)
10978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::CPSR));
10988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
10998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
1100c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
11018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
11026bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen
1103c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSOImmOperand(MCInst &Inst, unsigned Val,
11048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
11058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint32_t imm = Val & 0xFF;
11068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  uint32_t rot = (Val & 0xF00) >> 7;
1107ecb830e45c216209f4a8b95d687f1ef4e9185beeEli Friedman  uint32_t rot_imm = (imm >> rot) | (imm << ((32-rot) & 0x1F));
11088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(rot_imm));
1109c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
11108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
11118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1112c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegImmOperand(MCInst &Inst, unsigned Val,
11138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
1114a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
11158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1116fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1117fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Val, 5, 2);
1118fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 7, 5);
11198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Register-immediate
1121a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1122a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
11238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
11258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (type) {
11268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
11278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsl;
11288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
11308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsr;
11318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
11338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::asr;
11348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
11368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::ror;
11378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11386bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen  }
11398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Shift == ARM_AM::ror && imm == 0)
11418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Shift = ARM_AM::rrx;
11428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned Op = Shift | (imm << 3);
11448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Op));
11458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
114683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
11478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
11488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1149c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegRegOperand(MCInst &Inst, unsigned Val,
11508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
1151a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
11528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1153fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
1154fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Val, 5, 2);
1155fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rs = fieldFromInstruction(Val, 8, 4);
11568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Register-register
1158a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1159a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1160a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rs, Address, Decoder)))
1161a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
11628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
11638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM_AM::ShiftOpc Shift = ARM_AM::lsl;
11648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (type) {
11658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
11668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsl;
11678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
11698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::lsr;
11708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
11728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::asr;
11738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
11758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      Shift = ARM_AM::ror;
11768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
11776bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen  }
11786bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen
11798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Shift));
11806bcf52f00a4fc352e90ff11681a0e69f9757eb37Johnny Chen
118183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1182b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1183b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1184c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeRegListOperand(MCInst &Inst, unsigned Val,
11858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1186a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
118783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1188921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson  bool writebackLoad = false;
1189921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson  unsigned writebackReg = 0;
1190921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson  switch (Inst.getOpcode()) {
1191921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    default:
1192921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      break;
1193921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    case ARM::LDMIA_UPD:
1194921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    case ARM::LDMDB_UPD:
1195921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    case ARM::LDMIB_UPD:
1196921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    case ARM::LDMDA_UPD:
1197921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    case ARM::t2LDMIA_UPD:
1198921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson    case ARM::t2LDMDB_UPD:
1199921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      writebackLoad = true;
1200921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      writebackReg = Inst.getOperand(0).getReg();
1201921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      break;
1202921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson  }
1203921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson
120426d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson  // Empty register lists are not allowed.
12054dc8bdf87d402ad8c91d9a72777d9576c5461e40Benjamin Kramer  if (Val == 0) return MCDisassembler::Fail;
12068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  for (unsigned i = 0; i < 16; ++i) {
1207ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson    if (Val & (1 << i)) {
1208a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, i, Address, Decoder)))
1209a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
1210921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      // Writeback not allowed if Rn is in the target list.
1211921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson      if (writebackLoad && writebackReg == Inst.end()[-1].getReg())
1212921d01ae1ff4e1dad2daeed22f8259a7a520412fOwen Anderson        Check(S, MCDisassembler::SoftFail);
1213ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson    }
1214b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen  }
12158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
121683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1217b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1218b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1219c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSPRRegListOperand(MCInst &Inst, unsigned Val,
12208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1221a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
122283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1223fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1224fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned regs = fieldFromInstruction(Val, 0, 8);
12258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1226242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  // In case of unpredictable encoding, tweak the operands.
1227242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  if (regs == 0 || (Vd + regs) > 32) {
1228242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = Vd + regs > 32 ? 32 - Vd : regs;
1229242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = std::max( 1u, regs);
1230242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    S = MCDisassembler::SoftFail;
1231242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  }
1232242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover
1233a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Vd, Address, Decoder)))
1234a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1235ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  for (unsigned i = 0; i < (regs - 1); ++i) {
1236a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeSPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1237a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
1238ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
12398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
124083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1241b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1242b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1243c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDPRRegListOperand(MCInst &Inst, unsigned Val,
12448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1245a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
124683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1247fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = fieldFromInstruction(Val, 8, 5);
1248242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  unsigned regs = fieldFromInstruction(Val, 1, 7);
1249b422d0b65e15435b6aef4a92f5663db9ec6659d4Silviu Baranga
1250242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  // In case of unpredictable encoding, tweak the operands.
1251242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  if (regs == 0 || regs > 16 || (Vd + regs) > 32) {
1252242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = Vd + regs > 32 ? 32 - Vd : regs;
1253242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = std::max( 1u, regs);
1254242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    regs = std::min(16u, regs);
1255242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover    S = MCDisassembler::SoftFail;
1256242c9f4615feeee2fbdd1f29cd9a8e8ffd43c075Tim Northover  }
12578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1258a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
1259a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
1260ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  for (unsigned i = 0; i < (regs - 1); ++i) {
1261a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeDPRRegisterClass(Inst, ++Vd, Address, Decoder)))
1262a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
1263ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
12648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
126583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
1266b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1267b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1268c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeBitfieldMaskOperand(MCInst &Inst, unsigned Val,
12698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                      uint64_t Address, const void *Decoder) {
127010cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // This operand encodes a mask of contiguous zeros between a specified MSB
127110cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // and LSB.  To decode it, we create the mask of all bits MSB-and-lower,
127210cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // the mask of all bits LSB-and-lower, and then xor them to create
1273c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach  // the mask of that's all ones on [msb, lsb].  Finally we not it to
127410cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson  // create the final mask.
1275fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned msb = fieldFromInstruction(Val, 5, 5);
1276fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned lsb = fieldFromInstruction(Val, 0, 5);
127789db0f690c3238544e59ea3bf2b7a0d6bc8a6544Owen Anderson
1278cb775519279cd1471c490eb5bf4e3ce663fcdc7dOwen Anderson  DecodeStatus S = MCDisassembler::Success;
12791c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby  if (lsb > msb) {
12801c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    Check(S, MCDisassembler::SoftFail);
12811c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    // The check above will cause the warning for the "potentially undefined
12821c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    // instruction encoding" but we can't build a bad MCOperand value here
12831c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    // with a lsb > msb or else printing the MCInst will cause a crash.
12841c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby    lsb = msb;
12851c83093cd5f4f6d33e732c817bb5afd033531bebKevin Enderby  }
1286cb775519279cd1471c490eb5bf4e3ce663fcdc7dOwen Anderson
12878b22778431cdeb112366ed5dc6283b3a7af19018Owen Anderson  uint32_t msb_mask = 0xFFFFFFFF;
12888b22778431cdeb112366ed5dc6283b3a7af19018Owen Anderson  if (msb != 31) msb_mask = (1U << (msb+1)) - 1;
12898b22778431cdeb112366ed5dc6283b3a7af19018Owen Anderson  uint32_t lsb_mask = (1U << lsb) - 1;
129089db0f690c3238544e59ea3bf2b7a0d6bc8a6544Owen Anderson
12918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(~(msb_mask ^ lsb_mask)));
1292cb775519279cd1471c490eb5bf4e3ce663fcdc7dOwen Anderson  return S;
1293b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen}
1294b68a3ee82a8a34f7bae1d68d76f574e76a5535efJohnny Chen
1295c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCopMemInstruction(MCInst &Inst, unsigned Insn,
12968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
1297a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
129883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1299fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1300fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned CRd = fieldFromInstruction(Insn, 12, 4);
1301fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned coproc = fieldFromInstruction(Insn, 8, 4);
1302fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 8);
1303fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1304fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Insn, 23, 1);
13058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
13068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
13078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OFFSET:
13088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_PRE:
13098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_POST:
13108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OPTION:
13118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OFFSET:
13128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_PRE:
13138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_POST:
13148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OPTION:
13158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OFFSET:
13168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_PRE:
13178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_POST:
13188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OPTION:
13198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OFFSET:
13208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_PRE:
13218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_POST:
13228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OPTION:
13238a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_OFFSET:
13248a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_PRE:
13258a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_POST:
13268a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDC_OPTION:
13278a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_OFFSET:
13288a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_PRE:
13298a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_POST:
13308a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2LDCL_OPTION:
13318a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_OFFSET:
13328a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_PRE:
13338a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_POST:
13348a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STC_OPTION:
13358a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_OFFSET:
13368a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_PRE:
13378a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_POST:
13388a83f71301fdf0e2cea8ecdf413f192ac48ddc5cOwen Anderson    case ARM::t2STCL_OPTION:
13398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      if (coproc == 0xA || coproc == 0xB)
1340c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail;
13418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
13428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
13438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
13448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
13458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
13468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(coproc));
13478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(CRd));
1348a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1349a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
13508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
13518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
1352c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2_OFFSET:
1353c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2L_OFFSET:
1354c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2_PRE:
1355c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC2L_PRE:
1356c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2_OFFSET:
1357c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2L_OFFSET:
1358c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2_PRE:
1359c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC2L_PRE:
1360c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2_OFFSET:
1361c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2L_OFFSET:
1362c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2_PRE:
1363c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC2L_PRE:
1364c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2_OFFSET:
1365c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2L_OFFSET:
1366c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2_PRE:
1367c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC2L_PRE:
1368c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC_OFFSET:
1369c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDCL_OFFSET:
1370c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDC_PRE:
1371c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2LDCL_PRE:
1372c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC_OFFSET:
1373c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STCL_OFFSET:
1374c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STC_PRE:
1375c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::t2STCL_PRE:
1376c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC_OFFSET:
1377c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDCL_OFFSET:
1378c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDC_PRE:
1379c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::LDCL_PRE:
1380c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC_OFFSET:
1381c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STCL_OFFSET:
1382c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC_PRE:
1383c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STCL_PRE:
138481b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach      imm = ARM_AM::getAM5Opc(U ? ARM_AM::add : ARM_AM::sub, imm);
138581b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach      Inst.addOperand(MCOperand::CreateImm(imm));
138681b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach      break;
138781b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDC2_POST:
138881b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDC2L_POST:
138981b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STC2_POST:
139081b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STC2L_POST:
139181b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDC2_POST:
139281b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDC2L_POST:
139381b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::STC2_POST:
139481b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::STC2L_POST:
139581b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDC_POST:
139681b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2LDCL_POST:
139781b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STC_POST:
139881b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::t2STCL_POST:
139981b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDC_POST:
140081b2928d80047cb6c8ae0048185742abae1d9dfaJim Grosbach    case ARM::LDCL_POST:
1401c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STC_POST:
1402c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach    case ARM::STCL_POST:
14038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      imm |= U << 8;
1404c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      // fall through.
14058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
1406c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      // The 'option' variant doesn't encode 'U' in the immediate since
1407c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      // the immediate is unsigned [0,255].
1408c66e7afcf2810a2c1ebf08514eaf45c478e5ff67Jim Grosbach      Inst.addOperand(MCOperand::CreateImm(imm));
14098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
14118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
14138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OFFSET:
14148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_PRE:
14158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_POST:
14168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDC_OPTION:
14178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OFFSET:
14188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_PRE:
14198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_POST:
14208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDCL_OPTION:
14218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OFFSET:
14228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_PRE:
14238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_POST:
14248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STC_OPTION:
14258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OFFSET:
14268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_PRE:
14278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_POST:
14288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STCL_OPTION:
1429a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1430a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
14318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
14338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
14358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
143683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
14379899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan}
14389899f70a7406d632c82849978bf6981f1ee4ccb5Sean Callanan
1439a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
1440c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeAddrMode2IdxInstruction(MCInst &Inst, unsigned Insn,
1441c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                              uint64_t Address, const void *Decoder) {
1442a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
144383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1444fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1445fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1446fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1447fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
1448fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1449fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned reg = fieldFromInstruction(Insn, 25, 1);
1450fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
1451fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
14528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // On stores, the writeback operand precedes Rt.
14548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
14558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STR_POST_IMM:
14568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STR_POST_REG:
1457508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::STRB_POST_IMM:
1458508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::STRB_POST_REG:
1459342ebd5f380637d965504dcc350f9d0d79bbe599Jim Grosbach    case ARM::STRT_POST_REG:
1460342ebd5f380637d965504dcc350f9d0d79bbe599Jim Grosbach    case ARM::STRT_POST_IMM:
146110348e70d567fb61f6c762d99e91e215c720ebd1Jim Grosbach    case ARM::STRBT_POST_REG:
146210348e70d567fb61f6c762d99e91e215c720ebd1Jim Grosbach    case ARM::STRBT_POST_IMM:
1463a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1464a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
14658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
14678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
14698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1470a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1471a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
14728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // On loads, the writeback operand comes after Rt.
14748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
14758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDR_POST_IMM:
14768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDR_POST_REG:
1477508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::LDRB_POST_IMM:
1478508e1d3db536b736063385eb1f885b446a1385caOwen Anderson    case ARM::LDRB_POST_REG:
14798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRBT_POST_REG:
14808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRBT_POST_IMM:
148159999264e6cfc7f5d59c9a92c8cd9baaa53434f4Jim Grosbach    case ARM::LDRT_POST_REG:
148259999264e6cfc7f5d59c9a92c8cd9baaa53434f4Jim Grosbach    case ARM::LDRT_POST_IMM:
1483a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1484a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
14858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
14878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
14888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
14898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1490a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1491a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
14928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  ARM_AM::AddrOpc Op = ARM_AM::add;
1494fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  if (!fieldFromInstruction(Insn, 23, 1))
14958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Op = ARM_AM::sub;
14968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
14978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  bool writeback = (P == 0) || (W == 1);
14988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned idx_mode = 0;
14998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (P && writeback)
15008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    idx_mode = ARMII::IndexModePre;
15018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else if (!P && writeback)
15028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    idx_mode = ARMII::IndexModePost;
15038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1504a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (writeback && (Rn == 15 || Rn == Rt))
1505a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    S = MCDisassembler::SoftFail; // UNPREDICTABLE
150671156a6e00d3dc4c531a421a76b3b6ee0ae7d0abOwen Anderson
15078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (reg) {
1508a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
1509a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
15108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    ARM_AM::ShiftOpc Opc = ARM_AM::lsl;
1511fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    switch( fieldFromInstruction(Insn, 5, 2)) {
15128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 0:
15138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::lsl;
15148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 1:
15168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::lsr;
15178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 2:
15198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::asr;
15208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 3:
15228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Opc = ARM_AM::ror;
15238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
15248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      default:
1525c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail;
15268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
1527fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned amt = fieldFromInstruction(Insn, 7, 5);
152893c7c449a1351542fa5a275587187154dbedb8e0Tim Northover    if (Opc == ARM_AM::ror && amt == 0)
152993c7c449a1351542fa5a275587187154dbedb8e0Tim Northover      Opc = ARM_AM::rrx;
15308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    unsigned imm = ARM_AM::getAM2Opc(Op, amt, Opc, idx_mode);
15318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
15328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imm));
15338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
15348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
15358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    unsigned tmp = ARM_AM::getAM2Opc(Op, imm, ARM_AM::lsl, idx_mode);
15368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(tmp));
15378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
15388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1539a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1540a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
15418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
154283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
15438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
15448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1545c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSORegMemOperand(MCInst &Inst, unsigned Val,
15468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
1547a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
154883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1549fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 13, 4);
1550fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val,  0, 4);
1551fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Val, 5, 2);
1552fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 7, 5);
1553fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Val, 12, 1);
15548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
155551157d22348fdbd4b7975877d5b58e53a6d5d3a2Owen Anderson  ARM_AM::ShiftOpc ShOp = ARM_AM::lsl;
15568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (type) {
15578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
15588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::lsl;
15598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
15618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::lsr;
15628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
15648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::asr;
15658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
15678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      ShOp = ARM_AM::ror;
15688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
15698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
15708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
157193c7c449a1351542fa5a275587187154dbedb8e0Tim Northover  if (ShOp == ARM_AM::ror && imm == 0)
157293c7c449a1351542fa5a275587187154dbedb8e0Tim Northover    ShOp = ARM_AM::rrx;
157393c7c449a1351542fa5a275587187154dbedb8e0Tim Northover
1574a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1575a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1576a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1577a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
15788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  unsigned shift;
15798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (U)
15808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    shift = ARM_AM::getAM2Opc(ARM_AM::add, imm, ShOp);
15818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
15828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    shift = ARM_AM::getAM2Opc(ARM_AM::sub, imm, ShOp);
15838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(shift));
15848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
158583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
15868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
15878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1588a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
1589c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeAddrMode3Instruction(MCInst &Inst, unsigned Insn,
1590c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
1591a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
159283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1593fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
1594fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1595fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
1596fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned type = fieldFromInstruction(Insn, 22, 1);
1597fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 8, 4);
1598fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = ((~fieldFromInstruction(Insn, 23, 1)) & 1) << 8;
1599fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1600fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
1601fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
16026fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga  unsigned Rt2 = Rt + 1;
16038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
16048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  bool writeback = (W == 1) | (P == 0);
1605c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson
1606c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson  // For {LD,ST}RD, Rt must be even, else undefined.
1607c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson  switch (Inst.getOpcode()) {
1608c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::STRD:
1609c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::STRD_PRE:
1610c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::STRD_POST:
1611c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::LDRD:
1612c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::LDRD_PRE:
1613c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson    case ARM::LDRD_POST:
16146fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt & 0x1) S = MCDisassembler::SoftFail;
16156fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16166fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    default:
16176fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16186fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga  }
16196fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga  switch (Inst.getOpcode()) {
16206fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRD:
16216fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRD_PRE:
16226fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRD_POST:
16236fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (P == 0 && W == 1)
16246fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16256fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga
16266fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (writeback && (Rn == 15 || Rn == Rt || Rn == Rt2))
16276fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16286fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rm == 15)
16296fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16306fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt2 == 15)
16316fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
1632fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (!type && fieldFromInstruction(Insn, 8, 4))
16336fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16346fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16356fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRH:
16366fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRH_PRE:
16376fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::STRH_POST:
16386fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt == 15)
16396fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16406fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (writeback && (Rn == 15 || Rn == Rt))
16416fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16426fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && Rm == 15)
16436fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16446fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16456fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRD:
16466fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRD_PRE:
16476fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRD_POST:
16486fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rn == 15){
16496fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        if (Rt2 == 15)
16506fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga          S = MCDisassembler::SoftFail;
16516fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        break;
16526fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      }
16536fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (P == 0 && W == 1)
16546fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16556fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && (Rt2 == 15 || Rm == 15 || Rm == Rt || Rm == Rt2))
16566fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16576fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && writeback && Rn == 15)
16586fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16596fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (writeback && (Rn == Rt || Rn == Rt2))
16606fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16616fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16626fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRH:
16636fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRH_PRE:
16646fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRH_POST:
16656fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rn == 15){
16666fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        if (Rt == 15)
16676fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga          S = MCDisassembler::SoftFail;
16686fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        break;
16696fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      }
16706fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (Rt == 15)
16716fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16726fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && Rm == 15)
16736fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16746fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && writeback && (Rn == 15 || Rn == Rt))
16756fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16766fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      break;
16776fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSH:
16786fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSH_PRE:
16796fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSH_POST:
16806fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSB:
16816fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSB_PRE:
16826fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga    case ARM::LDRSB_POST:
16836fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && Rn == 15){
16846fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        if (Rt == 15)
16856fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga          S = MCDisassembler::SoftFail;
16866fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        break;
16876fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      }
16886fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (type && (Rt == 15 || (writeback && Rn == Rt)))
16896fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16906fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && (Rt == 15 || Rm == 15))
16916fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
16926fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga      if (!type && writeback && (Rn == 15 || Rn == Rt))
16936fe310e1555dedba2b36dedae9a88eb900ad1804Silviu Baranga        S = MCDisassembler::SoftFail;
1694c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson      break;
1695a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    default:
1696a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      break;
1697c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson  }
1698c537f3be0c4ff7030afcdcd9f55133ce68eef773Owen Anderson
16998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (writeback) { // Writeback
17008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (P)
17018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      U |= ARMII::IndexModePre << 9;
17028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    else
17038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      U |= ARMII::IndexModePost << 9;
17048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
17058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // On stores, the writeback operand precedes Rt.
17068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
17078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD:
17088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_PRE:
17098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_POST:
171079628e92e1f903d50340d4cd3d1ea8c5fff63a87Owen Anderson    case ARM::STRH:
171179628e92e1f903d50340d4cd3d1ea8c5fff63a87Owen Anderson    case ARM::STRH_PRE:
171279628e92e1f903d50340d4cd3d1ea8c5fff63a87Owen Anderson    case ARM::STRH_POST:
1713a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1714a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
17158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
17178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
17198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1721a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
1722a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
17238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
17248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD:
17258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_PRE:
17268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::STRD_POST:
17278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD:
17288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_PRE:
17298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_POST:
1730a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt+1, Address, Decoder)))
1731a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
17328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
17348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
17378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (writeback) {
17388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    // On loads, the writeback operand comes after Rt.
17398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
17408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD:
17418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_PRE:
17428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRD_POST:
17430d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRH:
17440d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRH_PRE:
17450d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRH_POST:
17460d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSH:
17470d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSH_PRE:
17480d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSH_POST:
17490d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSB:
17500d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSB_PRE:
17510d09499cf3e2d927cdc53ec79895303ac12808acOwen Anderson    case ARM::LDRSB_POST:
17528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRHTr:
17538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::LDRSBTr:
1754a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1755a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
17568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
17588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
17608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1762a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1763a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
17648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
17658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (type) {
17668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
17678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(U | (imm << 4) | Rm));
17688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
1769a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
1770a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
17718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(U));
17728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
17738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1774a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1775a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
17768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
177783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
17788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
17798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1780c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeRFEInstruction(MCInst &Inst, unsigned Insn,
17818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1782a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
178383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1784fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1785fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mode = fieldFromInstruction(Insn, 23, 2);
17868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
17878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (mode) {
17888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 0:
17898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::da;
17908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 1:
17928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::ia;
17938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 2:
17958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::db;
17968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
17978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case 3:
17988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      mode = ARM_AM::ib;
17998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
18008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
18018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
18028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(mode));
1803a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1804a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
18058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
180683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
18078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
18088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
180946e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuvillestatic DecodeStatus DecodeQADDInstruction(MCInst &Inst, unsigned Insn,
181046e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville                               uint64_t Address, const void *Decoder) {
181146e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
181246e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
181346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
181446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
181546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
181646e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  unsigned pred = fieldFromInstruction(Insn, 28, 4);
181746e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
181846e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (pred == 0xF)
181946e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
182046e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
182146e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
182246e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
182346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
182446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
182546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
182646e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
182746e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
182846e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
182946e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  return S;
183046e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville}
183146e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
1832c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemMultipleWritebackInstruction(MCInst &Inst,
18338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  unsigned Insn,
18348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
1835a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
183683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
1837fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
1838fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
1839fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned reglist = fieldFromInstruction(Insn, 0, 16);
18408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
18418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xF) {
1842ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville    // Ambiguous with RFE and SRS
18438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
1844846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDA:
18458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDA);
18468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1847846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDA_UPD:
18488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDA_UPD);
18498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1850846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDB:
18518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDB);
18528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1853846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMDB_UPD:
18548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEDB_UPD);
18558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1856846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIA:
18578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIA);
18588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1859846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIA_UPD:
18608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIA_UPD);
18618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1862846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIB:
18638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIB);
18648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1865846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::LDMIB_UPD:
18668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::RFEIB_UPD);
18678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
1868846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDA:
1869846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDA);
1870846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1871846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDA_UPD:
1872846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDA_UPD);
1873846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1874846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDB:
1875846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDB);
1876846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1877846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMDB_UPD:
1878846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSDB_UPD);
1879846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1880846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIA:
1881846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIA);
1882846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1883846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIA_UPD:
1884846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIA_UPD);
1885846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1886846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIB:
1887846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIB);
1888846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1889846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      case ARM::STMIB_UPD:
1890846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        Inst.setOpcode(ARM::SRSIB_UPD);
1891846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson        break;
1892846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      default:
1893ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville        return MCDisassembler::Fail;
18948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
1895846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson
1896846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson    // For stores (which become SRS's, the only operand is the mode.
1897fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    if (fieldFromInstruction(Insn, 20, 1) == 0) {
1898ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville      // Check SRS encoding constraints
1899ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville      if (!(fieldFromInstruction(Insn, 22, 1) == 1 &&
1900ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville            fieldFromInstruction(Insn, 20, 1) == 0))
1901ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville        return MCDisassembler::Fail;
1902ae50ddb2aeaec7dd91ef8db3918688c104a6baedAmaury de la Vieuville
1903846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      Inst.addOperand(
1904fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach          MCOperand::CreateImm(fieldFromInstruction(Insn, 0, 4)));
1905846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson      return S;
1906846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson    }
1907846dd95f87f62e2faa6092f99b521ecd9790121aOwen Anderson
19088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    return DecodeRFEInstruction(Inst, Insn, Address, Decoder);
19098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
19108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1911a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1912a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1913a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
1914a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail; // Tied
1915a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
1916a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
1917a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeRegListOperand(Inst, reglist, Address, Decoder)))
1918a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
19198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
192083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
19218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
19228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1923c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCPSInstruction(MCInst &Inst, unsigned Insn,
19248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
1925fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imod = fieldFromInstruction(Insn, 18, 2);
1926fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned M = fieldFromInstruction(Insn, 17, 1);
1927fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned iflags = fieldFromInstruction(Insn, 6, 3);
1928fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mode = fieldFromInstruction(Insn, 0, 5);
19298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1930a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
193114090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson
193246e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  // This decoder is called from multiple location that do not check
193346e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  // the full encoding is valid before they do.
193446e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville  if (fieldFromInstruction(Insn, 5, 1) != 0 ||
193546e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville      fieldFromInstruction(Insn, 16, 1) != 0 ||
193646e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville      fieldFromInstruction(Insn, 20, 8) != 0x10)
193746e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville    return MCDisassembler::Fail;
193846e136c952e0242308db2682ba2ec4020cdcd006Amaury de la Vieuville
193935008c2f8dcfe55960fe4efea3a26e526d437ad6Owen Anderson  // imod == '01' --> UNPREDICTABLE
194014090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
194114090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  // return failure here.  The '01' imod value is unprintable, so there's
194214090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  // nothing useful we could do even if we returned UNPREDICTABLE.
194335008c2f8dcfe55960fe4efea3a26e526d437ad6Owen Anderson
1944c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (imod == 1) return MCDisassembler::Fail;
194514090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson
194614090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  if (imod && M) {
19478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::CPS3p);
19488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
19498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
19508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
195114090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  } else if (imod && !M) {
19528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::CPS2p);
19538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
19548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
1955c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (mode) S = MCDisassembler::SoftFail;
195614090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  } else if (!imod && M) {
19578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::CPS1p);
19588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
1959c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (iflags) S = MCDisassembler::SoftFail;
19601dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson  } else {
196114090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson    // imod == '00' && M == '0' --> UNPREDICTABLE
19621dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson    Inst.setOpcode(ARM::CPS1p);
19631dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
1964c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
19651dd56f05e1bc3e7f66f2b0de4b5ea3692136a77fOwen Anderson  }
19668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
196714090bf2636edf5e46a2c12a312b1889f5335d7dOwen Anderson  return S;
19688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
19698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
1970c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2CPSInstruction(MCInst &Inst, unsigned Insn,
19716153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson                                 uint64_t Address, const void *Decoder) {
1972fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imod = fieldFromInstruction(Insn, 9, 2);
1973fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned M = fieldFromInstruction(Insn, 8, 1);
1974fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned iflags = fieldFromInstruction(Insn, 5, 3);
1975fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mode = fieldFromInstruction(Insn, 0, 5);
19766153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
1977a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
19786153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
19796153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // imod == '01' --> UNPREDICTABLE
19806153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // NOTE: Even though this is technically UNPREDICTABLE, we choose to
19816153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // return failure here.  The '01' imod value is unprintable, so there's
19826153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  // nothing useful we could do even if we returned UNPREDICTABLE.
19836153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
1984c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (imod == 1) return MCDisassembler::Fail;
19856153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
19866153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  if (imod && M) {
19876153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.setOpcode(ARM::t2CPS3p);
19886153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
19896153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
19906153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
19916153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  } else if (imod && !M) {
19926153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.setOpcode(ARM::t2CPS2p);
19936153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(imod));
19946153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(iflags));
1995c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (mode) S = MCDisassembler::SoftFail;
19966153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  } else if (!imod && M) {
19976153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.setOpcode(ARM::t2CPS1p);
19986153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson    Inst.addOperand(MCOperand::CreateImm(mode));
1999c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (iflags) S = MCDisassembler::SoftFail;
20006153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  } else {
20011ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    // imod == '00' && M == '0' --> this is a HINT instruction
20021ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    int imm = fieldFromInstruction(Insn, 0, 8);
20031ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    // HINT are defined only for immediate in [0..4]
20041ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    if(imm > 4) return MCDisassembler::Fail;
20051ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    Inst.setOpcode(ARM::t2HINT);
20061ad3a410beff11913db0573942fb51b651d01a13Quentin Colombet    Inst.addOperand(MCOperand::CreateImm(imm));
20076153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  }
20086153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
20096153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson  return S;
20106153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson}
20116153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
2012c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2MOVTWInstruction(MCInst &Inst, unsigned Insn,
20139e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                 uint64_t Address, const void *Decoder) {
20149e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  DecodeStatus S = MCDisassembler::Success;
20159e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2016fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 8, 4);
20179e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  unsigned imm = 0;
20189e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2019fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 0, 8) << 0);
2020fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 12, 3) << 8);
2021fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
2022fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 26, 1) << 11);
20239e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20249e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (Inst.getOpcode() == ARM::t2MOVTi16)
20259e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
20269e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby      return MCDisassembler::Fail;
20279e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!Check(S, DecoderGPRRegisterClass(Inst, Rd, Address, Decoder)))
20289e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    return MCDisassembler::Fail;
20299e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20309e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
20319e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm));
20329e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20339e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  return S;
20349e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
20359e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2036c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeArmMOVTWInstruction(MCInst &Inst, unsigned Insn,
20379e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                 uint64_t Address, const void *Decoder) {
20389e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  DecodeStatus S = MCDisassembler::Success;
20399e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2040fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2041fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
20429e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  unsigned imm = 0;
20439e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
2044fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 0, 12) << 0);
2045fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= (fieldFromInstruction(Insn, 16, 4) << 12);
20469e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20479e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (Inst.getOpcode() == ARM::MOVTi16)
20484521019c6fd23680c583abe086067fc1c569bad1Tim Northover    if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
20499e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby      return MCDisassembler::Fail;
20504521019c6fd23680c583abe086067fc1c569bad1Tim Northover
20514521019c6fd23680c583abe086067fc1c569bad1Tim Northover  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
20529e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    return MCDisassembler::Fail;
20539e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20549e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!tryAddingSymbolicOperand(Address, imm, false, 4, Inst, Decoder))
20559e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm));
20569e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20579e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
20589e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    return MCDisassembler::Fail;
20599e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
20609e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  return S;
20619e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby}
20626153a036f544beb03dfc4d58edc28cf42712743dOwen Anderson
2063c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSMLAInstruction(MCInst &Inst, unsigned Insn,
20648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
2065a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
206683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2067fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 16, 4);
2068fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 0, 4);
2069fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 8, 4);
2070fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Ra = fieldFromInstruction(Insn, 12, 4);
2071fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
20728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
20738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xF)
20748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
20758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2076a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
2077a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2078a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
2079a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2080a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
2081a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2082a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Ra, Address, Decoder)))
2083a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
20848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2085a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2086a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
20871fb6673bc2f0a404f4f914bf381c627402ac7c6bOwen Anderson
208883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
20898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
20908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2091c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrModeImm12Operand(MCInst &Inst, unsigned Val,
20928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                           uint64_t Address, const void *Decoder) {
2093a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
209483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2095fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned add = fieldFromInstruction(Val, 12, 1);
2096fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 12);
2097fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 13, 4);
20988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2099a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2100a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (!add) imm *= -1;
21038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (imm == 0 && !add) imm = INT32_MIN;
21048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
21059e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  if (Rn == 15)
21069e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    tryAddingPcLoadReferenceComment(Address, Address + imm + 8, Decoder);
21078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
210883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
21098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
21108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2111c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode5Operand(MCInst &Inst, unsigned Val,
21128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
2113a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
211483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2115fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 9, 4);
2116fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Val, 8, 1);
2117fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 8);
21188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2119a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2120a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (U)
21238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::add, imm)));
21248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
21258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(ARM_AM::getAM5Opc(ARM_AM::sub, imm)));
21268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
212783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
21288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
21298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2130c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode7Operand(MCInst &Inst, unsigned Val,
21318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
21328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  return DecodeGPRRegisterClass(Inst, Val, Address, Decoder);
21338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
21348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2135a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
21362a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin EnderbyDecodeT2BInstruction(MCInst &Inst, unsigned Insn,
21372a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                     uint64_t Address, const void *Decoder) {
2138445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  DecodeStatus Status = MCDisassembler::Success;
2139445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby
2140445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // Note the J1 and J2 values are from the encoded instruction.  So here
2141445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // change them to I1 and I2 values via as documented:
2142445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // I1 = NOT(J1 EOR S);
2143445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // I2 = NOT(J2 EOR S);
2144445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // and build the imm32 with one trailing zero as documented:
2145445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
2146445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned S = fieldFromInstruction(Insn, 26, 1);
2147445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned J1 = fieldFromInstruction(Insn, 13, 1);
2148445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned J2 = fieldFromInstruction(Insn, 11, 1);
2149445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned I1 = !(J1 ^ S);
2150445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned I2 = !(J2 ^ S);
2151445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned imm10 = fieldFromInstruction(Insn, 16, 10);
2152445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned imm11 = fieldFromInstruction(Insn, 0, 11);
2153445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  unsigned tmp = (S << 23) | (I1 << 22) | (I2 << 21) | (imm10 << 11) | imm11;
21548117ac555d06b23f61ddd06aa54d3dfa3e5b8e56Amaury de la Vieuville  int imm32 = SignExtend32<25>(tmp << 1);
2155445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
21562a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 4, Inst, Decoder))
2157445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm32));
2158445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby
2159445ba85b8d7bc8fb4689ca22131cadc80a034705Kevin Enderby  return Status;
21602a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby}
21612a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby
21622a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderbystatic DecodeStatus
2163c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeBranchImmInstruction(MCInst &Inst, unsigned Insn,
2164c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
2165a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
216683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2167fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
2168fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 24) << 2;
21698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xF) {
21718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.setOpcode(ARM::BLXi);
2172fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    imm |= fieldFromInstruction(Insn, 24, 1) << 1;
2173b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby    if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2174b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                  true, 4, Inst, Decoder))
2175793b811c5057365d847b7f9ae326358e76facfe2Benjamin Kramer    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
217683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson    return S;
21778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
21788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2179b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<26>(imm) + 8,
2180b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                true, 4, Inst, Decoder))
21819e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby    Inst.addOperand(MCOperand::CreateImm(SignExtend32<26>(imm)));
2182a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
2183a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
218583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
21868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
21878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
21888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2189c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeAddrMode6Operand(MCInst &Inst, unsigned Val,
21908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
2191a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
219283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2193fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
2194fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Val, 4, 2);
21958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2196a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2197a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
21988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (!align)
21998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(0));
22008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  else
22018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(4 << align));
22028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
220383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
22048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
22058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2206c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLDInstruction(MCInst &Inst, unsigned Insn,
22078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
2208a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
220983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2210fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2211fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2212fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2213fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2214fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2215fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
22168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
22178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // First output register
221828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  switch (Inst.getOpcode()) {
2219c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q16: case ARM::VLD1q32: case ARM::VLD1q64: case ARM::VLD1q8:
2220c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q16wb_fixed: case ARM::VLD1q16wb_register:
2221c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q32wb_fixed: case ARM::VLD1q32wb_register:
2222c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q64wb_fixed: case ARM::VLD1q64wb_register:
2223c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1q8wb_fixed: case ARM::VLD1q8wb_register:
2224c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d16: case ARM::VLD2d32: case ARM::VLD2d8:
2225c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d16wb_fixed: case ARM::VLD2d16wb_register:
2226c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d32wb_fixed: case ARM::VLD2d32wb_register:
2227c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2d8wb_fixed: case ARM::VLD2d8wb_register:
222828f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
222928f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
223028f08c93e75d291695ea89b9004145103292e85bJim Grosbach    break;
2231c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b16:
2232c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b32:
2233c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b8:
2234c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b16wb_fixed:
2235c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b16wb_register:
2236c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b32wb_fixed:
2237c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b32wb_register:
2238c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b8wb_fixed:
2239c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VLD2b8wb_register:
2240c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2241c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      return MCDisassembler::Fail;
2242c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    break;
224328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  default:
224428f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
224528f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
224628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
22478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
22488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Second output register
22498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
22508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8:
22518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16:
22528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32:
22538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8_UPD:
22548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16_UPD:
22558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32_UPD:
22568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8:
22578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16:
22588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32:
22598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
22608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
22618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
2262a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2263a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
22648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
22658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8:
22668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16:
22678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32:
22688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8_UPD:
22698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16_UPD:
22708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32_UPD:
22718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8:
22728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16:
22738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32:
22748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
22758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
22768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2277a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2278a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
22798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
22808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
22818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
22828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
22838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Third output register
22848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch(Inst.getOpcode()) {
22858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8:
22868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16:
22878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32:
22888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8_UPD:
22898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16_UPD:
22908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32_UPD:
22918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8:
22928d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16:
22938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32:
22948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
22958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
22968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
2297a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2298a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
22998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8:
23018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16:
23028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32:
23038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8_UPD:
23048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16_UPD:
23058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32_UPD:
23068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8:
23078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16:
23088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32:
23098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
23108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
23118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2312a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2313a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
23168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
23188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
23198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Fourth output register
23208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
23218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8:
23228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16:
23238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32:
23248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
23258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
23268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
2327a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2328a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8:
23318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16:
23328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32:
23338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
23348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
23358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2336a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2337a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
23388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
23408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
23418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
23428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
23438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Writeback operand
23448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
234510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d8wb_fixed:
234610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d16wb_fixed:
234710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d32wb_fixed:
234810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d64wb_fixed:
234910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d8wb_register:
235010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d16wb_register:
235110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d32wb_register:
235210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1d64wb_register:
235310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q8wb_fixed:
235410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q16wb_fixed:
235510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q32wb_fixed:
235610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q64wb_fixed:
235710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q8wb_register:
235810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q16wb_register:
235910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q32wb_register:
236010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    case ARM::VLD1q64wb_register:
23615921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d8Twb_fixed:
23625921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d8Twb_register:
23635921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d16Twb_fixed:
23645921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d16Twb_register:
23655921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d32Twb_fixed:
23665921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d32Twb_register:
23675921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d64Twb_fixed:
23685921675ff5ea632ab1e6d7aa5d1f263b858bbafaJim Grosbach    case ARM::VLD1d64Twb_register:
2369399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d8Qwb_fixed:
2370399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d8Qwb_register:
2371399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d16Qwb_fixed:
2372399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d16Qwb_register:
2373399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d32Qwb_fixed:
2374399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d32Qwb_register:
2375399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d64Qwb_fixed:
2376399cdca4d201f7232126c3a0643669971ede780aJim Grosbach    case ARM::VLD1d64Qwb_register:
2377a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d8wb_fixed:
2378a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d16wb_fixed:
2379a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d32wb_fixed:
2380a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8wb_fixed:
2381a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16wb_fixed:
2382a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32wb_fixed:
2383a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d8wb_register:
2384a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d16wb_register:
2385a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2d32wb_register:
2386a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q8wb_register:
2387a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q16wb_register:
2388a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2q32wb_register:
2389a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b8wb_fixed:
2390a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b16wb_fixed:
2391a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b32wb_fixed:
2392a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b8wb_register:
2393a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b16wb_register:
2394a4e3c7fc4ba2d55695b0484480685698132eba20Jim Grosbach    case ARM::VLD2b32wb_register:
2395a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby      Inst.addOperand(MCOperand::CreateImm(0));
2396a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby      break;
23978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d8_UPD:
23988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d16_UPD:
23998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3d32_UPD:
24008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q8_UPD:
24018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q16_UPD:
24028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD3q32_UPD:
24038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d8_UPD:
24048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d16_UPD:
24058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4d32_UPD:
24068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q8_UPD:
24078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q16_UPD:
24088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VLD4q32_UPD:
2409a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2410a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
24118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
24138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
24148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
24158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
24168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Base (register+alignment)
2417a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2418a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
24198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
24208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Offset (register)
242110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  switch (Inst.getOpcode()) {
242210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  default:
242310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // The below have been updated to have explicit am6offset split
242410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // between fixed and register offset. For those instructions not
242510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // yet updated, we need to add an additional reg0 operand for the
242610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // fixed variant.
242710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    //
242810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // The fixed offset encodes as Rm == 0xd, so we check for that.
242910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    if (Rm == 0xd) {
243010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach      Inst.addOperand(MCOperand::CreateReg(0));
243110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach      break;
243210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    }
243310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // Fall through to handle the register offset variant.
243410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d8wb_fixed:
243510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d16wb_fixed:
243610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d32wb_fixed:
243710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d64wb_fixed:
243804b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d8Twb_fixed:
243904b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d16Twb_fixed:
244004b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d32Twb_fixed:
244104b12a4cfb74ac65ea86d57bde5999ef6ab09ad4Owen Anderson  case ARM::VLD1d64Twb_fixed:
2442fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d8Qwb_fixed:
2443fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d16Qwb_fixed:
2444fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d32Qwb_fixed:
2445fb6ab2b30e822d292c557bda32f7eb0acd1004e2Owen Anderson  case ARM::VLD1d64Qwb_fixed:
244610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d8wb_register:
244710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d16wb_register:
244810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d32wb_register:
244910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1d64wb_register:
245010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q8wb_fixed:
245110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q16wb_fixed:
245210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q32wb_fixed:
245310b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q64wb_fixed:
245410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q8wb_register:
245510b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q16wb_register:
245610b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q32wb_register:
245710b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach  case ARM::VLD1q64wb_register:
245810b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
245910b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // variant encodes Rm == 0xf. Anything else is a register offset post-
246010b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    // increment and we need to add the register operand to the instruction.
246110b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    if (Rm != 0xD && Rm != 0xF &&
246210b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach        !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2463a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
246410b90a9bbf7dcae1568c03a03f9606f5395f2144Jim Grosbach    break;
2465a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2d8wb_fixed:
2466a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2d16wb_fixed:
2467a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2d32wb_fixed:
2468a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2b8wb_fixed:
2469a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2b16wb_fixed:
2470a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2b32wb_fixed:
2471a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2q8wb_fixed:
2472a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2q16wb_fixed:
2473a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby  case ARM::VLD2q32wb_fixed:
2474a69da35c127dd7e35ae6216d965670643dc55bb6Kevin Enderby    break;
2475ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
24768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
247783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
24788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
24798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2480aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST1Instruction(MCInst &Inst, unsigned Insn,
2481aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
248230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned type = fieldFromInstruction(Insn, 8, 4);
248330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned align = fieldFromInstruction(Insn, 4, 2);
2484aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 6 && (align & 2)) return MCDisassembler::Fail;
2485aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 7 && (align & 2)) return MCDisassembler::Fail;
2486aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 10 && align == 3) return MCDisassembler::Fail;
2487aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville
2488aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2489aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2490aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
249130a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
249230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2493aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST2Instruction(MCInst &Inst, unsigned Insn,
2494aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
249530a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned size = fieldFromInstruction(Insn, 6, 2);
2496aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (size == 3) return MCDisassembler::Fail;
249730a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
249830a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned type = fieldFromInstruction(Insn, 8, 4);
249930a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned align = fieldFromInstruction(Insn, 4, 2);
2500aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 8 && align == 3) return MCDisassembler::Fail;
2501aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (type == 9 && align == 3) return MCDisassembler::Fail;
2502aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville
2503aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2504aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2505aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
250630a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
250730a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2508aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST3Instruction(MCInst &Inst, unsigned Insn,
2509aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
251030a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned size = fieldFromInstruction(Insn, 6, 2);
2511aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (size == 3) return MCDisassembler::Fail;
251230a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
251330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned align = fieldFromInstruction(Insn, 4, 2);
2514aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (align & 2) return MCDisassembler::Fail;
251530a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2516aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2517aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2518aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
251930a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
252030a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2521aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuvillestatic DecodeStatus DecodeVLDST4Instruction(MCInst &Inst, unsigned Insn,
2522aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville                                   uint64_t Address, const void *Decoder) {
252330a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa  unsigned size = fieldFromInstruction(Insn, 6, 2);
2524aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  if (size == 3) return MCDisassembler::Fail;
252530a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2526aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  unsigned load = fieldFromInstruction(Insn, 21, 1);
2527aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville  return load ? DecodeVLDInstruction(Inst, Insn, Address, Decoder)
2528aa8003712e8b28bc4f263aeb79d8851146273a05Amaury de la Vieuville              : DecodeVSTInstruction(Inst, Insn, Address, Decoder);
252930a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa}
253030a7a7c1fdbd2607345dd1554e3436749fd75c6eMihai Popa
2531c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSTInstruction(MCInst &Inst, unsigned Insn,
25328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
2533a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
253483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2535fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2536fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2537fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned wb = fieldFromInstruction(Insn, 16, 4);
2538fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2539fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rn |= fieldFromInstruction(Insn, 4, 2) << 4;
2540fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
25418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
25428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Writeback Operand
25438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
25444334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d8wb_fixed:
25454334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d16wb_fixed:
25464334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d32wb_fixed:
25474334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d64wb_fixed:
25484334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d8wb_register:
25494334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d16wb_register:
25504334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d32wb_register:
25514334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1d64wb_register:
25524334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q8wb_fixed:
25534334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q16wb_fixed:
25544334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q32wb_fixed:
25554334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q64wb_fixed:
25564334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q8wb_register:
25574334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q16wb_register:
25584334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q32wb_register:
25594334e032525d6c9038605f3871b945e8cbe6fab7Jim Grosbach    case ARM::VST1q64wb_register:
2560d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d8Twb_fixed:
2561d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d16Twb_fixed:
2562d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d32Twb_fixed:
2563d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d64Twb_fixed:
2564d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d8Twb_register:
2565d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d16Twb_register:
2566d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d32Twb_register:
2567d5ca201891d238ca2185831524a1e3f2670224dfJim Grosbach    case ARM::VST1d64Twb_register:
25684c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d8Qwb_fixed:
25694c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d16Qwb_fixed:
25704c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d32Qwb_fixed:
25714c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d64Qwb_fixed:
25724c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d8Qwb_register:
25734c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d16Qwb_register:
25744c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d32Qwb_register:
25754c7edb3ad8bd513c59190f6ebee9bee34af7d247Jim Grosbach    case ARM::VST1d64Qwb_register:
2576bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d8wb_fixed:
2577bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d16wb_fixed:
2578bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d32wb_fixed:
2579bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d8wb_register:
2580bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d16wb_register:
2581bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2d32wb_register:
2582bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q8wb_fixed:
2583bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q16wb_fixed:
2584bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q32wb_fixed:
2585bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q8wb_register:
2586bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q16wb_register:
2587bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2q32wb_register:
2588bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b8wb_fixed:
2589bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b16wb_fixed:
2590bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b32wb_fixed:
2591bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b8wb_register:
2592bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b16wb_register:
2593bb3a2e4d0defc6854d37384d80858037dbbc5f20Jim Grosbach    case ARM::VST2b32wb_register:
2594b318cc16c9e959adb96294b3aa4940e74f68dde3Kevin Enderby      if (Rm == 0xF)
2595b318cc16c9e959adb96294b3aa4940e74f68dde3Kevin Enderby        return MCDisassembler::Fail;
2596f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby      Inst.addOperand(MCOperand::CreateImm(0));
2597f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby      break;
25988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8_UPD:
25998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16_UPD:
26008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32_UPD:
26018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8_UPD:
26028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16_UPD:
26038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32_UPD:
26048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
26058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
26068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
26078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
26088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
26098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2610a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, wb, Address, Decoder)))
2611a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
26128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
26138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
26148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
26158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
26168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
26178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Base (register+alignment)
2618a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrMode6Operand(Inst, Rn, Address, Decoder)))
2619a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
26208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
26218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // AddrMode6 Offset (register)
262260cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson  switch (Inst.getOpcode()) {
262360cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    default:
262460cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      if (Rm == 0xD)
262560cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson        Inst.addOperand(MCOperand::CreateReg(0));
262660cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      else if (Rm != 0xF) {
262760cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson        if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
262860cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson          return MCDisassembler::Fail;
262960cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      }
263060cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      break;
263160cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d8wb_fixed:
263260cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d16wb_fixed:
263360cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d32wb_fixed:
263460cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1d64wb_fixed:
263560cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q8wb_fixed:
263660cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q16wb_fixed:
263760cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q32wb_fixed:
263860cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson    case ARM::VST1q64wb_fixed:
2639f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d8Twb_fixed:
2640f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d16Twb_fixed:
2641f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d32Twb_fixed:
2642f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d64Twb_fixed:
2643f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d8Qwb_fixed:
2644f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d16Qwb_fixed:
2645f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d32Qwb_fixed:
2646f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST1d64Qwb_fixed:
2647f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2d8wb_fixed:
2648f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2d16wb_fixed:
2649f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2d32wb_fixed:
2650f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2q8wb_fixed:
2651f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2q16wb_fixed:
2652f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2q32wb_fixed:
2653f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2b8wb_fixed:
2654f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2b16wb_fixed:
2655f0586f08dfd5bf1889c15849e9c603b3985fce4aKevin Enderby    case ARM::VST2b32wb_fixed:
265660cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson      break;
2657ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
26588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
265960cb643f7561e5be7a3b5fe705535e96de72cbf5Owen Anderson
26608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // First input register
266128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  switch (Inst.getOpcode()) {
266228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q16:
266328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q32:
266428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64:
266528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q8:
266628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q16wb_fixed:
266728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q16wb_register:
266828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q32wb_fixed:
266928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q32wb_register:
267028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64wb_fixed:
267128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q64wb_register:
267228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q8wb_fixed:
267328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST1q8wb_register:
267428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d16:
267528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d32:
267628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d8:
267728f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d16wb_fixed:
267828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d16wb_register:
267928f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d32wb_fixed:
268028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d32wb_register:
268128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d8wb_fixed:
268228f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VST2d8wb_register:
268328f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
268428f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
268528f08c93e75d291695ea89b9004145103292e85bJim Grosbach    break;
2686c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b16:
2687c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b32:
2688c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b8:
2689c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b16wb_fixed:
2690c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b16wb_register:
2691c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b32wb_fixed:
2692c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b32wb_register:
2693c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b8wb_fixed:
2694c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach  case ARM::VST2b8wb_register:
2695c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
2696c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach      return MCDisassembler::Fail;
2697c3384c93c0e4c50da4ad093f08997507f9281c75Jim Grosbach    break;
269828f08c93e75d291695ea89b9004145103292e85bJim Grosbach  default:
269928f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
270028f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
270128f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
27028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
27038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Second input register
27048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
27058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8:
27068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16:
27078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32:
27088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8_UPD:
27098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16_UPD:
27108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32_UPD:
27118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8:
27128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16:
27138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32:
27148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
27158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
27168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
2717a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+1)%32, Address, Decoder)))
2718a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
27198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8:
27218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16:
27228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32:
27238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8_UPD:
27248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16_UPD:
27258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32_UPD:
27268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8:
27278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16:
27288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32:
27298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
27308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
27318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2732a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2733a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
27348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
27368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
27388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
27398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Third input register
27408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
27418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8:
27428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16:
27438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32:
27448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d8_UPD:
27458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d16_UPD:
27468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3d32_UPD:
27478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8:
27488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16:
27498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32:
27508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
27518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
27528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
2753a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2)%32, Address, Decoder)))
2754a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
27558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8:
27578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16:
27588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32:
27598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q8_UPD:
27608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q16_UPD:
27618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST3q32_UPD:
27628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8:
27638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16:
27648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32:
27658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
27668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
27678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2768a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+4)%32, Address, Decoder)))
2769a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
27708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
27728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
27748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
27758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Fourth input register
27768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
27778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8:
27788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16:
27798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32:
27808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d8_UPD:
27818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d16_UPD:
27828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4d32_UPD:
2783a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3)%32, Address, Decoder)))
2784a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
27858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8:
27878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16:
27888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32:
27898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q8_UPD:
27908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q16_UPD:
27918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VST4q32_UPD:
2792a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+6)%32, Address, Decoder)))
2793a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
27948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
27968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
27978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
27988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
279983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
28008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
28018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2802c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1DupInstruction(MCInst &Inst, unsigned Insn,
28038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
2804a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
280583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2806fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2807fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2808fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2809fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2810fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Insn, 4, 1);
2811fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 6, 2);
28128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
281324b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover  if (size == 0 && align == 1)
281424b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover    return MCDisassembler::Fail;
28158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  align *= (1 << size);
28168d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2817c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  switch (Inst.getOpcode()) {
2818c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq16: case ARM::VLD1DUPq32: case ARM::VLD1DUPq8:
2819c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq16wb_fixed: case ARM::VLD1DUPq16wb_register:
2820c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq32wb_fixed: case ARM::VLD1DUPq32wb_register:
2821c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD1DUPq8wb_fixed: case ARM::VLD1DUPq8wb_register:
2822c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2823c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2824c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
2825c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  default:
2826c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2827c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2828c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
2829c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  }
2830f1c8e3e70e222365b84f4cb7e87396ee85820711Owen Anderson  if (Rm != 0xF) {
2831a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2832a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2833ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
28348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2835a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2836a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
28378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
28388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2839096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  // The fixed offset post-increment encodes Rm == 0xd. The no-writeback
2840096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  // variant encodes Rm == 0xf. Anything else is a register offset post-
2841096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  // increment and we need to add the register operand to the instruction.
2842096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach  if (Rm != 0xD && Rm != 0xF &&
2843096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach      !Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2844096334e25ea68ac970942ecb680a82fbb8ad206cJim Grosbach    return MCDisassembler::Fail;
28458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
284683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
28478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
28488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2849c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2DupInstruction(MCInst &Inst, unsigned Insn,
28508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
2851a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
285283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2853fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2854fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2855fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2856fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2857fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Insn, 4, 1);
2858fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = 1 << fieldFromInstruction(Insn, 6, 2);
28598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  align *= 2*size;
28608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2861c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  switch (Inst.getOpcode()) {
2862c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd16: case ARM::VLD2DUPd32: case ARM::VLD2DUPd8:
2863c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd16wb_fixed: case ARM::VLD2DUPd16wb_register:
2864c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd32wb_fixed: case ARM::VLD2DUPd32wb_register:
2865c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  case ARM::VLD2DUPd8wb_fixed: case ARM::VLD2DUPd8wb_register:
2866c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rd, Address, Decoder)))
2867c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2868c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
28694d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd16x2: case ARM::VLD2DUPd32x2: case ARM::VLD2DUPd8x2:
28704d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd16x2wb_fixed: case ARM::VLD2DUPd16x2wb_register:
28714d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd32x2wb_fixed: case ARM::VLD2DUPd32x2wb_register:
28724d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach  case ARM::VLD2DUPd8x2wb_fixed: case ARM::VLD2DUPd8x2wb_register:
28734d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    if (!Check(S, DecodeDPairSpacedRegisterClass(Inst, Rd, Address, Decoder)))
28744d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach      return MCDisassembler::Fail;
28754d0983a4d734280d481bb56472fe44ad0ddc447dJim Grosbach    break;
2876c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  default:
2877c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2878c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach      return MCDisassembler::Fail;
2879c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach    break;
2880c0fc450f0754508871bc70f21e528bf2f1520da1Jim Grosbach  }
2881158c8a49c23d01297e7913c03c1fdb0760aee3a8Kevin Enderby
2882158c8a49c23d01297e7913c03c1fdb0760aee3a8Kevin Enderby  if (Rm != 0xF)
2883158c8a49c23d01297e7913c03c1fdb0760aee3a8Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(0));
28848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2885a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2886a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
28878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
28888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2889c5a2a33938182ccc5a1a94f7e1e2b3fdaff6a8b1Kevin Enderby  if (Rm != 0xD && Rm != 0xF) {
2890a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2891a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2892ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
28938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
289483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
28958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
28968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2897c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3DupInstruction(MCInst &Inst, unsigned Insn,
28988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                    uint64_t Address, const void *Decoder) {
2899a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
290083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2901fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2902fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2903fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
2904fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
2905fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
29068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2907a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2908a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2909a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2910a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2911a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2912a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
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(0));
29218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
29228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Rm == 0xD)
29238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
2924ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  else if (Rm != 0xF) {
2925a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2926a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2927ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
29288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
292983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
29308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
29318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2932c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4DupInstruction(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 size = fieldFromInstruction(Insn, 6, 2);
2941fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned inc = fieldFromInstruction(Insn, 5, 1) + 1;
2942fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned align = fieldFromInstruction(Insn, 4, 1);
29438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
29448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (size == 0x3) {
294524b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover    if (align == 0)
294624b9f258f194c5e472bf133f9bbf5ca26ad500d3Tim Northover      return MCDisassembler::Fail;
29478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    size = 4;
29488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    align = 16;
29498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
29508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    if (size == 2) {
29518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      size = 1 << size;
29528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      align *= 8;
29538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    } else {
29548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      size = 1 << size;
29558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      align *= 4*size;
29568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
29578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
29588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2959a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
2960a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2961a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+inc)%32, Address, Decoder)))
2962a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2963a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+2*inc)%32, Address, Decoder)))
2964a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2965a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, (Rd+3*inc)%32, Address, Decoder)))
2966a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
2967f1c8e3e70e222365b84f4cb7e87396ee85820711Owen Anderson  if (Rm != 0xF) {
2968a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2969a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2970ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
29718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2972a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
2973a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
29748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
29758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
29768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Rm == 0xD)
29778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(0));
2978ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  else if (Rm != 0xF) {
2979a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
2980a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
2981ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
29828d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
298383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
29848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
29858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
2986a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
2987c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeNEONModImmInstruction(MCInst &Inst, unsigned Insn,
2988c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                            uint64_t Address, const void *Decoder) {
2989a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
299083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
2991fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
2992fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
2993fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 4);
2994fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 3) << 4;
2995fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 24, 1) << 7;
2996fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 8, 4) << 8;
2997fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 5, 1) << 12;
2998fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Q = fieldFromInstruction(Insn, 6, 1);
29998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3000ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  if (Q) {
3001a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3002a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3003ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  } else {
3004a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3005a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3006ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
30098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
30108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
30118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv4i16:
30128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv2i32:
30138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv4i16:
30148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv2i32:
3015a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3016a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
30178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
30188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv8i16:
30198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VORRiv4i32:
30208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv8i16:
30218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::VBICiv4i32:
3022a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3023a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
30248d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
30258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
30268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
30278d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
30288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
302983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
30308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3032c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVSHLMaxInstruction(MCInst &Inst, unsigned Insn,
30338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                        uint64_t Address, const void *Decoder) {
3034a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
303583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3036fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3037fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3038fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3039fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3040fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 18, 2);
30418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3042a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeQPRRegisterClass(Inst, Rd, Address, Decoder)))
3043a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3044a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3045a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
30468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(8 << size));
30478d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
304883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
30498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3051c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight8Imm(MCInst &Inst, unsigned Val,
30528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
30538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(8 - Val));
3054c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
30558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3057c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight16Imm(MCInst &Inst, unsigned Val,
30588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
30598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(16 - Val));
3060c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
30618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30628d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3063c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight32Imm(MCInst &Inst, unsigned Val,
30648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
30658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(32 - Val));
3066c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
30678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3069c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeShiftRight64Imm(MCInst &Inst, unsigned Val,
30708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
30718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(64 - Val));
3072c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
30738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
30748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3075c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeTBLInstruction(MCInst &Inst, unsigned Insn,
30768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                               uint64_t Address, const void *Decoder) {
3077a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
307883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3080fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
3081fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3082fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rn |= fieldFromInstruction(Insn, 7, 1) << 4;
3083fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3084fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 5, 1) << 4;
3085fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned op = fieldFromInstruction(Insn, 6, 1);
30868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3087a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3088a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3089ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  if (op) {
3090a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
3091a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail; // Writeback
3092ae0bc5deaa30f1e20a6189e42ca412ba27ec7153Owen Anderson  }
30938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
309428f08c93e75d291695ea89b9004145103292e85bJim Grosbach  switch (Inst.getOpcode()) {
309528f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VTBL2:
309628f08c93e75d291695ea89b9004145103292e85bJim Grosbach  case ARM::VTBX2:
309728f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPairRegisterClass(Inst, Rn, Address, Decoder)))
309828f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
309928f08c93e75d291695ea89b9004145103292e85bJim Grosbach    break;
310028f08c93e75d291695ea89b9004145103292e85bJim Grosbach  default:
310128f08c93e75d291695ea89b9004145103292e85bJim Grosbach    if (!Check(S, DecodeDPRRegisterClass(Inst, Rn, Address, Decoder)))
310228f08c93e75d291695ea89b9004145103292e85bJim Grosbach      return MCDisassembler::Fail;
310328f08c93e75d291695ea89b9004145103292e85bJim Grosbach  }
31048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3105a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rm, Address, Decoder)))
3106a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
31078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
310883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3111c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSpecialReg(MCInst &Inst, uint16_t Insn,
31128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                     uint64_t Address, const void *Decoder) {
3113a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
311483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3115fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned dst = fieldFromInstruction(Insn, 8, 3);
3116fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 8);
31178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3118a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, dst, Address, Decoder)))
3119a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
31208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
312196425c846494c1c20a4c931f4783571295ab170cOwen Anderson  switch(Inst.getOpcode()) {
31221af7f7291d0689e2d58f900c9b5ecaddec56caa1Owen Anderson    default:
3123c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
312496425c846494c1c20a4c931f4783571295ab170cOwen Anderson    case ARM::tADR:
31259f7e8319947c65d9aef2a0f0984557c3b3a20656Owen Anderson      break; // tADR does not explicitly represent the PC as an operand.
312696425c846494c1c20a4c931f4783571295ab170cOwen Anderson    case ARM::tADDrSPi:
312796425c846494c1c20a4c931f4783571295ab170cOwen Anderson      Inst.addOperand(MCOperand::CreateReg(ARM::SP));
312896425c846494c1c20a4c931f4783571295ab170cOwen Anderson      break;
312996425c846494c1c20a4c931f4783571295ab170cOwen Anderson  }
31308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
31318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
313283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3135c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBROperand(MCInst &Inst, unsigned Val,
31368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
31372a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<12>(Val<<1) + 4,
31382a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 2, Inst, Decoder))
31392a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(SignExtend32<12>(Val << 1)));
3140c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3143c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2BROperand(MCInst &Inst, unsigned Val,
31448d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
31453610a15c3581dee713820f72d8ffe2e2a632b057Kevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<21>(Val) + 4,
31462a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 4, Inst, Decoder))
31472a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby    Inst.addOperand(MCOperand::CreateImm(SignExtend32<21>(Val)));
3148c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3151c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCmpBROperand(MCInst &Inst, unsigned Val,
31528d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
3153ce888351106a72825e2a107cb08d7130f3dce0eeGordon Keiser  if (!tryAddingSymbolicOperand(Address, Address + (Val<<1) + 4,
31542a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 2, Inst, Decoder))
3155ce888351106a72825e2a107cb08d7130f3dce0eeGordon Keiser    Inst.addOperand(MCOperand::CreateImm(Val << 1));
3156c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3159c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeRR(MCInst &Inst, unsigned Val,
31608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                 uint64_t Address, const void *Decoder) {
3161a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
316283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3163fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3164fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 3, 3);
31658d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3166a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3167a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3168a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, Rm, Address, Decoder)))
3169a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
31708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
317183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3174c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeIS(MCInst &Inst, unsigned Val,
31758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
3176a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
317783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3178fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 0, 3);
3179fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 3, 5);
31808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3181a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodetGPRRegisterClass(Inst, Rn, Address, Decoder)))
3182a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
31838d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
31848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
318583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
31868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3188c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModePC(MCInst &Inst, unsigned Val,
31898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
31909e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  unsigned imm = Val << 2;
31919e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby
31929e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  Inst.addOperand(MCOperand::CreateImm(imm));
31939e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby  tryAddingPcLoadReferenceComment(Address, (Address & ~2u) + imm + 4, Decoder);
31948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3195c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
31968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
31978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3198c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddrModeSP(MCInst &Inst, unsigned Val,
31998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
32008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3201b113ec55e897c85fda606409c1eedec4f89ec53fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
32028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3203c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
32048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3206c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeSOReg(MCInst &Inst, unsigned Val,
32078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                  uint64_t Address, const void *Decoder) {
3208a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
320983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3210fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 6, 4);
3211fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 2, 4);
3212fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 2);
32138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3214cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  // Thumb stores cannot use PC as dest register.
3215cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  switch (Inst.getOpcode()) {
3216cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHs:
3217cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBs:
3218cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRs:
3219cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    if (Rn == 15)
3220cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville      return MCDisassembler::Fail;
3221cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  default:
3222cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3223cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  }
3224cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville
3225a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3226a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3227a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
3228a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
32298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
32308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
323183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
32328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
32338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3234c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LoadShift(MCInst &Inst, unsigned Insn,
32358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                              uint64_t Address, const void *Decoder) {
3236a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
323783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3238ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3239fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3240ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
32410c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rn == 15) {
32428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (Inst.getOpcode()) {
32430c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRBs:
32440c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
32450c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32460c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRHs:
32470c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
32480c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32490c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHs:
32500c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
32510c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32520c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSBs:
32530c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
32540c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32550c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRs:
32560c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
32570c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32580c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLDs:
32590c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDpci);
32600c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32610c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLIs:
32620c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLIpci);
32630c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32640c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
32650c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
32668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
32678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3268ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3269ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
32708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
32710c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
32720c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
32730c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHs:
32740c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
32750c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRHs:
32760c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      // FIXME: this instruction is only available with MP extensions,
32770c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      // this should be checked first but we don't have access to the
32780c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      // feature bits here.
32790c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDWs);
32800c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32810c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
32820c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
32830c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
32840c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
32850c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
3286ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  switch (Inst.getOpcode()) {
3287ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2PLDs:
3288ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2PLDWs:
3289ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2PLIs:
3290ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3291ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3292ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3293ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville        return MCDisassembler::Fail;
32948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
32958d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3296fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addrmode = fieldFromInstruction(Insn, 4, 2);
3297fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  addrmode |= fieldFromInstruction(Insn, 0, 4) << 2;
3298fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  addrmode |= fieldFromInstruction(Insn, 16, 4) << 6;
3299a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2AddrModeSOReg(Inst, addrmode, Address, Decoder)))
3300a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
33018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
330283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
33038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
33048d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3305ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm8(MCInst &Inst, unsigned Insn,
3306ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3307ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3308ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3309ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3310ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3311ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned U = fieldFromInstruction(Insn, 9, 1);
3312ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3313ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (U << 8);
3314ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (Rn << 9);
3315ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3316ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3317ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3318ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRi8:
3319ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3320ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3321ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRBi8:
3322ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3323ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3324ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSBi8:
3325ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
3326ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3327ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRHi8:
3328ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3329ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3330ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSHi8:
3331ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3332ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
33330c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLDi8:
33340c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDpci);
33350c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33360c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLIi8:
33370c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLIpci);
33380c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
3339ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3340ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3341ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3342ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3343ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3344ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
33450c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
33460c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
33470c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHi8:
33480c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
33490c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
33500c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33510c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
33520c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
33530c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
33540c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  switch (Inst.getOpcode()) {
33550c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLDi8:
33560c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLIi8:
33574f7092176c3d3eaae0ea7af26aec2d77b3e4035fMihai Popa  case ARM::t2PLDWi8:
33580c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    break;
33590c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  default:
33600c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
33610c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
33620c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
33630c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
3364ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3365ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3366ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3367ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3368ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3369ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadImm12(MCInst &Inst, unsigned Insn,
3370ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3371ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3372ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3373ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3374ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3375ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned imm = fieldFromInstruction(Insn, 0, 12);
3376ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (Rn << 13);
3377ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3378ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3379ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3380ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRi12:
3381ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3382ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3383ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRHi12:
3384ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3385ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3386ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSHi12:
3387ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3388ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3389ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRBi12:
3390ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3391ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3392ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSBi12:
3393ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
3394ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
33950c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLDi12:
33960c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDpci);
33970c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
33980c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2PLIi12:
33990c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLIpci);
34000c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
3401ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3402ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3403ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3404ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3405ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3406ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
34070c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
34080c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
34090c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRSHi12:
34100c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
34110c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    case ARM::t2LDRHi12:
34120c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      Inst.setOpcode(ARM::t2PLDi12);
34130c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
34140c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    default:
34150c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      break;
34160c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
34170c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
34180c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
34190c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  switch (Inst.getOpcode()) {
34200c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLDi12:
34214f7092176c3d3eaae0ea7af26aec2d77b3e4035fMihai Popa  case ARM::t2PLDWi12:
34220c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLIi12:
34230c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    break;
34240c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  default:
34250c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
34260c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      return MCDisassembler::Fail;
34270c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
34280c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
3429ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecodeT2AddrModeImm12(Inst, imm, Address, Decoder)))
3430ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3431ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3432ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3433ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3434ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadT(MCInst &Inst, unsigned Insn,
3435ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3436ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3437ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3438ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3439ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3440ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned imm = fieldFromInstruction(Insn, 0, 8);
3441ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  imm |= (Rn << 9);
3442ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3443ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3444ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3445ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRT:
3446ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3447ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3448ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRBT:
3449ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3450ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3451ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRHT:
3452ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3453ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3454ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSBT:
3455ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSBpci);
3456ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3457ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSHT:
3458ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3459ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3460ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3461ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3462ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3463ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3464ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3465ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3466ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
3467ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3468ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!Check(S, DecodeT2AddrModeImm8(Inst, imm, Address, Decoder)))
3469ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return MCDisassembler::Fail;
3470ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3471ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3472ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3473ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuvillestatic DecodeStatus DecodeT2LoadLabel(MCInst &Inst, unsigned Insn,
3474ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville                                uint64_t Address, const void* Decoder) {
3475ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  DecodeStatus S = MCDisassembler::Success;
3476ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3477ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3478ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  unsigned U = fieldFromInstruction(Insn, 23, 1);
3479ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  int imm = fieldFromInstruction(Insn, 0, 12);
3480ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
34810c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  if (Rt == 15) {
34820c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    switch (Inst.getOpcode()) {
34830c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRBpci:
34840c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRHpci:
34850c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2PLDpci);
34860c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        break;
34870c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRSBpci:
34880c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2PLIpci);
34890c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        break;
34900c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      case ARM::t2LDRSHpci:
34910c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        return MCDisassembler::Fail;
34920c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      default:
34930c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        break;
34940c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    }
34950c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  }
34960c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville
34970c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  switch(Inst.getOpcode()) {
34980c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLDpci:
34990c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  case ARM::t2PLIpci:
35000c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville    break;
35010c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville  default:
3502ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3503ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3504ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3505ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3506ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (!U) {
3507ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    // Special case for #-0.
3508ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    if (imm == 0)
3509ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      imm = INT32_MIN;
3510ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    else
3511ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      imm = -imm;
3512ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3513ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  Inst.addOperand(MCOperand::CreateImm(imm));
3514ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3515ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  return S;
3516ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville}
3517ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3518c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8S4(MCInst &Inst, unsigned Val,
351910cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                           uint64_t Address, const void *Decoder) {
3520fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu  if (Val == 0)
3521fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    Inst.addOperand(MCOperand::CreateImm(INT32_MIN));
3522fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu  else {
3523fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    int imm = Val & 0xFF;
3524fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu
3525fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu    if (!(Val & 0x100)) imm *= -1;
35261144af3c9b4da48cd581156e05b24261c8de366aRichard Smith    Inst.addOperand(MCOperand::CreateImm(imm * 4));
3527fd652df8b36a9d3e6b09ae2b9f7bcb07e88fdfaaJiangning Liu  }
35288d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3529c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
35308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
35318d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3532c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8s4(MCInst &Inst, unsigned Val,
35338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                   uint64_t Address, const void *Decoder) {
3534a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
353583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3536fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 9, 4);
3537fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 9);
35388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3539a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3540a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3541a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2Imm8S4(Inst, imm, Address, Decoder)))
3542a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
35438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
354483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
35458d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
35468d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3547c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm0_1020s4(MCInst &Inst,unsigned Val,
3548b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach                                   uint64_t Address, const void *Decoder) {
3549b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  DecodeStatus S = MCDisassembler::Success;
3550b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3551fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 8, 4);
3552fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 8);
3553b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3554b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
3555b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach    return MCDisassembler::Fail;
3556b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3557b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  Inst.addOperand(MCOperand::CreateImm(imm));
3558b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3559b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach  return S;
3560b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach}
3561b6aed508e310e31dcb080e761ca856127cec0773Jim Grosbach
3562c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Imm8(MCInst &Inst, unsigned Val,
356310cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                         uint64_t Address, const void *Decoder) {
35648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  int imm = Val & 0xFF;
3565705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson  if (Val == 0)
3566705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson    imm = INT32_MIN;
3567705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson  else if (!(Val & 0x100))
3568705b48ff860e7484f0adee88362dbe1936ae936bOwen Anderson    imm *= -1;
35698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
35708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3571c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
35728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
35738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
35748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3575c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm8(MCInst &Inst, unsigned Val,
357610cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                 uint64_t Address, const void *Decoder) {
3577a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
357883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3579fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 9, 4);
3580fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 9);
35818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3582cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  // Thumb stores cannot use PC as dest register.
3583cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  switch (Inst.getOpcode()) {
3584cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRT:
3585cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBT:
3586cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHT:
3587cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRi8:
3588cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHi8:
3589cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBi8:
3590cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    if (Rn == 15)
3591cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville      return MCDisassembler::Fail;
3592cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3593cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  default:
3594cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3595cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  }
3596cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville
35978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  // Some instructions always use an additive offset.
35988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  switch (Inst.getOpcode()) {
35998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRT:
36008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRBT:
36018d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRHT:
36028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRSBT:
36038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    case ARM::t2LDRSHT:
3604ecd1c557904815e568258fc5420de479589b0a93Owen Anderson    case ARM::t2STRT:
3605ecd1c557904815e568258fc5420de479589b0a93Owen Anderson    case ARM::t2STRBT:
3606ecd1c557904815e568258fc5420de479589b0a93Owen Anderson    case ARM::t2STRHT:
36078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      imm |= 0x100;
36088d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
36098d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    default:
36108d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      break;
36118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
36128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3613a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3614a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3615a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2Imm8(Inst, imm, Address, Decoder)))
3616a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
36178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
361883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
36198d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
36208d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3621c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2LdStPre(MCInst &Inst, unsigned Insn,
3622a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson                                    uint64_t Address, const void *Decoder) {
3623a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  DecodeStatus S = MCDisassembler::Success;
3624a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3625fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3626fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3627fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addr = fieldFromInstruction(Insn, 0, 8);
3628fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  addr |= fieldFromInstruction(Insn, 9, 1) << 8;
3629a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  addr |= Rn << 9;
3630fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned load = fieldFromInstruction(Insn, 20, 1);
3631a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3632ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  if (Rn == 15) {
3633ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    switch (Inst.getOpcode()) {
3634ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDR_PRE:
3635ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDR_POST:
3636ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRpci);
3637ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3638ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRB_PRE:
3639ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRB_POST:
3640ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRBpci);
3641ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3642ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRH_PRE:
3643ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRH_POST:
3644ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRHpci);
3645ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3646ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSB_PRE:
3647ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSB_POST:
36480c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      if (Rt == 15)
36490c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2PLIpci);
36500c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville      else
36510c9f0c047dfba91bc7c0fb66f7e868e917d37c4cAmaury de la Vieuville        Inst.setOpcode(ARM::t2LDRSBpci);
3652ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3653ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSH_PRE:
3654ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    case ARM::t2LDRSH_POST:
3655ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      Inst.setOpcode(ARM::t2LDRSHpci);
3656ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      break;
3657ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    default:
3658ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville      return MCDisassembler::Fail;
3659ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    }
3660ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville    return DecodeT2LoadLabel(Inst, Insn, Address, Decoder);
3661ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville  }
3662ce046b98ed6c351779fc43599a80d588752bc1caAmaury de la Vieuville
3663a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  if (!load) {
3664a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3665a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson      return MCDisassembler::Fail;
3666a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  }
3667a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3668b78821d380b6f9514bd3b56b1c27ba367660228bJoe Abbey  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
3669a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    return MCDisassembler::Fail;
3670a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3671a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  if (load) {
3672a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3673a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson      return MCDisassembler::Fail;
3674a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  }
3675a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3676a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  if (!Check(S, DecodeT2AddrModeImm8(Inst, addr, Address, Decoder)))
3677a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson    return MCDisassembler::Fail;
3678a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson
3679a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson  return S;
3680a3157b402695ef9d5f6a03e8e3afc5bddf3a3df7Owen Anderson}
36818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3682c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2AddrModeImm12(MCInst &Inst, unsigned Val,
368310cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                  uint64_t Address, const void *Decoder) {
3684a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
368583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3686fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 13, 4);
3687fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Val, 0, 12);
36888d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3689cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  // Thumb stores cannot use PC as dest register.
3690cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  switch (Inst.getOpcode()) {
3691cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRi12:
3692cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRBi12:
3693cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  case ARM::t2STRHi12:
3694cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    if (Rn == 15)
3695cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville      return MCDisassembler::Fail;
3696cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  default:
3697cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville    break;
3698cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville  }
3699cea0032f73a56a62b692b25ca4084850cd51763bAmaury de la Vieuville
3700a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3701a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
37028d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
37038d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
370483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
37058d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37068d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
37078d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3708c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPImm(MCInst &Inst, uint16_t Insn,
370910cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                uint64_t Address, const void *Decoder) {
3710fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 7);
37118d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
37128d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
37138d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateReg(ARM::SP));
37148d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imm));
37158d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3716c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
37178d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37188d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3719c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbAddSPReg(MCInst &Inst, uint16_t Insn,
372010cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                uint64_t Address, const void *Decoder) {
3721a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
372283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
37238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Inst.getOpcode() == ARM::tADDrSP) {
3724fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned Rdm = fieldFromInstruction(Insn, 0, 3);
3725fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    Rdm |= fieldFromInstruction(Insn, 7, 1) << 3;
37268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3727a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3728a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3729bb32f1d545241ab957f402165cec359d4473c0caJim Grosbach    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3730a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rdm, Address, Decoder)))
3731a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
37328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else if (Inst.getOpcode() == ARM::tADDspr) {
3733fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned Rm = fieldFromInstruction(Insn, 3, 4);
37348d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
37358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
37368d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateReg(ARM::SP));
3737a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
3738a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
37398d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
37408d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
374183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
37428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37438d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3744c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbCPS(MCInst &Inst, uint16_t Insn,
374510cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                           uint64_t Address, const void *Decoder) {
3746fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imod = fieldFromInstruction(Insn, 4, 1) | 0x2;
3747fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned flags = fieldFromInstruction(Insn, 0, 3);
37488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
37498d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(imod));
37508d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(flags));
37518d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3752c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
37538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37548d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3755c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodePostIdxReg(MCInst &Inst, unsigned Insn,
375610cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                             uint64_t Address, const void *Decoder) {
3757a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
3758fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
3759fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned add = fieldFromInstruction(Insn, 4, 1);
37608d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3761b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rm, Address, Decoder)))
3762a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
37638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(add));
37648d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
376583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
37668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3768c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLXOffset(MCInst &Inst, unsigned Val,
376910cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                 uint64_t Address, const void *Decoder) {
3770dd051a0414d0c807388bdc9584b71729b3158571NAKAMURA Takumi  // Val is passed in as S:J1:J2:imm10H:imm10L:'0'
37712d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // Note only one trailing zero not two.  Also the J1 and J2 values are from
37722d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // the encoded instruction.  So here change to I1 and I2 values via:
37732d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I1 = NOT(J1 EOR S);
37742d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I2 = NOT(J2 EOR S);
37752d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // and build the imm32 with two trailing zeros as documented:
3776dd051a0414d0c807388bdc9584b71729b3158571NAKAMURA Takumi  // imm32 = SignExtend(S:I1:I2:imm10H:imm10L:'00', 32);
37772d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned S = (Val >> 23) & 1;
37782d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J1 = (Val >> 22) & 1;
37792d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J2 = (Val >> 21) & 1;
37802d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I1 = !(J1 ^ S);
37812d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I2 = !(J2 ^ S);
37822d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
37832d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  int imm32 = SignExtend32<25>(tmp << 1);
37842d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby
378501817c39a9d7ff864d0b5de4941eec93d2f9e3a8Jim Grosbach  if (!tryAddingSymbolicOperand(Address,
37862d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby                                (Address & ~2u) + imm32 + 4,
37879e5887b17e634b98f7c1cf0ee4f25c218097d08eKevin Enderby                                true, 4, Inst, Decoder))
37882d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm32));
3789c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
37908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
37918d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3792c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeCoprocessor(MCInst &Inst, unsigned Val,
37938d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                              uint64_t Address, const void *Decoder) {
37948d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (Val == 0xA || Val == 0xB)
3795c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
37968d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
37978d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
3798c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
37998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38008d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3801a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
3802c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeThumbTableBranch(MCInst &Inst, unsigned Insn,
38037f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach                       uint64_t Address, const void *Decoder) {
38047f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  DecodeStatus S = MCDisassembler::Success;
38057f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
3806fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3807fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
38087f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
38097f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  if (Rn == ARM::SP) S = MCDisassembler::SoftFail;
38107f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
38117f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return MCDisassembler::Fail;
38127f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rm, Address, Decoder)))
38137f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach    return MCDisassembler::Fail;
38147f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach  return S;
38157f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach}
38167f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbach
38177f739bee261debdf56bd89ac922b57eca53e91dcJim Grosbachstatic DecodeStatus
3818c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeThumb2BCCInstruction(MCInst &Inst, unsigned Insn,
3819c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                           uint64_t Address, const void *Decoder) {
3820a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
382183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3822fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 22, 4);
38238d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (pred == 0xE || pred == 0xF) {
3824fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned opc = fieldFromInstruction(Insn, 4, 28);
38258d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (opc) {
38268d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      default:
3827c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail;
3828b45b11bce1fd79b0973d2df8db295583b5477c62Owen Anderson      case 0xf3bf8f4:
38298d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::t2DSB);
38308d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
3831b45b11bce1fd79b0973d2df8db295583b5477c62Owen Anderson      case 0xf3bf8f5:
38328d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::t2DMB);
38338d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
3834b45b11bce1fd79b0973d2df8db295583b5477c62Owen Anderson      case 0xf3bf8f6:
38358d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.setOpcode(ARM::t2ISB);
38366de3c6f1a926f49cca2fd207ab4eeb6c35e0e068Owen Anderson        break;
38378d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
38388d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3839fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned imm = fieldFromInstruction(Insn, 0, 4);
3840c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson    return DecodeMemBarrierOption(Inst, imm, Address, Decoder);
38418d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
38428d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3843fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned brtarget = fieldFromInstruction(Insn, 0, 11) << 1;
3844fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 11, 1) << 19;
3845fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 13, 1) << 18;
3846fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 16, 6) << 12;
3847fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  brtarget |= fieldFromInstruction(Insn, 26, 1) << 20;
38488d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3849a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeT2BROperand(Inst, brtarget, Address, Decoder)))
3850a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3851a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3852a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
38538d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
385483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
38558d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38568d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
38578d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// Decode a shifted immediate operand.  These basically consist
38588d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// of an 8-bit value, and a 4-bit directive that specifies either
38598d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson// a splat operation or a rotation.
3860c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2SOImm(MCInst &Inst, unsigned Val,
38618d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                          uint64_t Address, const void *Decoder) {
3862fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned ctrl = fieldFromInstruction(Val, 10, 2);
38638d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  if (ctrl == 0) {
3864fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned byte = fieldFromInstruction(Val, 8, 2);
3865fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned imm = fieldFromInstruction(Val, 0, 8);
38668d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    switch (byte) {
38678d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 0:
38688d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm(imm));
38698d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
38708d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 1:
38718d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm((imm << 16) | imm));
38728d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
38738d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 2:
38748d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 8)));
38758d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
38768d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson      case 3:
38778d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        Inst.addOperand(MCOperand::CreateImm((imm << 24) | (imm << 16) |
38788d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson                                             (imm << 8)  |  imm));
38798d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson        break;
38808d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    }
38818d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  } else {
3882fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned unrot = fieldFromInstruction(Val, 0, 7) | 0x80;
3883fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach    unsigned rot = fieldFromInstruction(Val, 7, 5);
38848d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    unsigned imm = (unrot >> rot) | (unrot << ((32-rot)&31));
38858d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson    Inst.addOperand(MCOperand::CreateImm(imm));
38868d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson  }
38878d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3888c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
38898d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38908d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3891a6804444e874b27aee5921d4c6049df573c5e249Owen Andersonstatic DecodeStatus
3892c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeThumbBCCTargetOperand(MCInst &Inst, unsigned Val,
3893c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                            uint64_t Address, const void *Decoder){
3894c8f2fcc9a381f1e024656568f2face2f600e0328Richard Barton  if (!tryAddingSymbolicOperand(Address, Address + SignExtend32<9>(Val<<1) + 4,
38952a7d3a93735f97c2a4cabcc08a88d702c28cb0d4Kevin Enderby                                true, 2, Inst, Decoder))
3896c8f2fcc9a381f1e024656568f2face2f600e0328Richard Barton    Inst.addOperand(MCOperand::CreateImm(SignExtend32<9>(Val << 1)));
3897c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
38988d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
38998d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3900c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeThumbBLTargetOperand(MCInst &Inst, unsigned Val,
390110cbaab7b774e187c99790292dc1ed64dee2b0f3Owen Anderson                                       uint64_t Address, const void *Decoder){
39022d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // Val is passed in as S:J1:J2:imm10:imm11
39032d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // Note no trailing zero after imm11.  Also the J1 and J2 values are from
39042d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // the encoded instruction.  So here change to I1 and I2 values via:
39052d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I1 = NOT(J1 EOR S);
39062d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // I2 = NOT(J2 EOR S);
39072d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  // and build the imm32 with one trailing zero as documented:
3908dd051a0414d0c807388bdc9584b71729b3158571NAKAMURA Takumi  // imm32 = SignExtend(S:I1:I2:imm10:imm11:'0', 32);
39092d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned S = (Val >> 23) & 1;
39102d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J1 = (Val >> 22) & 1;
39112d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned J2 = (Val >> 21) & 1;
39122d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I1 = !(J1 ^ S);
39132d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned I2 = !(J2 ^ S);
39142d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  unsigned tmp = (Val & ~0x600000) | (I1 << 22) | (I2 << 21);
39152d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  int imm32 = SignExtend32<25>(tmp << 1);
39162d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby
39172d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby  if (!tryAddingSymbolicOperand(Address, Address + imm32 + 4,
3918b80d571ea85db5d52fafed0523cf59e693502198Kevin Enderby                                true, 4, Inst, Decoder))
39192d524b0765145f1c7888166c985a25452f16b2bcKevin Enderby    Inst.addOperand(MCOperand::CreateImm(imm32));
3920c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
39218d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson}
39228d7d2e1238fac58c01ccfb719d0cc5680a079561Owen Anderson
3923c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMemBarrierOption(MCInst &Inst, unsigned Val,
3924c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson                                   uint64_t Address, const void *Decoder) {
3925c1b7ca5ba28ded2d83ae534c8e072c2538d43295Jiangning Liu  if (Val & ~0xf)
3926c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    return MCDisassembler::Fail;
3927c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson
3928c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
3929c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
3930c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson}
3931c36481c4744cdbddec91dc3eca9245acaf2982daOwen Anderson
39324e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuvillestatic DecodeStatus DecodeInstSyncBarrierOption(MCInst &Inst, unsigned Val,
39334e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville                                        uint64_t Address, const void *Decoder) {
39344e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville  if (Val & ~0xf)
39354e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville    return MCDisassembler::Fail;
39364e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville
39374e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville  Inst.addOperand(MCOperand::CreateImm(Val));
39384e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville  return MCDisassembler::Success;
39394e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville}
39404e9a96d810eb0cc126ebe6f18e536b474c84940cAmaury de la Vieuville
3941c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeMSRMask(MCInst &Inst, unsigned Val,
394226d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson                          uint64_t Address, const void *Decoder) {
3943c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (!Val) return MCDisassembler::Fail;
394426d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
3945c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  return MCDisassembler::Success;
394626d2f0ac919f6ae868fe901fd4ad64af6f92da4dOwen Anderson}
3947cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
3948c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegLoad(MCInst &Inst, unsigned Insn,
3949c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                        uint64_t Address, const void *Decoder) {
3950a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
395183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3952fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
3953fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3954fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
39553f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
39563862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (Rn == 0xF)
39573862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville    S = MCDisassembler::SoftFail;
39583f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
39593862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
3960a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3961a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3962a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3963a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3964a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
39653f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
396683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
39673f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson}
39683f3570a38be37ca18c545bd1b4c89604ecaf7e31Owen Anderson
3969c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeDoubleRegStore(MCInst &Inst, unsigned Insn,
3970c40578250d391069d2d81ecaab58a83f2667e96eJim Grosbach                                         uint64_t Address, const void *Decoder){
3971a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
397283e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
3973fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
3974fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 0, 4);
3975fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3976fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
3977cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
3978d3af696c08923d4d376641b52c3b2cb5baa00487Tim Northover  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rd, Address, Decoder)))
3979a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3980cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
39813862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (Rn == 0xF || Rd == Rn || Rd == Rt || Rd == Rt+1)
39823862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville    S = MCDisassembler::SoftFail;
3983cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
39843862709058ecfe809c9d4b32e3bff0efe8ebe646Amaury de la Vieuville  if (!Check(S, DecodeGPRPairRegisterClass(Inst, Rt, Address, Decoder)))
3985a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3986a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
3987a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3988a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
3989a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
3990cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
399183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
3992cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson}
3993cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
3994c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreImm(MCInst &Inst, unsigned Insn,
39959ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                            uint64_t Address, const void *Decoder) {
3996a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
39979ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
3998fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
3999fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4000fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4001fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4002fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4003fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
40049ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4005c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
40069ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4007a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4008a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4009a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4010a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4011a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4012a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4013a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4014a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
40159ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
40169ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return S;
40179ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
40189ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4019c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDRPreReg(MCInst &Inst, unsigned Insn,
40209ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson                            uint64_t Address, const void *Decoder) {
4021a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
40229ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4023fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4024fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4025fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4026fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4027fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4028fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4029fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
40309ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4031c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
4032c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rm == 0xF) S = MCDisassembler::SoftFail;
40339ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4034a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4035a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4036a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4037a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4038a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4039a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4040a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4041a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
40429ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
40439ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson  return S;
40449ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson}
40459ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
40469ab0f25fc194b4315db1b87d38d4024054120bf6Owen Anderson
4047c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreImm(MCInst &Inst, unsigned Insn,
40487cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                            uint64_t Address, const void *Decoder) {
4049a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
405083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4051fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4052fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4053fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4054fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4055fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4056fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4057cbfc044acd722d14d0687c9cf099f3dca45e26d5Owen Anderson
4058c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
40597cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4060a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4061a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4062a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4063a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4064a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeAddrModeImm12Operand(Inst, imm, Address, Decoder)))
4065a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4066a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4067a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
40687cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
406983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
40707cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson}
40717cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4072c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSTRPreReg(MCInst &Inst, unsigned Insn,
40737cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson                            uint64_t Address, const void *Decoder) {
4074a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
407583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4076fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4077fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4078fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 0, 12);
4079fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 16, 4) << 13;
4080fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  imm |= fieldFromInstruction(Insn, 23, 1) << 12;
4081fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
40827cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4083c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy  if (Rn == 0xF || Rn == Rt) S = MCDisassembler::SoftFail;
40847cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
4085a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4086a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4087a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt, Address, Decoder)))
4088a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4089a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSORegMemOperand(Inst, imm, Address, Decoder)))
4090a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4091a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4092a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
40937cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson
409483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
40957cdbf086e4676494fc6a5b26c169285ae0bb740bOwen Anderson}
40967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4097c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD1LN(MCInst &Inst, unsigned Insn,
40987a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4099a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
410083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4101fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4102fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4103fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4104fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4105fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
41067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
41077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
41087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
41097a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
41107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4111c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
41127a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4113fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4114c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4115fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
41167a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
41177a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4118fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4119c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4120fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4121fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
41227a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
41237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
41247a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4125fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
4126c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4127fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4128eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4129eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4130eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0 :
4131eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4132eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4133eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4; break;
4134eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4135eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4136eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4137eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      break;
41387a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
41397a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4140a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4141a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
41427a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4143a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4144a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
41457a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4146a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4147a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
41487a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
41492cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4150c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4151a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4152a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4153c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
41542cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
41557a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
41567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4157a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4158a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
41597a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
41607a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
416183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
41627a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
41637a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4164c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST1LN(MCInst &Inst, unsigned Insn,
41657a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4166a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
416783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4168fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4169fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4170fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4171fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4172fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
41737a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
41747a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
41757a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
41767a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
41777a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4178c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
41797a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4180fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4181c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4182fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
41837a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
41847a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4185fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4186c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4187fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4188fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
41897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
41907a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
41917a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4192fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
4193c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4194fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4195eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4196eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4197eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0:
4198eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4199eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4200eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4; break;
4201eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4202eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4203eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4204eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      break;
42057a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
42067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
42077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4208a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4209a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4211a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4212a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42137a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
42142cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4215c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4216a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4217a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4218c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
42192cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
42207a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
42217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4222a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4223a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42247a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
42257a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
422683e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
42277a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
42287a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
42297a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4230c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD2LN(MCInst &Inst, unsigned Insn,
42317a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4232a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
423383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4234fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4235fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4236fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4237fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4238fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
42397a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
42407a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
42417a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
42427a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
42437a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
42447a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4245c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
42467a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4247fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
4248fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
42497a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
42507a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
42517a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4252fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4253fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
42547a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4255fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
42567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
42577a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
42587a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4259fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4260c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4261fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4262fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1) != 0)
42637a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4264fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
42657a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
42667a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
42677a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
42687a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4269a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4270a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4271a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4272a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42737a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4274a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4275a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
42767a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4277a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4278a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42797a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
42802cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4281c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4282a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4283a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4284c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
42852cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
42867a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
42877a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4288a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4289a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4290a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4291a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
42927a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
42937a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
429483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
42957a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
42967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4297c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST2LN(MCInst &Inst, unsigned Insn,
42987a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4299a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
430083e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4301fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4302fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4303fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4304fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4305fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
43067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
43077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
43087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
43097a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
43107a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
43117a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4312c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
43137a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4314fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
4315fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
43167a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 2;
43177a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4319fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4320fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
43217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4322fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
43237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
43247a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43257a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4326fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
4327c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4328fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4329fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1) != 0)
43307a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4331fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
43327a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
43337a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43347a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
43357a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
43367a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4337a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4338a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
43397a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4340a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4341a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
43427a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
43432cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4344c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4345a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4346a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4347c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
43482cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
43497a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
43507a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4351a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4352a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4353a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4354a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
43557a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
43567a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
435783e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
43587a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
43597a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
43607a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4361c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD3LN(MCInst &Inst, unsigned Insn,
43627a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4363a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
436483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4365fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4366fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4367fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4368fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4369fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
43707a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
43717a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
43727a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
43737a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
43747a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
43757a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4376c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
43777a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4378fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4379c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4380fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
43817a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43827a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4383fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4384c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4385fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4386fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
43877a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
43887a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4390fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 2))
4391c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4392fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4393fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
43947a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
43957a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
43967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
43977a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4398a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4399a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4400a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4401a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4402a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4403a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44057a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4406a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4407a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4409a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4410a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44117a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
4412eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  if (Rm != 0xF) {
4413c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4414a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4415a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4416c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
44172cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
44187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
44197a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4420a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4421a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4422a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4423a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4424a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4425a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44267a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
44277a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
442883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
44297a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
44307a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4431c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST3LN(MCInst &Inst, unsigned Insn,
44327a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4433a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
443483e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4435fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4436fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4437fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4438fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4439fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
44407a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44417a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
44427a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
44437a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
44447a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
44457a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4446c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
44477a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4448fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4449c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4450fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
44517a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44527a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4453fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
4454c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4455fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4456fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
44577a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
44587a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44597a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4460fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 2))
4461c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy        return MCDisassembler::Fail; // UNDEFINED
4462fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4463fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
44647a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
44657a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
44667a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
44677a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44687a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4469a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4470a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44717a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4472a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4473a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44747a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
44752cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4476c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4477a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4478a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4479c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
44802cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
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;
4487a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4488a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
44897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
44907a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
449183e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
44927a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
44937a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
44947a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4495c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVLD4LN(MCInst &Inst, unsigned Insn,
44967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4497a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
449883e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4499fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4500fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4501fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4502fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4503fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
45047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45057a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
45067a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
45077a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
45087a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
45097a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4510c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
45117a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4512fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
45137a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4514fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
45157a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45167a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4517fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
45187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4519fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4520fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
45217a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
45227a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4524eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4525eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0:
4526eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4527eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4528eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4529eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4530eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4531eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4532eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4533fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4534fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
45357a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
45367a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45377a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
45387a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4539a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4540a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4541a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4542a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4543a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4544a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4545a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4546a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
45477a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45487a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4549a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4550a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      return MCDisassembler::Fail;
45517a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4552a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4553a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
45547a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
45552cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4556c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4557a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4558a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson        return MCDisassembler::Fail;
4559c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
45602cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
45617a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
45627a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4563a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4564a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4565a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4566a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4567a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4568a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4569a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4570a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
45717a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
45727a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
457383e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
45747a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
45757a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4576c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVST4LN(MCInst &Inst, unsigned Insn,
45777a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson                         uint64_t Address, const void *Decoder) {
4578a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
457983e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson
4580fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4581fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Insn, 0, 4);
4582fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rd = fieldFromInstruction(Insn, 12, 4);
4583fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rd |= fieldFromInstruction(Insn, 22, 1) << 4;
4584fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned size = fieldFromInstruction(Insn, 10, 2);
45857a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
45867a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned align = 0;
45877a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned index = 0;
45887a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  unsigned inc = 1;
45897a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  switch (size) {
45907a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    default:
4591c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy      return MCDisassembler::Fail;
45927a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 0:
4593fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
45947a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 4;
4595fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 5, 3);
45967a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
45977a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 1:
4598fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 4, 1))
45997a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        align = 8;
4600fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 6, 2);
4601fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 5, 1))
46027a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
46037a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46047a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson    case 2:
4605eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      switch (fieldFromInstruction(Insn, 4, 2)) {
4606eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 0:
4607eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 0; break;
4608eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        case 3:
4609eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          return MCDisassembler::Fail;
4610eae1d34029c159306ce4a0472294de6cf9baedacTim Northover        default:
4611eae1d34029c159306ce4a0472294de6cf9baedacTim Northover          align = 4 << fieldFromInstruction(Insn, 4, 2); break;
4612eae1d34029c159306ce4a0472294de6cf9baedacTim Northover      }
4613eae1d34029c159306ce4a0472294de6cf9baedacTim Northover
4614fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      index = fieldFromInstruction(Insn, 7, 1);
4615fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach      if (fieldFromInstruction(Insn, 6, 1))
46167a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson        inc = 2;
46177a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson      break;
46187a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
46197a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
46207a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  if (Rm != 0xF) { // Writeback
4621a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4622a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46237a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
4624a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rn, Address, Decoder)))
4625a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46267a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(align));
46272cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson  if (Rm != 0xF) {
4628c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    if (Rm != 0xD) {
4629a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson      if (!Check(S, DecodeGPRRegisterClass(Inst, Rm, Address, Decoder)))
4630a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4631c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    } else
46322cbf2104507c855850b610ed910536058aa0c6eeOwen Anderson      Inst.addOperand(MCOperand::CreateReg(0));
46337a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  }
46347a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4635a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd, Address, Decoder)))
4636a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4637a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+inc, Address, Decoder)))
4638a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4639a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+2*inc, Address, Decoder)))
4640a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4641a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Rd+3*inc, Address, Decoder)))
4642a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
46437a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson  Inst.addOperand(MCOperand::CreateImm(index));
46447a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
464583e3f67fb68d497b600da83a62f000fcce7868a9Owen Anderson  return S;
46467a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson}
46477a2e1770ead7c2e3b7292ae466a41b560f3d272cOwen Anderson
4648c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVSRR(MCInst &Inst, unsigned Insn,
4649357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                                  uint64_t Address, const void *Decoder) {
4650a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
4651fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4652fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4653fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4654fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4655fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4656357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4657357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4658c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
4659357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4660a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4661a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4662a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4663a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4664a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4665a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4666a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4667a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4668a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4669a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4670357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4671357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  return S;
4672357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson}
4673357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4674c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVMOVRRS(MCInst &Inst, unsigned Insn,
4675357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson                                  uint64_t Address, const void *Decoder) {
4676a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
4677fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt  = fieldFromInstruction(Insn, 12, 4);
4678fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 16, 4);
4679fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm  = fieldFromInstruction(Insn,  5, 1);
4680fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4681fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= fieldFromInstruction(Insn, 0, 4) << 1;
4682357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4683357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  if (Rt == 0xF || Rt2 == 0xF || Rm == 0x1F)
4684c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
4685357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4686a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt  , Address, Decoder)))
4687a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4688a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeGPRRegisterClass(Inst, Rt2 , Address, Decoder)))
4689a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4690a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm  , Address, Decoder)))
4691a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4692a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodeSPRRegisterClass(Inst, Rm+1, Address, Decoder)))
4693a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4694a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4695a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson    return MCDisassembler::Fail;
4696357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson
4697357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson  return S;
4698357ec6850be0dff0038ea3a14f16066705284c0bOwen Anderson}
46998e1e60b5f8fd9c6233bdb8814ee40887555a0594Owen Anderson
4700c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeIT(MCInst &Inst, unsigned Insn,
4701eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson                             uint64_t Address, const void *Decoder) {
4702a6804444e874b27aee5921d4c6049df573c5e249Owen Anderson  DecodeStatus S = MCDisassembler::Success;
4703fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 4, 4);
4704fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned mask = fieldFromInstruction(Insn, 0, 4);
4705eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson
4706eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  if (pred == 0xF) {
4707eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson    pred = 0xE;
4708c047dcade506a5acaccb1548cb83a3f85f52d71dJames Molloy    S = MCDisassembler::SoftFail;
4709e234d02204e0e546c3555e7e894b8521d22a2121Owen Anderson  }
4710e234d02204e0e546c3555e7e894b8521d22a2121Owen Anderson
4711ff08da15cf3d0412ee9cc325fc5a720bcad178f2Amaury de la Vieuville  if (mask == 0x0)
4712ff08da15cf3d0412ee9cc325fc5a720bcad178f2Amaury de la Vieuville    return MCDisassembler::Fail;
4713eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson
4714eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(pred));
4715eaca928a3798e1fa7072457b94eccdd5b53b5d5fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(mask));
4716f44082091c5517a3275c57a8b58e36987c8227f0Owen Anderson  return S;
4717f44082091c5517a3275c57a8b58e36987c8227f0Owen Anderson}
4718a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4719a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachstatic DecodeStatus
4720c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeT2LDRDPreInstruction(MCInst &Inst, unsigned Insn,
4721a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                           uint64_t Address, const void *Decoder) {
4722a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  DecodeStatus S = MCDisassembler::Success;
4723a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4724fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4725fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4726fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4727fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4728fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
4729fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Insn, 23, 1);
4730fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
4731a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool writeback = (W == 1) | (P == 0);
4732a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4733a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  addr |= (U << 8) | (Rn << 9);
4734a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4735a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (writeback && (Rn == Rt || Rn == Rt2))
4736a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Check(S, MCDisassembler::SoftFail);
4737a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (Rt == Rt2)
4738a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Check(S, MCDisassembler::SoftFail);
4739a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4740a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt
4741a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4742a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4743a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt2
4744a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4745a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4746a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Writeback operand
4747a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4748a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4749a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
4750a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4751a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4752a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4753a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return S;
4754a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
4755a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4756a77295db19527503d6b290e4f34f273d0a789365Jim Grosbachstatic DecodeStatus
4757c89c744b69cecac576317a98322fd295e36e9886Craig TopperDecodeT2STRDPreInstruction(MCInst &Inst, unsigned Insn,
4758a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach                           uint64_t Address, const void *Decoder) {
4759a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  DecodeStatus S = MCDisassembler::Success;
4760a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4761fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Insn, 12, 4);
4762fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Insn, 8, 4);
4763fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Insn, 16, 4);
4764fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned addr = fieldFromInstruction(Insn, 0, 8);
4765fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned W = fieldFromInstruction(Insn, 21, 1);
4766fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned U = fieldFromInstruction(Insn, 23, 1);
4767fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned P = fieldFromInstruction(Insn, 24, 1);
4768a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  bool writeback = (W == 1) | (P == 0);
4769a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4770a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  addr |= (U << 8) | (Rn << 9);
4771a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4772a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (writeback && (Rn == Rt || Rn == Rt2))
4773a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    Check(S, MCDisassembler::SoftFail);
4774a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4775a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Writeback operand
4776a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rn, Address, Decoder)))
4777a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4778a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt
4779a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt, Address, Decoder)))
4780a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4781a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // Rt2
4782a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecoderGPRRegisterClass(Inst, Rt2, Address, Decoder)))
4783a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4784a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  // addr
4785a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  if (!Check(S, DecodeT2AddrModeImm8s4(Inst, addr, Address, Decoder)))
4786a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach    return MCDisassembler::Fail;
4787a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach
4788a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach  return S;
4789a77295db19527503d6b290e4f34f273d0a789365Jim Grosbach}
479008fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
4791c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2Adr(MCInst &Inst, uint32_t Insn,
479208fef885eb39339a47e3be7f0842b1db33683003Owen Anderson                                uint64_t Address, const void *Decoder) {
4793fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned sign1 = fieldFromInstruction(Insn, 21, 1);
4794fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned sign2 = fieldFromInstruction(Insn, 23, 1);
479508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  if (sign1 != sign2) return MCDisassembler::Fail;
479608fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
4797fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Val = fieldFromInstruction(Insn, 0, 8);
4798fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Val |= fieldFromInstruction(Insn, 12, 3) << 8;
4799fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Val |= fieldFromInstruction(Insn, 26, 1) << 11;
480008fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  Val |= sign1 << 12;
480108fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  Inst.addOperand(MCOperand::CreateImm(SignExtend32<13>(Val)));
480208fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
480308fef885eb39339a47e3be7f0842b1db33683003Owen Anderson  return MCDisassembler::Success;
480408fef885eb39339a47e3be7f0842b1db33683003Owen Anderson}
480508fef885eb39339a47e3be7f0842b1db33683003Owen Anderson
4806c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeT2ShifterImmOperand(MCInst &Inst, uint32_t Val,
48070afa0094afdfe589f407feb76948f273b414b278Owen Anderson                                              uint64_t Address,
48080afa0094afdfe589f407feb76948f273b414b278Owen Anderson                                              const void *Decoder) {
48090afa0094afdfe589f407feb76948f273b414b278Owen Anderson  DecodeStatus S = MCDisassembler::Success;
48100afa0094afdfe589f407feb76948f273b414b278Owen Anderson
48110afa0094afdfe589f407feb76948f273b414b278Owen Anderson  // Shift of "asr #32" is not allowed in Thumb2 mode.
48120afa0094afdfe589f407feb76948f273b414b278Owen Anderson  if (Val == 0x20) S = MCDisassembler::SoftFail;
48130afa0094afdfe589f407feb76948f273b414b278Owen Anderson  Inst.addOperand(MCOperand::CreateImm(Val));
48140afa0094afdfe589f407feb76948f273b414b278Owen Anderson  return S;
48150afa0094afdfe589f407feb76948f273b414b278Owen Anderson}
48160afa0094afdfe589f407feb76948f273b414b278Owen Anderson
4817c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeSwap(MCInst &Inst, unsigned Insn,
4818cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson                               uint64_t Address, const void *Decoder) {
4819fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt   = fieldFromInstruction(Insn, 12, 4);
4820fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2  = fieldFromInstruction(Insn, 0,  4);
4821fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn   = fieldFromInstruction(Insn, 16, 4);
4822fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned pred = fieldFromInstruction(Insn, 28, 4);
4823cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson
4824cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (pred == 0xF)
4825cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return DecodeCPSInstruction(Inst, Insn, Address, Decoder);
4826cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson
4827cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  DecodeStatus S = MCDisassembler::Success;
482835ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga
482935ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga  if (Rt == Rn || Rn == Rt2)
483035ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga    S = MCDisassembler::SoftFail;
483135ee7d28a69173ca0c11fb6b3271518bf4c5bff6Silviu Baranga
4832cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4833cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
4834cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4835cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
4836cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4837cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
4838cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  if (!Check(S, DecodePredicateOperand(Inst, pred, Address, Decoder)))
4839cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson    return MCDisassembler::Fail;
4840cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson
4841cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson  return S;
4842cb9fed665550376b7c65c7e1157a58911193e2e2Owen Anderson}
4843b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4844c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTD(MCInst &Inst, unsigned Insn,
4845b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder) {
4846fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
4847fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
4848fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
4849fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
4850fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 16, 6);
4851fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
48529eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville  unsigned op = fieldFromInstruction(Insn, 5, 1);
4853b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4854b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  DecodeStatus S = MCDisassembler::Success;
4855b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4856b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  // VMOVv2f32 is ambiguous with these decodings.
485722925d93e9c5d6159f24853457c858be5f08af04Owen Anderson  if (!(imm & 0x38) && cmode == 0xF) {
48589eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville    if (op == 1) return MCDisassembler::Fail;
4859b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    Inst.setOpcode(ARM::VMOVv2f32);
4860b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4861b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  }
4862b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4863c64835b0c57913b11abd648b76913390e62af8d6Amaury de la Vieuville  if (!(imm & 0x20)) return MCDisassembler::Fail;
4864b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4865b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Vd, Address, Decoder)))
4866b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
4867b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeDPRRegisterClass(Inst, Vm, Address, Decoder)))
4868b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
4869b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(64 - imm));
4870b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4871b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  return S;
4872b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson}
4873b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4874c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeVCVTQ(MCInst &Inst, unsigned Insn,
4875b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson                                uint64_t Address, const void *Decoder) {
4876fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vd = (fieldFromInstruction(Insn, 12, 4) << 0);
4877fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vd |= (fieldFromInstruction(Insn, 22, 1) << 4);
4878fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Vm = (fieldFromInstruction(Insn, 0, 4) << 0);
4879fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Vm |= (fieldFromInstruction(Insn, 5, 1) << 4);
4880fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned imm = fieldFromInstruction(Insn, 16, 6);
4881fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned cmode = fieldFromInstruction(Insn, 8, 4);
48829eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville  unsigned op = fieldFromInstruction(Insn, 5, 1);
4883b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4884b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  DecodeStatus S = MCDisassembler::Success;
4885b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4886b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  // VMOVv4f32 is ambiguous with these decodings.
4887b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!(imm & 0x38) && cmode == 0xF) {
48889eefea009fb559cf441254f7022a2824386852c6Amaury de la Vieuville    if (op == 1) return MCDisassembler::Fail;
4889b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    Inst.setOpcode(ARM::VMOVv4f32);
4890b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return DecodeNEONModImmInstruction(Inst, Insn, Address, Decoder);
4891b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  }
4892b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4893c64835b0c57913b11abd648b76913390e62af8d6Amaury de la Vieuville  if (!(imm & 0x20)) return MCDisassembler::Fail;
4894b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4895b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeQPRRegisterClass(Inst, Vd, Address, Decoder)))
4896b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
4897b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  if (!Check(S, DecodeQPRRegisterClass(Inst, Vm, Address, Decoder)))
4898b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson    return MCDisassembler::Fail;
4899b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  Inst.addOperand(MCOperand::CreateImm(64 - imm));
4900b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson
4901b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson  return S;
4902b589be9334ee5352dd263c406b99a90d413c0b2fOwen Anderson}
4903b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
49047c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombetstatic DecodeStatus DecodeImm0_4(MCInst &Inst, unsigned Insn, uint64_t Address,
49057c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet                                 const void *Decoder)
49067c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet{
49077c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet  unsigned Imm = fieldFromInstruction(Insn, 0, 3);
49087c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet  if (Imm > 4) return MCDisassembler::Fail;
49097c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet  Inst.addOperand(MCOperand::CreateImm(Imm));
49107c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet  return MCDisassembler::Success;
49117c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet}
49127c4cf030a898b5b4e0d2c66adf8dc068b1f1f070Quentin Colombet
4913c89c744b69cecac576317a98322fd295e36e9886Craig Topperstatic DecodeStatus DecodeLDR(MCInst &Inst, unsigned Val,
4914b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga                                uint64_t Address, const void *Decoder) {
4915b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  DecodeStatus S = MCDisassembler::Success;
4916b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
4917fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rn = fieldFromInstruction(Val, 16, 4);
4918fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Val, 12, 4);
4919fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rm = fieldFromInstruction(Val, 0, 4);
4920fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  Rm |= (fieldFromInstruction(Val, 23, 1) << 4);
4921fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Cond = fieldFromInstruction(Val, 28, 4);
4922b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
4923fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  if (fieldFromInstruction(Val, 8, 4) != 0 || Rn == Rt)
4924b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    S = MCDisassembler::SoftFail;
4925b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
4926b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4927b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
4928b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rn, Address, Decoder)))
4929b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
4930b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodeAddrMode7Operand(Inst, Rn, Address, Decoder)))
4931b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
4932b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodePostIdxReg(Inst, Rm, Address, Decoder)))
4933b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
4934b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  if (!Check(S, DecodePredicateOperand(Inst, Cond, Address, Decoder)))
4935b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga    return MCDisassembler::Fail;
4936b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
4937b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga  return S;
4938b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga}
4939b7c2ed66642b141a768b3074c465eba9d98665d8Silviu Baranga
4940fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Barangastatic DecodeStatus DecodeMRRC2(llvm::MCInst &Inst, unsigned Val,
4941fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga                                uint64_t Address, const void *Decoder) {
4942fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4943fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  DecodeStatus S = MCDisassembler::Success;
4944fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4945fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned CRm = fieldFromInstruction(Val, 0, 4);
4946fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned opc1 = fieldFromInstruction(Val, 4, 4);
4947fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned cop = fieldFromInstruction(Val, 8, 4);
4948fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt = fieldFromInstruction(Val, 12, 4);
4949fc1a161d76f5cc0204bed3bce3e27cf36ac76d22Jim Grosbach  unsigned Rt2 = fieldFromInstruction(Val, 16, 4);
4950fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4951fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if ((cop & ~0x1) == 0xa)
4952fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    return MCDisassembler::Fail;
4953fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4954fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if (Rt == Rt2)
4955fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    S = MCDisassembler::SoftFail;
4956fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4957fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  Inst.addOperand(MCOperand::CreateImm(cop));
4958fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  Inst.addOperand(MCOperand::CreateImm(opc1));
4959fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt, Address, Decoder)))
4960fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    return MCDisassembler::Fail;
4961fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  if (!Check(S, DecodeGPRnopcRegisterClass(Inst, Rt2, Address, Decoder)))
4962fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga    return MCDisassembler::Fail;
4963fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  Inst.addOperand(MCOperand::CreateImm(CRm));
4964fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4965fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga  return S;
4966fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga}
4967fa1ebc6abe95b79b7f82030eea53586a8704eb7eSilviu Baranga
4968