]> git.proxmox.com Git - qemu.git/blame - arm-dis.c
usb-uhci: symbolic names for pci registers
[qemu.git] / arm-dis.c
CommitLineData
aa0aa4fa 1/* Instruction printing code for the ARM
4b0f1a8b
PB
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 2007, Free Software Foundation, Inc.
aa0aa4fa
FB
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
6
4b0f1a8b 7 This file is part of libopcodes.
aa0aa4fa 8
4b0f1a8b
PB
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
aa0aa4fa 13
4b0f1a8b
PB
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
aa0aa4fa 18
4b0f1a8b 19 You should have received a copy of the GNU General Public License
8167ee88 20 along with this program; if not, see <http://www.gnu.org/licenses/>. */
4b0f1a8b
PB
21
22/* Start of qemu specific additions. Mostly this is stub definitions
23 for things we don't care about. */
aa0aa4fa
FB
24
25#include "dis-asm.h"
4b0f1a8b
PB
26#define ATTRIBUTE_UNUSED __attribute__((unused))
27#define ISSPACE(x) ((x) == ' ' || (x) == '\t' || (x) == '\n')
28
29#define ARM_EXT_V1 0
30#define ARM_EXT_V2 0
31#define ARM_EXT_V2S 0
32#define ARM_EXT_V3 0
33#define ARM_EXT_V3M 0
34#define ARM_EXT_V4 0
35#define ARM_EXT_V4T 0
36#define ARM_EXT_V5 0
37#define ARM_EXT_V5T 0
38#define ARM_EXT_V5ExP 0
39#define ARM_EXT_V5E 0
40#define ARM_EXT_V5J 0
41#define ARM_EXT_V6 0
42#define ARM_EXT_V6K 0
43#define ARM_EXT_V6Z 0
44#define ARM_EXT_V6T2 0
45#define ARM_EXT_V7 0
46#define ARM_EXT_DIV 0
47
48/* Co-processor space extensions. */
49#define ARM_CEXT_XSCALE 0
50#define ARM_CEXT_MAVERICK 0
51#define ARM_CEXT_IWMMXT 0
52
53#define FPU_FPA_EXT_V1 0
54#define FPU_FPA_EXT_V2 0
55#define FPU_VFP_EXT_NONE 0
56#define FPU_VFP_EXT_V1xD 0
57#define FPU_VFP_EXT_V1 0
58#define FPU_VFP_EXT_V2 0
59#define FPU_MAVERICK 0
60#define FPU_VFP_EXT_V3 0
61#define FPU_NEON_EXT_V1 0
62
63int floatformat_ieee_single_little;
64/* Assume host uses ieee float. */
65static void floatformat_to_double (int *ignored, unsigned char *data,
66 double *dest)
67{
68 union {
69 uint32_t i;
70 float f;
71 } u;
72 u.i = data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24);
73 *dest = u.f;
74}
75
76/* End of qemu specific additions. */
77
78/* FIXME: Belongs in global header. */
79#ifndef strneq
80#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
81#endif
aa0aa4fa 82
4b0f1a8b
PB
83#ifndef NUM_ELEM
84#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
85#endif
86
87struct opcode32
88{
89 unsigned long arch; /* Architecture defining this insn. */
90 unsigned long value, mask; /* Recognise insn if (op&mask)==value. */
91 const char *assembler; /* How to disassemble this insn. */
aa0aa4fa
FB
92};
93
4b0f1a8b 94struct opcode16
aa0aa4fa 95{
4b0f1a8b
PB
96 unsigned long arch; /* Architecture defining this insn. */
97 unsigned short value, mask; /* Recognise insn if (op&mask)==value. */
98 const char *assembler; /* How to disassemble this insn. */
aa0aa4fa
FB
99};
100
4b0f1a8b 101/* print_insn_coprocessor recognizes the following format control codes:
3b46e624 102
aa0aa4fa 103 %% %
4b0f1a8b
PB
104
105 %c print condition code (always bits 28-31 in ARM mode)
106 %q print shifter argument
107 %u print condition code (unconditional in ARM mode)
108 %A print address for ldc/stc/ldf/stf instruction
109 %B print vstm/vldm register list
110 %C print vstr/vldr address operand
111 %I print cirrus signed shift immediate: bits 0..3|4..6
112 %F print the COUNT field of a LFM/SFM instruction.
113 %P print floating point precision in arithmetic insn
114 %Q print floating point precision in ldf/stf insn
115 %R print floating point rounding mode
116
117 %<bitfield>r print as an ARM register
aa0aa4fa 118 %<bitfield>d print the bitfield in decimal
4b0f1a8b 119 %<bitfield>k print immediate for VFPv3 conversion instruction
aa0aa4fa
FB
120 %<bitfield>x print the bitfield in hex
121 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
aa0aa4fa
FB
122 %<bitfield>f print a floating point constant if >7 else a
123 floating point register
4b0f1a8b
PB
124 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
125 %<bitfield>g print as an iWMMXt 64-bit register
126 %<bitfield>G print as an iWMMXt general purpose or control register
127 %<bitfield>D print as a NEON D register
128 %<bitfield>Q print as a NEON Q register
129
130 %y<code> print a single precision VFP reg.
aa0aa4fa 131 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
4b0f1a8b 132 %z<code> print a double precision VFP reg
aa0aa4fa 133 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
4b0f1a8b
PB
134
135 %<bitfield>'c print specified char iff bitfield is all ones
136 %<bitfield>`c print specified char iff bitfield is all zeroes
137 %<bitfield>?ab... select from array of values in big endian order
138
139 %L print as an iWMMXt N/M width field.
140 %Z print the Immediate of a WSHUFH instruction.
141 %l like 'A' except use byte offsets for 'B' & 'H'
142 versions.
143 %i print 5-bit immediate in bits 8,3..0
144 (print "32" when 0)
145 %r print register offset address for wldt/wstr instruction
146*/
147
148/* Common coprocessor opcodes shared between Arm and Thumb-2. */
149
150static const struct opcode32 coprocessor_opcodes[] =
151{
152 /* XScale instructions. */
153 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
154 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
155 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
156 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
157 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
158
159 /* Intel Wireless MMX technology instructions. */
160#define FIRST_IWMMXT_INSN 0x0e130130
161#define IWMMXT_INSN_COUNT 73
162 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
163 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
164 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
165 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
166 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
167 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
168 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
169 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
170 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
171 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
172 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
173 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
174 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
175 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
176 {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
177 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
178 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
179 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
180 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
183 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
186 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
187 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
188 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
190 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
191 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
192 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
193 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
194 {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
196 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
197 {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
199 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
200 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
202 {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
203 {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
205 {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
206 {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
207 {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
208 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
209 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
210 {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
211 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
212 {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
213 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
214 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
215 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
216 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
217 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
218 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
219 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
220 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
221 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
222 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
223 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
224 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
225 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
226 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
227 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
228 {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
229 {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
230 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
231 {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
232 {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
233 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
234 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
235 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
236 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
237
238 /* Floating point coprocessor (FPA) instructions */
239 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
243 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
244 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
245 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
246 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
247 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
248 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
249 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
250 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
251 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
252 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
253 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
254 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
255 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
256 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
257 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
258 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
259 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
260 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
261 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
262 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
263 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
264 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
265 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
266 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
267 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
268 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
269 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
270 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
271 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
272 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
273 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
274 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
275 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
276 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
277 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
278 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
279 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
280 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
281 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
282
283 /* Register load/store */
284 {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
285 {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
286 {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
287 {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
288 {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
289 {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
290
291 /* Data transfer between ARM and NEON registers */
292 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
293 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
294 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
295 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
296 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
297 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
298 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
299 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
300 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
301 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
302 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
303 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
304 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
305 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
306
307 /* Floating point coprocessor (VFP) instructions */
308 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
309 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
310 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
311 {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "fmxr%c\tmvfr1, %12-15r"},
312 {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "fmxr%c\tmvfr0, %12-15r"},
313 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
314 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
315 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
316 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
317 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
318 {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr1"},
319 {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "fmrx%c\t%12-15r, mvfr0"},
320 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
321 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
322 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
323 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
324 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
325 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
326 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
327 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def %16-19x>, %12-15r"},
328 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def %16-19x>"},
329 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
330 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
331 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
332 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
333 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
334 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
335 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
336 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
337 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
338 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
339 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
340 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
341 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
342 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
343 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
344 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
345 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
346 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
347 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
348 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
349 {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
350 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
351 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
352 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
353 {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
354 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
355 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
356 {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"},
357 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"},
358 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"},
359 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
360 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
361 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
362 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
363 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
364 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
365 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
366 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
367 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
368 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
369 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
370 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
371 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
372 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
373 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
374 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
375 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
376 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
377 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
378 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
379 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
380 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
381 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
382 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
383 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
384 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
385 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
386 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
387 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
388 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
389 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
390 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
391
392 /* Cirrus coprocessor instructions. */
393 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
394 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
395 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
396 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
397 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
398 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
399 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
400 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
401 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
402 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
403 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
404 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
405 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
406 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
407 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
408 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
409 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
410 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
411 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
412 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
413 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
414 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
415 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
416 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
417 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
418 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
419 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
420 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
421 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
422 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
423 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
424 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
425 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
426 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
427 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
428 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
429 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
430 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
431 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
432 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
433 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
434 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
435 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
436 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
437 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
438 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
439 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
440 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
441 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
442 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
443 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
444 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
445 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
446 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
447 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
448 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
449 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
450 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
451 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
452 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
453 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
454 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
455 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
456 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
457 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
458 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
459 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
460 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
461 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
462 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
463 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
464 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
465 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
466 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
467 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
468 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
469 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
470 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
471 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
473 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
475 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
476 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
477
478 /* Generic coprocessor instructions */
479 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
480 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
481 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
482 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
483 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
484 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
485 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
486
487 /* V6 coprocessor instructions */
488 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
489 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
490
491 /* V5 coprocessor instructions */
492 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
493 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
494 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
495 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
496 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
497
498 {0, 0, 0, 0}
499};
500
501/* Neon opcode table: This does not encode the top byte -- that is
502 checked by the print_insn_neon routine, as it depends on whether we are
503 doing thumb32 or arm32 disassembly. */
504
505/* print_insn_neon recognizes the following format control codes:
506
507 %% %
508
509 %c print condition code
510 %A print v{st,ld}[1234] operands
511 %B print v{st,ld}[1234] any one operands
512 %C print v{st,ld}[1234] single->all operands
513 %D print scalar
514 %E print vmov, vmvn, vorr, vbic encoded constant
515 %F print vtbl,vtbx register list
516
517 %<bitfield>r print as an ARM register
518 %<bitfield>d print the bitfield in decimal
519 %<bitfield>e print the 2^N - bitfield in decimal
520 %<bitfield>D print as a NEON D register
521 %<bitfield>Q print as a NEON Q register
522 %<bitfield>R print as a NEON D or Q register
523 %<bitfield>Sn print byte scaled width limited by n
524 %<bitfield>Tn print short scaled width limited by n
525 %<bitfield>Un print long scaled width limited by n
526
527 %<bitfield>'c print specified char iff bitfield is all ones
528 %<bitfield>`c print specified char iff bitfield is all zeroes
529 %<bitfield>?ab... select from array of values in big endian order */
530
531static const struct opcode32 neon_opcodes[] =
532{
533 /* Extract */
534 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
535 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
536
537 /* Move data element to all lanes */
538 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
539 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
540 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
541
542 /* Table lookup */
543 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
544 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
545
546 /* Two registers, miscellaneous */
547 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
548 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
549 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
550 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
551 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
552 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
553 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
554 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
555 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
556 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
557 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
558 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
559 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
560 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
561 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
562 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
563 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
564 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
565 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
566 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
567 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
568 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
569 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
570 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
571 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
572 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
573 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
574 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
575 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
576 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
577 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
578 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
579 {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
580
581 /* Three registers of the same length */
582 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
583 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
584 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
585 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
586 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
587 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
588 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
589 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
590 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
591 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
592 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
593 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
594 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
595 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
596 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
597 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
598 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
599 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
600 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
601 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
602 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
616 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
617 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
618 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
619 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
625 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
626 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
627 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
628 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
629 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
630 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
631 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
632 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
633 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
634 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635
636 /* One register and an immediate value */
637 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
638 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
639 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
640 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
641 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
642 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
643 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
644 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
645 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
646 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
647 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
648 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
649 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
650
651 /* Two registers and a shift amount */
652 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
653 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
654 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
655 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
656 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
657 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
658 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
659 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
660 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
661 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
662 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
663 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
664 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
665 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
666 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
667 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
668 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
669 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
670 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
671 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
672 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
673 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
674 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
675 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
676 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
677 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
678 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
679 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
680 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
681 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
682 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
683 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
684 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
685 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
686 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
687 {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
688 {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
689 {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
690 {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
691 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
692 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
693 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
694 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
695 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
696 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
697 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
698 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
699 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
700 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
701 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
702 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
703 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
704 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
705 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
706 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
707 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
708 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
709 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
710
711 /* Three registers of different lengths */
712 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
713 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
714 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
715 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
716 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
717 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
718 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
719 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
720 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
721 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
722 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
723 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
724 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
725 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
726 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
727 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
728 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
729
730 /* Two registers and a scalar */
731 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
732 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
733 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
734 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
735 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
736 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
737 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
738 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
739 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
740 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
741 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
742 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
743 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
744 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
745 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
746 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
747 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
748 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
749 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
750 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
751 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
752 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
753
754 /* Element and structure load/store */
755 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
756 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
757 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
758 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
759 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
760 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
761 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
762 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
763 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
764 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
765 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
766 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
767 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
768 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
769 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
770 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
771 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
772 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
773 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
774
775 {0,0 ,0, 0}
776};
777
778/* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
779 ordered: they must be searched linearly from the top to obtain a correct
780 match. */
781
782/* print_insn_arm recognizes the following format control codes:
783
784 %% %
785
aa0aa4fa
FB
786 %a print address for ldr/str instruction
787 %s print address for ldr/str halfword/signextend instruction
788 %b print branch destination
4b0f1a8b 789 %c print condition code (always bits 28-31)
aa0aa4fa 790 %m print register mask for ldm/stm instruction
4b0f1a8b
PB
791 %o print operand2 (immediate or register + shift)
792 %p print 'p' iff bits 12-15 are 15
793 %t print 't' iff bit 21 set and bit 24 clear
794 %B print arm BLX(1) destination
aa0aa4fa 795 %C print the PSR sub type.
4b0f1a8b
PB
796 %U print barrier type.
797 %P print address for pli instruction.
798
799 %<bitfield>r print as an ARM register
800 %<bitfield>d print the bitfield in decimal
801 %<bitfield>W print the bitfield plus one in decimal
802 %<bitfield>x print the bitfield in hex
803 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
804
805 %<bitfield>'c print specified char iff bitfield is all ones
806 %<bitfield>`c print specified char iff bitfield is all zeroes
807 %<bitfield>?ab... select from array of values in big endian order
808
809 %e print arm SMI operand (bits 0..7,8..19).
810 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
811 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
812
813static const struct opcode32 arm_opcodes[] =
814{
815 /* ARM instructions. */
816 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
817 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
818 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
819 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
820 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
821 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
822 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
823
824 /* V7 instructions. */
825 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
826 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
827 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
828 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
829 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
830
831 /* ARM V6T2 instructions. */
832 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
833 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
834 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
835 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
836 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
837 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
838 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
839 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
840 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
841
842 /* ARM V6Z instructions. */
843 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
844
845 /* ARM V6K instructions. */
846 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
847 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
848 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
849 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
850 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
851 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
852 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
853
854 /* ARM V6K NOP hints. */
855 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
856 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
857 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
858 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
859 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
860
861 /* ARM V6 instructions. */
862 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
863 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
864 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
865 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
866 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
867 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
869 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
870 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
871 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
872 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
873 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
874 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
875 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
877 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
878 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
879 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
881 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
882 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
883 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
885 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
886 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
887 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
888 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
889 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
890 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
891 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
893 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
894 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
895 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
897 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
898 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
899 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
900 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
901 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
902 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
903 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
904 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
905 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
906 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
907 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
908 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
909 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
910 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
911 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
912 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
913 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
914 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
915 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
916 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
917 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
918 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
919 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
920 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
921 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
922 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
923 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
924 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
925 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
926 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
927 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
928 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
929 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
930 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
931 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
932 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
933 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
934 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
935 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
936 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
937 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
938 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
939 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
940 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
941 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
942 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
943 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
944 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
945 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
946 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
947 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
948 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
949 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
950 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
951 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
952 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
953 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
954 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
955 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
956 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
957 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
958 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
959 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
960 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
961 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
962 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
963 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
964 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
965 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
966 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
967 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
968 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
969 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
970 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
971 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
972 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
973 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
974 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
975 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
976 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
977 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
978 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
979 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
980 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
981 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
982 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
983 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
984
985 /* V5J instruction. */
986 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
987
988 /* V5 Instructions. */
989 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
990 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
991 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
992 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
993
994 /* V5E "El Segundo" Instructions. */
995 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
996 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
997 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
998 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
999 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1000 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1001 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1002
1003 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1004 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
1005
1006 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1007 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1008 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1009 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1010
1011 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1012 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1013 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1014 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1015
1016 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1017 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1018
1019 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1020 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1021 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1022 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1023
1024 /* ARM Instructions. */
1025 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%6's%5?hb%c\t%12-15r, %s"},
1026 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1027 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1028 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1029 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1030 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1031 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1032 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1033 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1034 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1035 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1036 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1037 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
1038 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
1039 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
1040 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
1041 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1042 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1043 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1044 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1045 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1046 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1047 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1048 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1049 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1050 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
1051 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1052 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1053 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1054 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1055 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
1056 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1057 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1058 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1059 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1060 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1061 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1062 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1063 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1064 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1065 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1066
1067 /* The rest. */
1068 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
1069 {0, 0x00000000, 0x00000000, 0}
1070};
1071
1072/* print_insn_thumb16 recognizes the following format control codes:
1073
aa0aa4fa 1074 %S print Thumb register (bits 3..5 as high number if bit 6 set)
4b0f1a8b 1075 %D print Thumb register (bits 0..2 as high number if bit 7 set)
aa0aa4fa
FB
1076 %<bitfield>I print bitfield as a signed decimal
1077 (top bit of range being the sign bit)
aa0aa4fa
FB
1078 %N print Thumb register mask (with LR)
1079 %O print Thumb register mask (with PC)
4b0f1a8b
PB
1080 %M print Thumb register mask
1081 %b print CZB's 6-bit unsigned branch destination
1082 %s print Thumb right-shift immediate (6..10; 0 == 32).
1083 %c print the condition code
1084 %C print the condition code, or "s" if not conditional
1085 %x print warning if conditional an not at end of IT block"
1086 %X print "\t; unpredictable <IT:code>" if conditional
1087 %I print IT instruction suffix and operands
1088 %<bitfield>r print bitfield as an ARM register
1089 %<bitfield>d print bitfield as a decimal
aa0aa4fa 1090 %<bitfield>H print (bitfield * 2) as a decimal
4b0f1a8b 1091 %<bitfield>W print (bitfield * 4) as a decimal
aa0aa4fa 1092 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
4b0f1a8b
PB
1093 %<bitfield>B print Thumb branch destination (signed displacement)
1094 %<bitfield>c print bitfield as a condition code
1095 %<bitnum>'c print specified char iff bit is one
1096 %<bitnum>?ab print a if bit is one else print b. */
aa0aa4fa 1097
4b0f1a8b 1098static const struct opcode16 thumb_opcodes[] =
aa0aa4fa
FB
1099{
1100 /* Thumb instructions. */
1101
4b0f1a8b
PB
1102 /* ARM V6K no-argument instructions. */
1103 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1104 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1105 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1106 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1107 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1108 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1109
1110 /* ARM V6T2 instructions. */
1111 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1112 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1113 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1114
1115 /* ARM V6. */
1116 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1117 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1118 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1119 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1120 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1121 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1122 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1123 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1124 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1125 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1126 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1127
aa0aa4fa 1128 /* ARM V5 ISA extends Thumb. */
4b0f1a8b
PB
1129 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1130 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1131 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1132 /* ARM V4T ISA (Thumb v1). */
1133 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
aa0aa4fa 1134 /* Format 4. */
4b0f1a8b
PB
1135 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1136 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1137 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1138 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1139 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1140 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1141 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1142 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1143 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1144 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1145 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1146 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1147 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1148 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1149 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1150 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
aa0aa4fa 1151 /* format 13 */
4b0f1a8b
PB
1152 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1153 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
aa0aa4fa 1154 /* format 5 */
4b0f1a8b
PB
1155 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1156 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1157 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1158 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
aa0aa4fa 1159 /* format 14 */
4b0f1a8b
PB
1160 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1161 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
aa0aa4fa 1162 /* format 2 */
4b0f1a8b
PB
1163 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1164 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1165 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1166 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
aa0aa4fa 1167 /* format 8 */
4b0f1a8b
PB
1168 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1169 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1170 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
aa0aa4fa 1171 /* format 7 */
4b0f1a8b
PB
1172 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1173 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
aa0aa4fa 1174 /* format 1 */
4b0f1a8b
PB
1175 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1176 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1177 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
aa0aa4fa 1178 /* format 3 */
4b0f1a8b
PB
1179 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1180 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1181 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1182 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
aa0aa4fa 1183 /* format 6 */
4b0f1a8b 1184 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
aa0aa4fa 1185 /* format 9 */
4b0f1a8b
PB
1186 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1187 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1188 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1189 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
aa0aa4fa 1190 /* format 10 */
4b0f1a8b
PB
1191 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1192 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
aa0aa4fa 1193 /* format 11 */
4b0f1a8b
PB
1194 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1195 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
aa0aa4fa 1196 /* format 12 */
4b0f1a8b
PB
1197 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r, %0-7a)"},
1198 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
aa0aa4fa 1199 /* format 15 */
4b0f1a8b
PB
1200 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1201 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
aa0aa4fa 1202 /* format 17 */
4b0f1a8b
PB
1203 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1204 /* format 16 */
1205 {ARM_EXT_V4T, 0xDE00, 0xFE00, "undefined"},
1206 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1207 /* format 18 */
1208 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1209
1210 /* The E800 .. FFFF range is unconditionally redirected to the
1211 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1212 are processed via that table. Thus, we can never encounter a
1213 bare "second half of BL/BLX(1)" instruction here. */
1214 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
1215 {0, 0, 0, 0}
aa0aa4fa
FB
1216};
1217
4b0f1a8b
PB
1218/* Thumb32 opcodes use the same table structure as the ARM opcodes.
1219 We adopt the convention that hw1 is the high 16 bits of .value and
1220 .mask, hw2 the low 16 bits.
1221
1222 print_insn_thumb32 recognizes the following format control codes:
1223
1224 %% %
1225
1226 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1227 %M print a modified 12-bit immediate (same location)
1228 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1229 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1230 %S print a possibly-shifted Rm
1231
1232 %a print the address of a plain load/store
1233 %w print the width and signedness of a core load/store
1234 %m print register mask for ldm/stm
1235
1236 %E print the lsb and width fields of a bfc/bfi instruction
1237 %F print the lsb and width fields of a sbfx/ubfx instruction
1238 %b print a conditional branch offset
1239 %B print an unconditional branch offset
1240 %s print the shift field of an SSAT instruction
1241 %R print the rotation field of an SXT instruction
1242 %U print barrier type.
1243 %P print address for pli instruction.
1244 %c print the condition code
1245 %x print warning if conditional an not at end of IT block"
1246 %X print "\t; unpredictable <IT:code>" if conditional
1247
1248 %<bitfield>d print bitfield in decimal
1249 %<bitfield>W print bitfield*4 in decimal
1250 %<bitfield>r print bitfield as an ARM register
1251 %<bitfield>c print bitfield as a condition code
1252
1253 %<bitfield>'c print specified char iff bitfield is all ones
1254 %<bitfield>`c print specified char iff bitfield is all zeroes
1255 %<bitfield>?ab... select from array of values in big endian order
1256
1257 With one exception at the bottom (done because BL and BLX(1) need
1258 to come dead last), this table was machine-sorted first in
1259 decreasing order of number of bits set in the mask, then in
1260 increasing numeric order of mask, then in increasing numeric order
1261 of opcode. This order is not the clearest for a human reader, but
1262 is guaranteed never to catch a special-case bit pattern with a more
1263 general mask, which is important, because this instruction encoding
1264 makes heavy use of special-case bit patterns. */
1265static const struct opcode32 thumb32_opcodes[] =
1266{
1267 /* V7 instructions. */
1268 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1269 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1270 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1271 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1272 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1273 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1274 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1275
1276 /* Instructions defined in the basic V6T2 set. */
1277 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1278 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1279 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1280 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1281 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"},
1282 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1283
1284 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1285 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1286 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1287 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1288 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1289 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1290 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1291 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1292 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1293 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1294 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1295 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1296 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1297 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1298 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1299 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1300 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1301 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1302 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1303 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1304 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1305 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1306 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1307 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1308 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1309 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1310 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1311 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1312 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1313 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1314 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1315 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1316 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1317 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1318 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1319 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1320 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1321 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1322 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1323 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1324 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1325 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1326 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1327 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1328 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1329 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1330 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1331 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1332 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1333 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1334 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1335 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1336 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1337 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1338 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1339 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1340 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1341 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1342 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1343 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1344 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1345 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1346 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1347 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1348 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1349 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1350 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1351 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1352 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1353 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1354 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1355 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1356 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1358 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1359 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1360 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1361 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1362 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1363 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1364 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1365 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1366 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1368 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1369 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1370 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1371 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1372 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1373 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1374 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1375 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1376 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1377 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1378 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1379 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1380 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1381 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1382 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1383 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1384 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1385 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1386 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1387 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1388 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1389 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1390 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1391 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1397 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1398 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1399 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1400 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1401 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1402 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1403 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1404 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1405 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1406 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1407 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1408 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1409 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1410 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1411 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1412 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1413 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1414 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1415 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1416 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1417 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1418 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1419 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1420 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1421 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1422 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1423 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1424 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1425 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1426 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1427 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1428 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1429 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1430 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1431 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1432 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1433 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1434 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1435 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1436 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1437 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1438 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1439 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1440 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1441 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1442 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1443 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1444 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1445 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1446 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1447 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1448 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1449 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1450 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1451 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1452 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1453 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1454 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1455 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1456
1457 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1458 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1459 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1460 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1461 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1462
1463 /* These have been 32-bit since the invention of Thumb. */
1464 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1465 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1466
1467 /* Fallback. */
1468 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1469 {0, 0, 0, 0}
1470};
aa0aa4fa 1471
4b0f1a8b
PB
1472static const char *const arm_conditional[] =
1473{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1474 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
aa0aa4fa 1475
4b0f1a8b
PB
1476static const char *const arm_fp_const[] =
1477{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
aa0aa4fa 1478
4b0f1a8b
PB
1479static const char *const arm_shift[] =
1480{"lsl", "lsr", "asr", "ror"};
aa0aa4fa
FB
1481
1482typedef struct
1483{
4b0f1a8b
PB
1484 const char *name;
1485 const char *description;
1486 const char *reg_names[16];
aa0aa4fa
FB
1487}
1488arm_regname;
1489
4b0f1a8b 1490static const arm_regname regnames[] =
aa0aa4fa
FB
1491{
1492 { "raw" , "Select raw register names",
1493 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1494 { "gcc", "Select register names used by GCC",
1495 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1496 { "std", "Select register names used in ARM's ISA documentation",
1497 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1498 { "apcs", "Select register names used in the APCS",
1499 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1500 { "atpcs", "Select register names used in the ATPCS",
1501 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1502 { "special-atpcs", "Select special register names used in the ATPCS",
4b0f1a8b
PB
1503 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1504};
1505
1506static const char *const iwmmxt_wwnames[] =
1507{"b", "h", "w", "d"};
1508
1509static const char *const iwmmxt_wwssnames[] =
1510{"b", "bus", "bc", "bss",
1511 "h", "hus", "hc", "hss",
1512 "w", "wus", "wc", "wss",
1513 "d", "dus", "dc", "dss"
aa0aa4fa
FB
1514};
1515
4b0f1a8b
PB
1516static const char *const iwmmxt_regnames[] =
1517{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1518 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1519};
1520
1521static const char *const iwmmxt_cregnames[] =
1522{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1523 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1524};
1525
1526/* Default to GCC register name set. */
1527static unsigned int regname_selected = 1;
aa0aa4fa
FB
1528
1529#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1530#define arm_regnames regnames[regname_selected].reg_names
1531
47cbc7aa 1532static bfd_boolean force_thumb = false;
4b0f1a8b
PB
1533
1534/* Current IT instruction state. This contains the same state as the IT
1535 bits in the CPSR. */
1536static unsigned int ifthen_state;
1537/* IT state for the next instruction. */
1538static unsigned int ifthen_next_state;
1539/* The address of the insn for which the IT state is valid. */
1540static bfd_vma ifthen_address;
1541#define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1542
1543/* Cached mapping symbol state. */
1544enum map_type {
1545 MAP_ARM,
1546 MAP_THUMB,
1547 MAP_DATA
1548};
aa0aa4fa 1549
4b0f1a8b
PB
1550enum map_type last_type;
1551int last_mapping_sym = -1;
1552bfd_vma last_mapping_addr = 0;
aa0aa4fa 1553
4b0f1a8b
PB
1554/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1555 Returns pointer to following character of the format string and
1556 fills in *VALUEP and *WIDTHP with the extracted value and number of
1557 bits extracted. WIDTHP can be NULL. */
1558
1559static const char *
1560arm_decode_bitfield (const char *ptr, unsigned long insn,
1561 unsigned long *valuep, int *widthp)
1562{
1563 unsigned long value = 0;
1564 int width = 0;
1565
1566 do
1567 {
1568 int start, end;
1569 int bits;
1570
1571 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1572 start = start * 10 + *ptr - '0';
1573 if (*ptr == '-')
1574 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1575 end = end * 10 + *ptr - '0';
1576 else
1577 end = start;
1578 bits = end - start;
1579 if (bits < 0)
1580 abort ();
1581 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1582 width += bits + 1;
1583 }
1584 while (*ptr++ == ',');
1585 *valuep = value;
1586 if (widthp)
1587 *widthp = width;
1588 return ptr - 1;
1589}
1590
aa0aa4fa 1591static void
4b0f1a8b
PB
1592arm_decode_shift (long given, fprintf_ftype func, void *stream,
1593 int print_shift)
aa0aa4fa
FB
1594{
1595 func (stream, "%s", arm_regnames[given & 0xf]);
3b46e624 1596
aa0aa4fa
FB
1597 if ((given & 0xff0) != 0)
1598 {
1599 if ((given & 0x10) == 0)
1600 {
1601 int amount = (given & 0xf80) >> 7;
1602 int shift = (given & 0x60) >> 5;
3b46e624 1603
aa0aa4fa
FB
1604 if (amount == 0)
1605 {
1606 if (shift == 3)
1607 {
1608 func (stream, ", rrx");
1609 return;
1610 }
3b46e624 1611
aa0aa4fa
FB
1612 amount = 32;
1613 }
3b46e624 1614
4b0f1a8b
PB
1615 if (print_shift)
1616 func (stream, ", %s #%d", arm_shift[shift], amount);
1617 else
1618 func (stream, ", #%d", amount);
aa0aa4fa 1619 }
4b0f1a8b 1620 else if (print_shift)
aa0aa4fa
FB
1621 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1622 arm_regnames[(given & 0xf00) >> 8]);
4b0f1a8b
PB
1623 else
1624 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
aa0aa4fa
FB
1625 }
1626}
1627
4b0f1a8b 1628/* Print one coprocessor instruction on INFO->STREAM.
47cbc7aa 1629 Return true if the instuction matched, false if this is not a
4b0f1a8b 1630 recognised coprocessor instruction. */
aa0aa4fa 1631
4b0f1a8b
PB
1632static bfd_boolean
1633print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1634 bfd_boolean thumb)
aa0aa4fa 1635{
4b0f1a8b
PB
1636 const struct opcode32 *insn;
1637 void *stream = info->stream;
1638 fprintf_ftype func = info->fprintf_func;
1639 unsigned long mask;
1640 unsigned long value;
1641 int cond;
1642
1643 for (insn = coprocessor_opcodes; insn->assembler; insn++)
aa0aa4fa 1644 {
4b0f1a8b
PB
1645 if (insn->value == FIRST_IWMMXT_INSN
1646 && info->mach != bfd_mach_arm_XScale
1647 && info->mach != bfd_mach_arm_iWMMXt
1648 && info->mach != bfd_mach_arm_iWMMXt2)
1649 insn = insn + IWMMXT_INSN_COUNT;
1650
1651 mask = insn->mask;
1652 value = insn->value;
1653 if (thumb)
1654 {
1655 /* The high 4 bits are 0xe for Arm conditional instructions, and
1656 0xe for arm unconditional instructions. The rest of the
1657 encoding is the same. */
1658 mask |= 0xf0000000;
1659 value |= 0xe0000000;
1660 if (ifthen_state)
1661 cond = IFTHEN_COND;
1662 else
1663 cond = 16;
1664 }
1665 else
1666 {
1667 /* Only match unconditional instuctions against unconditional
1668 patterns. */
1669 if ((given & 0xf0000000) == 0xf0000000)
1670 {
1671 mask |= 0xf0000000;
1672 cond = 16;
1673 }
1674 else
1675 {
1676 cond = (given >> 28) & 0xf;
1677 if (cond == 0xe)
1678 cond = 16;
1679 }
1680 }
1681 if ((given & mask) == value)
aa0aa4fa 1682 {
4b0f1a8b 1683 const char *c;
3b46e624 1684
aa0aa4fa
FB
1685 for (c = insn->assembler; *c; c++)
1686 {
1687 if (*c == '%')
1688 {
1689 switch (*++c)
1690 {
1691 case '%':
1692 func (stream, "%%");
1693 break;
1694
4b0f1a8b
PB
1695 case 'A':
1696 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
aa0aa4fa 1697
4b0f1a8b
PB
1698 if ((given & (1 << 24)) != 0)
1699 {
1700 int offset = given & 0xff;
aa0aa4fa 1701
4b0f1a8b
PB
1702 if (offset)
1703 func (stream, ", #%s%d]%s",
1704 ((given & 0x00800000) == 0 ? "-" : ""),
1705 offset * 4,
1706 ((given & 0x00200000) != 0 ? "!" : ""));
aa0aa4fa 1707 else
4b0f1a8b 1708 func (stream, "]");
aa0aa4fa
FB
1709 }
1710 else
1711 {
4b0f1a8b 1712 int offset = given & 0xff;
aa0aa4fa 1713
4b0f1a8b
PB
1714 func (stream, "]");
1715
1716 if (given & (1 << 21))
aa0aa4fa 1717 {
4b0f1a8b
PB
1718 if (offset)
1719 func (stream, ", #%s%d",
1720 ((given & 0x00800000) == 0 ? "-" : ""),
1721 offset * 4);
aa0aa4fa 1722 }
4b0f1a8b
PB
1723 else
1724 func (stream, ", {%d}", offset);
aa0aa4fa
FB
1725 }
1726 break;
1727
4b0f1a8b
PB
1728 case 'B':
1729 {
1730 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1731 int offset = (given >> 1) & 0x3f;
1732
1733 if (offset == 1)
1734 func (stream, "{d%d}", regno);
1735 else if (regno + offset > 32)
1736 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1737 else
1738 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1739 }
1740 break;
3b46e624 1741
4b0f1a8b
PB
1742 case 'C':
1743 {
1744 int rn = (given >> 16) & 0xf;
1745 int offset = (given & 0xff) * 4;
1746 int add = (given >> 23) & 1;
3b46e624 1747
4b0f1a8b 1748 func (stream, "[%s", arm_regnames[rn]);
3b46e624 1749
4b0f1a8b
PB
1750 if (offset)
1751 {
1752 if (!add)
1753 offset = -offset;
1754 func (stream, ", #%d", offset);
1755 }
1756 func (stream, "]");
1757 if (rn == 15)
1758 {
1759 func (stream, "\t; ");
1760 /* FIXME: Unsure if info->bytes_per_chunk is the
1761 right thing to use here. */
1762 info->print_address_func (offset + pc
1763 + info->bytes_per_chunk * 2, info);
1764 }
1765 }
1766 break;
aa0aa4fa
FB
1767
1768 case 'c':
4b0f1a8b 1769 func (stream, "%s", arm_conditional[cond]);
aa0aa4fa
FB
1770 break;
1771
1772 case 'I':
1773 /* Print a Cirrus/DSP shift immediate. */
1774 /* Immediates are 7bit signed ints with bits 0..3 in
1775 bits 0..3 of opcode and bits 4..6 in bits 5..7
1776 of opcode. */
1777 {
1778 int imm;
1779
1780 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1781
1782 /* Is ``imm'' a negative number? */
1783 if (imm & 0x40)
1784 imm |= (-1 << 7);
1785
1786 func (stream, "%d", imm);
1787 }
1788
1789 break;
1790
aa0aa4fa
FB
1791 case 'F':
1792 switch (given & 0x00408000)
1793 {
1794 case 0:
1795 func (stream, "4");
1796 break;
1797 case 0x8000:
1798 func (stream, "1");
1799 break;
1800 case 0x00400000:
1801 func (stream, "2");
1802 break;
1803 default:
1804 func (stream, "3");
1805 }
1806 break;
3b46e624 1807
aa0aa4fa
FB
1808 case 'P':
1809 switch (given & 0x00080080)
1810 {
1811 case 0:
1812 func (stream, "s");
1813 break;
1814 case 0x80:
1815 func (stream, "d");
1816 break;
1817 case 0x00080000:
1818 func (stream, "e");
1819 break;
1820 default:
1821 func (stream, _("<illegal precision>"));
1822 break;
1823 }
1824 break;
1825 case 'Q':
1826 switch (given & 0x00408000)
1827 {
1828 case 0:
1829 func (stream, "s");
1830 break;
1831 case 0x8000:
1832 func (stream, "d");
1833 break;
1834 case 0x00400000:
1835 func (stream, "e");
1836 break;
1837 default:
1838 func (stream, "p");
1839 break;
1840 }
1841 break;
1842 case 'R':
1843 switch (given & 0x60)
1844 {
1845 case 0:
1846 break;
1847 case 0x20:
1848 func (stream, "p");
1849 break;
1850 case 0x40:
1851 func (stream, "m");
1852 break;
1853 default:
1854 func (stream, "z");
1855 break;
1856 }
1857 break;
1858
5fafdf24 1859 case '0': case '1': case '2': case '3': case '4':
aa0aa4fa
FB
1860 case '5': case '6': case '7': case '8': case '9':
1861 {
4b0f1a8b
PB
1862 int width;
1863 unsigned long value;
1864
1865 c = arm_decode_bitfield (c, given, &value, &width);
aa0aa4fa
FB
1866
1867 switch (*c)
1868 {
4b0f1a8b
PB
1869 case 'r':
1870 func (stream, "%s", arm_regnames[value]);
1871 break;
1872 case 'D':
1873 func (stream, "d%ld", value);
1874 break;
1875 case 'Q':
1876 if (value & 1)
1877 func (stream, "<illegal reg q%ld.5>", value >> 1);
1878 else
1879 func (stream, "q%ld", value >> 1);
1880 break;
1881 case 'd':
1882 func (stream, "%ld", value);
1883 break;
1884 case 'k':
1885 {
1886 int from = (given & (1 << 7)) ? 32 : 16;
1887 func (stream, "%ld", from - value);
1888 }
1889 break;
1890
1891 case 'f':
1892 if (value > 7)
1893 func (stream, "#%s", arm_fp_const[value & 7]);
1894 else
1895 func (stream, "f%ld", value);
1896 break;
3b46e624 1897
4b0f1a8b
PB
1898 case 'w':
1899 if (width == 2)
1900 func (stream, "%s", iwmmxt_wwnames[value]);
1901 else
1902 func (stream, "%s", iwmmxt_wwssnames[value]);
1903 break;
3b46e624 1904
4b0f1a8b
PB
1905 case 'g':
1906 func (stream, "%s", iwmmxt_regnames[value]);
1907 break;
1908 case 'G':
1909 func (stream, "%s", iwmmxt_cregnames[value]);
1910 break;
3b46e624 1911
4b0f1a8b
PB
1912 case 'x':
1913 func (stream, "0x%lx", value);
1914 break;
1915
1916 case '`':
1917 c++;
1918 if (value == 0)
1919 func (stream, "%c", *c);
1920 break;
1921 case '\'':
1922 c++;
1923 if (value == ((1ul << width) - 1))
1924 func (stream, "%c", *c);
1925 break;
1926 case '?':
1927 func (stream, "%c", c[(1 << width) - (int)value]);
1928 c += 1 << width;
1929 break;
1930 default:
1931 abort ();
1932 }
1933 break;
3b46e624 1934
4b0f1a8b
PB
1935 case 'y':
1936 case 'z':
1937 {
1938 int single = *c++ == 'y';
1939 int regno;
3b46e624 1940
4b0f1a8b
PB
1941 switch (*c)
1942 {
1943 case '4': /* Sm pair */
1944 func (stream, "{");
1945 /* Fall through. */
1946 case '0': /* Sm, Dm */
1947 regno = given & 0x0000000f;
1948 if (single)
aa0aa4fa 1949 {
4b0f1a8b
PB
1950 regno <<= 1;
1951 regno += (given >> 5) & 1;
1952 }
1953 else
1954 regno += ((given >> 5) & 1) << 4;
1955 break;
3b46e624 1956
4b0f1a8b
PB
1957 case '1': /* Sd, Dd */
1958 regno = (given >> 12) & 0x0000000f;
1959 if (single)
1960 {
1961 regno <<= 1;
1962 regno += (given >> 22) & 1;
1963 }
1964 else
1965 regno += ((given >> 22) & 1) << 4;
1966 break;
3b46e624 1967
4b0f1a8b
PB
1968 case '2': /* Sn, Dn */
1969 regno = (given >> 16) & 0x0000000f;
1970 if (single)
1971 {
1972 regno <<= 1;
1973 regno += (given >> 7) & 1;
aa0aa4fa 1974 }
4b0f1a8b
PB
1975 else
1976 regno += ((given >> 7) & 1) << 4;
1977 break;
1978
1979 case '3': /* List */
1980 func (stream, "{");
1981 regno = (given >> 12) & 0x0000000f;
1982 if (single)
aa0aa4fa 1983 {
4b0f1a8b
PB
1984 regno <<= 1;
1985 regno += (given >> 22) & 1;
1986 }
1987 else
1988 regno += ((given >> 22) & 1) << 4;
1989 break;
3b46e624 1990
4b0f1a8b
PB
1991 default:
1992 abort ();
1993 }
3b46e624 1994
4b0f1a8b 1995 func (stream, "%c%d", single ? 's' : 'd', regno);
3b46e624 1996
4b0f1a8b
PB
1997 if (*c == '3')
1998 {
1999 int count = given & 0xff;
3b46e624 2000
4b0f1a8b
PB
2001 if (single == 0)
2002 count >>= 1;
3b46e624 2003
4b0f1a8b 2004 if (--count)
aa0aa4fa 2005 {
4b0f1a8b
PB
2006 func (stream, "-%c%d",
2007 single ? 's' : 'd',
2008 regno + count);
2009 }
3b46e624 2010
4b0f1a8b
PB
2011 func (stream, "}");
2012 }
2013 else if (*c == '4')
2014 func (stream, ", %c%d}", single ? 's' : 'd',
2015 regno + 1);
2016 }
2017 break;
3b46e624 2018
4b0f1a8b
PB
2019 case 'L':
2020 switch (given & 0x00400100)
2021 {
2022 case 0x00000000: func (stream, "b"); break;
2023 case 0x00400000: func (stream, "h"); break;
2024 case 0x00000100: func (stream, "w"); break;
2025 case 0x00400100: func (stream, "d"); break;
2026 default:
aa0aa4fa 2027 break;
4b0f1a8b
PB
2028 }
2029 break;
aa0aa4fa 2030
4b0f1a8b
PB
2031 case 'Z':
2032 {
2033 int value;
2034 /* given (20, 23) | given (0, 3) */
2035 value = ((given >> 16) & 0xf0) | (given & 0xf);
2036 func (stream, "%d", value);
2037 }
2038 break;
aa0aa4fa 2039
4b0f1a8b
PB
2040 case 'l':
2041 /* This is like the 'A' operator, except that if
2042 the width field "M" is zero, then the offset is
2043 *not* multiplied by four. */
2044 {
2045 int offset = given & 0xff;
2046 int multiplier = (given & 0x00000100) ? 4 : 1;
aa0aa4fa 2047
4b0f1a8b 2048 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
aa0aa4fa 2049
4b0f1a8b
PB
2050 if (offset)
2051 {
2052 if ((given & 0x01000000) != 0)
2053 func (stream, ", #%s%d]%s",
2054 ((given & 0x00800000) == 0 ? "-" : ""),
2055 offset * multiplier,
2056 ((given & 0x00200000) != 0 ? "!" : ""));
2057 else
2058 func (stream, "], #%s%d",
2059 ((given & 0x00800000) == 0 ? "-" : ""),
2060 offset * multiplier);
2061 }
2062 else
2063 func (stream, "]");
2064 }
2065 break;
aa0aa4fa 2066
4b0f1a8b
PB
2067 case 'r':
2068 {
2069 int imm4 = (given >> 4) & 0xf;
2070 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2071 int ubit = (given >> 23) & 1;
2072 const char *rm = arm_regnames [given & 0xf];
2073 const char *rn = arm_regnames [(given >> 16) & 0xf];
aa0aa4fa 2074
4b0f1a8b
PB
2075 switch (puw_bits)
2076 {
2077 case 1:
2078 /* fall through */
2079 case 3:
2080 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2081 if (imm4)
2082 func (stream, ", lsl #%d", imm4);
2083 break;
aa0aa4fa 2084
4b0f1a8b
PB
2085 case 4:
2086 /* fall through */
2087 case 5:
2088 /* fall through */
2089 case 6:
2090 /* fall through */
2091 case 7:
2092 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2093 if (imm4 > 0)
2094 func (stream, ", lsl #%d", imm4);
2095 func (stream, "]");
2096 if (puw_bits == 5 || puw_bits == 7)
2097 func (stream, "!");
aa0aa4fa 2098 break;
4b0f1a8b
PB
2099
2100 default:
2101 func (stream, "INVALID");
aa0aa4fa 2102 }
4b0f1a8b
PB
2103 }
2104 break;
aa0aa4fa 2105
4b0f1a8b
PB
2106 case 'i':
2107 {
2108 long imm5;
2109 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2110 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2111 }
aa0aa4fa
FB
2112 break;
2113
2114 default:
2115 abort ();
2116 }
2117 }
2118 }
2119 else
2120 func (stream, "%c", *c);
2121 }
47cbc7aa 2122 return true;
aa0aa4fa
FB
2123 }
2124 }
47cbc7aa 2125 return false;
aa0aa4fa
FB
2126}
2127
4b0f1a8b
PB
2128static void
2129print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
aa0aa4fa 2130{
4b0f1a8b
PB
2131 void *stream = info->stream;
2132 fprintf_ftype func = info->fprintf_func;
aa0aa4fa 2133
4b0f1a8b
PB
2134 if (((given & 0x000f0000) == 0x000f0000)
2135 && ((given & 0x02000000) == 0))
aa0aa4fa 2136 {
4b0f1a8b 2137 int offset = given & 0xfff;
aa0aa4fa 2138
4b0f1a8b 2139 func (stream, "[pc");
3b46e624 2140
4b0f1a8b
PB
2141 if (given & 0x01000000)
2142 {
2143 if ((given & 0x00800000) == 0)
2144 offset = - offset;
aa0aa4fa 2145
4b0f1a8b
PB
2146 /* Pre-indexed. */
2147 func (stream, ", #%d]", offset);
3b46e624 2148
4b0f1a8b 2149 offset += pc + 8;
3b46e624 2150
4b0f1a8b
PB
2151 /* Cope with the possibility of write-back
2152 being used. Probably a very dangerous thing
2153 for the programmer to do, but who are we to
2154 argue ? */
2155 if (given & 0x00200000)
2156 func (stream, "!");
2157 }
2158 else
2159 {
2160 /* Post indexed. */
2161 func (stream, "], #%d", offset);
3b46e624 2162
4b0f1a8b
PB
2163 /* ie ignore the offset. */
2164 offset = pc + 8;
2165 }
3b46e624 2166
4b0f1a8b
PB
2167 func (stream, "\t; ");
2168 info->print_address_func (offset, info);
2169 }
2170 else
2171 {
2172 func (stream, "[%s",
2173 arm_regnames[(given >> 16) & 0xf]);
2174 if ((given & 0x01000000) != 0)
2175 {
2176 if ((given & 0x02000000) == 0)
2177 {
2178 int offset = given & 0xfff;
2179 if (offset)
2180 func (stream, ", #%s%d",
2181 (((given & 0x00800000) == 0)
2182 ? "-" : ""), offset);
2183 }
2184 else
2185 {
2186 func (stream, ", %s",
2187 (((given & 0x00800000) == 0)
2188 ? "-" : ""));
2189 arm_decode_shift (given, func, stream, 1);
2190 }
aa0aa4fa 2191
4b0f1a8b
PB
2192 func (stream, "]%s",
2193 ((given & 0x00200000) != 0) ? "!" : "");
2194 }
2195 else
2196 {
2197 if ((given & 0x02000000) == 0)
2198 {
2199 int offset = given & 0xfff;
2200 if (offset)
2201 func (stream, "], #%s%d",
2202 (((given & 0x00800000) == 0)
2203 ? "-" : ""), offset);
2204 else
2205 func (stream, "]");
2206 }
2207 else
2208 {
2209 func (stream, "], %s",
2210 (((given & 0x00800000) == 0)
2211 ? "-" : ""));
2212 arm_decode_shift (given, func, stream, 1);
2213 }
2214 }
2215 }
2216}
2217
2218/* Print one neon instruction on INFO->STREAM.
47cbc7aa 2219 Return true if the instuction matched, false if this is not a
4b0f1a8b
PB
2220 recognised neon instruction. */
2221
2222static bfd_boolean
2223print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2224{
2225 const struct opcode32 *insn;
2226 void *stream = info->stream;
2227 fprintf_ftype func = info->fprintf_func;
2228
2229 if (thumb)
2230 {
2231 if ((given & 0xef000000) == 0xef000000)
2232 {
2233 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2234 unsigned long bit28 = given & (1 << 28);
2235
2236 given &= 0x00ffffff;
2237 if (bit28)
2238 given |= 0xf3000000;
2239 else
2240 given |= 0xf2000000;
2241 }
2242 else if ((given & 0xff000000) == 0xf9000000)
2243 given ^= 0xf9000000 ^ 0xf4000000;
2244 else
47cbc7aa 2245 return false;
4b0f1a8b
PB
2246 }
2247
2248 for (insn = neon_opcodes; insn->assembler; insn++)
2249 {
2250 if ((given & insn->mask) == insn->value)
2251 {
2252 const char *c;
2253
2254 for (c = insn->assembler; *c; c++)
2255 {
2256 if (*c == '%')
2257 {
2258 switch (*++c)
2259 {
2260 case '%':
2261 func (stream, "%%");
2262 break;
2263
2264 case 'c':
2265 if (thumb && ifthen_state)
2266 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2267 break;
2268
2269 case 'A':
2270 {
2271 static const unsigned char enc[16] =
2272 {
2273 0x4, 0x14, /* st4 0,1 */
2274 0x4, /* st1 2 */
2275 0x4, /* st2 3 */
2276 0x3, /* st3 4 */
2277 0x13, /* st3 5 */
2278 0x3, /* st1 6 */
2279 0x1, /* st1 7 */
2280 0x2, /* st2 8 */
2281 0x12, /* st2 9 */
2282 0x2, /* st1 10 */
2283 0, 0, 0, 0, 0
2284 };
2285 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2286 int rn = ((given >> 16) & 0xf);
2287 int rm = ((given >> 0) & 0xf);
2288 int align = ((given >> 4) & 0x3);
2289 int type = ((given >> 8) & 0xf);
2290 int n = enc[type] & 0xf;
2291 int stride = (enc[type] >> 4) + 1;
2292 int ix;
2293
2294 func (stream, "{");
2295 if (stride > 1)
2296 for (ix = 0; ix != n; ix++)
2297 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2298 else if (n == 1)
2299 func (stream, "d%d", rd);
2300 else
2301 func (stream, "d%d-d%d", rd, rd + n - 1);
2302 func (stream, "}, [%s", arm_regnames[rn]);
2303 if (align)
2304 func (stream, ", :%d", 32 << align);
2305 func (stream, "]");
2306 if (rm == 0xd)
2307 func (stream, "!");
2308 else if (rm != 0xf)
2309 func (stream, ", %s", arm_regnames[rm]);
2310 }
2311 break;
2312
2313 case 'B':
2314 {
2315 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2316 int rn = ((given >> 16) & 0xf);
2317 int rm = ((given >> 0) & 0xf);
2318 int idx_align = ((given >> 4) & 0xf);
2319 int align = 0;
2320 int size = ((given >> 10) & 0x3);
2321 int idx = idx_align >> (size + 1);
2322 int length = ((given >> 8) & 3) + 1;
2323 int stride = 1;
2324 int i;
2325
2326 if (length > 1 && size > 0)
2327 stride = (idx_align & (1 << size)) ? 2 : 1;
2328
2329 switch (length)
2330 {
2331 case 1:
2332 {
2333 int amask = (1 << size) - 1;
2334 if ((idx_align & (1 << size)) != 0)
47cbc7aa 2335 return false;
4b0f1a8b
PB
2336 if (size > 0)
2337 {
2338 if ((idx_align & amask) == amask)
2339 align = 8 << size;
2340 else if ((idx_align & amask) != 0)
47cbc7aa 2341 return false;
4b0f1a8b
PB
2342 }
2343 }
2344 break;
2345
2346 case 2:
2347 if (size == 2 && (idx_align & 2) != 0)
47cbc7aa 2348 return false;
4b0f1a8b
PB
2349 align = (idx_align & 1) ? 16 << size : 0;
2350 break;
2351
2352 case 3:
2353 if ((size == 2 && (idx_align & 3) != 0)
2354 || (idx_align & 1) != 0)
47cbc7aa 2355 return false;
4b0f1a8b
PB
2356 break;
2357
2358 case 4:
2359 if (size == 2)
2360 {
2361 if ((idx_align & 3) == 3)
47cbc7aa 2362 return false;
4b0f1a8b
PB
2363 align = (idx_align & 3) * 64;
2364 }
2365 else
2366 align = (idx_align & 1) ? 32 << size : 0;
2367 break;
2368
2369 default:
2370 abort ();
2371 }
2372
2373 func (stream, "{");
2374 for (i = 0; i < length; i++)
2375 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2376 rd + i * stride, idx);
2377 func (stream, "}, [%s", arm_regnames[rn]);
2378 if (align)
2379 func (stream, ", :%d", align);
2380 func (stream, "]");
2381 if (rm == 0xd)
2382 func (stream, "!");
2383 else if (rm != 0xf)
2384 func (stream, ", %s", arm_regnames[rm]);
2385 }
2386 break;
2387
2388 case 'C':
2389 {
2390 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2391 int rn = ((given >> 16) & 0xf);
2392 int rm = ((given >> 0) & 0xf);
2393 int align = ((given >> 4) & 0x1);
2394 int size = ((given >> 6) & 0x3);
2395 int type = ((given >> 8) & 0x3);
2396 int n = type + 1;
2397 int stride = ((given >> 5) & 0x1);
2398 int ix;
2399
2400 if (stride && (n == 1))
2401 n++;
2402 else
2403 stride++;
2404
2405 func (stream, "{");
2406 if (stride > 1)
2407 for (ix = 0; ix != n; ix++)
2408 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2409 else if (n == 1)
2410 func (stream, "d%d[]", rd);
2411 else
2412 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2413 func (stream, "}, [%s", arm_regnames[rn]);
2414 if (align)
2415 {
2416 int align = (8 * (type + 1)) << size;
2417 if (type == 3)
2418 align = (size > 1) ? align >> 1 : align;
2419 if (type == 2 || (type == 0 && !size))
2420 func (stream, ", :<bad align %d>", align);
2421 else
2422 func (stream, ", :%d", align);
2423 }
2424 func (stream, "]");
2425 if (rm == 0xd)
2426 func (stream, "!");
2427 else if (rm != 0xf)
2428 func (stream, ", %s", arm_regnames[rm]);
2429 }
2430 break;
2431
2432 case 'D':
2433 {
2434 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2435 int size = (given >> 20) & 3;
2436 int reg = raw_reg & ((4 << size) - 1);
2437 int ix = raw_reg >> size >> 2;
2438
2439 func (stream, "d%d[%d]", reg, ix);
2440 }
2441 break;
2442
2443 case 'E':
2444 /* Neon encoded constant for mov, mvn, vorr, vbic */
2445 {
2446 int bits = 0;
2447 int cmode = (given >> 8) & 0xf;
2448 int op = (given >> 5) & 0x1;
2449 unsigned long value = 0, hival = 0;
2450 unsigned shift;
2451 int size = 0;
2452 int isfloat = 0;
2453
2454 bits |= ((given >> 24) & 1) << 7;
2455 bits |= ((given >> 16) & 7) << 4;
2456 bits |= ((given >> 0) & 15) << 0;
2457
2458 if (cmode < 8)
2459 {
2460 shift = (cmode >> 1) & 3;
2461 value = (unsigned long)bits << (8 * shift);
2462 size = 32;
2463 }
2464 else if (cmode < 12)
2465 {
2466 shift = (cmode >> 1) & 1;
2467 value = (unsigned long)bits << (8 * shift);
2468 size = 16;
2469 }
2470 else if (cmode < 14)
2471 {
2472 shift = (cmode & 1) + 1;
2473 value = (unsigned long)bits << (8 * shift);
2474 value |= (1ul << (8 * shift)) - 1;
2475 size = 32;
2476 }
2477 else if (cmode == 14)
2478 {
2479 if (op)
2480 {
2481 /* bit replication into bytes */
2482 int ix;
2483 unsigned long mask;
2484
2485 value = 0;
2486 hival = 0;
2487 for (ix = 7; ix >= 0; ix--)
2488 {
2489 mask = ((bits >> ix) & 1) ? 0xff : 0;
2490 if (ix <= 3)
2491 value = (value << 8) | mask;
2492 else
2493 hival = (hival << 8) | mask;
2494 }
2495 size = 64;
2496 }
2497 else
2498 {
2499 /* byte replication */
2500 value = (unsigned long)bits;
2501 size = 8;
2502 }
2503 }
2504 else if (!op)
2505 {
2506 /* floating point encoding */
2507 int tmp;
2508
2509 value = (unsigned long)(bits & 0x7f) << 19;
2510 value |= (unsigned long)(bits & 0x80) << 24;
2511 tmp = bits & 0x40 ? 0x3c : 0x40;
2512 value |= (unsigned long)tmp << 24;
2513 size = 32;
2514 isfloat = 1;
2515 }
2516 else
2517 {
2518 func (stream, "<illegal constant %.8x:%x:%x>",
2519 bits, cmode, op);
2520 size = 32;
2521 break;
2522 }
2523 switch (size)
2524 {
2525 case 8:
2526 func (stream, "#%ld\t; 0x%.2lx", value, value);
2527 break;
2528
2529 case 16:
2530 func (stream, "#%ld\t; 0x%.4lx", value, value);
2531 break;
2532
2533 case 32:
2534 if (isfloat)
2535 {
2536 unsigned char valbytes[4];
2537 double fvalue;
2538
2539 /* Do this a byte at a time so we don't have to
2540 worry about the host's endianness. */
2541 valbytes[0] = value & 0xff;
2542 valbytes[1] = (value >> 8) & 0xff;
2543 valbytes[2] = (value >> 16) & 0xff;
2544 valbytes[3] = (value >> 24) & 0xff;
2545
2546 floatformat_to_double
2547 (&floatformat_ieee_single_little, valbytes,
2548 &fvalue);
2549
2550 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2551 value);
2552 }
2553 else
2554 func (stream, "#%ld\t; 0x%.8lx",
2555 (long) ((value & 0x80000000)
2556 ? value | ~0xffffffffl : value), value);
2557 break;
2558
2559 case 64:
2560 func (stream, "#0x%.8lx%.8lx", hival, value);
2561 break;
2562
2563 default:
2564 abort ();
2565 }
2566 }
2567 break;
2568
2569 case 'F':
2570 {
2571 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2572 int num = (given >> 8) & 0x3;
2573
2574 if (!num)
2575 func (stream, "{d%d}", regno);
2576 else if (num + regno >= 32)
2577 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2578 else
2579 func (stream, "{d%d-d%d}", regno, regno + num);
2580 }
2581 break;
2582
2583
2584 case '0': case '1': case '2': case '3': case '4':
2585 case '5': case '6': case '7': case '8': case '9':
2586 {
2587 int width;
2588 unsigned long value;
2589
2590 c = arm_decode_bitfield (c, given, &value, &width);
2591
2592 switch (*c)
2593 {
2594 case 'r':
2595 func (stream, "%s", arm_regnames[value]);
2596 break;
2597 case 'd':
2598 func (stream, "%ld", value);
2599 break;
2600 case 'e':
2601 func (stream, "%ld", (1ul << width) - value);
2602 break;
2603
2604 case 'S':
2605 case 'T':
2606 case 'U':
2607 /* various width encodings */
2608 {
2609 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2610 int limit;
2611 unsigned low, high;
2612
2613 c++;
2614 if (*c >= '0' && *c <= '9')
2615 limit = *c - '0';
2616 else if (*c >= 'a' && *c <= 'f')
2617 limit = *c - 'a' + 10;
2618 else
2619 abort ();
2620 low = limit >> 2;
2621 high = limit & 3;
2622
2623 if (value < low || value > high)
2624 func (stream, "<illegal width %d>", base << value);
2625 else
2626 func (stream, "%d", base << value);
2627 }
2628 break;
2629 case 'R':
2630 if (given & (1 << 6))
2631 goto Q;
2632 /* FALLTHROUGH */
2633 case 'D':
2634 func (stream, "d%ld", value);
2635 break;
2636 case 'Q':
2637 Q:
2638 if (value & 1)
2639 func (stream, "<illegal reg q%ld.5>", value >> 1);
2640 else
2641 func (stream, "q%ld", value >> 1);
2642 break;
2643
2644 case '`':
2645 c++;
2646 if (value == 0)
2647 func (stream, "%c", *c);
2648 break;
2649 case '\'':
2650 c++;
2651 if (value == ((1ul << width) - 1))
2652 func (stream, "%c", *c);
2653 break;
2654 case '?':
2655 func (stream, "%c", c[(1 << width) - (int)value]);
2656 c += 1 << width;
2657 break;
2658 default:
2659 abort ();
2660 }
2661 break;
2662
2663 default:
2664 abort ();
2665 }
2666 }
2667 }
2668 else
2669 func (stream, "%c", *c);
2670 }
47cbc7aa 2671 return true;
4b0f1a8b
PB
2672 }
2673 }
47cbc7aa 2674 return false;
4b0f1a8b
PB
2675}
2676
2677/* Print one ARM instruction from PC on INFO->STREAM. */
2678
2679static void
2680print_insn_arm_internal (bfd_vma pc, struct disassemble_info *info, long given)
2681{
2682 const struct opcode32 *insn;
2683 void *stream = info->stream;
2684 fprintf_ftype func = info->fprintf_func;
2685
47cbc7aa 2686 if (print_insn_coprocessor (pc, info, given, false))
4b0f1a8b
PB
2687 return;
2688
47cbc7aa 2689 if (print_insn_neon (info, given, false))
4b0f1a8b
PB
2690 return;
2691
2692 for (insn = arm_opcodes; insn->assembler; insn++)
2693 {
2694 if (insn->value == FIRST_IWMMXT_INSN
2695 && info->mach != bfd_mach_arm_XScale
2696 && info->mach != bfd_mach_arm_iWMMXt)
2697 insn = insn + IWMMXT_INSN_COUNT;
2698
2699 if ((given & insn->mask) == insn->value
2700 /* Special case: an instruction with all bits set in the condition field
2701 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2702 or by the catchall at the end of the table. */
2703 && ((given & 0xF0000000) != 0xF0000000
2704 || (insn->mask & 0xF0000000) == 0xF0000000
2705 || (insn->mask == 0 && insn->value == 0)))
2706 {
2707 const char *c;
2708
2709 for (c = insn->assembler; *c; c++)
2710 {
2711 if (*c == '%')
2712 {
2713 switch (*++c)
2714 {
2715 case '%':
2716 func (stream, "%%");
2717 break;
2718
2719 case 'a':
2720 print_arm_address (pc, info, given);
2721 break;
2722
2723 case 'P':
2724 /* Set P address bit and use normal address
2725 printing routine. */
2726 print_arm_address (pc, info, given | (1 << 24));
2727 break;
2728
2729 case 's':
2730 if ((given & 0x004f0000) == 0x004f0000)
2731 {
2732 /* PC relative with immediate offset. */
2733 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2734
2735 if ((given & 0x00800000) == 0)
2736 offset = -offset;
2737
2738 func (stream, "[pc, #%d]\t; ", offset);
2739 info->print_address_func (offset + pc + 8, info);
2740 }
2741 else
2742 {
2743 func (stream, "[%s",
2744 arm_regnames[(given >> 16) & 0xf]);
2745 if ((given & 0x01000000) != 0)
2746 {
2747 /* Pre-indexed. */
2748 if ((given & 0x00400000) == 0x00400000)
2749 {
2750 /* Immediate. */
2751 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2752 if (offset)
2753 func (stream, ", #%s%d",
2754 (((given & 0x00800000) == 0)
2755 ? "-" : ""), offset);
2756 }
2757 else
2758 {
2759 /* Register. */
2760 func (stream, ", %s%s",
2761 (((given & 0x00800000) == 0)
2762 ? "-" : ""),
2763 arm_regnames[given & 0xf]);
2764 }
2765
2766 func (stream, "]%s",
2767 ((given & 0x00200000) != 0) ? "!" : "");
2768 }
2769 else
2770 {
2771 /* Post-indexed. */
2772 if ((given & 0x00400000) == 0x00400000)
2773 {
2774 /* Immediate. */
2775 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2776 if (offset)
2777 func (stream, "], #%s%d",
2778 (((given & 0x00800000) == 0)
2779 ? "-" : ""), offset);
2780 else
2781 func (stream, "]");
2782 }
2783 else
2784 {
2785 /* Register. */
2786 func (stream, "], %s%s",
2787 (((given & 0x00800000) == 0)
2788 ? "-" : ""),
2789 arm_regnames[given & 0xf]);
2790 }
2791 }
2792 }
2793 break;
2794
2795 case 'b':
2796 {
2797 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2798 info->print_address_func (disp*4 + pc + 8, info);
2799 }
2800 break;
2801
2802 case 'c':
2803 if (((given >> 28) & 0xf) != 0xe)
2804 func (stream, "%s",
2805 arm_conditional [(given >> 28) & 0xf]);
2806 break;
2807
2808 case 'm':
2809 {
2810 int started = 0;
2811 int reg;
2812
2813 func (stream, "{");
2814 for (reg = 0; reg < 16; reg++)
2815 if ((given & (1 << reg)) != 0)
2816 {
2817 if (started)
2818 func (stream, ", ");
2819 started = 1;
2820 func (stream, "%s", arm_regnames[reg]);
2821 }
2822 func (stream, "}");
2823 }
2824 break;
2825
2826 case 'q':
2827 arm_decode_shift (given, func, stream, 0);
2828 break;
2829
2830 case 'o':
2831 if ((given & 0x02000000) != 0)
2832 {
2833 int rotate = (given & 0xf00) >> 7;
2834 int immed = (given & 0xff);
2835 immed = (((immed << (32 - rotate))
2836 | (immed >> rotate)) & 0xffffffff);
2837 func (stream, "#%d\t; 0x%x", immed, immed);
2838 }
2839 else
2840 arm_decode_shift (given, func, stream, 1);
2841 break;
2842
2843 case 'p':
2844 if ((given & 0x0000f000) == 0x0000f000)
2845 func (stream, "p");
2846 break;
2847
2848 case 't':
2849 if ((given & 0x01200000) == 0x00200000)
2850 func (stream, "t");
2851 break;
2852
2853 case 'A':
2854 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2855
2856 if ((given & (1 << 24)) != 0)
2857 {
2858 int offset = given & 0xff;
2859
2860 if (offset)
2861 func (stream, ", #%s%d]%s",
2862 ((given & 0x00800000) == 0 ? "-" : ""),
2863 offset * 4,
2864 ((given & 0x00200000) != 0 ? "!" : ""));
2865 else
2866 func (stream, "]");
2867 }
2868 else
2869 {
2870 int offset = given & 0xff;
2871
2872 func (stream, "]");
2873
2874 if (given & (1 << 21))
2875 {
2876 if (offset)
2877 func (stream, ", #%s%d",
2878 ((given & 0x00800000) == 0 ? "-" : ""),
2879 offset * 4);
2880 }
2881 else
2882 func (stream, ", {%d}", offset);
2883 }
2884 break;
2885
2886 case 'B':
2887 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2888 {
2889 bfd_vma address;
2890 bfd_vma offset = 0;
2891
2892 if (given & 0x00800000)
2893 /* Is signed, hi bits should be ones. */
2894 offset = (-1) ^ 0x00ffffff;
2895
2896 /* Offset is (SignExtend(offset field)<<2). */
2897 offset += given & 0x00ffffff;
2898 offset <<= 2;
2899 address = offset + pc + 8;
2900
2901 if (given & 0x01000000)
2902 /* H bit allows addressing to 2-byte boundaries. */
2903 address += 2;
2904
2905 info->print_address_func (address, info);
2906 }
2907 break;
2908
2909 case 'C':
2910 func (stream, "_");
2911 if (given & 0x80000)
2912 func (stream, "f");
2913 if (given & 0x40000)
2914 func (stream, "s");
2915 if (given & 0x20000)
2916 func (stream, "x");
2917 if (given & 0x10000)
2918 func (stream, "c");
2919 break;
2920
2921 case 'U':
2922 switch (given & 0xf)
2923 {
2924 case 0xf: func(stream, "sy"); break;
2925 case 0x7: func(stream, "un"); break;
2926 case 0xe: func(stream, "st"); break;
2927 case 0x6: func(stream, "unst"); break;
2928 default:
2929 func(stream, "#%d", (int)given & 0xf);
2930 break;
2931 }
2932 break;
2933
2934 case '0': case '1': case '2': case '3': case '4':
2935 case '5': case '6': case '7': case '8': case '9':
2936 {
2937 int width;
2938 unsigned long value;
2939
2940 c = arm_decode_bitfield (c, given, &value, &width);
2941
2942 switch (*c)
2943 {
2944 case 'r':
2945 func (stream, "%s", arm_regnames[value]);
2946 break;
2947 case 'd':
2948 func (stream, "%ld", value);
2949 break;
2950 case 'b':
2951 func (stream, "%ld", value * 8);
2952 break;
2953 case 'W':
2954 func (stream, "%ld", value + 1);
2955 break;
2956 case 'x':
2957 func (stream, "0x%08lx", value);
2958
2959 /* Some SWI instructions have special
2960 meanings. */
2961 if ((given & 0x0fffffff) == 0x0FF00000)
2962 func (stream, "\t; IMB");
2963 else if ((given & 0x0fffffff) == 0x0FF00001)
2964 func (stream, "\t; IMBRange");
2965 break;
2966 case 'X':
2967 func (stream, "%01lx", value & 0xf);
2968 break;
2969 case '`':
2970 c++;
2971 if (value == 0)
2972 func (stream, "%c", *c);
2973 break;
2974 case '\'':
2975 c++;
2976 if (value == ((1ul << width) - 1))
2977 func (stream, "%c", *c);
2978 break;
2979 case '?':
2980 func (stream, "%c", c[(1 << width) - (int)value]);
2981 c += 1 << width;
2982 break;
2983 default:
2984 abort ();
2985 }
2986 break;
2987
2988 case 'e':
2989 {
2990 int imm;
2991
2992 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2993 func (stream, "%d", imm);
2994 }
2995 break;
2996
2997 case 'E':
2998 /* LSB and WIDTH fields of BFI or BFC. The machine-
2999 language instruction encodes LSB and MSB. */
3000 {
3001 long msb = (given & 0x001f0000) >> 16;
3002 long lsb = (given & 0x00000f80) >> 7;
3003
3004 long width = msb - lsb + 1;
3005 if (width > 0)
3006 func (stream, "#%lu, #%lu", lsb, width);
3007 else
3008 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3009 }
3010 break;
3011
3012 case 'V':
3013 /* 16-bit unsigned immediate from a MOVT or MOVW
3014 instruction, encoded in bits 0:11 and 15:19. */
3015 {
3016 long hi = (given & 0x000f0000) >> 4;
3017 long lo = (given & 0x00000fff);
3018 long imm16 = hi | lo;
3019 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
3020 }
3021 break;
3022
3023 default:
3024 abort ();
3025 }
3026 }
3027 }
3028 else
3029 func (stream, "%c", *c);
3030 }
3031 return;
3032 }
3033 }
3034 abort ();
3035}
3036
3037/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3038
3039static void
3040print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3041{
3042 const struct opcode16 *insn;
3043 void *stream = info->stream;
3044 fprintf_ftype func = info->fprintf_func;
3045
3046 for (insn = thumb_opcodes; insn->assembler; insn++)
3047 if ((given & insn->mask) == insn->value)
3048 {
3049 const char *c = insn->assembler;
3050 for (; *c; c++)
3051 {
3052 int domaskpc = 0;
3053 int domasklr = 0;
3054
3055 if (*c != '%')
3056 {
3057 func (stream, "%c", *c);
3058 continue;
3059 }
3060
3061 switch (*++c)
3062 {
3063 case '%':
3064 func (stream, "%%");
3065 break;
3066
3067 case 'c':
3068 if (ifthen_state)
3069 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3070 break;
3071
3072 case 'C':
3073 if (ifthen_state)
3074 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3075 else
3076 func (stream, "s");
3077 break;
3078
3079 case 'I':
3080 {
3081 unsigned int tmp;
3082
3083 ifthen_next_state = given & 0xff;
3084 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3085 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3086 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3087 }
3088 break;
3089
3090 case 'x':
3091 if (ifthen_next_state)
3092 func (stream, "\t; unpredictable branch in IT block\n");
3093 break;
3094
3095 case 'X':
3096 if (ifthen_state)
3097 func (stream, "\t; unpredictable <IT:%s>",
3098 arm_conditional[IFTHEN_COND]);
3099 break;
3100
3101 case 'S':
3102 {
3103 long reg;
3104
3105 reg = (given >> 3) & 0x7;
3106 if (given & (1 << 6))
3107 reg += 8;
3108
3109 func (stream, "%s", arm_regnames[reg]);
3110 }
3111 break;
3112
3113 case 'D':
3114 {
3115 long reg;
3116
3117 reg = given & 0x7;
3118 if (given & (1 << 7))
3119 reg += 8;
3120
3121 func (stream, "%s", arm_regnames[reg]);
3122 }
3123 break;
3124
3125 case 'N':
3126 if (given & (1 << 8))
3127 domasklr = 1;
3128 /* Fall through. */
3129 case 'O':
3130 if (*c == 'O' && (given & (1 << 8)))
3131 domaskpc = 1;
3132 /* Fall through. */
3133 case 'M':
3134 {
3135 int started = 0;
3136 int reg;
3137
3138 func (stream, "{");
3139
3140 /* It would be nice if we could spot
3141 ranges, and generate the rS-rE format: */
3142 for (reg = 0; (reg < 8); reg++)
3143 if ((given & (1 << reg)) != 0)
3144 {
3145 if (started)
3146 func (stream, ", ");
3147 started = 1;
3148 func (stream, "%s", arm_regnames[reg]);
3149 }
3150
3151 if (domasklr)
3152 {
3153 if (started)
3154 func (stream, ", ");
3155 started = 1;
3156 func (stream, arm_regnames[14] /* "lr" */);
3157 }
3158
3159 if (domaskpc)
3160 {
3161 if (started)
3162 func (stream, ", ");
3163 func (stream, arm_regnames[15] /* "pc" */);
3164 }
aa0aa4fa 3165
4b0f1a8b
PB
3166 func (stream, "}");
3167 }
3168 break;
aa0aa4fa 3169
4b0f1a8b
PB
3170 case 'b':
3171 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3172 {
3173 bfd_vma address = (pc + 4
3174 + ((given & 0x00f8) >> 2)
3175 + ((given & 0x0200) >> 3));
3176 info->print_address_func (address, info);
3177 }
3178 break;
aa0aa4fa 3179
4b0f1a8b
PB
3180 case 's':
3181 /* Right shift immediate -- bits 6..10; 1-31 print
3182 as themselves, 0 prints as 32. */
3183 {
3184 long imm = (given & 0x07c0) >> 6;
3185 if (imm == 0)
3186 imm = 32;
3187 func (stream, "#%ld", imm);
3188 }
3189 break;
aa0aa4fa 3190
4b0f1a8b
PB
3191 case '0': case '1': case '2': case '3': case '4':
3192 case '5': case '6': case '7': case '8': case '9':
3193 {
3194 int bitstart = *c++ - '0';
3195 int bitend = 0;
3b46e624 3196
4b0f1a8b
PB
3197 while (*c >= '0' && *c <= '9')
3198 bitstart = (bitstart * 10) + *c++ - '0';
aa0aa4fa 3199
4b0f1a8b
PB
3200 switch (*c)
3201 {
3202 case '-':
3203 {
3204 long reg;
3205
3206 c++;
3207 while (*c >= '0' && *c <= '9')
3208 bitend = (bitend * 10) + *c++ - '0';
3209 if (!bitend)
3210 abort ();
3211 reg = given >> bitstart;
3212 reg &= (2 << (bitend - bitstart)) - 1;
3213 switch (*c)
3214 {
3215 case 'r':
3216 func (stream, "%s", arm_regnames[reg]);
3217 break;
3218
3219 case 'd':
3220 func (stream, "%ld", reg);
3221 break;
3222
3223 case 'H':
3224 func (stream, "%ld", reg << 1);
3225 break;
3226
3227 case 'W':
3228 func (stream, "%ld", reg << 2);
3229 break;
3230
3231 case 'a':
3232 /* PC-relative address -- the bottom two
3233 bits of the address are dropped
3234 before the calculation. */
3235 info->print_address_func
3236 (((pc + 4) & ~3) + (reg << 2), info);
3237 break;
3238
3239 case 'x':
3240 func (stream, "0x%04lx", reg);
3241 break;
3242
3243 case 'B':
3244 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3245 info->print_address_func (reg * 2 + pc + 4, info);
3246 break;
3247
3248 case 'c':
3249 func (stream, "%s", arm_conditional [reg]);
3250 break;
3251
3252 default:
3253 abort ();
3254 }
3255 }
3256 break;
3257
3258 case '\'':
3259 c++;
3260 if ((given & (1 << bitstart)) != 0)
3261 func (stream, "%c", *c);
3262 break;
3263
3264 case '?':
3265 ++c;
3266 if ((given & (1 << bitstart)) != 0)
3267 func (stream, "%c", *c++);
3268 else
3269 func (stream, "%c", *++c);
3270 break;
3271
3272 default:
3273 abort ();
3274 }
3275 }
3276 break;
3277
3278 default:
3279 abort ();
3280 }
3281 }
3282 return;
3283 }
aa0aa4fa
FB
3284
3285 /* No match. */
3286 abort ();
3287}
3288
4b0f1a8b
PB
3289/* Return the name of an V7M special register. */
3290static const char *
3291psr_name (int regno)
3292{
3293 switch (regno)
3294 {
3295 case 0: return "APSR";
3296 case 1: return "IAPSR";
3297 case 2: return "EAPSR";
3298 case 3: return "PSR";
3299 case 5: return "IPSR";
3300 case 6: return "EPSR";
3301 case 7: return "IEPSR";
3302 case 8: return "MSP";
3303 case 9: return "PSP";
3304 case 16: return "PRIMASK";
3305 case 17: return "BASEPRI";
3306 case 18: return "BASEPRI_MASK";
3307 case 19: return "FAULTMASK";
3308 case 20: return "CONTROL";
3309 default: return "<unknown>";
3310 }
3311}
3312
3313/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
aa0aa4fa 3314
4b0f1a8b
PB
3315static void
3316print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
aa0aa4fa 3317{
4b0f1a8b
PB
3318 const struct opcode32 *insn;
3319 void *stream = info->stream;
3320 fprintf_ftype func = info->fprintf_func;
3b46e624 3321
47cbc7aa 3322 if (print_insn_coprocessor (pc, info, given, true))
4b0f1a8b 3323 return;
5fafdf24 3324
47cbc7aa 3325 if (print_insn_neon (info, given, true))
4b0f1a8b 3326 return;
aa0aa4fa 3327
4b0f1a8b
PB
3328 for (insn = thumb32_opcodes; insn->assembler; insn++)
3329 if ((given & insn->mask) == insn->value)
3330 {
3331 const char *c = insn->assembler;
3332 for (; *c; c++)
aa0aa4fa 3333 {
4b0f1a8b
PB
3334 if (*c != '%')
3335 {
3336 func (stream, "%c", *c);
3337 continue;
3338 }
3339
3340 switch (*++c)
3341 {
3342 case '%':
3343 func (stream, "%%");
3344 break;
3345
3346 case 'c':
3347 if (ifthen_state)
3348 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3349 break;
3350
3351 case 'x':
3352 if (ifthen_next_state)
3353 func (stream, "\t; unpredictable branch in IT block\n");
3354 break;
3355
3356 case 'X':
3357 if (ifthen_state)
3358 func (stream, "\t; unpredictable <IT:%s>",
3359 arm_conditional[IFTHEN_COND]);
3360 break;
3361
3362 case 'I':
3363 {
3364 unsigned int imm12 = 0;
3365 imm12 |= (given & 0x000000ffu);
3366 imm12 |= (given & 0x00007000u) >> 4;
3367 imm12 |= (given & 0x04000000u) >> 15;
3368 func (stream, "#%u\t; 0x%x", imm12, imm12);
3369 }
3370 break;
3b46e624 3371
4b0f1a8b
PB
3372 case 'M':
3373 {
3374 unsigned int bits = 0, imm, imm8, mod;
3375 bits |= (given & 0x000000ffu);
3376 bits |= (given & 0x00007000u) >> 4;
3377 bits |= (given & 0x04000000u) >> 15;
3378 imm8 = (bits & 0x0ff);
3379 mod = (bits & 0xf00) >> 8;
3380 switch (mod)
3381 {
3382 case 0: imm = imm8; break;
3383 case 1: imm = ((imm8<<16) | imm8); break;
3384 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3385 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3386 default:
3387 mod = (bits & 0xf80) >> 7;
3388 imm8 = (bits & 0x07f) | 0x80;
3389 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3390 }
3391 func (stream, "#%u\t; 0x%x", imm, imm);
3392 }
3393 break;
3394
3395 case 'J':
3396 {
3397 unsigned int imm = 0;
3398 imm |= (given & 0x000000ffu);
3399 imm |= (given & 0x00007000u) >> 4;
3400 imm |= (given & 0x04000000u) >> 15;
3401 imm |= (given & 0x000f0000u) >> 4;
3402 func (stream, "#%u\t; 0x%x", imm, imm);
3403 }
3404 break;
3405
3406 case 'K':
3407 {
3408 unsigned int imm = 0;
3409 imm |= (given & 0x000f0000u) >> 16;
3410 imm |= (given & 0x00000ff0u) >> 0;
3411 imm |= (given & 0x0000000fu) << 12;
3412 func (stream, "#%u\t; 0x%x", imm, imm);
3413 }
3414 break;
3415
3416 case 'S':
3417 {
3418 unsigned int reg = (given & 0x0000000fu);
3419 unsigned int stp = (given & 0x00000030u) >> 4;
3420 unsigned int imm = 0;
3421 imm |= (given & 0x000000c0u) >> 6;
3422 imm |= (given & 0x00007000u) >> 10;
3423
3424 func (stream, "%s", arm_regnames[reg]);
3425 switch (stp)
3426 {
3427 case 0:
3428 if (imm > 0)
3429 func (stream, ", lsl #%u", imm);
3430 break;
3431
3432 case 1:
3433 if (imm == 0)
3434 imm = 32;
3435 func (stream, ", lsr #%u", imm);
3436 break;
3437
3438 case 2:
3439 if (imm == 0)
3440 imm = 32;
3441 func (stream, ", asr #%u", imm);
3442 break;
3443
3444 case 3:
3445 if (imm == 0)
3446 func (stream, ", rrx");
3447 else
3448 func (stream, ", ror #%u", imm);
3449 }
3450 }
3451 break;
3452
3453 case 'a':
3454 {
3455 unsigned int Rn = (given & 0x000f0000) >> 16;
3456 unsigned int U = (given & 0x00800000) >> 23;
3457 unsigned int op = (given & 0x00000f00) >> 8;
3458 unsigned int i12 = (given & 0x00000fff);
3459 unsigned int i8 = (given & 0x000000ff);
47cbc7aa 3460 bfd_boolean writeback = false, postind = false;
4b0f1a8b
PB
3461 int offset = 0;
3462
3463 func (stream, "[%s", arm_regnames[Rn]);
3464 if (U) /* 12-bit positive immediate offset */
3465 offset = i12;
3466 else if (Rn == 15) /* 12-bit negative immediate offset */
3467 offset = -(int)i12;
3468 else if (op == 0x0) /* shifted register offset */
3469 {
3470 unsigned int Rm = (i8 & 0x0f);
3471 unsigned int sh = (i8 & 0x30) >> 4;
3472 func (stream, ", %s", arm_regnames[Rm]);
3473 if (sh)
3474 func (stream, ", lsl #%u", sh);
3475 func (stream, "]");
3476 break;
3477 }
3478 else switch (op)
3479 {
3480 case 0xE: /* 8-bit positive immediate offset */
3481 offset = i8;
3482 break;
3483
3484 case 0xC: /* 8-bit negative immediate offset */
3485 offset = -i8;
3486 break;
3487
3488 case 0xF: /* 8-bit + preindex with wb */
3489 offset = i8;
47cbc7aa 3490 writeback = true;
4b0f1a8b
PB
3491 break;
3492
3493 case 0xD: /* 8-bit - preindex with wb */
3494 offset = -i8;
47cbc7aa 3495 writeback = true;
4b0f1a8b
PB
3496 break;
3497
3498 case 0xB: /* 8-bit + postindex */
3499 offset = i8;
47cbc7aa 3500 postind = true;
4b0f1a8b
PB
3501 break;
3502
3503 case 0x9: /* 8-bit - postindex */
3504 offset = -i8;
47cbc7aa 3505 postind = true;
4b0f1a8b
PB
3506 break;
3507
3508 default:
3509 func (stream, ", <undefined>]");
3510 goto skip;
3511 }
3512
3513 if (postind)
3514 func (stream, "], #%d", offset);
3515 else
3516 {
3517 if (offset)
3518 func (stream, ", #%d", offset);
3519 func (stream, writeback ? "]!" : "]");
3520 }
3521
3522 if (Rn == 15)
3523 {
3524 func (stream, "\t; ");
3525 info->print_address_func (((pc + 4) & ~3) + offset, info);
3526 }
3527 }
3528 skip:
3529 break;
3530
3531 case 'A':
3532 {
3533 unsigned int P = (given & 0x01000000) >> 24;
3534 unsigned int U = (given & 0x00800000) >> 23;
3535 unsigned int W = (given & 0x00400000) >> 21;
3536 unsigned int Rn = (given & 0x000f0000) >> 16;
3537 unsigned int off = (given & 0x000000ff);
3538
3539 func (stream, "[%s", arm_regnames[Rn]);
3540 if (P)
3541 {
3542 if (off || !U)
3543 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3544 func (stream, "]");
3545 if (W)
3546 func (stream, "!");
3547 }
3548 else
3549 {
3550 func (stream, "], ");
3551 if (W)
3552 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3553 else
3554 func (stream, "{%u}", off);
3555 }
3556 }
3557 break;
3558
3559 case 'w':
3560 {
3561 unsigned int Sbit = (given & 0x01000000) >> 24;
3562 unsigned int type = (given & 0x00600000) >> 21;
3563 switch (type)
3564 {
3565 case 0: func (stream, Sbit ? "sb" : "b"); break;
3566 case 1: func (stream, Sbit ? "sh" : "h"); break;
3567 case 2:
3568 if (Sbit)
3569 func (stream, "??");
3570 break;
3571 case 3:
3572 func (stream, "??");
3573 break;
3574 }
3575 }
3576 break;
3577
3578 case 'm':
3579 {
3580 int started = 0;
3581 int reg;
3582
3583 func (stream, "{");
3584 for (reg = 0; reg < 16; reg++)
3585 if ((given & (1 << reg)) != 0)
3586 {
3587 if (started)
3588 func (stream, ", ");
3589 started = 1;
3590 func (stream, "%s", arm_regnames[reg]);
3591 }
3592 func (stream, "}");
3593 }
3594 break;
3595
3596 case 'E':
3597 {
3598 unsigned int msb = (given & 0x0000001f);
3599 unsigned int lsb = 0;
3600 lsb |= (given & 0x000000c0u) >> 6;
3601 lsb |= (given & 0x00007000u) >> 10;
3602 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3603 }
3604 break;
3605
3606 case 'F':
3607 {
3608 unsigned int width = (given & 0x0000001f) + 1;
3609 unsigned int lsb = 0;
3610 lsb |= (given & 0x000000c0u) >> 6;
3611 lsb |= (given & 0x00007000u) >> 10;
3612 func (stream, "#%u, #%u", lsb, width);
3613 }
3614 break;
3615
3616 case 'b':
3617 {
3618 unsigned int S = (given & 0x04000000u) >> 26;
3619 unsigned int J1 = (given & 0x00002000u) >> 13;
3620 unsigned int J2 = (given & 0x00000800u) >> 11;
3621 int offset = 0;
3622
3623 offset |= !S << 20;
3624 offset |= J2 << 19;
3625 offset |= J1 << 18;
3626 offset |= (given & 0x003f0000) >> 4;
3627 offset |= (given & 0x000007ff) << 1;
3628 offset -= (1 << 20);
3629
3630 info->print_address_func (pc + 4 + offset, info);
3631 }
3632 break;
3633
3634 case 'B':
3635 {
3636 unsigned int S = (given & 0x04000000u) >> 26;
3637 unsigned int I1 = (given & 0x00002000u) >> 13;
3638 unsigned int I2 = (given & 0x00000800u) >> 11;
3639 int offset = 0;
3640
3641 offset |= !S << 24;
3642 offset |= !(I1 ^ S) << 23;
3643 offset |= !(I2 ^ S) << 22;
3644 offset |= (given & 0x03ff0000u) >> 4;
3645 offset |= (given & 0x000007ffu) << 1;
3646 offset -= (1 << 24);
3647 offset += pc + 4;
3648
3649 /* BLX target addresses are always word aligned. */
3650 if ((given & 0x00001000u) == 0)
3651 offset &= ~2u;
3652
3653 info->print_address_func (offset, info);
3654 }
3655 break;
3656
3657 case 's':
3658 {
3659 unsigned int shift = 0;
3660 shift |= (given & 0x000000c0u) >> 6;
3661 shift |= (given & 0x00007000u) >> 10;
3662 if (given & 0x00200000u)
3663 func (stream, ", asr #%u", shift);
3664 else if (shift)
3665 func (stream, ", lsl #%u", shift);
3666 /* else print nothing - lsl #0 */
3667 }
3668 break;
3669
3670 case 'R':
3671 {
3672 unsigned int rot = (given & 0x00000030) >> 4;
3673 if (rot)
3674 func (stream, ", ror #%u", rot * 8);
3675 }
3676 break;
3677
3678 case 'U':
3679 switch (given & 0xf)
3680 {
3681 case 0xf: func(stream, "sy"); break;
3682 case 0x7: func(stream, "un"); break;
3683 case 0xe: func(stream, "st"); break;
3684 case 0x6: func(stream, "unst"); break;
3685 default:
3686 func(stream, "#%d", (int)given & 0xf);
3687 break;
3688 }
3689 break;
3690
3691 case 'C':
3692 if ((given & 0xff) == 0)
3693 {
3694 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3695 if (given & 0x800)
3696 func (stream, "f");
3697 if (given & 0x400)
3698 func (stream, "s");
3699 if (given & 0x200)
3700 func (stream, "x");
3701 if (given & 0x100)
3702 func (stream, "c");
3703 }
3704 else
3705 {
3706 func (stream, psr_name (given & 0xff));
3707 }
3708 break;
3709
3710 case 'D':
3711 if ((given & 0xff) == 0)
3712 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3713 else
3714 func (stream, psr_name (given & 0xff));
3715 break;
3716
3717 case '0': case '1': case '2': case '3': case '4':
3718 case '5': case '6': case '7': case '8': case '9':
3719 {
3720 int width;
3721 unsigned long val;
3722
3723 c = arm_decode_bitfield (c, given, &val, &width);
3724
3725 switch (*c)
3726 {
3727 case 'd': func (stream, "%lu", val); break;
3728 case 'W': func (stream, "%lu", val * 4); break;
3729 case 'r': func (stream, "%s", arm_regnames[val]); break;
3730
3731 case 'c':
3732 func (stream, "%s", arm_conditional[val]);
3733 break;
3734
3735 case '\'':
3736 c++;
3737 if (val == ((1ul << width) - 1))
3738 func (stream, "%c", *c);
3739 break;
3740
3741 case '`':
3742 c++;
3743 if (val == 0)
3744 func (stream, "%c", *c);
3745 break;
3746
3747 case '?':
3748 func (stream, "%c", c[(1 << width) - (int)val]);
3749 c += 1 << width;
3750 break;
3751
3752 default:
3753 abort ();
3754 }
3755 }
3756 break;
3b46e624 3757
4b0f1a8b
PB
3758 default:
3759 abort ();
3760 }
3761 }
3762 return;
3763 }
3764
3765 /* No match. */
3766 abort ();
aa0aa4fa
FB
3767}
3768
4b0f1a8b 3769/* Print data bytes on INFO->STREAM. */
aa0aa4fa
FB
3770
3771static void
4b0f1a8b
PB
3772print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
3773 long given)
aa0aa4fa 3774{
4b0f1a8b
PB
3775 switch (info->bytes_per_chunk)
3776 {
3777 case 1:
3778 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3779 break;
3780 case 2:
3781 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3782 break;
3783 case 4:
3784 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3785 break;
3786 default:
3787 abort ();
3788 }
3789}
aa0aa4fa 3790
4b0f1a8b
PB
3791/* Search back through the insn stream to determine if this instruction is
3792 conditionally executed. */
3793static void
3794find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3795 bfd_boolean little)
3796{
3797 unsigned char b[2];
3798 unsigned int insn;
3799 int status;
3800 /* COUNT is twice the number of instructions seen. It will be odd if we
3801 just crossed an instruction boundary. */
3802 int count;
3803 int it_count;
3804 unsigned int seen_it;
3805 bfd_vma addr;
3806
3807 ifthen_address = pc;
3808 ifthen_state = 0;
3809
3810 addr = pc;
3811 count = 1;
3812 it_count = 0;
3813 seen_it = 0;
3814 /* Scan backwards looking for IT instructions, keeping track of where
3815 instruction boundaries are. We don't know if something is actually an
3816 IT instruction until we find a definite instruction boundary. */
3817 for (;;)
aa0aa4fa 3818 {
4b0f1a8b
PB
3819 if (addr == 0 || info->symbol_at_address_func(addr, info))
3820 {
3821 /* A symbol must be on an instruction boundary, and will not
3822 be within an IT block. */
3823 if (seen_it && (count & 1))
3824 break;
3825
3826 return;
3827 }
3828 addr -= 2;
3829 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3830 if (status)
3831 return;
aa0aa4fa 3832
4b0f1a8b
PB
3833 if (little)
3834 insn = (b[0]) | (b[1] << 8);
3835 else
3836 insn = (b[1]) | (b[0] << 8);
3837 if (seen_it)
3838 {
3839 if ((insn & 0xf800) < 0xe800)
3840 {
3841 /* Addr + 2 is an instruction boundary. See if this matches
3842 the expected boundary based on the position of the last
3843 IT candidate. */
3844 if (count & 1)
3845 break;
3846 seen_it = 0;
3847 }
3848 }
3849 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
aa0aa4fa 3850 {
4b0f1a8b
PB
3851 /* This could be an IT instruction. */
3852 seen_it = insn;
3853 it_count = count >> 1;
aa0aa4fa 3854 }
4b0f1a8b
PB
3855 if ((insn & 0xf800) >= 0xe800)
3856 count++;
aa0aa4fa 3857 else
4b0f1a8b
PB
3858 count = (count + 2) | 1;
3859 /* IT blocks contain at most 4 instructions. */
3860 if (count >= 8 && !seen_it)
3861 return;
aa0aa4fa 3862 }
4b0f1a8b
PB
3863 /* We found an IT instruction. */
3864 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3865 if ((ifthen_state & 0xf) == 0)
3866 ifthen_state = 0;
aa0aa4fa
FB
3867}
3868
3869/* NOTE: There are no checks in these routines that
3870 the relevant number of data bytes exist. */
3871
3872int
4b0f1a8b 3873print_insn_arm (bfd_vma pc, struct disassemble_info *info)
aa0aa4fa 3874{
4b0f1a8b
PB
3875 unsigned char b[4];
3876 long given;
3877 int status;
47cbc7aa
JQ
3878 int is_thumb = false;
3879 int is_data = false;
4b0f1a8b
PB
3880 unsigned int size = 4;
3881 void (*printer) (bfd_vma, struct disassemble_info *, long);
3882#if 0
47cbc7aa 3883 bfd_boolean found = false;
aa0aa4fa
FB
3884
3885 if (info->disassembler_options)
3886 {
3887 parse_disassembler_options (info->disassembler_options);
3b46e624 3888
aa0aa4fa
FB
3889 /* To avoid repeated parsing of these options, we remove them here. */
3890 info->disassembler_options = NULL;
3891 }
3b46e624 3892
4b0f1a8b
PB
3893 /* First check the full symtab for a mapping symbol, even if there
3894 are no usable non-mapping symbols for this address. */
3895 if (info->symtab != NULL
3896 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
c2d551ff 3897 {
4b0f1a8b
PB
3898 bfd_vma addr;
3899 int n;
3900 int last_sym = -1;
3901 enum map_type type = MAP_ARM;
3902
3903 if (pc <= last_mapping_addr)
3904 last_mapping_sym = -1;
3905 is_thumb = (last_type == MAP_THUMB);
47cbc7aa 3906 found = false;
4b0f1a8b
PB
3907 /* Start scanning at the start of the function, or wherever
3908 we finished last time. */
3909 n = info->symtab_pos + 1;
3910 if (n < last_mapping_sym)
3911 n = last_mapping_sym;
3912
3913 /* Scan up to the location being disassembled. */
3914 for (; n < info->symtab_size; n++)
3915 {
3916 addr = bfd_asymbol_value (info->symtab[n]);
3917 if (addr > pc)
3918 break;
3919 if ((info->section == NULL
3920 || info->section == info->symtab[n]->section)
3921 && get_sym_code_type (info, n, &type))
3922 {
3923 last_sym = n;
47cbc7aa 3924 found = true;
4b0f1a8b
PB
3925 }
3926 }
3927
3928 if (!found)
3929 {
3930 n = info->symtab_pos;
3931 if (n < last_mapping_sym - 1)
3932 n = last_mapping_sym - 1;
3933
3934 /* No mapping symbol found at this address. Look backwards
3935 for a preceeding one. */
3936 for (; n >= 0; n--)
3937 {
3938 if (get_sym_code_type (info, n, &type))
3939 {
3940 last_sym = n;
47cbc7aa 3941 found = true;
4b0f1a8b
PB
3942 break;
3943 }
3944 }
3945 }
3946
3947 last_mapping_sym = last_sym;
3948 last_type = type;
3949 is_thumb = (last_type == MAP_THUMB);
3950 is_data = (last_type == MAP_DATA);
3951
3952 /* Look a little bit ahead to see if we should print out
3953 two or four bytes of data. If there's a symbol,
3954 mapping or otherwise, after two bytes then don't
3955 print more. */
3956 if (is_data)
3957 {
3958 size = 4 - (pc & 3);
3959 for (n = last_sym + 1; n < info->symtab_size; n++)
3960 {
3961 addr = bfd_asymbol_value (info->symtab[n]);
3962 if (addr > pc)
3963 {
3964 if (addr - pc < size)
3965 size = addr - pc;
3966 break;
3967 }
3968 }
3969 /* If the next symbol is after three bytes, we need to
3970 print only part of the data, so that we can use either
3971 .byte or .short. */
3972 if (size == 3)
3973 size = (pc & 1) ? 1 : 2;
3974 }
c2d551ff 3975 }
3b46e624 3976
4b0f1a8b 3977 if (info->symbols != NULL)
aa0aa4fa
FB
3978 {
3979 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3980 {
3981 coff_symbol_type * cs;
3b46e624 3982
aa0aa4fa
FB
3983 cs = coffsymbol (*info->symbols);
3984 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
3985 || cs->native->u.syment.n_sclass == C_THUMBSTAT
3986 || cs->native->u.syment.n_sclass == C_THUMBLABEL
3987 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
3988 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
3989 }
4b0f1a8b
PB
3990 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
3991 && !found)
aa0aa4fa 3992 {
4b0f1a8b
PB
3993 /* If no mapping symbol has been found then fall back to the type
3994 of the function symbol. */
aa0aa4fa
FB
3995 elf_symbol_type * es;
3996 unsigned int type;
3b46e624 3997
aa0aa4fa
FB
3998 es = *(elf_symbol_type **)(info->symbols);
3999 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3b46e624 4000
aa0aa4fa
FB
4001 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4002 }
4003 }
4b0f1a8b
PB
4004#else
4005 int little;
3b46e624 4006
aa0aa4fa 4007 little = (info->endian == BFD_ENDIAN_LITTLE);
4b0f1a8b
PB
4008 is_thumb |= (pc & 1);
4009 pc &= ~(bfd_vma)1;
4010#endif
aa0aa4fa 4011
4b0f1a8b 4012 if (force_thumb)
47cbc7aa 4013 is_thumb = true;
3b46e624 4014
4b0f1a8b 4015 info->bytes_per_line = 4;
3b46e624 4016
4b0f1a8b
PB
4017 if (is_data)
4018 {
4019 int i;
4020
4021 /* size was already set above. */
4022 info->bytes_per_chunk = size;
4023 printer = print_insn_data;
3b46e624 4024
4b0f1a8b
PB
4025 status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
4026 given = 0;
4027 if (little)
4028 for (i = size - 1; i >= 0; i--)
4029 given = b[i] | (given << 8);
4030 else
4031 for (i = 0; i < (int) size; i++)
4032 given = b[i] | (given << 8);
4033 }
4034 else if (!is_thumb)
4035 {
4036 /* In ARM mode endianness is a straightforward issue: the instruction
4037 is four bytes long and is either ordered 0123 or 3210. */
4038 printer = print_insn_arm_internal;
4039 info->bytes_per_chunk = 4;
4040 size = 4;
4041
4042 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4043 if (little)
4044 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4045 else
4046 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
aa0aa4fa
FB
4047 }
4048 else
4049 {
4b0f1a8b
PB
4050 /* In Thumb mode we have the additional wrinkle of two
4051 instruction lengths. Fortunately, the bits that determine
4052 the length of the current instruction are always to be found
4053 in the first two bytes. */
4054 printer = print_insn_thumb16;
4055 info->bytes_per_chunk = 2;
4056 size = 2;
4057
4058 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4059 if (little)
4060 given = (b[0]) | (b[1] << 8);
4061 else
4062 given = (b[1]) | (b[0] << 8);
3b46e624 4063
4b0f1a8b 4064 if (!status)
aa0aa4fa 4065 {
4b0f1a8b
PB
4066 /* These bit patterns signal a four-byte Thumb
4067 instruction. */
4068 if ((given & 0xF800) == 0xF800
4069 || (given & 0xF800) == 0xF000
4070 || (given & 0xF800) == 0xE800)
aa0aa4fa 4071 {
4b0f1a8b
PB
4072 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4073 if (little)
4074 given = (b[0]) | (b[1] << 8) | (given << 16);
4075 else
4076 given = (b[1]) | (b[0] << 8) | (given << 16);
3b46e624 4077
4b0f1a8b
PB
4078 printer = print_insn_thumb32;
4079 size = 4;
aa0aa4fa 4080 }
4b0f1a8b
PB
4081 }
4082
4083 if (ifthen_address != pc)
4084 find_ifthen_state(pc, info, little);
4085
4086 if (ifthen_state)
4087 {
4088 if ((ifthen_state & 0xf) == 0x8)
4089 ifthen_next_state = 0;
aa0aa4fa 4090 else
4b0f1a8b
PB
4091 ifthen_next_state = (ifthen_state & 0xe0)
4092 | ((ifthen_state & 0xf) << 1);
aa0aa4fa 4093 }
aa0aa4fa 4094 }
3b46e624 4095
4b0f1a8b
PB
4096 if (status)
4097 {
4098 info->memory_error_func (status, pc, info);
4099 return -1;
4100 }
aa0aa4fa
FB
4101 if (info->flags & INSN_HAS_RELOC)
4102 /* If the instruction has a reloc associated with it, then
4103 the offset field in the instruction will actually be the
4104 addend for the reloc. (We are using REL type relocs).
4105 In such cases, we can ignore the pc when computing
4106 addresses, since the addend is not currently pc-relative. */
4107 pc = 0;
aa0aa4fa 4108
4b0f1a8b
PB
4109 printer (pc, info, given);
4110
4111 if (is_thumb)
4112 {
4113 ifthen_state = ifthen_next_state;
4114 ifthen_address += size;
4115 }
4116 return size;
aa0aa4fa 4117}