disasm-a64.cc revision ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dc
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; 63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 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 } 98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(AddSubImmediate)"; 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); 107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 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 } 145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(AddSubShifted)"; 146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitAddSubExtended(Instruction* instr) { 152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 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 } 183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(AddSubExtended)"; 184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitAddSubWithCarry(Instruction* instr) { 190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_zr = RnIsZROrSP(instr); 191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 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 } 218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(AddSubWithCarry)"; 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); 227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rds, 'Rn, 'ITri"; 229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LogicalImmediateMask)) { 231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_w_imm: 232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_x_imm: mnemonic = "and"; break; 233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_w_imm: 234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_x_imm: { 235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "orr"; 236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSize 237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl : kWRegSize; 238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr && !IsMovzMovnImm(reg_size, instr->ImmLogical())) { 239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mov"; 240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rds, 'ITri"; 241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_w_imm: 245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_x_imm: mnemonic = "eor"; break; 246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_w_imm: 247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_x_imm: { 248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ands"; 249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "tst"; 251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rn, 'ITri"; 252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(LogicalImmediate)"; 256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbool Disassembler::IsMovzMovnImm(unsigned reg_size, uint64_t value) { 262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT((reg_size == kXRegSize) || 263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((reg_size == kWRegSize) && (value <= 0xffffffff))); 264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Test for movz: 16 bits set at positions 0, 16, 32 or 48. 266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (((value & 0xffffffffffff0000UL) == 0UL) || 267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0xffffffff0000ffffUL) == 0UL) || 268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0xffff0000ffffffffUL) == 0UL) || 269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0x0000ffffffffffffUL) == 0UL)) { 270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Test for movn: NOT(16 bits set at positions 0, 16, 32 or 48). 274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((reg_size == kXRegSize) && 275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (((value & 0xffffffffffff0000UL) == 0xffffffffffff0000UL) || 276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0xffffffff0000ffffUL) == 0xffffffff0000ffffUL) || 277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0xffff0000ffffffffUL) == 0xffff0000ffffffffUL) || 278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0x0000ffffffffffffUL) == 0x0000ffffffffffffUL))) { 279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((reg_size == kWRegSize) && 282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (((value & 0xffff0000) == 0xffff0000) || 283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((value & 0x0000ffff) == 0x0000ffff))) { 284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return true; 285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return false; 287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLogicalShifted(Instruction* instr) { 291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rd_is_zr = RdIsZROrSP(instr); 292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_zr = RnIsZROrSP(instr); 293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm'HLo"; 295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LogicalShiftedMask)) { 297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_w: 298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case AND_x: mnemonic = "and"; break; 299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BIC_w: 300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BIC_x: mnemonic = "bic"; break; 301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_w: 302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EOR_x: mnemonic = "eor"; break; 303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EON_w: 304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EON_x: mnemonic = "eon"; break; 305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BICS_w: 306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BICS_x: mnemonic = "bics"; break; 307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_w: 308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ANDS_x: { 309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ands"; 310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rd_is_zr) { 311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "tst"; 312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rn, 'Rm'HLo"; 313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_w: 317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORR_x: { 318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "orr"; 319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr && (instr->ImmDPShift() == 0) && (instr->ShiftDP() == LSL)) { 320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mov"; 321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rd, 'Rm"; 322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORN_w: 326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ORN_x: { 327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "orn"; 328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_zr) { 329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mvn"; 330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rd, 'Rm'HLo"; 331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(LogicalShifted)"; 335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalCompareRegister(Instruction* instr) { 342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rn, 'Rm, 'INzcv, 'Cond"; 344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalCompareRegisterMask)) { 346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_w: 347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_x: mnemonic = "ccmn"; break; 348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_w: 349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_x: mnemonic = "ccmp"; break; 350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(ConditionalCompareRegister)"; 351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalCompareImmediate(Instruction* instr) { 357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rn, 'IP, 'INzcv, 'Cond"; 359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalCompareImmediateMask)) { 361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_w_imm: 362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMN_x_imm: mnemonic = "ccmn"; break; 363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_w_imm: 364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CCMP_x_imm: mnemonic = "ccmp"; break; 365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(ConditionalCompareImmediate)"; 366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalSelect(Instruction* instr) { 372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rnm_is_zr = (RnIsZROrSP(instr) && RmIsZROrSP(instr)); 373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool rn_is_rm = (instr->Rn() == instr->Rm()); 374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm, 'Cond"; 376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_test = "'Rd, 'CInv"; 377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_update = "'Rd, 'Rn, 'CInv"; 378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalSelectMask)) { 380ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSEL_w: 381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSEL_x: mnemonic = "csel"; break; 382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINC_w: 383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINC_x: { 384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csinc"; 385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rnm_is_zr) { 386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cset"; 387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_test; 388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (rn_is_rm) { 389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cinc"; 390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_update; 391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINV_w: 395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSINV_x: { 396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csinv"; 397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rnm_is_zr) { 398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csetm"; 399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_test; 400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (rn_is_rm) { 401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cinv"; 402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_update; 403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSNEG_w: 407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CSNEG_x: { 408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "csneg"; 409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rn_is_rm) { 410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "cneg"; 411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_update; 412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(ConditionalSelect)"; 416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitBitfield(Instruction* instr) { 422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned s = instr->ImmS(); 423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned r = instr->ImmR(); 424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned rd_size_minus_1 = 425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((instr->SixtyFourBits() == 1) ? kXRegSize : kWRegSize) - 1; 426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(Bitfield)"; 428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_shift_right = "'Rd, 'Rn, 'IBr"; 429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_extend = "'Rd, 'Wn"; 430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_bfiz = "'Rd, 'Rn, 'IBZ-r, 'IBs+1"; 431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_bfx = "'Rd, 'Rn, 'IBr, 'IBs-r+1"; 432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_lsl = "'Rd, 'Rn, 'IBZ-r"; 433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(BitfieldMask)) { 435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBFM_w: 436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SBFM_x: { 437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sbfx"; 438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (r == 0) { 440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_extend; 441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s == 7) { 442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sxtb"; 443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s == 15) { 444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sxth"; 445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if ((s == 31) && (instr->SixtyFourBits() == 1)) { 446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sxtw"; 447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s == rd_size_minus_1) { 451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "asr"; 452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_shift_right; 453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s < r) { 454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "sbfiz"; 455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfiz; 456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UBFM_w: 460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UBFM_x: { 461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ubfx"; 462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (r == 0) { 464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_extend; 465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s == 7) { 466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "uxtb"; 467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s == 15) { 468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "uxth"; 469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s == rd_size_minus_1) { 474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "lsr"; 475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_shift_right; 476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (r == s + 1) { 477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "lsl"; 478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_lsl; 479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (s < r) { 480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ubfiz"; 481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfiz; 482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BFM_w: 486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BFM_x: { 487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "bfxil"; 488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfx; 489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (s < r) { 490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "bfi"; 491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_bfiz; 492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitExtract(Instruction* instr) { 500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm, 'IExtract"; 502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ExtractMask)) { 504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EXTR_w: 505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case EXTR_x: { 506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Rn() == instr->Rm()) { 507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ror"; 508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = "'Rd, 'Rn, 'IExtract"; 509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "extr"; 511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(Extract)"; 515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitPCRelAddressing(Instruction* instr) { 521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(PCRelAddressingMask)) { 522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case ADR: Format(instr, "adr", "'Xd, 'AddrPCRelByte"); break; 523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // ADRP is not implemented. 524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: Format(instr, "unknown", "(PCRelAddressing)"); 525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitConditionalBranch(Instruction* instr) { 530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ConditionalBranchMask)) { 531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case B_cond: Format(instr, "b.'CBrn", "'BImmCond"); break; 532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: Format(instr, "unknown", "(ConditionalBranch)"); 533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitUnconditionalBranchToRegister(Instruction* instr) { 538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Xn"; 540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(UnconditionalBranchToRegisterMask)) { 542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BR: mnemonic = "br"; break; 543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BLR: mnemonic = "blr"; break; 544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case RET: { 545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "ret"; 546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Rn() == kLinkRegCode) { 547ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = NULL; 548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 550ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(UnconditionalBranchToRegister)"; 552ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 553ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 555ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitUnconditionalBranch(Instruction* instr) { 558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'BImmUncn"; 560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(UnconditionalBranchMask)) { 562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case B: mnemonic = "b"; break; 563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BL: mnemonic = "bl"; break; 564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(UnconditionalBranch)"; 565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 566ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 567ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitDataProcessing1Source(Instruction* instr) { 571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn"; 573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(DataProcessing1SourceMask)) { 575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_w: \ 577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_x: mnemonic = B; break; 578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(RBIT, "rbit"); 579ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(REV16, "rev16"); 580ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(REV, "rev"); 581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(CLZ, "clz"); 582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(CLS, "cls"); 583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case REV32_x: mnemonic = "rev32"; break; 585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(DataProcessing1Source)"; 586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitDataProcessing2Source(Instruction* instr) { 592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'Rn, 'Rm"; 594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(DataProcessing2SourceMask)) { 596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_w: \ 598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_x: mnemonic = B; break; 599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(UDIV, "udiv"); 600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(SDIV, "sdiv"); 601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(LSLV, "lsl"); 602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(LSRV, "lsr"); 603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(ASRV, "asr"); 604ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(RORV, "ror"); 605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(DataProcessing2Source)"; 607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 611ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitDataProcessing3Source(Instruction* instr) { 613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl bool ra_is_zr = RaIsZROrSP(instr); 614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Xd, 'Wn, 'Wm, 'Xa"; 616ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rrr = "'Rd, 'Rn, 'Rm"; 617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rrrr = "'Rd, 'Rn, 'Rm, 'Ra"; 618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_xww = "'Xd, 'Wn, 'Wm"; 619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_xxx = "'Xd, 'Xn, 'Xm"; 620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(DataProcessing3SourceMask)) { 622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MADD_w: 623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MADD_x: { 624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "madd"; 625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrrr; 626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mul"; 628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrr; 629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MSUB_w: 633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MSUB_x: { 634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "msub"; 635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrrr; 636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mneg"; 638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_rrr; 639ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SMADDL_x: { 643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smaddl"; 644ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 645ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smull"; 646ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 647ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 648ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 649ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 650ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SMSUBL_x: { 651ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smsubl"; 652ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 653ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smnegl"; 654ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 655ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 656ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 657ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 658ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UMADDL_x: { 659ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umaddl"; 660ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 661ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umull"; 662ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 663ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 664ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 665ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 666ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UMSUBL_x: { 667ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umsubl"; 668ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (ra_is_zr) { 669ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umnegl"; 670ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xww; 671ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 672ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 673ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 674ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SMULH_x: { 675ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "smulh"; 676ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xxx; 677ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 678ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 679ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UMULH_x: { 680ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "umulh"; 681ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = form_xxx; 682ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 683ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 684ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(DataProcessing3Source)"; 685ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 686ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 687ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 688ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 689ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 690ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitCompareBranch(Instruction* instr) { 691ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 692ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rt, 'BImmCmpa"; 693ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 694ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(CompareBranchMask)) { 695ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBZ_w: 696ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBZ_x: mnemonic = "cbz"; break; 697ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBNZ_w: 698ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case CBNZ_x: mnemonic = "cbnz"; break; 699ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(CompareBranch)"; 700ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 701ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 702ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 703ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 704ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 705ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitTestBranch(Instruction* instr) { 706ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 707ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Xt, 'IS, 'BImmTest"; 708ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 709ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(TestBranchMask)) { 710ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case TBZ: mnemonic = "tbz"; break; 711ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case TBNZ: mnemonic = "tbnz"; break; 712ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(TestBranch)"; 713ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 714ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 715ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 716ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 717ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 718ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitMoveWideImmediate(Instruction* instr) { 719ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 720ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Rd, 'IMoveImm"; 721ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 722ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Print the shift separately for movk, to make it clear which half word will 723ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // be overwritten. Movn and movz print the computed immediate, which includes 724ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // shift calculation. 725ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(MoveWideImmediateMask)) { 726ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVN_w: 727ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVN_x: mnemonic = "movn"; break; 728ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVZ_w: 729ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVZ_x: mnemonic = "movz"; break; 730ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVK_w: 731ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MOVK_x: mnemonic = "movk"; form = "'Rd, 'IMoveLSL"; break; 732ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(MoveWideImmediate)"; 733ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 734ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 735ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 736ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 737ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 738ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LOAD_STORE_LIST(V) \ 739ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STRB_w, "strb", "'Wt") \ 740ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STRH_w, "strh", "'Wt") \ 741ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_w, "str", "'Wt") \ 742ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_x, "str", "'Xt") \ 743ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRB_w, "ldrb", "'Wt") \ 744ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRH_w, "ldrh", "'Wt") \ 745ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_w, "ldr", "'Wt") \ 746ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_x, "ldr", "'Xt") \ 747ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSB_x, "ldrsb", "'Xt") \ 748ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSH_x, "ldrsh", "'Xt") \ 749ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSW_x, "ldrsw", "'Xt") \ 750ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSB_w, "ldrsb", "'Wt") \ 751ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDRSH_w, "ldrsh", "'Wt") \ 752ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_s, "str", "'St") \ 753ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STR_d, "str", "'Dt") \ 754ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_s, "ldr", "'St") \ 755ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDR_d, "ldr", "'Dt") 756ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 757ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePreIndex(Instruction* instr) { 758ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 759ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePreIndex)"; 760ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 761ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePreIndexMask)) { 762ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_PREINDEX(A, B, C) \ 763ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_pre: mnemonic = B; form = C ", ['Xns'ILS]!"; break; 764ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_PREINDEX) 765ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_PREINDEX 766ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 767ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 768ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 769ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 770ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 771ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePostIndex(Instruction* instr) { 772ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 773ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePostIndex)"; 774ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 775ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePostIndexMask)) { 776ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_POSTINDEX(A, B, C) \ 777ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_post: mnemonic = B; form = C ", ['Xns]'ILS"; break; 778ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_POSTINDEX) 779ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_POSTINDEX 780ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 781ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 782ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 783ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 784ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 785ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStoreUnsignedOffset(Instruction* instr) { 786ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 787ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStoreUnsignedOffset)"; 788ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 789ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStoreUnsignedOffsetMask)) { 790ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_UNSIGNEDOFFSET(A, B, C) \ 791ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_unsigned: mnemonic = B; form = C ", ['Xns'ILU]"; break; 792ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_UNSIGNEDOFFSET) 793ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_UNSIGNEDOFFSET 794ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case PRFM_unsigned: mnemonic = "prfm"; form = "'PrefOp, ['Xn'ILU]"; 795ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 796ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 797ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 798ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 799ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 800ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStoreRegisterOffset(Instruction* instr) { 801ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 802ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStoreRegisterOffset)"; 803ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 804ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStoreRegisterOffsetMask)) { 805ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LS_REGISTEROFFSET(A, B, C) \ 806ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_reg: mnemonic = B; form = C ", ['Xns, 'Offsetreg]"; break; 807ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_LIST(LS_REGISTEROFFSET) 808ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LS_REGISTEROFFSET 809ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case PRFM_reg: mnemonic = "prfm"; form = "'PrefOp, ['Xns, 'Offsetreg]"; 810ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 811ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 812ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 813ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 814ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 815ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStoreUnscaledOffset(Instruction* instr) { 816ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 817ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Wt, ['Xns'ILS]"; 818ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_x = "'Xt, ['Xns'ILS]"; 819ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_s = "'St, ['Xns'ILS]"; 820ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_d = "'Dt, ['Xns'ILS]"; 821ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 822ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStoreUnscaledOffsetMask)) { 823ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STURB_w: mnemonic = "sturb"; break; 824ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STURH_w: mnemonic = "sturh"; break; 825ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_w: mnemonic = "stur"; break; 826ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_x: mnemonic = "stur"; form = form_x; break; 827ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_s: mnemonic = "stur"; form = form_s; break; 828ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STUR_d: mnemonic = "stur"; form = form_d; break; 829ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURB_w: mnemonic = "ldurb"; break; 830ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURH_w: mnemonic = "ldurh"; break; 831ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_w: mnemonic = "ldur"; break; 832ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_x: mnemonic = "ldur"; form = form_x; break; 833ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_s: mnemonic = "ldur"; form = form_s; break; 834ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDUR_d: mnemonic = "ldur"; form = form_d; break; 835ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSB_x: form = form_x; // Fall through. 836ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSB_w: mnemonic = "ldursb"; break; 837ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSH_x: form = form_x; // Fall through. 838ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSH_w: mnemonic = "ldursh"; break; 839ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDURSW_x: mnemonic = "ldursw"; form = form_x; break; 840ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(LoadStoreUnscaledOffset)"; 841ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 842ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 843ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 844ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 845ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 846ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadLiteral(Instruction* instr) { 847ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "ldr"; 848ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadLiteral)"; 849ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 850ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadLiteralMask)) { 851ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_w_lit: form = "'Wt, 'ILLiteral 'LValue"; break; 852ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_x_lit: form = "'Xt, 'ILLiteral 'LValue"; break; 853ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_s_lit: form = "'St, 'ILLiteral 'LValue"; break; 854ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_d_lit: form = "'Dt, 'ILLiteral 'LValue"; break; 855ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: mnemonic = "unknown"; 856ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 857ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 858ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 859ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 860ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 861ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#define LOAD_STORE_PAIR_LIST(V) \ 862ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_w, "stp", "'Wt, 'Wt2", "4") \ 863ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_w, "ldp", "'Wt, 'Wt2", "4") \ 864ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDPSW_x, "ldpsw", "'Xt, 'Xt2", "4") \ 865ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_x, "stp", "'Xt, 'Xt2", "8") \ 866ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_x, "ldp", "'Xt, 'Xt2", "8") \ 867ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_s, "stp", "'St, 'St2", "4") \ 868ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_s, "ldp", "'St, 'St2", "4") \ 869ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(STP_d, "stp", "'Dt, 'Dt2", "8") \ 870ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl V(LDP_d, "ldp", "'Dt, 'Dt2", "8") 871ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 872ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairPostIndex(Instruction* instr) { 873ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 874ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePairPostIndex)"; 875ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 876ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairPostIndexMask)) { 877ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LSP_POSTINDEX(A, B, C, D) \ 878ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_post: mnemonic = B; form = C ", ['Xns]'ILP" D; break; 879ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_PAIR_LIST(LSP_POSTINDEX) 880ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LSP_POSTINDEX 881ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 882ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 883ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 884ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 885ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 886ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairPreIndex(Instruction* instr) { 887ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 888ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePairPreIndex)"; 889ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 890ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairPreIndexMask)) { 891ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LSP_PREINDEX(A, B, C, D) \ 892ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_pre: mnemonic = B; form = C ", ['Xns'ILP" D "]!"; break; 893ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_PAIR_LIST(LSP_PREINDEX) 894ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LSP_PREINDEX 895ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 896ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 897ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 898ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 899ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 900ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairOffset(Instruction* instr) { 901ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 902ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(LoadStorePairOffset)"; 903ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 904ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairOffsetMask)) { 905ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define LSP_OFFSET(A, B, C, D) \ 906ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_off: mnemonic = B; form = C ", ['Xns'ILP" D "]"; break; 907ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl LOAD_STORE_PAIR_LIST(LSP_OFFSET) 908ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef LSP_OFFSET 909ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 910ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 911ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 912ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 913ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 914ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitLoadStorePairNonTemporal(Instruction* instr) { 915ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 916ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form; 917ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 918ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadStorePairNonTemporalMask)) { 919ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_w: mnemonic = "stnp"; form = "'Wt, 'Wt2, ['Xns'ILP4]"; break; 920ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_w: mnemonic = "ldnp"; form = "'Wt, 'Wt2, ['Xns'ILP4]"; break; 921ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_x: mnemonic = "stnp"; form = "'Xt, 'Xt2, ['Xns'ILP8]"; break; 922ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_x: mnemonic = "ldnp"; form = "'Xt, 'Xt2, ['Xns'ILP8]"; break; 923ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_s: mnemonic = "stnp"; form = "'St, 'St2, ['Xns'ILP4]"; break; 924ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_s: mnemonic = "ldnp"; form = "'St, 'St2, ['Xns'ILP4]"; break; 925ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case STNP_d: mnemonic = "stnp"; form = "'Dt, 'Dt2, ['Xns'ILP8]"; break; 926ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDNP_d: mnemonic = "ldnp"; form = "'Dt, 'Dt2, ['Xns'ILP8]"; break; 927ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(LoadStorePairNonTemporal)"; 928ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 929ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 930ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 931ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 932ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 933ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPCompare(Instruction* instr) { 934ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 935ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fn, 'Fm"; 936ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_zero = "'Fn, #0.0"; 937ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 938ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPCompareMask)) { 939ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_s_zero: 940ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_d_zero: form = form_zero; // Fall through. 941ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_s: 942ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCMP_d: mnemonic = "fcmp"; break; 943ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPCompare)"; 944ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 945ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 946ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 947ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 948ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 949ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPConditionalCompare(Instruction* instr) { 950ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 951ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fn, 'Fm, 'INzcv, 'Cond"; 952ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 953ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPConditionalCompareMask)) { 954ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCCMP_s: 955ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCCMP_d: mnemonic = "fccmp"; break; 956ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPConditionalCompare)"; 957ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 958ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 959ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 960ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 961ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 962ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPConditionalSelect(Instruction* instr) { 963ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 964ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn, 'Fm, 'Cond"; 965ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 966ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPConditionalSelectMask)) { 967ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCSEL_s: 968ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCSEL_d: mnemonic = "fcsel"; break; 969ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPConditionalSelect)"; 970ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 971ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 972ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 973ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 974ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 975ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPDataProcessing1Source(Instruction* instr) { 976ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 977ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn"; 978ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 979ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPDataProcessing1SourceMask)) { 980ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 981ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_s: \ 982ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_d: mnemonic = B; break; 983ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMOV, "fmov"); 984ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FABS, "fabs"); 985ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNEG, "fneg"); 986ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FSQRT, "fsqrt"); 987ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTN, "frintn"); 988ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTP, "frintp"); 989ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTM, "frintm"); 990ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTZ, "frintz"); 991ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTA, "frinta"); 992ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTX, "frintx"); 993ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FRINTI, "frinti"); 994ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 995ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVT_ds: mnemonic = "fcvt"; form = "'Dd, 'Sn"; break; 996ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVT_sd: mnemonic = "fcvt"; form = "'Sd, 'Dn"; break; 997ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPDataProcessing1Source)"; 998ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 999ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1000ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1001ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1002ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1003ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPDataProcessing2Source(Instruction* instr) { 1004ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 1005ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn, 'Fm"; 1006ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1007ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPDataProcessing2SourceMask)) { 1008ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 1009ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_s: \ 1010ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_d: mnemonic = B; break; 1011ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMUL, "fmul"); 1012ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FDIV, "fdiv"); 1013ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FADD, "fadd"); 1014ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FSUB, "fsub"); 1015ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMAX, "fmax"); 1016ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMIN, "fmin"); 1017ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMAXNM, "fmaxnm"); 1018ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMINNM, "fminnm"); 1019ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNMUL, "fnmul"); 1020ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 1021ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPDataProcessing2Source)"; 1022ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1023ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1024ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1025ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1026ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1027ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPDataProcessing3Source(Instruction* instr) { 1028ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 1029ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "'Fd, 'Fn, 'Fm, 'Fa"; 1030ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1031ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPDataProcessing3SourceMask)) { 1032ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #define FORMAT(A, B) \ 1033ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_s: \ 1034ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case A##_d: mnemonic = B; break; 1035ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMADD, "fmadd"); 1036ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FMSUB, "fmsub"); 1037ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNMADD, "fnmadd"); 1038ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl FORMAT(FNMSUB, "fnmsub"); 1039ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl #undef FORMAT 1040ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: form = "(FPDataProcessing3Source)"; 1041ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1042ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1043ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1044ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1045ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1046ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPImmediate(Instruction* instr) { 1047ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 1048ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(FPImmediate)"; 1049ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1050ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPImmediateMask)) { 1051ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_s_imm: mnemonic = "fmov"; form = "'Sd, 'IFPSingle"; break; 1052ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_d_imm: mnemonic = "fmov"; form = "'Dd, 'IFPDouble"; break; 1053ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1054ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1055ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1056ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1057ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1058ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPIntegerConvert(Instruction* instr) { 1059ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 1060ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(FPIntegerConvert)"; 1061ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rf = "'Rd, 'Fn"; 1062ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_fr = "'Fd, 'Rn"; 1063ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1064ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPIntegerConvertMask)) { 1065ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_ws: 1066ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_xd: mnemonic = "fmov"; form = form_rf; break; 1067ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_sw: 1068ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FMOV_dx: mnemonic = "fmov"; form = form_fr; break; 1069ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_ws: 1070ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_xs: 1071ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_wd: 1072ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMS_xd: mnemonic = "fcvtms"; form = form_rf; break; 1073ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_ws: 1074ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_xs: 1075ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_wd: 1076ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTMU_xd: mnemonic = "fcvtmu"; form = form_rf; break; 1077ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_ws: 1078ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_xs: 1079ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_wd: 1080ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNS_xd: mnemonic = "fcvtns"; form = form_rf; break; 1081ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_ws: 1082ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_xs: 1083ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_wd: 1084ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTNU_xd: mnemonic = "fcvtnu"; form = form_rf; break; 1085ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xd: 1086ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_ws: 1087ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_wd: 1088ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xs: mnemonic = "fcvtzu"; form = form_rf; break; 1089ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xd: 1090ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_wd: 1091ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xs: 1092ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_ws: mnemonic = "fcvtzs"; form = form_rf; break; 1093ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dw: 1094ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dx: mnemonic = "scvtf"; form = form_fr; break; 1095ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dw: 1096ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dx: mnemonic = "ucvtf"; form = form_fr; break; 1097ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1098ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1099ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitFPFixedPointConvert(Instruction* instr) { 1103ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 1104ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(FPFixedPointConvert)"; 1105ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_rf = "'Rd, 'Fn, 'IFPFBits"; 1106ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form_fr = "'Fd, 'Rn, 'IFPFBits"; 1107ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(FPFixedPointConvertMask)) { 1109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_ws_fixed: 1110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xs_fixed: 1111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_wd_fixed: 1112ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZS_xd_fixed: mnemonic = "fcvtzs"; form = form_rf; break; 1113ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_ws_fixed: 1114ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xs_fixed: 1115ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_wd_fixed: 1116ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case FCVTZU_xd_fixed: mnemonic = "fcvtzu"; form = form_rf; break; 1117ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_sw_fixed: 1118ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_sx_fixed: 1119ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dw_fixed: 1120ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case SCVTF_dx_fixed: mnemonic = "scvtf"; form = form_fr; break; 1121ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_sw_fixed: 1122ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_sx_fixed: 1123ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dw_fixed: 1124ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case UCVTF_dx_fixed: mnemonic = "ucvtf"; form = form_fr; break; 1125ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1126ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1127ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1128ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1130ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitSystem(Instruction* instr) { 1131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Some system instructions hijack their Op and Cp fields to represent a 1132ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // range of immediates instead of indicating a different instruction. This 1133ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // makes the decoding tricky. 1134ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *mnemonic = "unknown"; 1135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char *form = "(System)"; 1136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->Mask(SystemSysRegFMask) == SystemSysRegFixed) { 1138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(SystemSysRegMask)) { 1139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MRS: { 1140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "mrs"; 1141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->ImmSystemRegister()) { 1142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case NZCV: form = "'Xt, nzcv"; break; 1143ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case MSR: { 1147ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "msr"; 1148ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->ImmSystemRegister()) { 1149ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case NZCV: form = "nzcv, 'Xt"; break; 1150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1152ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1154ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (instr->Mask(SystemHintFMask) == SystemHintFixed) { 1155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(instr->Mask(SystemHintMask) == HINT); 1156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->ImmHint()) { 1157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case NOP: { 1158ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl mnemonic = "nop"; 1159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl form = NULL; 1160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1161ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, mnemonic, form); 1166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitException(Instruction* instr) { 1170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(ExceptionMask)) { 1171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case HLT: Format(instr, "hlt", "'IDebug"); break; 1172ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case BRK: Format(instr, "brk", "'IDebug"); break; 1173ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: Format(instr, "unknown", "(Exception)"); 1174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1176ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1178ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::VisitUnknown(Instruction* instr) { 1179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Format(instr, "unknown", "(Unknown)"); 1180ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1181ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1182ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1183ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::ProcessOutput(Instruction* /*instr*/) { 1184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // The base disasm does nothing more than disassembling into a buffer. 1185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::Format(Instruction* instr, const char* mnemonic, 1189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(mnemonic != NULL); 1191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ResetOutput(); 1192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Substitute(instr, mnemonic); 1193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format != NULL) { 1194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_++] = ' '; 1195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Substitute(instr, format); 1196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_] = 0; 1198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ProcessOutput(instr); 1199ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1200ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1202ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::Substitute(Instruction* instr, const char* string) { 1203ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char chr = *string++; 1204ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl while (chr != '\0') { 1205ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (chr == '\'') { 1206ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl string += SubstituteField(instr, string); 1207ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_++] = chr; 1209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1210ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl chr = *string++; 1211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1212ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1214ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteField(Instruction* instr, const char* format) { 1216ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[0]) { 1217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'R': // Register. X or W, selected by sf bit. 1218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'F': // FP Register. S or D, selected by type field. 1219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'W': 1220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'X': 1221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'S': 1222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'D': return SubstituteRegisterField(instr, format); 1223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'I': return SubstituteImmediateField(instr, format); 1224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': return SubstituteLiteralField(instr, format); 1225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'H': return SubstituteShiftField(instr, format); 1226ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'P': return SubstitutePrefetchField(instr, format); 1227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'C': return SubstituteConditionField(instr, format); 1228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'E': return SubstituteExtendField(instr, format); 1229ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'A': return SubstitutePCRelAddressField(instr, format); 1230ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'B': return SubstituteBranchTargetField(instr, format); 1231ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'O': return SubstituteLSRegOffsetField(instr, format); 1232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: { 1233ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl UNREACHABLE(); 1234ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 1; 1235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1238ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteRegisterField(Instruction* instr, 1241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned reg_num = 0; 1243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned field_len = 2; 1244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'd': reg_num = instr->Rd(); break; 1246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'n': reg_num = instr->Rn(); break; 1247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'm': reg_num = instr->Rm(); break; 1248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'a': reg_num = instr->Ra(); break; 1249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 't': { 1250ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[2] == '2') { 1251ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_num = instr->Rt2(); 1252ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl field_len = 3; 1253ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1254ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_num = instr->Rt(); 1255ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1256ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1257ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1258ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: UNREACHABLE(); 1259ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1260ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1261ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Increase field length for registers tagged as stack. 1262ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[2] == 's') { 1263ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl field_len = 3; 1264ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1265ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1266ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char reg_type; 1267ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[0] == 'R') { 1268ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Register type is R: use sf bit to choose X and W. 1269ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_type = instr->SixtyFourBits() ? 'x' : 'w'; 1270ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (format[0] == 'F') { 1271ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Floating-point register: use type field to choose S or D. 1272ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_type = ((instr->FPType() & 1) == 0) ? 's' : 'd'; 1273ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1274ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Register type is specified. Make it lower case. 1275ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reg_type = format[0] + 0x20; 1276ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1277ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1278ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if ((reg_num != kZeroRegCode) || (reg_type == 's') || (reg_type == 'd')) { 1279ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // A normal register: w0 - w30, x0 - x30, s0 - s31, d0 - d31. 1280ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%c%d", reg_type, reg_num); 1281ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else if (format[2] == 's') { 1282ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Disassemble w31/x31 as stack pointer wsp/sp. 1283ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%s", (reg_type == 'w') ? "wsp" : "sp"); 1284ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1285ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Disassemble w31/x31 as zero register wzr/xzr. 1286ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%czr", reg_type); 1287ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1288ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1289ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return field_len; 1290ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1291ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1292ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1293ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteImmediateField(Instruction* instr, 1294ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1295ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(format[0] == 'I'); 1296ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1297ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1298ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'M': { // IMoveImm or IMoveLSL. 1299ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[5] == 'I') { 1300ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl uint64_t imm = instr->ImmMoveWide() << (16 * instr->ShiftMoveWide()); 1301ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64, imm); 1302ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1303ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(format[5] == 'L'); 1304ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64, instr->ImmMoveWide()); 1305ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ShiftMoveWide() > 0) { 1306ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", lsl #%d", 16 * instr->ShiftMoveWide()); 1307ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1308ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1309ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1310ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1311ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': { 1312ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[2]) { 1313ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': { // ILLiteral - Immediate Load Literal. 1314ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%" PRId64, 1315ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmLLiteral() << kLiteralEntrySizeLog2); 1316ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 9; 1317ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1318ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'S': { // ILS - Immediate Load/Store. 1319ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmLS() != 0) { 1320ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", #%" PRId64, instr->ImmLS()); 1321ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1322ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1323ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1324ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'P': { // ILPx - Immediate Load/Store Pair, x = access size. 1325ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmLSPair() != 0) { 1326ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // format[3] is the scale value. Convert to a number. 1327ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int scale = format[3] - 0x30; 1328ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", #%" PRId64, instr->ImmLSPair() * scale); 1329ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1330ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 4; 1331ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1332ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'U': { // ILU - Immediate Load/Store Unsigned. 1333ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmLSUnsigned() != 0) { 1334ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", #%" PRIu64, 1335ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmLSUnsigned() << instr->SizeLS()); 1336ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1337ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1338ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1339ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1340ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1341ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'C': { // ICondB - Immediate Conditional Branch. 1342ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t offset = instr->ImmCondBranch() << 2; 1343ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char sign = (offset >= 0) ? '+' : '-'; 1344ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%c0x%" PRIx64, sign, offset); 1345ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1346ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1347ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'A': { // IAddSub. 1348ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(instr->ShiftAddSub() <= 1); 1349ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t imm = instr->ImmAddSub() << (12 * instr->ShiftAddSub()); 1350ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64 " (%" PRId64 ")", imm, imm); 1351ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 7; 1352ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1353ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'F': { // IFPSingle, IFPDouble or IFPFBits. 1354ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[3] == 'F') { // IFPFbits. 1355ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", 64 - instr->FPScale()); 1356ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1357ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1358ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64 " (%.4f)", instr->ImmFP(), 1359ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl format[3] == 'S' ? instr->ImmFP32() : instr->ImmFP64()); 1360ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 9; 1361ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1362ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1363ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'T': { // ITri - Immediate Triangular Encoded. 1364ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%" PRIx64, instr->ImmLogical()); 1365ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 4; 1366ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1367ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'N': { // INzcv. 1368ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int nzcv = (instr->Nzcv() << Flags_offset); 1369ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%c%c%c%c", ((nzcv & NFlag) == 0) ? 'n' : 'N', 1370ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((nzcv & ZFlag) == 0) ? 'z' : 'Z', 1371ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((nzcv & CFlag) == 0) ? 'c' : 'C', 1372ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ((nzcv & VFlag) == 0) ? 'v' : 'V'); 1373ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 5; 1374ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1375ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'P': { // IP - Conditional compare. 1376ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", instr->ImmCondCmp()); 1377ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 2; 1378ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1379ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'B': { // Bitfields. 1380ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return SubstituteBitfieldImmediateField(instr, format); 1381ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1382ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'E': { // IExtract. 1383ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", instr->ImmS()); 1384ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1385ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1386ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'S': { // IS - Test and branch bit. 1387ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", (instr->ImmTestBranchBit5() << 5) | 1388ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmTestBranchBit40()); 1389ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 2; 1390ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1391ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'D': { // IDebug - HLT and BRK instructions. 1392ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#0x%x", instr->ImmException()); 1393ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1394ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1395ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: { 1396ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl UNIMPLEMENTED(); 1397ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 1398ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1399ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1400ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1401ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1402ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1403ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteBitfieldImmediateField(Instruction* instr, 1404ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1405ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT((format[0] == 'I') && (format[1] == 'B')); 1406ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned r = instr->ImmR(); 1407ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned s = instr->ImmS(); 1408ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1409ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[2]) { 1410ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'r': { // IBr. 1411ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", r); 1412ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1413ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1414ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 's': { // IBs+1 or IBs-r+1. 1415ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (format[3] == '+') { 1416ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", s + 1); 1417ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 5; 1418ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1419ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(format[3] == '-'); 1420ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", s - r + 1); 1421ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 7; 1422ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1423ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1424ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'Z': { // IBZ-r. 1425ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT((format[3] == '-') && (format[4] == 'r')); 1426ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned reg_size = (instr->SixtyFourBits() == 1) ? kXRegSize : kWRegSize; 1427ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%d", reg_size - r); 1428ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 5; 1429ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1430ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: { 1431ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl UNREACHABLE(); 1432ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 1433ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1434ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1435ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1436ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1437ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1438ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteLiteralField(Instruction* instr, 1439ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1440ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(strncmp(format, "LValue", 6) == 0); 1441ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1442ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1443ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (instr->Mask(LoadLiteralMask)) { 1444ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_s_lit: AppendToOutput("(%.4f)", instr->LiteralFP32()); break; 1445ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_d_lit: AppendToOutput("(%.4f)", instr->LiteralFP64()); break; 1446ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_w_lit: 1447ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("(0x%08" PRIx32 ")", instr->Literal32()); 1448ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1449ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case LDR_x_lit: 1450ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("(0x%016" PRIx64 ")", instr->Literal64()); 1451ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1452ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: UNREACHABLE(); 1453ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1454ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1455ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1456ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1457ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1458ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1459ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteShiftField(Instruction* instr, const char* format) { 1460ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(format[0] == 'H'); 1461ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(instr->ShiftDP() <= 0x3); 1462ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1463ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1464ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'D': { // HDP. 1465ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(instr->ShiftDP() != ROR); 1466ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } // Fall through. 1467ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'L': { // HLo. 1468ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmDPShift() != 0) { 1469ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* shift_type[] = {"lsl", "lsr", "asr", "ror"}; 1470ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", %s #%" PRId64, shift_type[instr->ShiftDP()], 1471ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->ImmDPShift()); 1472ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1473ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1474ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1475ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: 1476ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl UNIMPLEMENTED(); 1477ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 0; 1478ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1479ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1480ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1481ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1482ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteConditionField(Instruction* instr, 1483ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1484ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(format[0] == 'C'); 1485ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* condition_code[] = { "eq", "ne", "hs", "lo", 1486ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "mi", "pl", "vs", "vc", 1487ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "hi", "ls", "ge", "lt", 1488ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "gt", "le", "al", "nv" }; 1489ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int cond; 1490ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[1]) { 1491ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'B': cond = instr->ConditionBranch(); break; 1492ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'I': { 1493ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl cond = InvertCondition(static_cast<Condition>(instr->Condition())); 1494ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl break; 1495ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1496ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: cond = instr->Condition(); 1497ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1498ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%s", condition_code[cond]); 1499ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 4; 1500ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1501ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1502ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1503ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstitutePCRelAddressField(Instruction* instr, 1504ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1505ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1506ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(strncmp(format, "AddrPCRel", 9) == 0); 1507ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1508ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int offset = instr->ImmPCRel(); 1509ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1510ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Only ADR (AddrPCRelByte) is supported. 1511ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(strcmp(format, "AddrPCRelByte") == 0); 1512ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1513ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char sign = '+'; 1514ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (offset < 0) { 1515ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl offset = -offset; 1516ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sign = '-'; 1517ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1518ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // TODO: Extend this to support printing the target address. 1519ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%c0x%x", sign, offset); 1520ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 13; 1521ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1522ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1523ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1524ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteBranchTargetField(Instruction* instr, 1525ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1526ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(strncmp(format, "BImm", 4) == 0); 1527ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1528ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int64_t offset = 0; 1529ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl switch (format[5]) { 1530ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmUncn - unconditional branch immediate. 1531ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'n': offset = instr->ImmUncondBranch(); break; 1532ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmCond - conditional branch immediate. 1533ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'o': offset = instr->ImmCondBranch(); break; 1534ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmCmpa - compare and branch immediate. 1535ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'm': offset = instr->ImmCmpBranch(); break; 1536ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // BImmTest - test and branch immediate. 1537ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl case 'e': offset = instr->ImmTestBranch(); break; 1538ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl default: UNIMPLEMENTED(); 1539ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1540ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl offset <<= kInstructionSizeLog2; 1541ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char sign = '+'; 1542ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (offset < 0) { 1543ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl offset = -offset; 1544ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl sign = '-'; 1545ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1546ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("#%c0x%" PRIx64, sign, offset); 1547ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 8; 1548ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1549ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1550ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1551ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteExtendField(Instruction* instr, 1552ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1553ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(strncmp(format, "Ext", 3) == 0); 1554ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(instr->ExtendMode() <= 7); 1555ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1556ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1557ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* extend_mode[] = { "uxtb", "uxth", "uxtw", "uxtx", 1558ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "sxtb", "sxth", "sxtw", "sxtx" }; 1559ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1560ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // If rd or rn is SP, uxtw on 32-bit registers and uxtx on 64-bit 1561ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // registers becomes lsl. 1562ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (((instr->Rd() == kZeroRegCode) || (instr->Rn() == kZeroRegCode)) && 1563ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (((instr->ExtendMode() == UXTW) && (instr->SixtyFourBits() == 0)) || 1564ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl (instr->ExtendMode() == UXTX))) { 1565ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmExtendShift() > 0) { 1566ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", lsl #%d", instr->ImmExtendShift()); 1567ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1568ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1569ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", %s", extend_mode[instr->ExtendMode()]); 1570ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (instr->ImmExtendShift() > 0) { 1571ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(" #%d", instr->ImmExtendShift()); 1572ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1573ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1574ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 3; 1575ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1576ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1577ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1578ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstituteLSRegOffsetField(Instruction* instr, 1579ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1580ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(strncmp(format, "Offsetreg", 9) == 0); 1581ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* extend_mode[] = { "undefined", "undefined", "uxtw", "lsl", 1582ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl "undefined", "undefined", "sxtw", "sxtx" }; 1583ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1584ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1585ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned shift = instr->ImmShiftLS(); 1586ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl Extend ext = static_cast<Extend>(instr->ExtendMode()); 1587ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl char reg_type = ((ext == UXTW) || (ext == SXTW)) ? 'w' : 'x'; 1588ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1589ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl unsigned rm = instr->Rm(); 1590ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (rm == kZeroRegCode) { 1591ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%czr", reg_type); 1592ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } else { 1593ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("%c%d", reg_type, rm); 1594ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1595ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1596ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl // Extend mode UXTX is an alias for shift mode LSL here. 1597ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (!((ext == UXTX) && (shift == 0))) { 1598ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(", %s", extend_mode[ext]); 1599ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl if (shift != 0) { 1600ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput(" #%d", instr->SizeLS()); 1601ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1602ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl } 1603ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 9; 1604ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1605ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1606ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1607ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlint Disassembler::SubstitutePrefetchField(Instruction* instr, 1608ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* format) { 1609ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl ASSERT(format[0] == 'P'); 1610ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl USE(format); 1611ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1612ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int prefetch_mode = instr->PrefetchMode(); 1613ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1614ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* ls = (prefetch_mode & 0x10) ? "st" : "ld"; 1615ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl int level = (prefetch_mode >> 1) + 1; 1616ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl const char* ks = (prefetch_mode & 1) ? "strm" : "keep"; 1617ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1618ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl AppendToOutput("p%sl%d%s", ls, level, ks); 1619ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl return 6; 1620ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1621ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1622ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1623ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::ResetOutput() { 1624ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_pos_ = 0; 1625ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_[buffer_pos_] = 0; 1626ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1627ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1628ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1629ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid Disassembler::AppendToOutput(const char* format, ...) { 1630ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl va_list args; 1631ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl va_start(args, format); 1632ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl buffer_pos_ += vsnprintf(&buffer_[buffer_pos_], buffer_size_, format, args); 1633ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl va_end(args); 1634ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1635ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1636ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl 1637ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlvoid PrintDisassembler::ProcessOutput(Instruction* instr) { 1638ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl fprintf(stream_, "0x%016" PRIx64 " %08" PRIx32 "\t\t%s\n", 1639ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl reinterpret_cast<uint64_t>(instr), 1640ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl instr->InstructionBits(), 1641ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl GetOutput()); 1642ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} 1643ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl} // namespace vixl 1644