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