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