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