decoder-a64.cc revision 578645f14e122d2b87d907e298cda7e7d0babf1f
1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Copyright 2013, ARM Limited
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// All rights reserved.
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Redistribution and use in source and binary forms, with or without
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// modification, are permitted provided that the following conditions are met:
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions of source code must retain the above copyright notice,
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer.
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Redistributions in binary form must reproduce the above copyright notice,
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     this list of conditions and the following disclaimer in the documentation
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     and/or other materials provided with the distribution.
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//   * Neither the name of ARM Limited nor the names of its contributors may be
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     used to endorse or promote products derived from this software without
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//     specific prior written permission.
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl//
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "globals.h"
28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "utils.h"
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#include "a64/decoder-a64.h"
30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl {
32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl// Top-level instruction decode function.
33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::Decode(Instruction *instr) {
34578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if (instr->Bits(28, 27) == 0) {
35578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    VisitUnallocated(instr);
36578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  } else {
37578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    switch (instr->Bits(27, 24)) {
38578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 0:   PC relative addressing.
39578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x0: DecodePCRelAddressing(instr); break;
40578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
41578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 1:   Add/sub immediate.
42578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x1: DecodeAddSubImmediate(instr); break;
43578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
44578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // A:   Logical shifted register.
45578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Add/sub with carry.
46578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Conditional compare register.
47578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Conditional compare immediate.
48578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Conditional select.
49578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Data processing 1 source.
50578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Data processing 2 source.
51578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // B:   Add/sub shifted register.
52578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Add/sub extended register.
53578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Data processing 3 source.
54578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0xA:
55578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0xB: DecodeDataProcessing(instr); break;
56578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
57578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 2:   Logical immediate.
58578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Move wide immediate.
59578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x2: DecodeLogical(instr); break;
60578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
61578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 3:   Bitfield.
62578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Extract.
63578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x3: DecodeBitfieldExtract(instr); break;
64578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
65578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 4:   Unconditional branch immediate.
66578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Exception generation.
67578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Compare and branch immediate.
68578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 5:   Compare and branch immediate.
69578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Conditional branch.
70578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      System.
71578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 6,7: Unconditional branch.
72578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Test and branch immediate.
73578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x4:
74578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x5:
75578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x6:
76578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x7: DecodeBranchSystemException(instr); break;
77578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
78578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // 8,9: Load/store register pair post-index.
79578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load register literal.
80578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store register unscaled immediate.
81578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store register immediate post-index.
82578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store register immediate pre-index.
83578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store register offset.
84578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store exclusive.
85578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // C,D: Load/store register pair offset.
86578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store register pair pre-index.
87578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Load/store register unsigned immediate.
88578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Advanced SIMD.
89578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x8:
90578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0x9:
91578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0xC:
92578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0xD: DecodeLoadStore(instr); break;
93578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
94578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // E:   FP fixed point conversion.
95578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP integer conversion.
96578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP data processing 1 source.
97578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP compare.
98578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP immediate.
99578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP data processing 2 source.
100578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP conditional compare.
101578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      FP conditional select.
102578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Advanced SIMD.
103578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      // F:   FP data processing 3 source.
104578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      //      Advanced SIMD.
105578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0xE:
106578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      case 0xF: DecodeFP(instr); break;
107578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::AppendVisitor(DecoderVisitor* new_visitor) {
112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.remove(new_visitor);
113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.push_front(new_visitor);
114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::PrependVisitor(DecoderVisitor* new_visitor) {
118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.remove(new_visitor);
119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.push_back(new_visitor);
120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor,
124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                  DecoderVisitor* registered_visitor) {
125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.remove(new_visitor);
126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::list<DecoderVisitor*>::iterator it;
127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (it = visitors_.begin(); it != visitors_.end(); it++) {
128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (*it == registered_visitor) {
129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      visitors_.insert(it, new_visitor);
130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return;
131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // We reached the end of the list. The last element must be
134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // registered_visitor.
135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ASSERT(*it == registered_visitor);
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.insert(it, new_visitor);
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor,
141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                                 DecoderVisitor* registered_visitor) {
142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.remove(new_visitor);
143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  std::list<DecoderVisitor*>::iterator it;
144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  for (it = visitors_.begin(); it != visitors_.end(); it++) {
145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (*it == registered_visitor) {
146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      it++;
147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      visitors_.insert(it, new_visitor);
148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      return;
149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // We reached the end of the list. The last element must be
152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  // registered_visitor.
153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ASSERT(*it == registered_visitor);
154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.push_back(new_visitor);
155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::RemoveVisitor(DecoderVisitor* visitor) {
159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  visitors_.remove(visitor);
160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
163578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodePCRelAddressing(Instruction* instr) {
164578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT(instr->Bits(27, 24) == 0x0);
165578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level
166578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // decode.
167578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT(instr->Bit(28) == 0x1);
168578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  VisitPCRelAddressing(instr);
169578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
170578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
171578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
172578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeBranchSystemException(Instruction* instr) {
173578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT((instr->Bits(27, 24) == 0x4) ||
174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0x5) ||
175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0x6) ||
176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0x7) );
177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
178578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  switch (instr->Bits(31, 29)) {
179578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 0:
180578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 4: {
181578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitUnconditionalBranch(instr);
182578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      break;
183578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
184578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 1:
185578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 5: {
186578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bit(25) == 0) {
187578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitCompareBranch(instr);
188578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
189578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitTestBranch(instr);
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
191578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      break;
192578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
193578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 2: {
194578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bit(25) == 0) {
195578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Bit(24) == 0x1) ||
196578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x01000010) == 0x00000010)) {
197578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        } else {
199578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitConditionalBranch(instr);
200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
201578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
202578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
204578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      break;
205578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
206578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 6: {
207578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bit(25) == 0) {
208578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if (instr->Bit(24) == 0) {
209578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if ((instr->Bits(4, 2) != 0) ||
210578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001D) == 0x00200001) ||
211578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001D) == 0x00400001) ||
212578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001E) == 0x00200002) ||
213578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001E) == 0x00400002) ||
214578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001C) == 0x00600000) ||
215578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001C) == 0x00800000) ||
216578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00E0001F) == 0x00A00000) ||
217578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00C0001C) == 0x00C00000)) {
218578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
219578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            VisitException(instr);
221578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          }
222578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
223578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Bits(23, 22) == 0) {
224578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0);
225578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if ((instr->Bits(21, 19) == 0x4) ||
226578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (masked_003FF0E0 == 0x00033000) ||
227578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (masked_003FF0E0 == 0x003FF020) ||
228578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (masked_003FF0E0 == 0x003FF060) ||
229578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (masked_003FF0E0 == 0x003FF0E0) ||
230578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x00388000) == 0x00008000) ||
231578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x0038E000) == 0x00000000) ||
232578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x0039E000) == 0x00002000) ||
233578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003AE000) == 0x00002000) ||
234578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003CE000) == 0x00042000) ||
235578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003FFFC0) == 0x000320C0) ||
236578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003FF100) == 0x00032100) ||
237578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003FF200) == 0x00032200) ||
238578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003FF400) == 0x00032400) ||
239578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x003FF800) == 0x00032800) ||
240578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x0038F000) == 0x00005000) ||
241578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x0038E000) == 0x00006000)) {
242578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitUnallocated(instr);
243578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
244578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitSystem(instr);
245578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            }
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          } else {
247578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          }
249578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        }
250578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
251578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Bit(24) == 0x1) ||
252578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Bits(20, 16) != 0x1F) ||
253578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Bits(15, 10) != 0) ||
254578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Bits(4, 0) != 0) ||
255578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Bits(24, 21) == 0x3) ||
256578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Bits(24, 22) == 0x3)) {
257578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        } else {
259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          VisitUnconditionalBranchToRegister(instr);
260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
262578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      break;
263578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
264578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 3:
265578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    case 7: {
266578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitUnallocated(instr);
267578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      break;
268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
273578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeLoadStore(Instruction* instr) {
274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ASSERT((instr->Bits(27, 24) == 0x8) ||
275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0x9) ||
276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0xC) ||
277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0xD) );
278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if (instr->Bit(24) == 0) {
280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (instr->Bit(28) == 0) {
281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (instr->Bit(29) == 0) {
282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        if (instr->Bit(26) == 0) {
283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          // TODO: VisitLoadStoreExclusive.
284578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnimplemented(instr);
285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        } else {
286578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          DecodeAdvSIMDLoadStore(instr);
287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
289578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Bits(31, 30) == 0x3) ||
290578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0xC4400000) == 0x40000000)) {
291578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        } else {
293578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Bit(23) == 0) {
294578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if (instr->Mask(0xC4400000) == 0xC0400000) {
295578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitUnallocated(instr);
296578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
297578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitLoadStorePairNonTemporal(instr);
298578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            }
299578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
300578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitLoadStorePairPostIndex(instr);
301578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          }
302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      if (instr->Bit(29) == 0) {
306578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if (instr->Mask(0xC4000000) == 0xC4000000) {
307578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
308578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
309578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitLoadLiteral(instr);
310578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        }
311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
312578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Mask(0x84C00000) == 0x80C00000) ||
313578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x44800000) == 0x44800000) ||
314578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x84800000) == 0x84800000)) {
315578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
316578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
317578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Bit(21) == 0) {
318578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            switch (instr->Bits(11, 10)) {
319578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              case 0: {
320578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitLoadStoreUnscaledOffset(instr);
321578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                break;
322578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
323578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              case 1: {
324578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                if (instr->Mask(0xC4C00000) == 0xC0800000) {
325578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  VisitUnallocated(instr);
326578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                } else {
327578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  VisitLoadStorePostIndex(instr);
328578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                }
329578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                break;
330578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
331578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              case 2: {
332578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                // TODO: VisitLoadStoreRegisterOffsetUnpriv.
333578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnimplemented(instr);
334578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                break;
335578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
336578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              case 3: {
337578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                if (instr->Mask(0xC4C00000) == 0xC0800000) {
338578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  VisitUnallocated(instr);
339578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                } else {
340578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  VisitLoadStorePreIndex(instr);
341578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                }
342578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                break;
343578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            }
345578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
346578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if (instr->Bits(11, 10) == 0x2) {
347578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if (instr->Bit(14) == 0) {
348578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
349578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
350578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitLoadStoreRegisterOffset(instr);
351578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
352578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
353578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitUnallocated(instr);
354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl            }
355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          }
356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (instr->Bit(28) == 0) {
361578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bit(29) == 0) {
362578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
364578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Bits(31, 30) == 0x3) ||
365578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0xC4400000) == 0x40000000)) {
366578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
367578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
368578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Bit(23) == 0) {
369578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitLoadStorePairOffset(instr);
370578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
371578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitLoadStorePairPreIndex(instr);
372578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          }
373578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        }
374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
376578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bit(29) == 0) {
377578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
378578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
379578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Mask(0x84C00000) == 0x80C00000) ||
380578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x44800000) == 0x44800000) ||
381578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x84800000) == 0x84800000)) {
382578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
383578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
384578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitLoadStoreUnsignedOffset(instr);
385578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        }
386578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      }
387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
392578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeLogical(Instruction* instr) {
393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ASSERT(instr->Bits(27, 24) == 0x2);
394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
395578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if (instr->Mask(0x80400000) == 0x00400000) {
396578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    VisitUnallocated(instr);
397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
398578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    if (instr->Bit(23) == 0) {
399578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitLogicalImmediate(instr);
400578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    } else {
401578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bits(30, 29) == 0x1) {
402578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
403578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
404578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitMoveWideImmediate(instr);
405578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      }
406578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
411578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeBitfieldExtract(Instruction* instr) {
412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ASSERT(instr->Bits(27, 24) == 0x3);
413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
414578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if ((instr->Mask(0x80400000) == 0x80000000) ||
415578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      (instr->Mask(0x80400000) == 0x00400000) ||
416578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      (instr->Mask(0x80008000) == 0x00008000)) {
417578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    VisitUnallocated(instr);
418578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  } else if (instr->Bit(23) == 0) {
419578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    if ((instr->Mask(0x80200000) == 0x00200000) ||
420578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        (instr->Mask(0x60000000) == 0x60000000)) {
421578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitUnallocated(instr);
422578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    } else {
423578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitBitfield(instr);
424578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
426578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    if ((instr->Mask(0x60200000) == 0x00200000) ||
427578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        (instr->Mask(0x60000000) != 0x00000000)) {
428578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitUnallocated(instr);
429578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    } else {
430578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitExtract(instr);
431578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    }
432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
436578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeAddSubImmediate(Instruction* instr) {
437578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT(instr->Bits(27, 24) == 0x1);
438578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if (instr->Bit(23) == 1) {
439578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    VisitUnallocated(instr);
440578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  } else {
441578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    VisitAddSubImmediate(instr);
442578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  }
443578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
444578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
445578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
446578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeDataProcessing(Instruction* instr) {
447578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT((instr->Bits(27, 24) == 0xA) ||
448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0xB) );
449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
450578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if (instr->Bit(24) == 0) {
451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (instr->Bit(28) == 0) {
452578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Mask(0x80008000) == 0x00008000) {
453578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
454578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
455578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitLogicalShifted(instr);
456578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      }
457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      switch (instr->Bits(23, 21)) {
459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        case 0: {
460578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Mask(0x0000FC00) != 0) {
461578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
462578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
463578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitAddSubWithCarry(instr);
464578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          }
465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          break;
466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        case 2: {
468578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if ((instr->Bit(29) == 0) ||
469578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              (instr->Mask(0x00000410) != 0)) {
470578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          } else {
472578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if (instr->Bit(11) == 0) {
473578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitConditionalCompareRegister(instr);
474578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
475578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitConditionalCompareImmediate(instr);
476578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            }
477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          }
478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          break;
479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        case 4: {
481578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Mask(0x20000800) != 0x00000000) {
482578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
483578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
484578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitConditionalSelect(instr);
485578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          }
486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          break;
487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        case 6: {
489578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Bit(29) == 0x1) {
490578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          } else {
492578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if (instr->Bit(30) == 0) {
493578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if ((instr->Bit(15) == 0x1) ||
494578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(15, 11) == 0) ||
495578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(15, 12) == 0x1) ||
496578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(15, 12) == 0x3) ||
497578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(15, 13) == 0x3) ||
498578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x8000EC00) == 0x00004C00) ||
499578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x8000E800) == 0x80004000) ||
500578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x8000E400) == 0x80004000)) {
501578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
502578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
503578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitDataProcessing2Source(instr);
504578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
505578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
506578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if ((instr->Bit(13) == 1) ||
507578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(20, 16) != 0) ||
508578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(15, 14) != 0) ||
509578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA01FFC00) == 0x00000C00) ||
510578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x201FF800) == 0x00001800)) {
511578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
512578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
513578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitDataProcessing1Source(instr);
514578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
515578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            }
516578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            break;
517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          }
518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
519578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        case 1:
520578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        case 3:
521578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        case 5:
522578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        case 7: VisitUnallocated(instr); break;
523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  } else {
526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if (instr->Bit(28) == 0) {
527578645f14e122d2b87d907e298cda7e7d0babf1farmvixl     if (instr->Bit(21) == 0) {
528578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Bits(23, 22) == 0x3) ||
529578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x80008000) == 0x00008000)) {
530578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
531578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
532578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitAddSubShifted(instr);
533578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        }
534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
535578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if ((instr->Mask(0x00C00000) != 0x00000000) ||
536578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x00001400) == 0x00001400) ||
537578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            (instr->Mask(0x00001800) == 0x00001800)) {
538578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitUnallocated(instr);
539578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
540578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          VisitAddSubExtended(instr);
541578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        }
542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
544578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if ((instr->Bit(30) == 0x1) ||
545578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Bits(30, 29) == 0x1) ||
546578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Mask(0xE0600000) == 0x00200000) ||
547578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Mask(0xE0608000) == 0x00400000) ||
548578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Mask(0x60608000) == 0x00408000) ||
549578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Mask(0x60E00000) == 0x00E00000) ||
550578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Mask(0x60E00000) == 0x00800000) ||
551578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          (instr->Mask(0x60E00000) == 0x00600000)) {
552578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
553578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else {
554578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitDataProcessing3Source(instr);
555578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      }
556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
561578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeFP(Instruction* instr) {
562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  ASSERT((instr->Bits(27, 24) == 0xE) ||
563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl         (instr->Bits(27, 24) == 0xF) );
564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
565578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  if (instr->Bit(28) == 0) {
566578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    DecodeAdvSIMDDataProcessing(instr);
567578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  } else {
568578645f14e122d2b87d907e298cda7e7d0babf1farmvixl    if (instr->Bit(29) == 1) {
569578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      VisitUnallocated(instr);
570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    } else {
571578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      if (instr->Bits(31, 30) == 0x3) {
572578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        VisitUnallocated(instr);
573578645f14e122d2b87d907e298cda7e7d0babf1farmvixl      } else if (instr->Bits(31, 30) == 0x1) {
574578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        DecodeAdvSIMDDataProcessing(instr);
575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      } else {
576578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        if (instr->Bit(24) == 0) {
577578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Bit(21) == 0) {
578578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if ((instr->Bit(23) == 1) ||
579578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Bit(18) == 1) ||
580578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x80008000) == 0x00000000) ||
581578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x000E0000) == 0x00000000) ||
582578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x000E0000) == 0x000A0000) ||
583578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x00160000) == 0x00000000) ||
584578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                (instr->Mask(0x00160000) == 0x00120000)) {
585578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitUnallocated(instr);
586578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
587578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitFPFixedPointConvert(instr);
588578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            }
589578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
590578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            if (instr->Bits(15, 10) == 32) {
591578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              VisitUnallocated(instr);
592578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else if (instr->Bits(15, 10) == 0) {
593578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if ((instr->Bits(23, 22) == 0x3) ||
594578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x000E0000) == 0x000A0000) ||
595578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x000E0000) == 0x000C0000) ||
596578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x00160000) == 0x00120000) ||
597578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x00160000) == 0x00140000) ||
598578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x20C40000) == 0x00800000) ||
599578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x20C60000) == 0x00840000) ||
600578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0C60000) == 0x80060000) ||
601578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0C60000) == 0x00860000) ||
602578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0C60000) == 0x00460000) ||
603578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0CE0000) == 0x80860000) ||
604578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0CE0000) == 0x804E0000) ||
605578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0CE0000) == 0x000E0000) ||
606578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0D60000) == 0x00160000) ||
607578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0D60000) == 0x80560000) ||
608578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0D60000) == 0x80960000)) {
609578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
610578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
611578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitFPIntegerConvert(instr);
612578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
613578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else if (instr->Bits(14, 10) == 16) {
614578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000);
615578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if ((instr->Mask(0x80180000) != 0) ||
616578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (masked_A0DF8000 == 0x00020000) ||
617578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (masked_A0DF8000 == 0x00030000) ||
618578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (masked_A0DF8000 == 0x00068000) ||
619578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (masked_A0DF8000 == 0x00428000) ||
620578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (masked_A0DF8000 == 0x00430000) ||
621578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (masked_A0DF8000 == 0x00468000) ||
622578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0D80000) == 0x00800000) ||
623578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0DE0000) == 0x00C00000) ||
624578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0DF0000) == 0x00C30000) ||
625578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0xA0DC0000) == 0x00C40000)) {
626578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
627578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
628578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitFPDataProcessing1Source(instr);
629578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
630578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else if (instr->Bits(13, 10) == 8) {
631578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if ((instr->Bits(15, 14) != 0) ||
632578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Bits(2, 0) != 0) ||
633578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x80800000) != 0x00000000)) {
634578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
635578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
636578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitFPCompare(instr);
637578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
638578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else if (instr->Bits(12, 10) == 4) {
639578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if ((instr->Bits(9, 5) != 0) ||
640578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  (instr->Mask(0x80800000) != 0x00000000)) {
641578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
642578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
643578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitFPImmediate(instr);
644578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
645578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            } else {
646578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              if (instr->Mask(0x80800000) != 0x00000000) {
647578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                VisitUnallocated(instr);
648578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              } else {
649578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                switch (instr->Bits(11, 10)) {
650578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  case 1: {
651578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    VisitFPConditionalCompare(instr);
652578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    break;
653578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  }
654578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  case 2: {
655578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    if ((instr->Bits(15, 14) == 0x3) ||
656578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                        (instr->Mask(0x00009000) == 0x00009000) ||
657578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                        (instr->Mask(0x0000A000) == 0x0000A000)) {
658578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                      VisitUnallocated(instr);
659578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    } else {
660578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                      VisitFPDataProcessing2Source(instr);
661578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    }
662578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    break;
663578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  }
664578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  case 3: {
665578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    VisitFPConditionalSelect(instr);
666578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                    break;
667578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  }
668578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                  default: UNREACHABLE();
669578645f14e122d2b87d907e298cda7e7d0babf1farmvixl                }
670578645f14e122d2b87d907e298cda7e7d0babf1farmvixl              }
671578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            }
672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          }
673578645f14e122d2b87d907e298cda7e7d0babf1farmvixl        } else {
674578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          // Bit 30 == 1 has been handled earlier.
675578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          ASSERT(instr->Bit(30) == 0);
676578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          if (instr->Mask(0xA0800000) != 0) {
677578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitUnallocated(instr);
678578645f14e122d2b87d907e298cda7e7d0babf1farmvixl          } else {
679578645f14e122d2b87d907e298cda7e7d0babf1farmvixl            VisitFPDataProcessing3Source(instr);
680ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl          }
681ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        }
682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      }
683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }
684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
685ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}
686ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
687578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
688578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeAdvSIMDLoadStore(Instruction* instr) {
689578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // TODO: Implement Advanced SIMD load/store instruction decode.
690578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT(instr->Bits(29, 25) == 0x6);
691578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  VisitUnimplemented(instr);
692578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
693578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
694578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
695578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Decoder::DecodeAdvSIMDDataProcessing(Instruction* instr) {
696578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  // TODO: Implement Advanced SIMD data processing instruction decode.
697578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  ASSERT(instr->Bits(27, 25) == 0x7);
698578645f14e122d2b87d907e298cda7e7d0babf1farmvixl  VisitUnimplemented(instr);
699578645f14e122d2b87d907e298cda7e7d0babf1farmvixl}
700578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
701578645f14e122d2b87d907e298cda7e7d0babf1farmvixl
702ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define DEFINE_VISITOR_CALLERS(A)                                              \
703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  void Decoder::Visit##A(Instruction *instr) {                                 \
704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    ASSERT(instr->Mask(A##FMask) == A##Fixed);                                 \
705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    std::list<DecoderVisitor*>::iterator it;                                   \
706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    for (it = visitors_.begin(); it != visitors_.end(); it++) {                \
707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      (*it)->Visit##A(instr);                                                  \
708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    }                                                                          \
709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  }
710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlVISITOR_LIST(DEFINE_VISITOR_CALLERS)
711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef DEFINE_VISITOR_CALLERS
712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl}  // namespace vixl
713