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