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 "a64/disasm-a64.h" 28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlnamespace vixl { 30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDisassembler::Disassembler() { 32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_size_ = 256; 33ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_ = reinterpret_cast<char*>(malloc(buffer_size_)); 34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_pos_ = 0; 35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl own_buffer_ = true; 36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDisassembler::Disassembler(char* text_buffer, int buffer_size) { 40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_size_ = buffer_size; 41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_ = text_buffer; 42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_pos_ = 0; 43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl own_buffer_ = false; 44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlDisassembler::~Disassembler() { 48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (own_buffer_) { 49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl free(buffer_); 50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 52ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlchar* Disassembler::GetOutput() { 55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return buffer_; 56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitAddSubImmediate(Instruction* instr) { 60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool stack_op = (rd_is_zr || RnIsZROrSP(instr)) && 62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (instr->ImmAddSub() == 0) ? true : false; 63578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rds, 'Rns, 'IAddSub"; 65ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_cmp = "'Rns, 'IAddSub"; 66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_mov = "'Rds, 'Rns"; 67ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(AddSubImmediateMask)) { 69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADD_w_imm: 70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADD_x_imm: { 71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "add"; 72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (stack_op) { 73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mov"; 74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_mov; 75ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 78ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADDS_w_imm: 79ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADDS_x_imm: { 80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "adds"; 81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cmn"; 83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_cmp; 84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUB_w_imm: 88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUB_x_imm: mnemonic = "sub"; break; 89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUBS_w_imm: 90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUBS_x_imm: { 91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "subs"; 92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cmp"; 94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_cmp; 95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 981123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitAddSubShifted(Instruction* instr) { 105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_zr = RnIsZROrSP(instr); 107578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm'HDP"; 109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_cmp = "'Rn, 'Rm'HDP"; 110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_neg = "'Rd, 'Rm'HDP"; 111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(AddSubShiftedMask)) { 113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADD_w_shift: 114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADD_x_shift: mnemonic = "add"; break; 115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADDS_w_shift: 116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADDS_x_shift: { 117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "adds"; 118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cmn"; 120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_cmp; 121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUB_w_shift: 125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUB_x_shift: { 126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sub"; 127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr) { 128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "neg"; 129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_neg; 130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUBS_w_shift: 134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUBS_x_shift: { 135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "subs"; 136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cmp"; 138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_cmp; 139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (rn_is_zr) { 140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "negs"; 141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_neg; 142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitAddSubExtended(Instruction* instr) { 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 153578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Extend mode = static_cast<Extend>(instr->ExtendMode()); 155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = ((mode == UXTX) || (mode == SXTX)) ? 156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "'Rds, 'Rns, 'Xm'Ext" : "'Rds, 'Rns, 'Wm'Ext"; 157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_cmp = ((mode == UXTX) || (mode == SXTX)) ? 158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "'Rns, 'Xm'Ext" : "'Rns, 'Wm'Ext"; 159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(AddSubExtendedMask)) { 161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADD_w_ext: 162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADD_x_ext: mnemonic = "add"; break; 163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADDS_w_ext: 164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADDS_x_ext: { 165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "adds"; 166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cmn"; 168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_cmp; 169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUB_w_ext: 173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUB_x_ext: mnemonic = "sub"; break; 174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUBS_w_ext: 175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SUBS_x_ext: { 176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "subs"; 177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cmp"; 179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_cmp; 180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1831123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitAddSubWithCarry(Instruction* instr) { 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_zr = RnIsZROrSP(instr); 191578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm"; 193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_neg = "'Rd, 'Rm"; 194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(AddSubWithCarryMask)) { 196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADC_w: 197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADC_x: mnemonic = "adc"; break; 198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADCS_w: 199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADCS_x: mnemonic = "adcs"; break; 200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBC_w: 201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBC_x: { 202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sbc"; 203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr) { 204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ngc"; 205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_neg; 206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBCS_w: 210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBCS_x: { 211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sbcs"; 212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr) { 213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ngcs"; 214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_neg; 215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 2181123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLogicalImmediate(Instruction* instr) { 225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_zr = RnIsZROrSP(instr); 227578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rds, 'Rn, 'ITri"; 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 230578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (instr->ImmLogical() == 0) { 231578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // The immediate encoded in the instruction is not in the expected format. 232578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Format(instr, "unallocated", "(LogicalImmediate)"); 233578645f14e122d2b87d907e298cda7e7d0babf1farmvixl return; 234578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } 235578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LogicalImmediateMask)) { 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_w_imm: 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_x_imm: mnemonic = "and"; break; 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_w_imm: 240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_x_imm: { 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "orr"; 2427f2db39dffaca523429c67a71054bb19c108f31fAndreas Gampe unsigned reg_size = (instr->SixtyFourBits() != 0) ? kXRegSize 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : kWRegSize; 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr && !IsMovzMovnImm(reg_size, instr->ImmLogical())) { 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mov"; 246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rds, 'ITri"; 247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_w_imm: 251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_x_imm: mnemonic = "eor"; break; 252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_w_imm: 253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_x_imm: { 254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ands"; 255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "tst"; 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rn, 'ITri"; 258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 2611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Disassembler::IsMovzMovnImm(unsigned reg_size, uint64_t value) { 2681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((reg_size == kXRegSize) || 2691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl ((reg_size == kWRegSize) && (value <= 0xffffffff))); 270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Test for movz: 16 bits set at positions 0, 16, 32 or 48. 272ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl if (((value & UINT64_C(0xffffffffffff0000)) == 0) || 273ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl ((value & UINT64_C(0xffffffff0000ffff)) == 0) || 274ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl ((value & UINT64_C(0xffff0000ffffffff)) == 0) || 275ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl ((value & UINT64_C(0x0000ffffffffffff)) == 0)) { 276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Test for movn: NOT(16 bits set at positions 0, 16, 32 or 48). 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((reg_size == kXRegSize) && 281ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl (((~value & UINT64_C(0xffffffffffff0000)) == 0) || 282ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl ((~value & UINT64_C(0xffffffff0000ffff)) == 0) || 283ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl ((~value & UINT64_C(0xffff0000ffffffff)) == 0) || 284ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl ((~value & UINT64_C(0x0000ffffffffffff)) == 0))) { 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((reg_size == kWRegSize) && 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (((value & 0xffff0000) == 0xffff0000) || 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0x0000ffff) == 0x0000ffff))) { 290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLogicalShifted(Instruction* instr) { 297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_zr = RnIsZROrSP(instr); 299578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm'HLo"; 301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LogicalShiftedMask)) { 303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_w: 304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_x: mnemonic = "and"; break; 305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BIC_w: 306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BIC_x: mnemonic = "bic"; break; 307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_w: 308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_x: mnemonic = "eor"; break; 309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EON_w: 310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EON_x: mnemonic = "eon"; break; 311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BICS_w: 312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BICS_x: mnemonic = "bics"; break; 313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_w: 314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_x: { 315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ands"; 316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "tst"; 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rn, 'Rm'HLo"; 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_w: 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_x: { 324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "orr"; 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr && (instr->ImmDPShift() == 0) && (instr->ShiftDP() == LSL)) { 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mov"; 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rd, 'Rm"; 328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORN_w: 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORN_x: { 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "orn"; 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr) { 335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mvn"; 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rd, 'Rm'HLo"; 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 3401123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalCompareRegister(Instruction* instr) { 348578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rn, 'Rm, 'INzcv, 'Cond"; 350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalCompareRegisterMask)) { 352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_w: 353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_x: mnemonic = "ccmn"; break; 354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_w: 355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_x: mnemonic = "ccmp"; break; 3561123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalCompareImmediate(Instruction* instr) { 363578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rn, 'IP, 'INzcv, 'Cond"; 365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalCompareImmediateMask)) { 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_w_imm: 368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_x_imm: mnemonic = "ccmn"; break; 369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_w_imm: 370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_x_imm: mnemonic = "ccmp"; break; 3711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalSelect(Instruction* instr) { 378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rnm_is_zr = (RnIsZROrSP(instr) && RmIsZROrSP(instr)); 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_rm = (instr->Rn() == instr->Rm()); 380578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm, 'Cond"; 382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_test = "'Rd, 'CInv"; 383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_update = "'Rd, 'Rn, 'CInv"; 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 385578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Condition cond = static_cast<Condition>(instr->Condition()); 386578645f14e122d2b87d907e298cda7e7d0babf1farmvixl bool invertible_cond = (cond != al) && (cond != nv); 387578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalSelectMask)) { 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSEL_w: 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSEL_x: mnemonic = "csel"; break; 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINC_w: 392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINC_x: { 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csinc"; 394578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (rnm_is_zr && invertible_cond) { 395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cset"; 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_test; 397578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (rn_is_rm && invertible_cond) { 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cinc"; 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_update; 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINV_w: 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINV_x: { 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csinv"; 406578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (rnm_is_zr && invertible_cond) { 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csetm"; 408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_test; 409578645f14e122d2b87d907e298cda7e7d0babf1farmvixl } else if (rn_is_rm && invertible_cond) { 410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cinv"; 411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_update; 412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSNEG_w: 416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSNEG_x: { 417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csneg"; 418578645f14e122d2b87d907e298cda7e7d0babf1farmvixl if (rn_is_rm && invertible_cond) { 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cneg"; 420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_update; 421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 4241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitBitfield(Instruction* instr) { 431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned s = instr->ImmS(); 432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned r = instr->ImmR(); 433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned rd_size_minus_1 = 4347f2db39dffaca523429c67a71054bb19c108f31fAndreas Gampe ((instr->SixtyFourBits() != 0) ? kXRegSize : kWRegSize) - 1; 435578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 436578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *form = ""; 437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_shift_right = "'Rd, 'Rn, 'IBr"; 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_extend = "'Rd, 'Wn"; 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_bfiz = "'Rd, 'Rn, 'IBZ-r, 'IBs+1"; 440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_bfx = "'Rd, 'Rn, 'IBr, 'IBs-r+1"; 441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_lsl = "'Rd, 'Rn, 'IBZ-r"; 442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(BitfieldMask)) { 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBFM_w: 445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBFM_x: { 446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sbfx"; 447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (r == 0) { 449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_extend; 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s == 7) { 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sxtb"; 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s == 15) { 453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sxth"; 4547f2db39dffaca523429c67a71054bb19c108f31fAndreas Gampe } else if ((s == 31) && (instr->SixtyFourBits() != 0)) { 455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sxtw"; 456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s == rd_size_minus_1) { 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "asr"; 461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_shift_right; 462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s < r) { 463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sbfiz"; 464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfiz; 465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UBFM_w: 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UBFM_x: { 470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ubfx"; 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (r == 0) { 473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_extend; 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s == 7) { 475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "uxtb"; 476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s == 15) { 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "uxth"; 478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s == rd_size_minus_1) { 483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "lsr"; 484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_shift_right; 485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (r == s + 1) { 486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "lsl"; 487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_lsl; 488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s < r) { 489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ubfiz"; 490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfiz; 491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BFM_w: 495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BFM_x: { 496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "bfxil"; 497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s < r) { 499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "bfi"; 500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfiz; 501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitExtract(Instruction* instr) { 509578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm, 'IExtract"; 511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ExtractMask)) { 513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EXTR_w: 514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EXTR_x: { 515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Rn() == instr->Rm()) { 516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ror"; 517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rd, 'Rn, 'IExtract"; 518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "extr"; 520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 5231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitPCRelAddressing(Instruction* instr) { 530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(PCRelAddressingMask)) { 531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break; 532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // ADRP is not implemented. 533578645f14e122d2b87d907e298cda7e7d0babf1farmvixl default: Format(instr, "unimplemented", "(PCRelAddressing)"); 534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalBranch(Instruction* instr) { 539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalBranchMask)) { 540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case B_cond: Format(instr, "b.'CBrn", "'BImmCond"); break; 5411123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) { 547578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Xn"; 549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 550ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(UnconditionalBranchToRegisterMask)) { 551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BR: mnemonic = "br"; break; 552ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BLR: mnemonic = "blr"; break; 553ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case RET: { 554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ret"; 555ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Rn() == kLinkRegCode) { 556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = NULL; 557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(UnconditionalBranchToRegister)"; 561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 566ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitUnconditionalBranch(Instruction* instr) { 567578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'BImmUncn"; 569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(UnconditionalBranchMask)) { 571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case B: mnemonic = "b"; break; 572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BL: mnemonic = "bl"; break; 5731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 579ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitDataProcessing1Source(Instruction* instr) { 580578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn"; 582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(DataProcessing1SourceMask)) { 584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_w: \ 586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_x: mnemonic = B; break; 587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(RBIT, "rbit"); 588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(REV16, "rev16"); 589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(REV, "rev"); 590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(CLZ, "clz"); 591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(CLS, "cls"); 592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case REV32_x: mnemonic = "rev32"; break; 5941123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitDataProcessing2Source(Instruction* instr) { 601578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm"; 603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 604ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(DataProcessing2SourceMask)) { 605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_w: \ 607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_x: mnemonic = B; break; 608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(UDIV, "udiv"); 609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(SDIV, "sdiv"); 610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(LSLV, "lsl"); 611ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(LSRV, "lsr"); 612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(ASRV, "asr"); 613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(RORV, "ror"); 614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(DataProcessing2Source)"; 616ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitDataProcessing3Source(Instruction* instr) { 622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool ra_is_zr = RaIsZROrSP(instr); 623578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Xd, 'Wn, 'Wm, 'Xa"; 625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rrr = "'Rd, 'Rn, 'Rm"; 626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rrrr = "'Rd, 'Rn, 'Rm, 'Ra"; 627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_xww = "'Xd, 'Wn, 'Wm"; 628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_xxx = "'Xd, 'Xn, 'Xm"; 629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(DataProcessing3SourceMask)) { 631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MADD_w: 632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MADD_x: { 633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "madd"; 634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrrr; 635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mul"; 637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrr; 638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 639ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MSUB_w: 642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MSUB_x: { 643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "msub"; 644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrrr; 645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mneg"; 647ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrr; 648ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 649ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 650ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 651ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SMADDL_x: { 652ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smaddl"; 653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 654ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smull"; 655ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 656ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SMSUBL_x: { 660ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smsubl"; 661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 662ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smnegl"; 663ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 664ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 665ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 666ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 667ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UMADDL_x: { 668ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umaddl"; 669ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umull"; 671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 674ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UMSUBL_x: { 676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umsubl"; 677ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umnegl"; 679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 680ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 681ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SMULH_x: { 684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smulh"; 685ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xxx; 686ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 687ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 688ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UMULH_x: { 689ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umulh"; 690ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xxx; 691ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 692ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 6931123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 694ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 695ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 696ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 697ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 698ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 699ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitCompareBranch(Instruction* instr) { 700578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 701ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rt, 'BImmCmpa"; 702ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(CompareBranchMask)) { 704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBZ_w: 705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBZ_x: mnemonic = "cbz"; break; 706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBNZ_w: 707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBNZ_x: mnemonic = "cbnz"; break; 7081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitTestBranch(Instruction* instr) { 715578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 716578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // If the top bit of the immediate is clear, the tested register is 717578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // disassembled as Wt, otherwise Xt. As the top bit of the immediate is 718578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // encoded in bit 31 of the instruction, we can reuse the Rt form, which 719578645f14e122d2b87d907e298cda7e7d0babf1farmvixl // uses bit 31 (normally "sf") to choose the register size. 720578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *form = "'Rt, 'IS, 'BImmTest"; 721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(TestBranchMask)) { 723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case TBZ: mnemonic = "tbz"; break; 724ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case TBNZ: mnemonic = "tbnz"; break; 7251123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 727ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 728ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 729ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 730ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 731ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitMoveWideImmediate(Instruction* instr) { 732578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'IMoveImm"; 734ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 735ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Print the shift separately for movk, to make it clear which half word will 736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // be overwritten. Movn and movz print the computed immediate, which includes 737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // shift calculation. 738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(MoveWideImmediateMask)) { 739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVN_w: 740ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVN_x: mnemonic = "movn"; break; 741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVZ_w: 742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVZ_x: mnemonic = "movz"; break; 743ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVK_w: 744ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVK_x: mnemonic = "movk"; form = "'Rd, 'IMoveLSL"; break; 7451123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 747ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 748ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 749ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 750ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LOAD_STORE_LIST(V) \ 752ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STRB_w, "strb", "'Wt") \ 753ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STRH_w, "strh", "'Wt") \ 754ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_w, "str", "'Wt") \ 755ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_x, "str", "'Xt") \ 756ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRB_w, "ldrb", "'Wt") \ 757ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRH_w, "ldrh", "'Wt") \ 758ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_w, "ldr", "'Wt") \ 759ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_x, "ldr", "'Xt") \ 760ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSB_x, "ldrsb", "'Xt") \ 761ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSH_x, "ldrsh", "'Xt") \ 762ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSW_x, "ldrsw", "'Xt") \ 763ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSB_w, "ldrsb", "'Wt") \ 764ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSH_w, "ldrsh", "'Wt") \ 765ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_s, "str", "'St") \ 766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_d, "str", "'Dt") \ 767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_s, "ldr", "'St") \ 768ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_d, "ldr", "'Dt") 769ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePreIndex(Instruction* instr) { 771578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePreIndex)"; 773ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 774ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePreIndexMask)) { 775ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_PREINDEX(A, B, C) \ 776ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_pre: mnemonic = B; form = C ", ['Xns'ILS]!"; break; 777ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_PREINDEX) 778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_PREINDEX 779ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 780ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 781ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 782ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePostIndex(Instruction* instr) { 785578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 786ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePostIndex)"; 787ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 788ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePostIndexMask)) { 789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_POSTINDEX(A, B, C) \ 790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_post: mnemonic = B; form = C ", ['Xns]'ILS"; break; 791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_POSTINDEX) 792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_POSTINDEX 793ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) { 799578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStoreUnsignedOffset)"; 801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 802ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStoreUnsignedOffsetMask)) { 803ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_UNSIGNEDOFFSET(A, B, C) \ 804ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_unsigned: mnemonic = B; form = C ", ['Xns'ILU]"; break; 805ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_UNSIGNEDOFFSET) 806ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_UNSIGNEDOFFSET 807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case PRFM_unsigned: mnemonic = "prfm"; form = "'PrefOp, ['Xn'ILU]"; 808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 810ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 811ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 812ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 813ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) { 814578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStoreRegisterOffset)"; 816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 817ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStoreRegisterOffsetMask)) { 818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_REGISTEROFFSET(A, B, C) \ 819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_reg: mnemonic = B; form = C ", ['Xns, 'Offsetreg]"; break; 820ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_REGISTEROFFSET) 821ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_REGISTEROFFSET 822ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case PRFM_reg: mnemonic = "prfm"; form = "'PrefOp, ['Xns, 'Offsetreg]"; 823ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 824ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) { 829578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Wt, ['Xns'ILS]"; 831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_x = "'Xt, ['Xns'ILS]"; 832ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_s = "'St, ['Xns'ILS]"; 833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_d = "'Dt, ['Xns'ILS]"; 834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStoreUnscaledOffsetMask)) { 836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STURB_w: mnemonic = "sturb"; break; 837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STURH_w: mnemonic = "sturh"; break; 838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_w: mnemonic = "stur"; break; 839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_x: mnemonic = "stur"; form = form_x; break; 840ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_s: mnemonic = "stur"; form = form_s; break; 841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_d: mnemonic = "stur"; form = form_d; break; 842ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURB_w: mnemonic = "ldurb"; break; 843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURH_w: mnemonic = "ldurh"; break; 844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_w: mnemonic = "ldur"; break; 845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_x: mnemonic = "ldur"; form = form_x; break; 846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_s: mnemonic = "ldur"; form = form_s; break; 847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_d: mnemonic = "ldur"; form = form_d; break; 848ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSB_x: form = form_x; // Fall through. 849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSB_w: mnemonic = "ldursb"; break; 850ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSH_x: form = form_x; // Fall through. 851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSH_w: mnemonic = "ldursh"; break; 852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSW_x: mnemonic = "ldursw"; form = form_x; break; 853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(LoadStoreUnscaledOffset)"; 854ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 858ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadLiteral(Instruction* instr) { 860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "ldr"; 861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadLiteral)"; 862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadLiteralMask)) { 864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_w_lit: form = "'Wt, 'ILLiteral 'LValue"; break; 865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_x_lit: form = "'Xt, 'ILLiteral 'LValue"; break; 866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_s_lit: form = "'St, 'ILLiteral 'LValue"; break; 867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_d_lit: form = "'Dt, 'ILLiteral 'LValue"; break; 868578645f14e122d2b87d907e298cda7e7d0babf1farmvixl default: mnemonic = "unimplemented"; 869ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 870ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 871ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LOAD_STORE_PAIR_LIST(V) \ 875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_w, "stp", "'Wt, 'Wt2", "4") \ 876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_w, "ldp", "'Wt, 'Wt2", "4") \ 877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDPSW_x, "ldpsw", "'Xt, 'Xt2", "4") \ 878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_x, "stp", "'Xt, 'Xt2", "8") \ 879ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_x, "ldp", "'Xt, 'Xt2", "8") \ 880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_s, "stp", "'St, 'St2", "4") \ 881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_s, "ldp", "'St, 'St2", "4") \ 882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_d, "stp", "'Dt, 'Dt2", "8") \ 883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_d, "ldp", "'Dt, 'Dt2", "8") 884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) { 886578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 887ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePairPostIndex)"; 888ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 889ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairPostIndexMask)) { 890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LSP_POSTINDEX(A, B, C, D) \ 891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_post: mnemonic = B; form = C ", ['Xns]'ILP" D; break; 892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_PAIR_LIST(LSP_POSTINDEX) 893ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LSP_POSTINDEX 894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 895ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 896ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) { 900578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePairPreIndex)"; 902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 903ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairPreIndexMask)) { 904ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LSP_PREINDEX(A, B, C, D) \ 905ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_pre: mnemonic = B; form = C ", ['Xns'ILP" D "]!"; break; 906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_PAIR_LIST(LSP_PREINDEX) 907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LSP_PREINDEX 908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 912ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 913ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairOffset(Instruction* instr) { 914578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 915ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePairOffset)"; 916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 917ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairOffsetMask)) { 918ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LSP_OFFSET(A, B, C, D) \ 919ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_off: mnemonic = B; form = C ", ['Xns'ILP" D "]"; break; 920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_PAIR_LIST(LSP_OFFSET) 921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LSP_OFFSET 922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 923ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 924ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 925ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 926ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairNonTemporal(Instruction* instr) { 928578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form; 930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairNonTemporalMask)) { 932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_w: mnemonic = "stnp"; form = "'Wt, 'Wt2, ['Xns'ILP4]"; break; 933ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_w: mnemonic = "ldnp"; form = "'Wt, 'Wt2, ['Xns'ILP4]"; break; 934ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_x: mnemonic = "stnp"; form = "'Xt, 'Xt2, ['Xns'ILP8]"; break; 935ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_x: mnemonic = "ldnp"; form = "'Xt, 'Xt2, ['Xns'ILP8]"; break; 936ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_s: mnemonic = "stnp"; form = "'St, 'St2, ['Xns'ILP4]"; break; 937ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_s: mnemonic = "ldnp"; form = "'St, 'St2, ['Xns'ILP4]"; break; 938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_d: mnemonic = "stnp"; form = "'Dt, 'Dt2, ['Xns'ILP8]"; break; 939ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_d: mnemonic = "ldnp"; form = "'Dt, 'Dt2, ['Xns'ILP8]"; break; 940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(LoadStorePairNonTemporal)"; 941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 942ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 943ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 944ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 945ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 946ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPCompare(Instruction* instr) { 947578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 948ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fn, 'Fm"; 949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_zero = "'Fn, #0.0"; 950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPCompareMask)) { 952ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_s_zero: 953ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_d_zero: form = form_zero; // Fall through. 954ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_s: 955ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_d: mnemonic = "fcmp"; break; 956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPCompare)"; 957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 959ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 960ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 961ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 962ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPConditionalCompare(Instruction* instr) { 963578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unmplemented"; 964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fn, 'Fm, 'INzcv, 'Cond"; 965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPConditionalCompareMask)) { 967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCCMP_s: 968ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCCMP_d: mnemonic = "fccmp"; break; 969578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case FCCMPE_s: 970578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case FCCMPE_d: mnemonic = "fccmpe"; break; 971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPConditionalCompare)"; 972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 974ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPConditionalSelect(Instruction* instr) { 978578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 979ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn, 'Fm, 'Cond"; 980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPConditionalSelectMask)) { 982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCSEL_s: 983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCSEL_d: mnemonic = "fcsel"; break; 9841123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 985ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 986ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 990ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPDataProcessing1Source(Instruction* instr) { 991578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 992ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn"; 993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPDataProcessing1SourceMask)) { 995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 996ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_s: \ 997ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_d: mnemonic = B; break; 998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMOV, "fmov"); 999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FABS, "fabs"); 1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNEG, "fneg"); 1001ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FSQRT, "fsqrt"); 1002ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTN, "frintn"); 1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTP, "frintp"); 1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTM, "frintm"); 1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTZ, "frintz"); 1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTA, "frinta"); 1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTX, "frintx"); 1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTI, "frinti"); 1009ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 1010ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVT_ds: mnemonic = "fcvt"; form = "'Dd, 'Sn"; break; 1011ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVT_sd: mnemonic = "fcvt"; form = "'Sd, 'Dn"; break; 1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPDataProcessing1Source)"; 1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1018ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPDataProcessing2Source(Instruction* instr) { 1019578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 1020ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn, 'Fm"; 1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPDataProcessing2SourceMask)) { 1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 1024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_s: \ 1025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_d: mnemonic = B; break; 1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMUL, "fmul"); 1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FDIV, "fdiv"); 1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FADD, "fadd"); 1029ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FSUB, "fsub"); 1030ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMAX, "fmax"); 1031ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMIN, "fmin"); 1032ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMAXNM, "fmaxnm"); 1033ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMINNM, "fminnm"); 1034ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNMUL, "fnmul"); 1035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 10361123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 1037ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1038ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1039ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1040ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1041ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1042ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPDataProcessing3Source(Instruction* instr) { 1043578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 1044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn, 'Fm, 'Fa"; 1045ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1046ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPDataProcessing3SourceMask)) { 1047ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 1048ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_s: \ 1049ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_d: mnemonic = B; break; 1050ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMADD, "fmadd"); 1051ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMSUB, "fmsub"); 1052ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNMADD, "fnmadd"); 1053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNMSUB, "fnmsub"); 1054ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 10551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 1056ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1060ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1061ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPImmediate(Instruction* instr) { 1062578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(FPImmediate)"; 1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1065ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPImmediateMask)) { 1066ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_s_imm: mnemonic = "fmov"; form = "'Sd, 'IFPSingle"; break; 1067ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_d_imm: mnemonic = "fmov"; form = "'Dd, 'IFPDouble"; break; 10681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 1069ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1070ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1072ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1073ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1074ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPIntegerConvert(Instruction* instr) { 1075578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 1076ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(FPIntegerConvert)"; 1077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rf = "'Rd, 'Fn"; 1078ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_fr = "'Fd, 'Rn"; 1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1080ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPIntegerConvertMask)) { 1081ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_ws: 1082ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_xd: mnemonic = "fmov"; form = form_rf; break; 1083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_sw: 1084ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_dx: mnemonic = "fmov"; form = form_fr; break; 1085f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAS_ws: 1086f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAS_xs: 1087f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAS_wd: 1088f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAS_xd: mnemonic = "fcvtas"; form = form_rf; break; 1089f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAU_ws: 1090f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAU_xs: 1091f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAU_wd: 1092f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case FCVTAU_xd: mnemonic = "fcvtau"; form = form_rf; break; 1093ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_ws: 1094ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_xs: 1095ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_wd: 1096ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_xd: mnemonic = "fcvtms"; form = form_rf; break; 1097ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_ws: 1098ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_xs: 1099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_wd: 1100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_xd: mnemonic = "fcvtmu"; form = form_rf; break; 1101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_ws: 1102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_xs: 1103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_wd: 1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_xd: mnemonic = "fcvtns"; form = form_rf; break; 1105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_ws: 1106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_xs: 1107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_wd: 1108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_xd: mnemonic = "fcvtnu"; form = form_rf; break; 1109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xd: 1110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_ws: 1111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_wd: 1112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xs: mnemonic = "fcvtzu"; form = form_rf; break; 1113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xd: 1114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_wd: 1115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xs: 1116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_ws: mnemonic = "fcvtzs"; form = form_rf; break; 1117578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case SCVTF_sw: 1118578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case SCVTF_sx: 1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dw: 1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dx: mnemonic = "scvtf"; form = form_fr; break; 1121578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case UCVTF_sw: 1122578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case UCVTF_sx: 1123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dw: 1124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dx: mnemonic = "ucvtf"; form = form_fr; break; 1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPFixedPointConvert(Instruction* instr) { 1131578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = ""; 1132578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *form = "'Rd, 'Fn, 'IFPFBits"; 1133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_fr = "'Fd, 'Rn, 'IFPFBits"; 1134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPFixedPointConvertMask)) { 1136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_ws_fixed: 1137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xs_fixed: 1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_wd_fixed: 1139578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case FCVTZS_xd_fixed: mnemonic = "fcvtzs"; break; 1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_ws_fixed: 1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xs_fixed: 1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_wd_fixed: 1143578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case FCVTZU_xd_fixed: mnemonic = "fcvtzu"; break; 1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_sw_fixed: 1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_sx_fixed: 1146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dw_fixed: 1147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dx_fixed: mnemonic = "scvtf"; form = form_fr; break; 1148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_sw_fixed: 1149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_sx_fixed: 1150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dw_fixed: 1151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dx_fixed: mnemonic = "ucvtf"; form = form_fr; break; 11521123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 1153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitSystem(Instruction* instr) { 1159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Some system instructions hijack their Op and Cp fields to represent a 1160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // range of immediates instead of indicating a different instruction. This 1161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // makes the decoding tricky. 1162578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 1163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(System)"; 1164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) { 1166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(SystemSysRegMask)) { 1167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MRS: { 1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mrs"; 1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->ImmSystemRegister()) { 1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case NZCV: form = "'Xt, nzcv"; break; 1171578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case FPCR: form = "'Xt, fpcr"; break; 1172578645f14e122d2b87d907e298cda7e7d0babf1farmvixl default: form = "'Xt, (unknown)"; break; 1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MSR: { 1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "msr"; 1178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->ImmSystemRegister()) { 1179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case NZCV: form = "nzcv, 'Xt"; break; 1180578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case FPCR: form = "fpcr, 'Xt"; break; 1181578645f14e122d2b87d907e298cda7e7d0babf1farmvixl default: form = "(unknown), 'Xt"; break; 1182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 11871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->Mask(SystemHintMask) == HINT); 1188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->ImmHint()) { 1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case NOP: { 1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "nop"; 1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = NULL; 1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1195f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } else if (instr->Mask(MemBarrierFMask) == MemBarrierFixed) { 1196f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl switch (instr->Mask(MemBarrierMask)) { 1197f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case DMB: { 1198f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl mnemonic = "dmb"; 1199f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl form = "'M"; 1200f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl break; 1201f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1202f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case DSB: { 1203f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl mnemonic = "dsb"; 1204f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl form = "'M"; 1205f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl break; 1206f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1207f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case ISB: { 1208f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl mnemonic = "isb"; 1209f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl form = NULL; 1210f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl break; 1211f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1212f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl } 1213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitException(Instruction* instr) { 1220578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *mnemonic = "unimplemented"; 1221578645f14e122d2b87d907e298cda7e7d0babf1farmvixl const char *form = "'IDebug"; 1222578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 1223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ExceptionMask)) { 1224578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case HLT: mnemonic = "hlt"; break; 1225578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case BRK: mnemonic = "brk"; break; 1226578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case SVC: mnemonic = "svc"; break; 1227578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case HVC: mnemonic = "hvc"; break; 1228578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case SMC: mnemonic = "smc"; break; 1229578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case DCPS1: mnemonic = "dcps1"; form = "{'IDebug}"; break; 1230578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case DCPS2: mnemonic = "dcps2"; form = "{'IDebug}"; break; 1231578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case DCPS3: mnemonic = "dcps3"; form = "{'IDebug}"; break; 1232578645f14e122d2b87d907e298cda7e7d0babf1farmvixl default: form = "(Exception)"; 1233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1234578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Format(instr, mnemonic, form); 1235578645f14e122d2b87d907e298cda7e7d0babf1farmvixl} 1236578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 1237578645f14e122d2b87d907e298cda7e7d0babf1farmvixl 1238578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Disassembler::VisitUnimplemented(Instruction* instr) { 1239578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Format(instr, "unimplemented", "(Unimplemented)"); 1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1243578645f14e122d2b87d907e298cda7e7d0babf1farmvixlvoid Disassembler::VisitUnallocated(Instruction* instr) { 1244578645f14e122d2b87d907e298cda7e7d0babf1farmvixl Format(instr, "unallocated", "(Unallocated)"); 1245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::ProcessOutput(Instruction* /*instr*/) { 1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The base disasm does nothing more than disassembling into a buffer. 1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::Format(Instruction* instr, const char* mnemonic, 1254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 12551123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(mnemonic != NULL); 1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ResetOutput(); 1257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Substitute(instr, mnemonic); 1258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format != NULL) { 1259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_++] = ' '; 1260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Substitute(instr, format); 1261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_] = 0; 1263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ProcessOutput(instr); 1264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::Substitute(Instruction* instr, const char* string) { 1268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char chr = *string++; 1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl while (chr != '\0') { 1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (chr == '\'') { 1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl string += SubstituteField(instr, string); 1272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_++] = chr; 1274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl chr = *string++; 1276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteField(Instruction* instr, const char* format) { 1281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[0]) { 1282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'R': // Register. X or W, selected by sf bit. 1283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'F': // FP Register. S or D, selected by type field. 1284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'W': 1285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'X': 1286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'S': 1287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'D': return SubstituteRegisterField(instr, format); 1288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'I': return SubstituteImmediateField(instr, format); 1289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': return SubstituteLiteralField(instr, format); 1290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'H': return SubstituteShiftField(instr, format); 1291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'P': return SubstitutePrefetchField(instr, format); 1292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'C': return SubstituteConditionField(instr, format); 1293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'E': return SubstituteExtendField(instr, format); 1294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'A': return SubstitutePCRelAddressField(instr, format); 1295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'B': return SubstituteBranchTargetField(instr, format); 1296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'O': return SubstituteLSRegOffsetField(instr, format); 1297f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl case 'M': return SubstituteBarrierField(instr, format); 1298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: { 12991123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_UNREACHABLE(); 1300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 1; 1301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteRegisterField(Instruction* instr, 1307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned reg_num = 0; 1309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned field_len = 2; 1310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'd': reg_num = instr->Rd(); break; 1312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'n': reg_num = instr->Rn(); break; 1313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'm': reg_num = instr->Rm(); break; 1314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'a': reg_num = instr->Ra(); break; 1315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 't': { 1316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[2] == '2') { 1317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_num = instr->Rt2(); 1318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl field_len = 3; 1319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_num = instr->Rt(); 1321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 13241123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 1325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Increase field length for registers tagged as stack. 1328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[2] == 's') { 1329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl field_len = 3; 1330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char reg_type; 1333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[0] == 'R') { 1334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Register type is R: use sf bit to choose X and W. 1335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_type = instr->SixtyFourBits() ? 'x' : 'w'; 1336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (format[0] == 'F') { 1337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Floating-point register: use type field to choose S or D. 1338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_type = ((instr->FPType() & 1) == 0) ? 's' : 'd'; 1339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Register type is specified. Make it lower case. 1341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_type = format[0] + 0x20; 1342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((reg_num != kZeroRegCode) || (reg_type == 's') || (reg_type == 'd')) { 1345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // A normal register: w0 - w30, x0 - x30, s0 - s31, d0 - d31. 1346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%c%d", reg_type, reg_num); 1347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (format[2] == 's') { 1348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Disassemble w31/x31 as stack pointer wsp/sp. 1349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%s", (reg_type == 'w') ? "wsp" : "sp"); 1350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Disassemble w31/x31 as zero register wzr/xzr. 1352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%czr", reg_type); 1353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return field_len; 1356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteImmediateField(Instruction* instr, 1360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 13611123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[0] == 'I'); 1362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'M': { // IMoveImm or IMoveLSL. 1365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[5] == 'I') { 1366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t imm = instr->ImmMoveWide() << (16 * instr->ShiftMoveWide()); 1367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64, imm); 1368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 13691123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[5] == 'L'); 1370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide()); 1371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ShiftMoveWide() > 0) { 1372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide()); 1373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': { 1378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[2]) { 1379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': { // ILLiteral - Immediate Load Literal. 1380578645f14e122d2b87d907e298cda7e7d0babf1farmvixl AppendToOutput("pc%+" PRId64, 1381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmLLiteral() << kLiteralEntrySizeLog2); 1382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 9; 1383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'S': { // ILS - Immediate Load/Store. 1385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmLS() != 0) { 1386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", #%" PRId64, instr->ImmLS()); 1387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'P': { // ILPx - Immediate Load/Store Pair, x = access size. 1391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmLSPair() != 0) { 1392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // format[3] is the scale value. Convert to a number. 1393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int scale = format[3] - 0x30; 1394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", #%" PRId64, instr->ImmLSPair() * scale); 1395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 4; 1397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'U': { // ILU - Immediate Load/Store Unsigned. 1399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmLSUnsigned() != 0) { 1400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", #%" PRIu64, 1401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmLSUnsigned() << instr->SizeLS()); 1402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'C': { // ICondB - Immediate Conditional Branch. 1408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t offset = instr->ImmCondBranch() << 2; 1409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char sign = (offset >= 0) ? '+' : '-'; 1410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%c0x%" PRIx64, sign, offset); 1411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'A': { // IAddSub. 14141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->ShiftAddSub() <= 1); 1415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t imm = instr->ImmAddSub() << (12 * instr->ShiftAddSub()); 1416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64 " (%" PRId64 ")", imm, imm); 1417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 7; 1418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'F': { // IFPSingle, IFPDouble or IFPFBits. 1420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[3] == 'F') { // IFPFbits. 1421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", 64 - instr->FPScale()); 1422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(), 1425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl format[3] == 'S' ? instr->ImmFP32() : instr->ImmFP64()); 1426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 9; 1427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'T': { // ITri - Immediate Triangular Encoded. 1430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64, instr->ImmLogical()); 1431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 4; 1432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'N': { // INzcv. 1434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int nzcv = (instr->Nzcv() << Flags_offset); 1435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%c%c%c%c", ((nzcv & NFlag) == 0) ? 'n' : 'N', 1436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((nzcv & ZFlag) == 0) ? 'z' : 'Z', 1437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((nzcv & CFlag) == 0) ? 'c' : 'C', 1438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((nzcv & VFlag) == 0) ? 'v' : 'V'); 1439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 5; 1440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'P': { // IP - Conditional compare. 1442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", instr->ImmCondCmp()); 1443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 2; 1444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'B': { // Bitfields. 1446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return SubstituteBitfieldImmediateField(instr, format); 1447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'E': { // IExtract. 1449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", instr->ImmS()); 1450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'S': { // IS - Test and branch bit. 1453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) | 1454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmTestBranchBit40()); 1455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 2; 1456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'D': { // IDebug - HLT and BRK instructions. 1458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%x", instr->ImmException()); 1459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: { 14621123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_UNIMPLEMENTED(); 1463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 1464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteBitfieldImmediateField(Instruction* instr, 1470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 14711123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((format[0] == 'I') && (format[1] == 'B')); 1472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned r = instr->ImmR(); 1473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned s = instr->ImmS(); 1474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[2]) { 1476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'r': { // IBr. 1477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", r); 1478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 's': { // IBs+1 or IBs-r+1. 1481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[3] == '+') { 1482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", s + 1); 1483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 5; 1484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 14851123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[3] == '-'); 1486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", s - r + 1); 1487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 7; 1488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'Z': { // IBZ-r. 14911123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT((format[3] == '-') && (format[4] == 'r')); 14927f2db39dffaca523429c67a71054bb19c108f31fAndreas Gampe unsigned reg_size = (instr->SixtyFourBits() != 0) ? kXRegSize : kWRegSize; 1493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", reg_size - r); 1494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 5; 1495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: { 14971123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_UNREACHABLE(); 1498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 1499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteLiteralField(Instruction* instr, 1505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 15061123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(strncmp(format, "LValue", 6) == 0); 1507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadLiteralMask)) { 1510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_w_lit: 1511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_x_lit: 1512578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case LDR_s_lit: 1513578645f14e122d2b87d907e298cda7e7d0babf1farmvixl case LDR_d_lit: AppendToOutput("(addr %p)", instr->LiteralAddress()); break; 15141123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNREACHABLE(); 1515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteShiftField(Instruction* instr, const char* format) { 15221123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[0] == 'H'); 15231123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->ShiftDP() <= 0x3); 1524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'D': { // HDP. 15271123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->ShiftDP() != ROR); 1528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } // Fall through. 1529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': { // HLo. 1530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmDPShift() != 0) { 1531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* shift_type[] = {"lsl", "lsr", "asr", "ror"}; 1532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", %s #%" PRId64, shift_type[instr->ShiftDP()], 1533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmDPShift()); 1534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 15381123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_UNIMPLEMENTED(); 1539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 1540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteConditionField(Instruction* instr, 1545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 15461123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[0] == 'C'); 1547ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* condition_code[] = { "eq", "ne", "hs", "lo", 1548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "mi", "pl", "vs", "vc", 1549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "hi", "ls", "ge", "lt", 1550ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "gt", "le", "al", "nv" }; 1551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int cond; 1552ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1553ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'B': cond = instr->ConditionBranch(); break; 1554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'I': { 1555ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cond = InvertCondition(static_cast<Condition>(instr->Condition())); 1556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: cond = instr->Condition(); 1559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%s", condition_code[cond]); 1561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 4; 1562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstitutePCRelAddressField(Instruction* instr, 1566ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1567ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 15681123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(strncmp(format, "AddrPCRel", 9) == 0); 1569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int offset = instr->ImmPCRel(); 1571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only ADR (AddrPCRelByte) is supported. 15731123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(strcmp(format, "AddrPCRelByte") == 0); 1574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char sign = '+'; 1576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (offset < 0) { 1577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl offset = -offset; 1578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sign = '-'; 1579ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 15801123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_STATIC_ASSERT(sizeof(*instr) == 1); 15811123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl AppendToOutput("#%c0x%x (addr %p)", sign, offset, instr + offset); 1582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 13; 1583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteBranchTargetField(Instruction* instr, 1587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 15881123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(strncmp(format, "BImm", 4) == 0); 1589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t offset = 0; 1591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[5]) { 1592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmUncn - unconditional branch immediate. 1593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'n': offset = instr->ImmUncondBranch(); break; 1594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmCond - conditional branch immediate. 1595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'o': offset = instr->ImmCondBranch(); break; 1596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmCmpa - compare and branch immediate. 1597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'm': offset = instr->ImmCmpBranch(); break; 1598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmTest - test and branch immediate. 1599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'e': offset = instr->ImmTestBranch(); break; 16001123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl default: VIXL_UNIMPLEMENTED(); 1601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl offset <<= kInstructionSizeLog2; 1603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char sign = '+'; 1604ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (offset < 0) { 1605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl offset = -offset; 1606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sign = '-'; 1607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 16081123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_STATIC_ASSERT(sizeof(*instr) == 1); 16091123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl AppendToOutput("#%c0x%" PRIx64 " (addr %p)", sign, offset, instr + offset); 1610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1611ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteExtendField(Instruction* instr, 1615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 16161123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(strncmp(format, "Ext", 3) == 0); 16171123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(instr->ExtendMode() <= 7); 1618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* extend_mode[] = { "uxtb", "uxth", "uxtw", "uxtx", 1621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "sxtb", "sxth", "sxtw", "sxtx" }; 1622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If rd or rn is SP, uxtw on 32-bit registers and uxtx on 64-bit 1624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registers becomes lsl. 1625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (((instr->Rd() == kZeroRegCode) || (instr->Rn() == kZeroRegCode)) && 1626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) || 1627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (instr->ExtendMode() == UXTX))) { 1628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmExtendShift() > 0) { 1629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", lsl #%d", instr->ImmExtendShift()); 1630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", %s", extend_mode[instr->ExtendMode()]); 1633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmExtendShift() > 0) { 1634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(" #%d", instr->ImmExtendShift()); 1635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1639ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteLSRegOffsetField(Instruction* instr, 1642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 16431123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(strncmp(format, "Offsetreg", 9) == 0); 1644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* extend_mode[] = { "undefined", "undefined", "uxtw", "lsl", 1645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "undefined", "undefined", "sxtw", "sxtx" }; 1646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1647ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1648ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned shift = instr->ImmShiftLS(); 1649ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Extend ext = static_cast<Extend>(instr->ExtendMode()); 1650ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char reg_type = ((ext == UXTW) || (ext == SXTW)) ? 'w' : 'x'; 1651ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1652ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned rm = instr->Rm(); 1653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rm == kZeroRegCode) { 1654ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%czr", reg_type); 1655ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1656ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%c%d", reg_type, rm); 1657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Extend mode UXTX is an alias for shift mode LSL here. 1660ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!((ext == UXTX) && (shift == 0))) { 1661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", %s", extend_mode[ext]); 1662ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (shift != 0) { 1663ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(" #%d", instr->SizeLS()); 1664ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1665ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1666ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 9; 1667ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1668ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1669ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstitutePrefetchField(Instruction* instr, 1671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 16721123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[0] == 'P'); 1673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1674ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int prefetch_mode = instr->PrefetchMode(); 1676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1677ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* ls = (prefetch_mode & 0x10) ? "st" : "ld"; 1678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int level = (prefetch_mode >> 1) + 1; 1679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* ks = (prefetch_mode & 1) ? "strm" : "keep"; 1680ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1681ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("p%sl%d%s", ls, level, ks); 1682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1685f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixlint Disassembler::SubstituteBarrierField(Instruction* instr, 1686f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl const char* format) { 16871123fee00a9cef7f1b448eab3c2ca333dbd426d7armvixl VIXL_ASSERT(format[0] == 'M'); 1688f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl USE(format); 1689f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1690f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl static const char* options[4][4] = { 1691f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl { "sy (0b0000)", "oshld", "oshst", "osh" }, 1692f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl { "sy (0b0100)", "nshld", "nshst", "nsh" }, 1693f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl { "sy (0b1000)", "ishld", "ishst", "ish" }, 1694f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl { "sy (0b1100)", "ld", "st", "sy" } 1695f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl }; 1696f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl int domain = instr->ImmBarrierDomain(); 1697f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl int type = instr->ImmBarrierType(); 1698f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl 1699f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl AppendToOutput("%s", options[domain][type]); 1700f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl return 1; 1701f37fdc0b307fc66239b8b754b0465d36bc0f8aedarmvixl} 1702ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::ResetOutput() { 1704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_pos_ = 0; 1705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_] = 0; 1706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::AppendToOutput(const char* format, ...) { 1710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl va_list args; 1711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl va_start(args, format); 1712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_pos_ += vsnprintf(&buffer_[buffer_pos_], buffer_size_, format, args); 1713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl va_end(args); 1714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1716ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid PrintDisassembler::ProcessOutput(Instruction* instr) { 1718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(stream_, "0x%016" PRIx64 " %08" PRIx32 "\t\t%s\n", 1719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reinterpret_cast<uint64_t>(instr), 1720ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->InstructionBits(), 1721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GetOutput()); 1722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 1724