10cc8b6ece4b3e757e11a906a81ece292437713abarmvixl// Copyright 2014, 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 270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/globals.h" 280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/utils.h" 290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl#include "vixl/a64/decoder-a64.h" 30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 3239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl 3339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeInstruction(const 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) { 11239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl visitors_.push_back(new_visitor); 113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::PrependVisitor(DecoderVisitor* new_visitor) { 11739ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl visitors_.push_front(new_visitor); 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::InsertVisitorBefore(DecoderVisitor* new_visitor, 122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DecoderVisitor* registered_visitor) { 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl std::list<DecoderVisitor*>::iterator it; 124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (it = visitors_.begin(); it != visitors_.end(); it++) { 125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (*it == registered_visitor) { 126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl visitors_.insert(it, new_visitor); 127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return; 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We reached the end of the list. The last element must be 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registered_visitor. 1321123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(*it == registered_visitor); 133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl visitors_.insert(it, new_visitor); 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::InsertVisitorAfter(DecoderVisitor* new_visitor, 138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl DecoderVisitor* registered_visitor) { 139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl std::list<DecoderVisitor*>::iterator it; 140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (it = visitors_.begin(); it != visitors_.end(); it++) { 141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (*it == registered_visitor) { 142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl it++; 143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl visitors_.insert(it, new_visitor); 144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return; 145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // We reached the end of the list. The last element must be 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registered_visitor. 1491123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(*it == registered_visitor); 150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl visitors_.push_back(new_visitor); 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Decoder::RemoveVisitor(DecoderVisitor* visitor) { 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl visitors_.remove(visitor); 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 15939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodePCRelAddressing(const Instruction* instr) { 1601123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Bits(27, 24) == 0x0); 161578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // We know bit 28 is set, as <b28:b27> = 0 is filtered out at the top level 162578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // decode. 1631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Bit(28) == 0x1); 164578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitPCRelAddressing(instr); 165578645f14e122d2b87d907e298cda7e7d0babf1farmvixl} 166578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 167578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 16839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeBranchSystemException(const Instruction* instr) { 1691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((instr->Bits(27, 24) == 0x4) || 17090b0414b6c794be58f34813f84c2c06e6a15be91armvixl (instr->Bits(27, 24) == 0x5) || 17190b0414b6c794be58f34813f84c2c06e6a15be91armvixl (instr->Bits(27, 24) == 0x6) || 17290b0414b6c794be58f34813f84c2c06e6a15be91armvixl (instr->Bits(27, 24) == 0x7) ); 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 174578645f14e122d2b87d907e298cda7e7d0babf1farmvixl switch (instr->Bits(31, 29)) { 175578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 0: 176578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 4: { 177578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnconditionalBranch(instr); 178578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 179578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 180578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 1: 181578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 5: { 182578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(25) == 0) { 183578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitCompareBranch(instr); 184578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 185578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitTestBranch(instr); 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 187578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 188578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 189578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 2: { 190578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(25) == 0) { 191578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bit(24) == 0x1) || 192578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x01000010) == 0x00000010)) { 193578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 195578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitConditionalBranch(instr); 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 197578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 198578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 200578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 201578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 202578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 6: { 203578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(25) == 0) { 204578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(24) == 0) { 205578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(4, 2) != 0) || 206578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001D) == 0x00200001) || 207578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001D) == 0x00400001) || 208578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001E) == 0x00200002) || 209578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001E) == 0x00400002) || 210578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001C) == 0x00600000) || 211578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001C) == 0x00800000) || 212578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00E0001F) == 0x00A00000) || 213578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00C0001C) == 0x00C00000)) { 214578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 215578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl VisitException(instr); 217578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 218578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 219578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bits(23, 22) == 0) { 220578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const Instr masked_003FF0E0 = instr->Mask(0x003FF0E0); 221578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(21, 19) == 0x4) || 222578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_003FF0E0 == 0x00033000) || 223578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_003FF0E0 == 0x003FF020) || 224578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_003FF0E0 == 0x003FF060) || 225578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_003FF0E0 == 0x003FF0E0) || 226578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00388000) == 0x00008000) || 227578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x0038E000) == 0x00000000) || 228578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x0039E000) == 0x00002000) || 229578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003AE000) == 0x00002000) || 230578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003CE000) == 0x00042000) || 231578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003FFFC0) == 0x000320C0) || 232578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003FF100) == 0x00032100) || 233578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003FF200) == 0x00032200) || 234578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003FF400) == 0x00032400) || 235578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x003FF800) == 0x00032800) || 236578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x0038F000) == 0x00005000) || 237578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x0038E000) == 0x00006000)) { 238578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 239578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 240578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitSystem(instr); 241578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 243578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 245578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 246578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 247578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bit(24) == 0x1) || 248578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(20, 16) != 0x1F) || 249578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(15, 10) != 0) || 250578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(4, 0) != 0) || 251578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(24, 21) == 0x3) || 252578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(24, 22) == 0x3)) { 253578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl VisitUnconditionalBranchToRegister(instr); 256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 258578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 259578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 260578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 3: 261578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 7: { 262578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 263578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 26939ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeLoadStore(const Instruction* instr) { 2701123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((instr->Bits(27, 24) == 0x8) || 27190b0414b6c794be58f34813f84c2c06e6a15be91armvixl (instr->Bits(27, 24) == 0x9) || 27290b0414b6c794be58f34813f84c2c06e6a15be91armvixl (instr->Bits(27, 24) == 0xC) || 27390b0414b6c794be58f34813f84c2c06e6a15be91armvixl (instr->Bits(27, 24) == 0xD) ); 2740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl // TODO(all): rearrange the tree to integrate this branch. 2750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if ((instr->Bit(28) == 0) && (instr->Bit(29) == 0) && (instr->Bit(26) == 1)) { 2760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl DecodeNEONLoadStore(instr); 2770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl return; 2780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Bit(24) == 0) { 281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Bit(28) == 0) { 282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Bit(29) == 0) { 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Bit(26) == 0) { 28490b0414b6c794be58f34813f84c2c06e6a15be91armvixl VisitLoadStoreExclusive(instr); 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 2860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VIXL_UNREACHABLE(); 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 39239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeLogical(const Instruction* instr) { 3931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_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 41139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeBitfieldExtract(const Instruction* instr) { 4121123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_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 43639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeAddSubImmediate(const Instruction* instr) { 4371123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Bits(27, 24) == 0x1); 438578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(23) == 1) { 439578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 440578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 441578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitAddSubImmediate(instr); 442578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 443578645f14e122d2b87d907e298cda7e7d0babf1farmvixl} 444578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 445578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 44639ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeDataProcessing(const Instruction* instr) { 4471123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((instr->Bits(27, 24) == 0xA) || 4481123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl (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); 4910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VIXL_FALLTHROUGH(); 492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 493578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(30) == 0) { 494578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bit(15) == 0x1) || 495578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(15, 11) == 0) || 496578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(15, 12) == 0x1) || 497578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(15, 12) == 0x3) || 498578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(15, 13) == 0x3) || 499578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x8000EC00) == 0x00004C00) || 500578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x8000E800) == 0x80004000) || 501578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x8000E400) == 0x80004000)) { 502578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 503578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 504578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitDataProcessing2Source(instr); 505578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 506578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 507578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bit(13) == 1) || 508578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(20, 16) != 0) || 509578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(15, 14) != 0) || 510578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA01FFC00) == 0x00000C00) || 511578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x201FF800) == 0x00001800)) { 512578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 513578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 514578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitDataProcessing1Source(instr); 515578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 516578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 517578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 520578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 1: 521578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 3: 522578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 5: 523578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 7: VisitUnallocated(instr); break; 524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Bit(28) == 0) { 528578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(21) == 0) { 529578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(23, 22) == 0x3) || 530578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x80008000) == 0x00008000)) { 531578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 532578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 533578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitAddSubShifted(instr); 534578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 536578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Mask(0x00C00000) != 0x00000000) || 537578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00001400) == 0x00001400) || 538578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00001800) == 0x00001800)) { 539578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 540578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 541578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitAddSubExtended(instr); 542578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 545578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bit(30) == 0x1) || 546578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(30, 29) == 0x1) || 547578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xE0600000) == 0x00200000) || 548578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xE0608000) == 0x00400000) || 549578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x60608000) == 0x00408000) || 550578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x60E00000) == 0x00E00000) || 551578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x60E00000) == 0x00800000) || 552578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x60E00000) == 0x00600000)) { 553578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 554578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 555578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitDataProcessing3Source(instr); 556578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 56239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlvoid Decoder::DecodeFP(const Instruction* instr) { 5631123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((instr->Bits(27, 24) == 0xE) || 5641123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl (instr->Bits(27, 24) == 0xF)); 565578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(28) == 0) { 5660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl DecodeNEONVectorDataProcessing(instr); 567578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 5680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(31, 30) == 0x3) { 569578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 5700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else if (instr->Bits(31, 30) == 0x1) { 5710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl DecodeNEONScalarDataProcessing(instr); 572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 5730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(29) == 0) { 574578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(24) == 0) { 575578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bit(21) == 0) { 576578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bit(23) == 1) || 577578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bit(18) == 1) || 578578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x80008000) == 0x00000000) || 579578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x000E0000) == 0x00000000) || 580578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x000E0000) == 0x000A0000) || 581578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00160000) == 0x00000000) || 582578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00160000) == 0x00120000)) { 583578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 584578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 585578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPFixedPointConvert(instr); 586578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 587578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 588578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Bits(15, 10) == 32) { 589578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 590578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (instr->Bits(15, 10) == 0) { 591578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(23, 22) == 0x3) || 592578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x000E0000) == 0x000A0000) || 593578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x000E0000) == 0x000C0000) || 594578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00160000) == 0x00120000) || 595578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00160000) == 0x00140000) || 596578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x20C40000) == 0x00800000) || 597578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x20C60000) == 0x00840000) || 598578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0C60000) == 0x80060000) || 599578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0C60000) == 0x00860000) || 600578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0C60000) == 0x00460000) || 601578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0CE0000) == 0x80860000) || 602578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0CE0000) == 0x804E0000) || 603578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0CE0000) == 0x000E0000) || 604578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0D60000) == 0x00160000) || 605578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0D60000) == 0x80560000) || 606578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0D60000) == 0x80960000)) { 607578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 608578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 609578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPIntegerConvert(instr); 610578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 611578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (instr->Bits(14, 10) == 16) { 612578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const Instr masked_A0DF8000 = instr->Mask(0xA0DF8000); 613578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Mask(0x80180000) != 0) || 614578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_A0DF8000 == 0x00020000) || 615578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_A0DF8000 == 0x00030000) || 616578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_A0DF8000 == 0x00068000) || 617578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_A0DF8000 == 0x00428000) || 618578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_A0DF8000 == 0x00430000) || 619578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (masked_A0DF8000 == 0x00468000) || 620578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0D80000) == 0x00800000) || 621578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0DE0000) == 0x00C00000) || 622578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0DF0000) == 0x00C30000) || 623578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0xA0DC0000) == 0x00C40000)) { 624578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 625578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 626578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPDataProcessing1Source(instr); 627578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 628578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (instr->Bits(13, 10) == 8) { 629578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(15, 14) != 0) || 630578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Bits(2, 0) != 0) || 631578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x80800000) != 0x00000000)) { 632578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 633578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 634578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPCompare(instr); 635578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 636578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (instr->Bits(12, 10) == 4) { 637578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(9, 5) != 0) || 638578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x80800000) != 0x00000000)) { 639578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 640578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 641578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPImmediate(instr); 642578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 643578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 644578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Mask(0x80800000) != 0x00000000) { 645578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 646578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 647578645f14e122d2b87d907e298cda7e7d0babf1farmvixl switch (instr->Bits(11, 10)) { 648578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 1: { 649578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPConditionalCompare(instr); 650578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 651578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 652578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 2: { 653578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if ((instr->Bits(15, 14) == 0x3) || 654578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x00009000) == 0x00009000) || 655578645f14e122d2b87d907e298cda7e7d0babf1farmvixl (instr->Mask(0x0000A000) == 0x0000A000)) { 656578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 657578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 658578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPDataProcessing2Source(instr); 659578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 660578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 661578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 662578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case 3: { 663578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPConditionalSelect(instr); 664578645f14e122d2b87d907e298cda7e7d0babf1farmvixl break; 665578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 6661123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 667578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 668578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 669578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 671578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 672578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // Bit 30 == 1 has been handled earlier. 6731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Bit(30) == 0); 674578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->Mask(0xA0800000) != 0) { 675578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitUnallocated(instr); 676578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else { 677578645f14e122d2b87d907e298cda7e7d0babf1farmvixl VisitFPDataProcessing3Source(instr); 678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 6800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 6810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 685ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 686ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 687578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 6880cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Decoder::DecodeNEONLoadStore(const Instruction* instr) { 6891123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Bits(29, 25) == 0x6); 6900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(31) == 0) { 6910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if ((instr->Bit(24) == 0) && (instr->Bit(21) == 1)) { 6920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 6930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl return; 6940cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 6950cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 6960cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(23) == 0) { 6970cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(20, 16) == 0) { 6980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(24) == 0) { 6990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONLoadStoreMultiStruct(instr); 7000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONLoadStoreSingleStruct(instr); 7020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(24) == 0) { 7080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONLoadStoreMultiStructPostIndex(instr); 7090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONLoadStoreSingleStructPostIndex(instr); 7110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl} 7170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 7180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl 7190cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Decoder::DecodeNEONVectorDataProcessing(const Instruction* instr) { 7200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VIXL_ASSERT(instr->Bits(28, 25) == 0x7); 7210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(31) == 0) { 7220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(24) == 0) { 7230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(21) == 0) { 7240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(15) == 0) { 7250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(10) == 0) { 7260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(29) == 0) { 7270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(11) == 0) { 7280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONTable(instr); 7290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONPerm(instr); 7310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONExtract(instr); 7340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(23, 22) == 0) { 7370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONCopy(instr); 7380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(10) == 0) { 7470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(11) == 0) { 7480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEON3Different(instr); 7490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(18, 17) == 0) { 7510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(20) == 0) { 7520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(19) == 0) { 7530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEON2RegMisc(instr); 7540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(30, 29) == 0x2) { 7560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitCryptoAES(instr); 7570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(19) == 0) { 7630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONAcrossLanes(instr); 7640cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7650cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7660cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7670cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7680cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7690cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7700cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7710cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7720cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7730cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEON3Same(instr); 7740cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7750cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7760cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7770cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(10) == 0) { 7780cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONByIndexedElement(instr); 7790cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7800cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(23) == 0) { 7810cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(22, 19) == 0) { 7820cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONModifiedImmediate(instr); 7830cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7840cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONShiftImmediate(instr); 7850cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7860cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7870cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7880cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7890cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7900cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 7910cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 7920cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 7930cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 794578645f14e122d2b87d907e298cda7e7d0babf1farmvixl} 795578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 796578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 7970cc8b6ece4b3e757e11a906a81ece292437713abarmvixlvoid Decoder::DecodeNEONScalarDataProcessing(const Instruction* instr) { 7980cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VIXL_ASSERT(instr->Bits(28, 25) == 0xF); 7990cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(24) == 0) { 8000cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(21) == 0) { 8010cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(15) == 0) { 8020cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(10) == 0) { 8030cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(29) == 0) { 8040cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(11) == 0) { 8050cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitCrypto3RegSHA(instr); 8060cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8070cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8080cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8090cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8100cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8110cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8120cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8130cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(23, 22) == 0) { 8140cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalarCopy(instr); 8150cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8160cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8170cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8180cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8190cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8200cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8210cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8220cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8230cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(10) == 0) { 8240cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(11) == 0) { 8250cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalar3Diff(instr); 8260cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8270cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bits(18, 17) == 0) { 8280cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(20) == 0) { 8290cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(19) == 0) { 8300cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalar2RegMisc(instr); 8310cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8320cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(29) == 0) { 8330cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitCrypto2RegSHA(instr); 8340cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8350cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8360cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8370cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8380cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8390cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(19) == 0) { 8400cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalarPairwise(instr); 8410cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8420cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8430cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8440cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8450cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8460cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8470cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8480cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8490cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8500cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalar3Same(instr); 8510cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8520cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8530cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8540cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(10) == 0) { 8550cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalarByIndexedElement(instr); 8560cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8570cc8b6ece4b3e757e11a906a81ece292437713abarmvixl if (instr->Bit(23) == 0) { 8580cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitNEONScalarShiftImmediate(instr); 8590cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } else { 8600cc8b6ece4b3e757e11a906a81ece292437713abarmvixl VisitUnallocated(instr); 8610cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8620cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 8630cc8b6ece4b3e757e11a906a81ece292437713abarmvixl } 864578645f14e122d2b87d907e298cda7e7d0babf1farmvixl} 865578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 866578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define DEFINE_VISITOR_CALLERS(A) \ 86839ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl void Decoder::Visit##A(const Instruction *instr) { \ 8691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Mask(A##FMask) == A##Fixed); \ 870ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl std::list<DecoderVisitor*>::iterator it; \ 871ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl for (it = visitors_.begin(); it != visitors_.end(); it++) { \ 872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (*it)->Visit##A(instr); \ 873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } \ 874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlVISITOR_LIST(DEFINE_VISITOR_CALLERS) 876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#undef DEFINE_VISITOR_CALLERS 877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 878