1/* Instruction printing code for the ARM
2   Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3   2007, Free Software Foundation, Inc.
4   Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5   Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7   This file is part of libopcodes.
8
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.
13
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.
18
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
21
22/* Start of qemu specific additions.  Mostly this is stub definitions
23   for things we don't care about.  */
24
25#include "dis-asm.h"
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
63/* Assume host uses ieee float.  */
64static void floatformat_to_double (unsigned char *data, double *dest)
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
80
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.  */
90};
91
92struct opcode16
93{
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.  */
97};
98
99/* print_insn_coprocessor recognizes the following format control codes:
100
101   %%			%
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
116   %<bitfield>d		print the bitfield in decimal
117   %<bitfield>k		print immediate for VFPv3 conversion instruction
118   %<bitfield>x		print the bitfield in hex
119   %<bitfield>X		print the bitfield as 1 hex digit without leading "0x"
120   %<bitfield>f		print a floating point constant if >7 else a
121			floating point register
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.
129			  Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
130   %z<code>		print a double precision VFP reg
131			  Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
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
784   %a			print address for ldr/str instruction
785   %s                   print address for ldr/str halfword/signextend instruction
786   %b			print branch destination
787   %c			print condition code (always bits 28-31)
788   %m			print register mask for ldm/stm instruction
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
793   %C			print the PSR sub type.
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
1072   %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
1073   %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
1074   %<bitfield>I         print bitfield as a signed decimal
1075   				(top bit of range being the sign bit)
1076   %N                   print Thumb register mask (with LR)
1077   %O                   print Thumb register mask (with PC)
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
1088   %<bitfield>H         print (bitfield * 2) as a decimal
1089   %<bitfield>W         print (bitfield * 4) as a decimal
1090   %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
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.  */
1095
1096static const struct opcode16 thumb_opcodes[] =
1097{
1098  /* Thumb instructions.  */
1099
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
1126  /* ARM V5 ISA extends Thumb.  */
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)"},
1132  /* Format 4.  */
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"},
1149  /* format 13 */
1150  {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1151  {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1152  /* format 5 */
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"},
1157  /* format 14 */
1158  {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1159  {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1160  /* format 2 */
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"},
1165  /* format 8 */
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]"},
1169  /* format 7 */
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]"},
1172  /* format 1 */
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"},
1176  /* format 3 */
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"},
1181  /* format 6 */
1182  {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1183  /* format 9 */
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]"},
1188  /* format 10 */
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]"},
1191  /* format 11 */
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]"},
1194  /* format 12 */
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"},
1197  /* format 15 */
1198  {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1199  {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1200  /* format 17 */
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}
1214};
1215
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};
1469
1470static const char *const arm_conditional[] =
1471{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1472 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1473
1474static const char *const arm_fp_const[] =
1475{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1476
1477static const char *const arm_shift[] =
1478{"lsl", "lsr", "asr", "ror"};
1479
1480typedef struct
1481{
1482  const char *name;
1483  const char *description;
1484  const char *reg_names[16];
1485}
1486arm_regname;
1487
1488static const arm_regname regnames[] =
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",
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"
1512};
1513
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;
1526
1527#define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1528#define arm_regnames      regnames[regname_selected].reg_names
1529
1530static bfd_boolean force_thumb = false;
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};
1547
1548enum map_type last_type;
1549int last_mapping_sym = -1;
1550bfd_vma last_mapping_addr = 0;
1551
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
1589static void
1590arm_decode_shift (long given, fprintf_function func, void *stream,
1591		  int print_shift)
1592{
1593  func (stream, "%s", arm_regnames[given & 0xf]);
1594
1595  if ((given & 0xff0) != 0)
1596    {
1597      if ((given & 0x10) == 0)
1598	{
1599	  int amount = (given & 0xf80) >> 7;
1600	  int shift = (given & 0x60) >> 5;
1601
1602	  if (amount == 0)
1603	    {
1604	      if (shift == 3)
1605		{
1606		  func (stream, ", rrx");
1607		  return;
1608		}
1609
1610	      amount = 32;
1611	    }
1612
1613	  if (print_shift)
1614	    func (stream, ", %s #%d", arm_shift[shift], amount);
1615	  else
1616	    func (stream, ", #%d", amount);
1617	}
1618      else if (print_shift)
1619	func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1620	      arm_regnames[(given & 0xf00) >> 8]);
1621      else
1622	func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1623    }
1624}
1625
1626/* Print one coprocessor instruction on INFO->STREAM.
1627   Return true if the instuction matched, false if this is not a
1628   recognised coprocessor instruction.  */
1629
1630static bfd_boolean
1631print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1632			bfd_boolean thumb)
1633{
1634  const struct opcode32 *insn;
1635  void *stream = info->stream;
1636  fprintf_function func = info->fprintf_func;
1637  unsigned long mask;
1638  unsigned long value;
1639  int cond;
1640
1641  for (insn = coprocessor_opcodes; insn->assembler; insn++)
1642    {
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)
1680	{
1681	  const char *c;
1682
1683	  for (c = insn->assembler; *c; c++)
1684	    {
1685	      if (*c == '%')
1686		{
1687		  switch (*++c)
1688		    {
1689		    case '%':
1690		      func (stream, "%%");
1691		      break;
1692
1693		    case 'A':
1694		      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1695
1696		      if ((given & (1 << 24)) != 0)
1697			{
1698			  int offset = given & 0xff;
1699
1700			  if (offset)
1701			    func (stream, ", #%s%d]%s",
1702				  ((given & 0x00800000) == 0 ? "-" : ""),
1703				  offset * 4,
1704				  ((given & 0x00200000) != 0 ? "!" : ""));
1705			  else
1706			    func (stream, "]");
1707			}
1708		      else
1709			{
1710			  int offset = given & 0xff;
1711
1712			  func (stream, "]");
1713
1714			  if (given & (1 << 21))
1715			    {
1716			      if (offset)
1717				func (stream, ", #%s%d",
1718				      ((given & 0x00800000) == 0 ? "-" : ""),
1719				      offset * 4);
1720			    }
1721			  else
1722			    func (stream, ", {%d}", offset);
1723			}
1724		      break;
1725
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;
1739
1740		    case 'C':
1741		      {
1742			int rn = (given >> 16) & 0xf;
1743			int offset = (given & 0xff) * 4;
1744			int add = (given >> 23) & 1;
1745
1746			func (stream, "[%s", arm_regnames[rn]);
1747
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;
1765
1766		    case 'c':
1767		      func (stream, "%s", arm_conditional[cond]);
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
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;
1805
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
1857		    case '0': case '1': case '2': case '3': case '4':
1858		    case '5': case '6': case '7': case '8': case '9':
1859		      {
1860			int width;
1861			unsigned long value;
1862
1863			c = arm_decode_bitfield (c, given, &value, &width);
1864
1865			switch (*c)
1866			  {
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;
1895
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;
1902
1903			  case 'g':
1904			    func (stream, "%s", iwmmxt_regnames[value]);
1905			    break;
1906			  case 'G':
1907			    func (stream, "%s", iwmmxt_cregnames[value]);
1908			    break;
1909
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;
1932
1933		      case 'y':
1934		      case 'z':
1935			{
1936			  int single = *c++ == 'y';
1937			  int regno;
1938
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)
1947				{
1948				  regno <<= 1;
1949				  regno += (given >> 5) & 1;
1950				}
1951                              else
1952                                regno += ((given >> 5) & 1) << 4;
1953			      break;
1954
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;
1965
1966			    case '2': /* Sn, Dn */
1967			      regno = (given >> 16) & 0x0000000f;
1968			      if (single)
1969				{
1970				  regno <<= 1;
1971				  regno += (given >> 7) & 1;
1972				}
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)
1981				{
1982				  regno <<= 1;
1983				  regno += (given >> 22) & 1;
1984				}
1985                              else
1986                                regno += ((given >> 22) & 1) << 4;
1987			      break;
1988
1989			    default:
1990			      abort ();
1991			    }
1992
1993			  func (stream, "%c%d", single ? 's' : 'd', regno);
1994
1995			  if (*c == '3')
1996			    {
1997			      int count = given & 0xff;
1998
1999			      if (single == 0)
2000				count >>= 1;
2001
2002			      if (--count)
2003				{
2004				  func (stream, "-%c%d",
2005					single ? 's' : 'd',
2006					regno + count);
2007				}
2008
2009			      func (stream, "}");
2010			    }
2011			  else if (*c == '4')
2012			    func (stream, ", %c%d}", single ? 's' : 'd',
2013				  regno + 1);
2014			}
2015			break;
2016
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:
2025			    break;
2026			  }
2027			break;
2028
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;
2037
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;
2045
2046			  func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2047
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;
2064
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];
2072
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;
2082
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, "!");
2096			      break;
2097
2098			    default:
2099			      func (stream, "INVALID");
2100			    }
2101			}
2102			break;
2103
2104		      case 'i':
2105			{
2106			  long imm5;
2107			  imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2108			  func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2109			}
2110			break;
2111
2112		      default:
2113			abort ();
2114		      }
2115		    }
2116		}
2117	      else
2118		func (stream, "%c", *c);
2119	    }
2120	  return true;
2121	}
2122    }
2123  return false;
2124}
2125
2126static void
2127print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2128{
2129  void *stream = info->stream;
2130  fprintf_function func = info->fprintf_func;
2131
2132  if (((given & 0x000f0000) == 0x000f0000)
2133      && ((given & 0x02000000) == 0))
2134    {
2135      int offset = given & 0xfff;
2136
2137      func (stream, "[pc");
2138
2139      if (given & 0x01000000)
2140	{
2141	  if ((given & 0x00800000) == 0)
2142	    offset = - offset;
2143
2144	  /* Pre-indexed.  */
2145	  func (stream, ", #%d]", offset);
2146
2147	  offset += pc + 8;
2148
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);
2160
2161	  /* ie ignore the offset.  */
2162	  offset = pc + 8;
2163	}
2164
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	    }
2189
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.
2217   Return true if the instuction matched, false if this is not a
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_function 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
2243	return false;
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)
2333                                return false;
2334                              if (size > 0)
2335                                {
2336                                  if ((idx_align & amask) == amask)
2337                                    align = 8 << size;
2338                                  else if ((idx_align & amask) != 0)
2339                                    return false;
2340                                }
2341                              }
2342                            break;
2343
2344                          case 2:
2345                            if (size == 2 && (idx_align & 2) != 0)
2346                              return false;
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)
2353                              return false;
2354                            break;
2355
2356                          case 4:
2357                            if (size == 2)
2358                              {
2359                                if ((idx_align & 3) == 3)
2360                                  return false;
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			    break;
2519			  }
2520                        switch (size)
2521                          {
2522                          case 8:
2523			    func (stream, "#%ld\t; 0x%.2lx", value, value);
2524                            break;
2525
2526                          case 16:
2527                            func (stream, "#%ld\t; 0x%.4lx", value, value);
2528                            break;
2529
2530                          case 32:
2531                            if (isfloat)
2532                              {
2533                                unsigned char valbytes[4];
2534                                double fvalue;
2535
2536                                /* Do this a byte at a time so we don't have to
2537                                   worry about the host's endianness.  */
2538                                valbytes[0] = value & 0xff;
2539                                valbytes[1] = (value >> 8) & 0xff;
2540                                valbytes[2] = (value >> 16) & 0xff;
2541                                valbytes[3] = (value >> 24) & 0xff;
2542
2543                                floatformat_to_double (valbytes, &fvalue);
2544
2545                                func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2546                                      value);
2547                              }
2548                            else
2549                              func (stream, "#%ld\t; 0x%.8lx",
2550				(long) ((value & 0x80000000)
2551					? value | ~0xffffffffl : value), value);
2552                            break;
2553
2554                          case 64:
2555                            func (stream, "#0x%.8lx%.8lx", hival, value);
2556                            break;
2557
2558                          default:
2559                            abort ();
2560                          }
2561		      }
2562		      break;
2563
2564		    case 'F':
2565		      {
2566			int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2567			int num = (given >> 8) & 0x3;
2568
2569			if (!num)
2570			  func (stream, "{d%d}", regno);
2571			else if (num + regno >= 32)
2572			  func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2573			else
2574			  func (stream, "{d%d-d%d}", regno, regno + num);
2575		      }
2576		      break;
2577
2578
2579		    case '0': case '1': case '2': case '3': case '4':
2580		    case '5': case '6': case '7': case '8': case '9':
2581		      {
2582			int width;
2583			unsigned long value;
2584
2585			c = arm_decode_bitfield (c, given, &value, &width);
2586
2587			switch (*c)
2588			  {
2589			  case 'r':
2590			    func (stream, "%s", arm_regnames[value]);
2591			    break;
2592			  case 'd':
2593			    func (stream, "%ld", value);
2594			    break;
2595			  case 'e':
2596			    func (stream, "%ld", (1ul << width) - value);
2597			    break;
2598
2599			  case 'S':
2600			  case 'T':
2601			  case 'U':
2602			    /* various width encodings */
2603			    {
2604			      int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2605			      int limit;
2606			      unsigned low, high;
2607
2608			      c++;
2609			      if (*c >= '0' && *c <= '9')
2610				limit = *c - '0';
2611			      else if (*c >= 'a' && *c <= 'f')
2612				limit = *c - 'a' + 10;
2613			      else
2614				abort ();
2615			      low = limit >> 2;
2616			      high = limit & 3;
2617
2618			      if (value < low || value > high)
2619				func (stream, "<illegal width %d>", base << value);
2620			      else
2621				func (stream, "%d", base << value);
2622			    }
2623			    break;
2624			  case 'R':
2625			    if (given & (1 << 6))
2626			      goto Q;
2627			    /* FALLTHROUGH */
2628			  case 'D':
2629			    func (stream, "d%ld", value);
2630			    break;
2631			  case 'Q':
2632			  Q:
2633			    if (value & 1)
2634			      func (stream, "<illegal reg q%ld.5>", value >> 1);
2635			    else
2636			      func (stream, "q%ld", value >> 1);
2637			    break;
2638
2639			  case '`':
2640			    c++;
2641			    if (value == 0)
2642			      func (stream, "%c", *c);
2643			    break;
2644			  case '\'':
2645			    c++;
2646			    if (value == ((1ul << width) - 1))
2647			      func (stream, "%c", *c);
2648			    break;
2649			  case '?':
2650			    func (stream, "%c", c[(1 << width) - (int)value]);
2651			    c += 1 << width;
2652			    break;
2653			  default:
2654			    abort ();
2655			  }
2656			break;
2657
2658		      default:
2659			abort ();
2660		      }
2661		    }
2662		}
2663	      else
2664		func (stream, "%c", *c);
2665	    }
2666	  return true;
2667	}
2668    }
2669  return false;
2670}
2671
2672/* Print one ARM instruction from PC on INFO->STREAM.  */
2673
2674static void
2675print_insn_arm_internal (bfd_vma pc, struct disassemble_info *info, long given)
2676{
2677  const struct opcode32 *insn;
2678  void *stream = info->stream;
2679  fprintf_function func = info->fprintf_func;
2680
2681  if (print_insn_coprocessor (pc, info, given, false))
2682    return;
2683
2684  if (print_insn_neon (info, given, false))
2685    return;
2686
2687  for (insn = arm_opcodes; insn->assembler; insn++)
2688    {
2689      if (insn->value == FIRST_IWMMXT_INSN
2690	  && info->mach != bfd_mach_arm_XScale
2691	  && info->mach != bfd_mach_arm_iWMMXt)
2692	insn = insn + IWMMXT_INSN_COUNT;
2693
2694      if ((given & insn->mask) == insn->value
2695	  /* Special case: an instruction with all bits set in the condition field
2696	     (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2697	     or by the catchall at the end of the table.  */
2698	  && ((given & 0xF0000000) != 0xF0000000
2699	      || (insn->mask & 0xF0000000) == 0xF0000000
2700	      || (insn->mask == 0 && insn->value == 0)))
2701	{
2702	  const char *c;
2703
2704	  for (c = insn->assembler; *c; c++)
2705	    {
2706	      if (*c == '%')
2707		{
2708		  switch (*++c)
2709		    {
2710		    case '%':
2711		      func (stream, "%%");
2712		      break;
2713
2714		    case 'a':
2715		      print_arm_address (pc, info, given);
2716		      break;
2717
2718		    case 'P':
2719		      /* Set P address bit and use normal address
2720			 printing routine.  */
2721		      print_arm_address (pc, info, given | (1 << 24));
2722		      break;
2723
2724		    case 's':
2725                      if ((given & 0x004f0000) == 0x004f0000)
2726			{
2727                          /* PC relative with immediate offset.  */
2728			  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2729
2730			  if ((given & 0x00800000) == 0)
2731			    offset = -offset;
2732
2733			  func (stream, "[pc, #%d]\t; ", offset);
2734			  info->print_address_func (offset + pc + 8, info);
2735			}
2736		      else
2737			{
2738			  func (stream, "[%s",
2739				arm_regnames[(given >> 16) & 0xf]);
2740			  if ((given & 0x01000000) != 0)
2741			    {
2742                              /* Pre-indexed.  */
2743			      if ((given & 0x00400000) == 0x00400000)
2744				{
2745                                  /* Immediate.  */
2746                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2747				  if (offset)
2748				    func (stream, ", #%s%d",
2749					  (((given & 0x00800000) == 0)
2750					   ? "-" : ""), offset);
2751				}
2752			      else
2753				{
2754                                  /* Register.  */
2755				  func (stream, ", %s%s",
2756					(((given & 0x00800000) == 0)
2757					 ? "-" : ""),
2758                                        arm_regnames[given & 0xf]);
2759				}
2760
2761			      func (stream, "]%s",
2762				    ((given & 0x00200000) != 0) ? "!" : "");
2763			    }
2764			  else
2765			    {
2766                              /* Post-indexed.  */
2767			      if ((given & 0x00400000) == 0x00400000)
2768				{
2769                                  /* Immediate.  */
2770                                  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2771				  if (offset)
2772				    func (stream, "], #%s%d",
2773					  (((given & 0x00800000) == 0)
2774					   ? "-" : ""), offset);
2775				  else
2776				    func (stream, "]");
2777				}
2778			      else
2779				{
2780                                  /* Register.  */
2781				  func (stream, "], %s%s",
2782					(((given & 0x00800000) == 0)
2783					 ? "-" : ""),
2784                                        arm_regnames[given & 0xf]);
2785				}
2786			    }
2787			}
2788		      break;
2789
2790		    case 'b':
2791		      {
2792			int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2793			info->print_address_func (disp*4 + pc + 8, info);
2794		      }
2795		      break;
2796
2797		    case 'c':
2798		      if (((given >> 28) & 0xf) != 0xe)
2799			func (stream, "%s",
2800			      arm_conditional [(given >> 28) & 0xf]);
2801		      break;
2802
2803		    case 'm':
2804		      {
2805			int started = 0;
2806			int reg;
2807
2808			func (stream, "{");
2809			for (reg = 0; reg < 16; reg++)
2810			  if ((given & (1 << reg)) != 0)
2811			    {
2812			      if (started)
2813				func (stream, ", ");
2814			      started = 1;
2815			      func (stream, "%s", arm_regnames[reg]);
2816			    }
2817			func (stream, "}");
2818		      }
2819		      break;
2820
2821		    case 'q':
2822		      arm_decode_shift (given, func, stream, 0);
2823		      break;
2824
2825		    case 'o':
2826		      if ((given & 0x02000000) != 0)
2827			{
2828			  int rotate = (given & 0xf00) >> 7;
2829			  int immed = (given & 0xff);
2830			  immed = (((immed << (32 - rotate))
2831				    | (immed >> rotate)) & 0xffffffff);
2832			  func (stream, "#%d\t; 0x%x", immed, immed);
2833			}
2834		      else
2835			arm_decode_shift (given, func, stream, 1);
2836		      break;
2837
2838		    case 'p':
2839		      if ((given & 0x0000f000) == 0x0000f000)
2840			func (stream, "p");
2841		      break;
2842
2843		    case 't':
2844		      if ((given & 0x01200000) == 0x00200000)
2845			func (stream, "t");
2846		      break;
2847
2848		    case 'A':
2849		      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2850
2851		      if ((given & (1 << 24)) != 0)
2852			{
2853			  int offset = given & 0xff;
2854
2855			  if (offset)
2856			    func (stream, ", #%s%d]%s",
2857				  ((given & 0x00800000) == 0 ? "-" : ""),
2858				  offset * 4,
2859				  ((given & 0x00200000) != 0 ? "!" : ""));
2860			  else
2861			    func (stream, "]");
2862			}
2863		      else
2864			{
2865			  int offset = given & 0xff;
2866
2867			  func (stream, "]");
2868
2869			  if (given & (1 << 21))
2870			    {
2871			      if (offset)
2872				func (stream, ", #%s%d",
2873				      ((given & 0x00800000) == 0 ? "-" : ""),
2874				      offset * 4);
2875			    }
2876			  else
2877			    func (stream, ", {%d}", offset);
2878			}
2879		      break;
2880
2881		    case 'B':
2882		      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
2883		      {
2884			bfd_vma address;
2885			bfd_vma offset = 0;
2886
2887			if (given & 0x00800000)
2888			  /* Is signed, hi bits should be ones.  */
2889			  offset = (-1) ^ 0x00ffffff;
2890
2891			/* Offset is (SignExtend(offset field)<<2).  */
2892			offset += given & 0x00ffffff;
2893			offset <<= 2;
2894			address = offset + pc + 8;
2895
2896			if (given & 0x01000000)
2897			  /* H bit allows addressing to 2-byte boundaries.  */
2898			  address += 2;
2899
2900		        info->print_address_func (address, info);
2901		      }
2902		      break;
2903
2904		    case 'C':
2905		      func (stream, "_");
2906		      if (given & 0x80000)
2907			func (stream, "f");
2908		      if (given & 0x40000)
2909			func (stream, "s");
2910		      if (given & 0x20000)
2911			func (stream, "x");
2912		      if (given & 0x10000)
2913			func (stream, "c");
2914		      break;
2915
2916		    case 'U':
2917		      switch (given & 0xf)
2918			{
2919			case 0xf: func(stream, "sy"); break;
2920			case 0x7: func(stream, "un"); break;
2921			case 0xe: func(stream, "st"); break;
2922			case 0x6: func(stream, "unst"); break;
2923			default:
2924			  func(stream, "#%d", (int)given & 0xf);
2925			  break;
2926			}
2927		      break;
2928
2929		    case '0': case '1': case '2': case '3': case '4':
2930		    case '5': case '6': case '7': case '8': case '9':
2931		      {
2932			int width;
2933			unsigned long value;
2934
2935			c = arm_decode_bitfield (c, given, &value, &width);
2936
2937			switch (*c)
2938			  {
2939			  case 'r':
2940			    func (stream, "%s", arm_regnames[value]);
2941			    break;
2942			  case 'd':
2943			    func (stream, "%ld", value);
2944			    break;
2945			  case 'b':
2946			    func (stream, "%ld", value * 8);
2947			    break;
2948			  case 'W':
2949			    func (stream, "%ld", value + 1);
2950			    break;
2951			  case 'x':
2952			    func (stream, "0x%08lx", value);
2953
2954			    /* Some SWI instructions have special
2955			       meanings.  */
2956			    if ((given & 0x0fffffff) == 0x0FF00000)
2957			      func (stream, "\t; IMB");
2958			    else if ((given & 0x0fffffff) == 0x0FF00001)
2959			      func (stream, "\t; IMBRange");
2960			    break;
2961			  case 'X':
2962			    func (stream, "%01lx", value & 0xf);
2963			    break;
2964			  case '`':
2965			    c++;
2966			    if (value == 0)
2967			      func (stream, "%c", *c);
2968			    break;
2969			  case '\'':
2970			    c++;
2971			    if (value == ((1ul << width) - 1))
2972			      func (stream, "%c", *c);
2973			    break;
2974			  case '?':
2975			    func (stream, "%c", c[(1 << width) - (int)value]);
2976			    c += 1 << width;
2977			    break;
2978			  default:
2979			    abort ();
2980			  }
2981			break;
2982
2983		      case 'e':
2984			{
2985			  int imm;
2986
2987			  imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2988			  func (stream, "%d", imm);
2989			}
2990			break;
2991
2992		      case 'E':
2993			/* LSB and WIDTH fields of BFI or BFC.  The machine-
2994			   language instruction encodes LSB and MSB.  */
2995			{
2996			  long msb = (given & 0x001f0000) >> 16;
2997			  long lsb = (given & 0x00000f80) >> 7;
2998
2999			  long width = msb - lsb + 1;
3000			  if (width > 0)
3001			    func (stream, "#%lu, #%lu", lsb, width);
3002			  else
3003			    func (stream, "(invalid: %lu:%lu)", lsb, msb);
3004			}
3005			break;
3006
3007		      case 'V':
3008			/* 16-bit unsigned immediate from a MOVT or MOVW
3009			   instruction, encoded in bits 0:11 and 15:19.  */
3010			{
3011			  long hi = (given & 0x000f0000) >> 4;
3012			  long lo = (given & 0x00000fff);
3013			  long imm16 = hi | lo;
3014			  func (stream, "#%lu\t; 0x%lx", imm16, imm16);
3015			}
3016			break;
3017
3018		      default:
3019			abort ();
3020		      }
3021		    }
3022		}
3023	      else
3024		func (stream, "%c", *c);
3025	    }
3026	  return;
3027	}
3028    }
3029  abort ();
3030}
3031
3032/* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
3033
3034static void
3035print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3036{
3037  const struct opcode16 *insn;
3038  void *stream = info->stream;
3039  fprintf_function func = info->fprintf_func;
3040
3041  for (insn = thumb_opcodes; insn->assembler; insn++)
3042    if ((given & insn->mask) == insn->value)
3043      {
3044	const char *c = insn->assembler;
3045	for (; *c; c++)
3046	  {
3047	    int domaskpc = 0;
3048	    int domasklr = 0;
3049
3050	    if (*c != '%')
3051	      {
3052		func (stream, "%c", *c);
3053		continue;
3054	      }
3055
3056	    switch (*++c)
3057	      {
3058	      case '%':
3059		func (stream, "%%");
3060		break;
3061
3062	      case 'c':
3063		if (ifthen_state)
3064		  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3065		break;
3066
3067	      case 'C':
3068		if (ifthen_state)
3069		  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3070		else
3071		  func (stream, "s");
3072		break;
3073
3074	      case 'I':
3075		{
3076		  unsigned int tmp;
3077
3078		  ifthen_next_state = given & 0xff;
3079		  for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3080		    func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3081		  func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3082		}
3083		break;
3084
3085	      case 'x':
3086		if (ifthen_next_state)
3087		  func (stream, "\t; unpredictable branch in IT block\n");
3088		break;
3089
3090	      case 'X':
3091		if (ifthen_state)
3092		  func (stream, "\t; unpredictable <IT:%s>",
3093			arm_conditional[IFTHEN_COND]);
3094		break;
3095
3096	      case 'S':
3097		{
3098		  long reg;
3099
3100		  reg = (given >> 3) & 0x7;
3101		  if (given & (1 << 6))
3102		    reg += 8;
3103
3104		  func (stream, "%s", arm_regnames[reg]);
3105		}
3106		break;
3107
3108	      case 'D':
3109		{
3110		  long reg;
3111
3112		  reg = given & 0x7;
3113		  if (given & (1 << 7))
3114		    reg += 8;
3115
3116		  func (stream, "%s", arm_regnames[reg]);
3117		}
3118		break;
3119
3120	      case 'N':
3121		if (given & (1 << 8))
3122		  domasklr = 1;
3123		/* Fall through.  */
3124	      case 'O':
3125		if (*c == 'O' && (given & (1 << 8)))
3126		  domaskpc = 1;
3127		/* Fall through.  */
3128	      case 'M':
3129		{
3130		  int started = 0;
3131		  int reg;
3132
3133		  func (stream, "{");
3134
3135		  /* It would be nice if we could spot
3136		     ranges, and generate the rS-rE format: */
3137		  for (reg = 0; (reg < 8); reg++)
3138		    if ((given & (1 << reg)) != 0)
3139		      {
3140			if (started)
3141			  func (stream, ", ");
3142			started = 1;
3143			func (stream, "%s", arm_regnames[reg]);
3144		      }
3145
3146		  if (domasklr)
3147		    {
3148		      if (started)
3149			func (stream, ", ");
3150		      started = 1;
3151		      func (stream, "%s", arm_regnames[14] /* "lr" */);
3152		    }
3153
3154		  if (domaskpc)
3155		    {
3156		      if (started)
3157			func (stream, ", ");
3158		      func (stream, "%s", arm_regnames[15] /* "pc" */);
3159		    }
3160
3161		  func (stream, "}");
3162		}
3163		break;
3164
3165	      case 'b':
3166		/* Print ARM V6T2 CZB address: pc+4+6 bits.  */
3167		{
3168		  bfd_vma address = (pc + 4
3169				     + ((given & 0x00f8) >> 2)
3170				     + ((given & 0x0200) >> 3));
3171		  info->print_address_func (address, info);
3172		}
3173		break;
3174
3175	      case 's':
3176		/* Right shift immediate -- bits 6..10; 1-31 print
3177		   as themselves, 0 prints as 32.  */
3178		{
3179		  long imm = (given & 0x07c0) >> 6;
3180		  if (imm == 0)
3181		    imm = 32;
3182		  func (stream, "#%ld", imm);
3183		}
3184		break;
3185
3186	      case '0': case '1': case '2': case '3': case '4':
3187	      case '5': case '6': case '7': case '8': case '9':
3188		{
3189		  int bitstart = *c++ - '0';
3190		  int bitend = 0;
3191
3192		  while (*c >= '0' && *c <= '9')
3193		    bitstart = (bitstart * 10) + *c++ - '0';
3194
3195		  switch (*c)
3196		    {
3197		    case '-':
3198		      {
3199			long reg;
3200
3201			c++;
3202			while (*c >= '0' && *c <= '9')
3203			  bitend = (bitend * 10) + *c++ - '0';
3204			if (!bitend)
3205			  abort ();
3206			reg = given >> bitstart;
3207			reg &= (2 << (bitend - bitstart)) - 1;
3208			switch (*c)
3209			  {
3210			  case 'r':
3211			    func (stream, "%s", arm_regnames[reg]);
3212			    break;
3213
3214			  case 'd':
3215			    func (stream, "%ld", reg);
3216			    break;
3217
3218			  case 'H':
3219			    func (stream, "%ld", reg << 1);
3220			    break;
3221
3222			  case 'W':
3223			    func (stream, "%ld", reg << 2);
3224			    break;
3225
3226			  case 'a':
3227			    /* PC-relative address -- the bottom two
3228			       bits of the address are dropped
3229			       before the calculation.  */
3230			    info->print_address_func
3231			      (((pc + 4) & ~3) + (reg << 2), info);
3232			    break;
3233
3234			  case 'x':
3235			    func (stream, "0x%04lx", reg);
3236			    break;
3237
3238			  case 'B':
3239			    reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3240			    info->print_address_func (reg * 2 + pc + 4, info);
3241			    break;
3242
3243			  case 'c':
3244			    func (stream, "%s", arm_conditional [reg]);
3245			    break;
3246
3247			  default:
3248			    abort ();
3249			  }
3250		      }
3251		      break;
3252
3253		    case '\'':
3254		      c++;
3255		      if ((given & (1 << bitstart)) != 0)
3256			func (stream, "%c", *c);
3257		      break;
3258
3259		    case '?':
3260		      ++c;
3261		      if ((given & (1 << bitstart)) != 0)
3262			func (stream, "%c", *c++);
3263		      else
3264			func (stream, "%c", *++c);
3265		      break;
3266
3267		    default:
3268		      abort ();
3269		    }
3270		}
3271		break;
3272
3273	      default:
3274		abort ();
3275	      }
3276	  }
3277	return;
3278      }
3279
3280  /* No match.  */
3281  abort ();
3282}
3283
3284/* Return the name of an V7M special register.  */
3285static const char *
3286psr_name (int regno)
3287{
3288  switch (regno)
3289    {
3290    case 0: return "APSR";
3291    case 1: return "IAPSR";
3292    case 2: return "EAPSR";
3293    case 3: return "PSR";
3294    case 5: return "IPSR";
3295    case 6: return "EPSR";
3296    case 7: return "IEPSR";
3297    case 8: return "MSP";
3298    case 9: return "PSP";
3299    case 16: return "PRIMASK";
3300    case 17: return "BASEPRI";
3301    case 18: return "BASEPRI_MASK";
3302    case 19: return "FAULTMASK";
3303    case 20: return "CONTROL";
3304    default: return "<unknown>";
3305    }
3306}
3307
3308/* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
3309
3310static void
3311print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3312{
3313  const struct opcode32 *insn;
3314  void *stream = info->stream;
3315  fprintf_function func = info->fprintf_func;
3316
3317  if (print_insn_coprocessor (pc, info, given, true))
3318    return;
3319
3320  if (print_insn_neon (info, given, true))
3321    return;
3322
3323  for (insn = thumb32_opcodes; insn->assembler; insn++)
3324    if ((given & insn->mask) == insn->value)
3325      {
3326	const char *c = insn->assembler;
3327	for (; *c; c++)
3328	  {
3329	    if (*c != '%')
3330	      {
3331		func (stream, "%c", *c);
3332		continue;
3333	      }
3334
3335	    switch (*++c)
3336	      {
3337	      case '%':
3338		func (stream, "%%");
3339		break;
3340
3341	      case 'c':
3342		if (ifthen_state)
3343		  func (stream, "%s", arm_conditional[IFTHEN_COND]);
3344		break;
3345
3346	      case 'x':
3347		if (ifthen_next_state)
3348		  func (stream, "\t; unpredictable branch in IT block\n");
3349		break;
3350
3351	      case 'X':
3352		if (ifthen_state)
3353		  func (stream, "\t; unpredictable <IT:%s>",
3354			arm_conditional[IFTHEN_COND]);
3355		break;
3356
3357	      case 'I':
3358		{
3359		  unsigned int imm12 = 0;
3360		  imm12 |= (given & 0x000000ffu);
3361		  imm12 |= (given & 0x00007000u) >> 4;
3362		  imm12 |= (given & 0x04000000u) >> 15;
3363		  func (stream, "#%u\t; 0x%x", imm12, imm12);
3364		}
3365		break;
3366
3367	      case 'M':
3368		{
3369		  unsigned int bits = 0, imm, imm8, mod;
3370		  bits |= (given & 0x000000ffu);
3371		  bits |= (given & 0x00007000u) >> 4;
3372		  bits |= (given & 0x04000000u) >> 15;
3373		  imm8 = (bits & 0x0ff);
3374		  mod = (bits & 0xf00) >> 8;
3375		  switch (mod)
3376		    {
3377		    case 0: imm = imm8; break;
3378		    case 1: imm = ((imm8<<16) | imm8); break;
3379		    case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3380		    case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3381		    default:
3382		      mod  = (bits & 0xf80) >> 7;
3383		      imm8 = (bits & 0x07f) | 0x80;
3384		      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3385		    }
3386		  func (stream, "#%u\t; 0x%x", imm, imm);
3387		}
3388		break;
3389
3390	      case 'J':
3391		{
3392		  unsigned int imm = 0;
3393		  imm |= (given & 0x000000ffu);
3394		  imm |= (given & 0x00007000u) >> 4;
3395		  imm |= (given & 0x04000000u) >> 15;
3396		  imm |= (given & 0x000f0000u) >> 4;
3397		  func (stream, "#%u\t; 0x%x", imm, imm);
3398		}
3399		break;
3400
3401	      case 'K':
3402		{
3403		  unsigned int imm = 0;
3404		  imm |= (given & 0x000f0000u) >> 16;
3405		  imm |= (given & 0x00000ff0u) >> 0;
3406		  imm |= (given & 0x0000000fu) << 12;
3407		  func (stream, "#%u\t; 0x%x", imm, imm);
3408		}
3409		break;
3410
3411	      case 'S':
3412		{
3413		  unsigned int reg = (given & 0x0000000fu);
3414		  unsigned int stp = (given & 0x00000030u) >> 4;
3415		  unsigned int imm = 0;
3416		  imm |= (given & 0x000000c0u) >> 6;
3417		  imm |= (given & 0x00007000u) >> 10;
3418
3419		  func (stream, "%s", arm_regnames[reg]);
3420		  switch (stp)
3421		    {
3422		    case 0:
3423		      if (imm > 0)
3424			func (stream, ", lsl #%u", imm);
3425		      break;
3426
3427		    case 1:
3428		      if (imm == 0)
3429			imm = 32;
3430		      func (stream, ", lsr #%u", imm);
3431		      break;
3432
3433		    case 2:
3434		      if (imm == 0)
3435			imm = 32;
3436		      func (stream, ", asr #%u", imm);
3437		      break;
3438
3439		    case 3:
3440		      if (imm == 0)
3441			func (stream, ", rrx");
3442		      else
3443			func (stream, ", ror #%u", imm);
3444		    }
3445		}
3446		break;
3447
3448	      case 'a':
3449		{
3450		  unsigned int Rn  = (given & 0x000f0000) >> 16;
3451		  unsigned int U   = (given & 0x00800000) >> 23;
3452		  unsigned int op  = (given & 0x00000f00) >> 8;
3453		  unsigned int i12 = (given & 0x00000fff);
3454		  unsigned int i8  = (given & 0x000000ff);
3455		  bfd_boolean writeback = false, postind = false;
3456		  int offset = 0;
3457
3458		  func (stream, "[%s", arm_regnames[Rn]);
3459		  if (U) /* 12-bit positive immediate offset */
3460		    offset = i12;
3461		  else if (Rn == 15) /* 12-bit negative immediate offset */
3462		    offset = -(int)i12;
3463		  else if (op == 0x0) /* shifted register offset */
3464		    {
3465		      unsigned int Rm = (i8 & 0x0f);
3466		      unsigned int sh = (i8 & 0x30) >> 4;
3467		      func (stream, ", %s", arm_regnames[Rm]);
3468		      if (sh)
3469			func (stream, ", lsl #%u", sh);
3470		      func (stream, "]");
3471		      break;
3472		    }
3473		  else switch (op)
3474		    {
3475		    case 0xE:  /* 8-bit positive immediate offset */
3476		      offset = i8;
3477		      break;
3478
3479		    case 0xC:  /* 8-bit negative immediate offset */
3480		      offset = -i8;
3481		      break;
3482
3483		    case 0xF:  /* 8-bit + preindex with wb */
3484		      offset = i8;
3485		      writeback = true;
3486		      break;
3487
3488		    case 0xD:  /* 8-bit - preindex with wb */
3489		      offset = -i8;
3490		      writeback = true;
3491		      break;
3492
3493		    case 0xB:  /* 8-bit + postindex */
3494		      offset = i8;
3495		      postind = true;
3496		      break;
3497
3498		    case 0x9:  /* 8-bit - postindex */
3499		      offset = -i8;
3500		      postind = true;
3501		      break;
3502
3503		    default:
3504		      func (stream, ", <undefined>]");
3505		      goto skip;
3506		    }
3507
3508		  if (postind)
3509		    func (stream, "], #%d", offset);
3510		  else
3511		    {
3512		      if (offset)
3513			func (stream, ", #%d", offset);
3514		      func (stream, writeback ? "]!" : "]");
3515		    }
3516
3517		  if (Rn == 15)
3518		    {
3519		      func (stream, "\t; ");
3520		      info->print_address_func (((pc + 4) & ~3) + offset, info);
3521		    }
3522		}
3523	      skip:
3524		break;
3525
3526	      case 'A':
3527		{
3528		  unsigned int P   = (given & 0x01000000) >> 24;
3529		  unsigned int U   = (given & 0x00800000) >> 23;
3530		  unsigned int W   = (given & 0x00400000) >> 21;
3531		  unsigned int Rn  = (given & 0x000f0000) >> 16;
3532		  unsigned int off = (given & 0x000000ff);
3533
3534		  func (stream, "[%s", arm_regnames[Rn]);
3535		  if (P)
3536		    {
3537		      if (off || !U)
3538			func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3539		      func (stream, "]");
3540		      if (W)
3541			func (stream, "!");
3542		    }
3543		  else
3544		    {
3545		      func (stream, "], ");
3546		      if (W)
3547			func (stream, "#%c%u", U ? '+' : '-', off * 4);
3548		      else
3549			func (stream, "{%u}", off);
3550		    }
3551		}
3552		break;
3553
3554	      case 'w':
3555		{
3556		  unsigned int Sbit = (given & 0x01000000) >> 24;
3557		  unsigned int type = (given & 0x00600000) >> 21;
3558		  switch (type)
3559		    {
3560		    case 0: func (stream, Sbit ? "sb" : "b"); break;
3561		    case 1: func (stream, Sbit ? "sh" : "h"); break;
3562		    case 2:
3563		      if (Sbit)
3564			func (stream, "??");
3565		      break;
3566		    case 3:
3567		      func (stream, "??");
3568		      break;
3569		    }
3570		}
3571		break;
3572
3573	      case 'm':
3574		{
3575		  int started = 0;
3576		  int reg;
3577
3578		  func (stream, "{");
3579		  for (reg = 0; reg < 16; reg++)
3580		    if ((given & (1 << reg)) != 0)
3581		      {
3582			if (started)
3583			  func (stream, ", ");
3584			started = 1;
3585			func (stream, "%s", arm_regnames[reg]);
3586		      }
3587		  func (stream, "}");
3588		}
3589		break;
3590
3591	      case 'E':
3592		{
3593		  unsigned int msb = (given & 0x0000001f);
3594		  unsigned int lsb = 0;
3595		  lsb |= (given & 0x000000c0u) >> 6;
3596		  lsb |= (given & 0x00007000u) >> 10;
3597		  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3598		}
3599		break;
3600
3601	      case 'F':
3602		{
3603		  unsigned int width = (given & 0x0000001f) + 1;
3604		  unsigned int lsb = 0;
3605		  lsb |= (given & 0x000000c0u) >> 6;
3606		  lsb |= (given & 0x00007000u) >> 10;
3607		  func (stream, "#%u, #%u", lsb, width);
3608		}
3609		break;
3610
3611	      case 'b':
3612		{
3613		  unsigned int S = (given & 0x04000000u) >> 26;
3614		  unsigned int J1 = (given & 0x00002000u) >> 13;
3615		  unsigned int J2 = (given & 0x00000800u) >> 11;
3616		  int offset = 0;
3617
3618		  offset |= !S << 20;
3619		  offset |= J2 << 19;
3620		  offset |= J1 << 18;
3621		  offset |= (given & 0x003f0000) >> 4;
3622		  offset |= (given & 0x000007ff) << 1;
3623		  offset -= (1 << 20);
3624
3625		  info->print_address_func (pc + 4 + offset, info);
3626		}
3627		break;
3628
3629	      case 'B':
3630		{
3631		  unsigned int S = (given & 0x04000000u) >> 26;
3632		  unsigned int I1 = (given & 0x00002000u) >> 13;
3633		  unsigned int I2 = (given & 0x00000800u) >> 11;
3634		  int offset = 0;
3635
3636		  offset |= !S << 24;
3637		  offset |= !(I1 ^ S) << 23;
3638		  offset |= !(I2 ^ S) << 22;
3639		  offset |= (given & 0x03ff0000u) >> 4;
3640		  offset |= (given & 0x000007ffu) << 1;
3641		  offset -= (1 << 24);
3642		  offset += pc + 4;
3643
3644		  /* BLX target addresses are always word aligned.  */
3645		  if ((given & 0x00001000u) == 0)
3646		      offset &= ~2u;
3647
3648		  info->print_address_func (offset, info);
3649		}
3650		break;
3651
3652	      case 's':
3653		{
3654		  unsigned int shift = 0;
3655		  shift |= (given & 0x000000c0u) >> 6;
3656		  shift |= (given & 0x00007000u) >> 10;
3657		  if (given & 0x00200000u)
3658		    func (stream, ", asr #%u", shift);
3659		  else if (shift)
3660		    func (stream, ", lsl #%u", shift);
3661		  /* else print nothing - lsl #0 */
3662		}
3663		break;
3664
3665	      case 'R':
3666		{
3667		  unsigned int rot = (given & 0x00000030) >> 4;
3668		  if (rot)
3669		    func (stream, ", ror #%u", rot * 8);
3670		}
3671		break;
3672
3673	      case 'U':
3674		switch (given & 0xf)
3675		  {
3676		  case 0xf: func(stream, "sy"); break;
3677		  case 0x7: func(stream, "un"); break;
3678		  case 0xe: func(stream, "st"); break;
3679		  case 0x6: func(stream, "unst"); break;
3680		  default:
3681		    func(stream, "#%d", (int)given & 0xf);
3682		    break;
3683		  }
3684		break;
3685
3686	      case 'C':
3687		if ((given & 0xff) == 0)
3688		  {
3689		    func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3690		    if (given & 0x800)
3691		      func (stream, "f");
3692		    if (given & 0x400)
3693		      func (stream, "s");
3694		    if (given & 0x200)
3695		      func (stream, "x");
3696		    if (given & 0x100)
3697		      func (stream, "c");
3698		  }
3699		else
3700		  {
3701		    func (stream, "%s", psr_name (given & 0xff));
3702		  }
3703		break;
3704
3705	      case 'D':
3706		if ((given & 0xff) == 0)
3707		  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3708		else
3709		  func (stream, "%s", psr_name (given & 0xff));
3710		break;
3711
3712	      case '0': case '1': case '2': case '3': case '4':
3713	      case '5': case '6': case '7': case '8': case '9':
3714		{
3715		  int width;
3716		  unsigned long val;
3717
3718		  c = arm_decode_bitfield (c, given, &val, &width);
3719
3720		  switch (*c)
3721		    {
3722		    case 'd': func (stream, "%lu", val); break;
3723		    case 'W': func (stream, "%lu", val * 4); break;
3724		    case 'r': func (stream, "%s", arm_regnames[val]); break;
3725
3726		    case 'c':
3727		      func (stream, "%s", arm_conditional[val]);
3728		      break;
3729
3730		    case '\'':
3731		      c++;
3732		      if (val == ((1ul << width) - 1))
3733			func (stream, "%c", *c);
3734		      break;
3735
3736		    case '`':
3737		      c++;
3738		      if (val == 0)
3739			func (stream, "%c", *c);
3740		      break;
3741
3742		    case '?':
3743		      func (stream, "%c", c[(1 << width) - (int)val]);
3744		      c += 1 << width;
3745		      break;
3746
3747		    default:
3748		      abort ();
3749		    }
3750		}
3751		break;
3752
3753	      default:
3754		abort ();
3755	      }
3756	  }
3757	return;
3758      }
3759
3760  /* No match.  */
3761  abort ();
3762}
3763
3764/* Print data bytes on INFO->STREAM.  */
3765
3766static void
3767print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
3768		 long given)
3769{
3770  switch (info->bytes_per_chunk)
3771    {
3772    case 1:
3773      info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3774      break;
3775    case 2:
3776      info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3777      break;
3778    case 4:
3779      info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3780      break;
3781    default:
3782      abort ();
3783    }
3784}
3785
3786/* Search back through the insn stream to determine if this instruction is
3787   conditionally executed.  */
3788static void
3789find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3790		   bfd_boolean little)
3791{
3792  unsigned char b[2];
3793  unsigned int insn;
3794  int status;
3795  /* COUNT is twice the number of instructions seen.  It will be odd if we
3796     just crossed an instruction boundary.  */
3797  int count;
3798  int it_count;
3799  unsigned int seen_it;
3800  bfd_vma addr;
3801
3802  ifthen_address = pc;
3803  ifthen_state = 0;
3804
3805  addr = pc;
3806  count = 1;
3807  it_count = 0;
3808  seen_it = 0;
3809  /* Scan backwards looking for IT instructions, keeping track of where
3810     instruction boundaries are.  We don't know if something is actually an
3811     IT instruction until we find a definite instruction boundary.  */
3812  for (;;)
3813    {
3814      if (addr == 0 || info->symbol_at_address_func(addr, info))
3815	{
3816	  /* A symbol must be on an instruction boundary, and will not
3817	     be within an IT block.  */
3818	  if (seen_it && (count & 1))
3819	    break;
3820
3821	  return;
3822	}
3823      addr -= 2;
3824      status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3825      if (status)
3826	return;
3827
3828      if (little)
3829	insn = (b[0]) | (b[1] << 8);
3830      else
3831	insn = (b[1]) | (b[0] << 8);
3832      if (seen_it)
3833	{
3834	  if ((insn & 0xf800) < 0xe800)
3835	    {
3836	      /* Addr + 2 is an instruction boundary.  See if this matches
3837	         the expected boundary based on the position of the last
3838		 IT candidate.  */
3839	      if (count & 1)
3840		break;
3841	      seen_it = 0;
3842	    }
3843	}
3844      if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3845	{
3846	  /* This could be an IT instruction.  */
3847	  seen_it = insn;
3848	  it_count = count >> 1;
3849	}
3850      if ((insn & 0xf800) >= 0xe800)
3851	count++;
3852      else
3853	count = (count + 2) | 1;
3854      /* IT blocks contain at most 4 instructions.  */
3855      if (count >= 8 && !seen_it)
3856	return;
3857    }
3858  /* We found an IT instruction.  */
3859  ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3860  if ((ifthen_state & 0xf) == 0)
3861    ifthen_state = 0;
3862}
3863
3864/* NOTE: There are no checks in these routines that
3865   the relevant number of data bytes exist.  */
3866
3867int
3868print_insn_arm (bfd_vma pc, struct disassemble_info *info)
3869{
3870  unsigned char b[4];
3871  long		given;
3872  int           status;
3873  int           is_thumb = false;
3874  int           is_data = false;
3875  unsigned int	size = 4;
3876  void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
3877#if 0
3878  bfd_boolean   found = false;
3879
3880  if (info->disassembler_options)
3881    {
3882      parse_disassembler_options (info->disassembler_options);
3883
3884      /* To avoid repeated parsing of these options, we remove them here.  */
3885      info->disassembler_options = NULL;
3886    }
3887
3888  /* First check the full symtab for a mapping symbol, even if there
3889     are no usable non-mapping symbols for this address.  */
3890  if (info->symtab != NULL
3891      && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3892    {
3893      bfd_vma addr;
3894      int n;
3895      int last_sym = -1;
3896      enum map_type type = MAP_ARM;
3897
3898      if (pc <= last_mapping_addr)
3899	last_mapping_sym = -1;
3900      is_thumb = (last_type == MAP_THUMB);
3901      found = false;
3902      /* Start scanning at the start of the function, or wherever
3903	 we finished last time.  */
3904      n = info->symtab_pos + 1;
3905      if (n < last_mapping_sym)
3906	n = last_mapping_sym;
3907
3908      /* Scan up to the location being disassembled.  */
3909      for (; n < info->symtab_size; n++)
3910	{
3911	  addr = bfd_asymbol_value (info->symtab[n]);
3912	  if (addr > pc)
3913	    break;
3914	  if ((info->section == NULL
3915	       || info->section == info->symtab[n]->section)
3916	      && get_sym_code_type (info, n, &type))
3917	    {
3918	      last_sym = n;
3919	      found = true;
3920	    }
3921	}
3922
3923      if (!found)
3924	{
3925	  n = info->symtab_pos;
3926	  if (n < last_mapping_sym - 1)
3927	    n = last_mapping_sym - 1;
3928
3929	  /* No mapping symbol found at this address.  Look backwards
3930	     for a preceeding one.  */
3931	  for (; n >= 0; n--)
3932	    {
3933	      if (get_sym_code_type (info, n, &type))
3934		{
3935		  last_sym = n;
3936		  found = true;
3937		  break;
3938		}
3939	    }
3940	}
3941
3942      last_mapping_sym = last_sym;
3943      last_type = type;
3944      is_thumb = (last_type == MAP_THUMB);
3945      is_data = (last_type == MAP_DATA);
3946
3947      /* Look a little bit ahead to see if we should print out
3948	 two or four bytes of data.  If there's a symbol,
3949	 mapping or otherwise, after two bytes then don't
3950	 print more.  */
3951      if (is_data)
3952	{
3953	  size = 4 - (pc & 3);
3954	  for (n = last_sym + 1; n < info->symtab_size; n++)
3955	    {
3956	      addr = bfd_asymbol_value (info->symtab[n]);
3957	      if (addr > pc)
3958		{
3959		  if (addr - pc < size)
3960		    size = addr - pc;
3961		  break;
3962		}
3963	    }
3964	  /* If the next symbol is after three bytes, we need to
3965	     print only part of the data, so that we can use either
3966	     .byte or .short.  */
3967	  if (size == 3)
3968	    size = (pc & 1) ? 1 : 2;
3969	}
3970    }
3971
3972  if (info->symbols != NULL)
3973    {
3974      if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3975	{
3976	  coff_symbol_type * cs;
3977
3978	  cs = coffsymbol (*info->symbols);
3979	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
3980		      || cs->native->u.syment.n_sclass == C_THUMBSTAT
3981		      || cs->native->u.syment.n_sclass == C_THUMBLABEL
3982		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
3983		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
3984	}
3985      else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
3986	       && !found)
3987	{
3988	  /* If no mapping symbol has been found then fall back to the type
3989	     of the function symbol.  */
3990	  elf_symbol_type *  es;
3991	  unsigned int       type;
3992
3993	  es = *(elf_symbol_type **)(info->symbols);
3994	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3995
3996	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
3997	}
3998    }
3999#else
4000  int little;
4001
4002  little = (info->endian == BFD_ENDIAN_LITTLE);
4003  is_thumb |= (pc & 1);
4004  pc &= ~(bfd_vma)1;
4005#endif
4006
4007  if (force_thumb)
4008    is_thumb = true;
4009
4010  info->bytes_per_line = 4;
4011
4012  if (is_data)
4013    {
4014      int i;
4015
4016      /* size was already set above.  */
4017      info->bytes_per_chunk = size;
4018      printer = print_insn_data;
4019
4020      status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
4021      given = 0;
4022      if (little)
4023	for (i = size - 1; i >= 0; i--)
4024	  given = b[i] | (given << 8);
4025      else
4026	for (i = 0; i < (int) size; i++)
4027	  given = b[i] | (given << 8);
4028    }
4029  else if (!is_thumb)
4030    {
4031      /* In ARM mode endianness is a straightforward issue: the instruction
4032	 is four bytes long and is either ordered 0123 or 3210.  */
4033      printer = print_insn_arm_internal;
4034      info->bytes_per_chunk = 4;
4035      size = 4;
4036
4037      status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4038      if (little)
4039	given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4040      else
4041	given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4042    }
4043  else
4044    {
4045      /* In Thumb mode we have the additional wrinkle of two
4046	 instruction lengths.  Fortunately, the bits that determine
4047	 the length of the current instruction are always to be found
4048	 in the first two bytes.  */
4049      printer = print_insn_thumb16;
4050      info->bytes_per_chunk = 2;
4051      size = 2;
4052
4053      status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4054      if (little)
4055	given = (b[0]) | (b[1] << 8);
4056      else
4057	given = (b[1]) | (b[0] << 8);
4058
4059      if (!status)
4060	{
4061	  /* These bit patterns signal a four-byte Thumb
4062	     instruction.  */
4063	  if ((given & 0xF800) == 0xF800
4064	      || (given & 0xF800) == 0xF000
4065	      || (given & 0xF800) == 0xE800)
4066	    {
4067	      status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4068	      if (little)
4069		given = (b[0]) | (b[1] << 8) | (given << 16);
4070	      else
4071		given = (b[1]) | (b[0] << 8) | (given << 16);
4072
4073	      printer = print_insn_thumb32;
4074	      size = 4;
4075	    }
4076	}
4077
4078      if (ifthen_address != pc)
4079	find_ifthen_state(pc, info, little);
4080
4081      if (ifthen_state)
4082	{
4083	  if ((ifthen_state & 0xf) == 0x8)
4084	    ifthen_next_state = 0;
4085	  else
4086	    ifthen_next_state = (ifthen_state & 0xe0)
4087				| ((ifthen_state & 0xf) << 1);
4088	}
4089    }
4090
4091  if (status)
4092    {
4093      info->memory_error_func (status, pc, info);
4094      return -1;
4095    }
4096  if (info->flags & INSN_HAS_RELOC)
4097    /* If the instruction has a reloc associated with it, then
4098       the offset field in the instruction will actually be the
4099       addend for the reloc.  (We are using REL type relocs).
4100       In such cases, we can ignore the pc when computing
4101       addresses, since the addend is not currently pc-relative.  */
4102    pc = 0;
4103
4104  /* We include the hexdump of the instruction. The format here
4105     matches that used by objdump and the ARM ARM (in particular,
4106     32 bit Thumb instructions are displayed as pairs of halfwords,
4107     not as a single word.)  */
4108  if (is_thumb)
4109    {
4110      if (size == 2)
4111	{
4112	  info->fprintf_func(info->stream, "%04lx       ",
4113			     ((unsigned long)given) & 0xffff);
4114	}
4115      else
4116	{
4117	  info->fprintf_func(info->stream, "%04lx %04lx  ",
4118			     (((unsigned long)given) >> 16) & 0xffff,
4119			     ((unsigned long)given) & 0xffff);
4120	}
4121    }
4122  else
4123    {
4124      info->fprintf_func(info->stream, "%08lx      ",
4125			 ((unsigned long)given) & 0xffffffff);
4126    }
4127
4128  printer (pc, info, given);
4129
4130  if (is_thumb)
4131    {
4132      ifthen_state = ifthen_next_state;
4133      ifthen_address += size;
4134    }
4135  return size;
4136}
4137