xref: /openbsd-src/gnu/usr.bin/binutils-2.17/opcodes/arm-dis.c (revision 50b7afb2c2c0993b0894d4e34bf857cb13ed9c80)
1 /* Instruction printing code for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3    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, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22 
23 #include "sysdep.h"
24 
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
29 
30 /* FIXME: This shouldn't be done here.  */
31 #include "coff/internal.h"
32 #include "libcoff.h"
33 #include "elf-bfd.h"
34 #include "elf/internal.h"
35 #include "elf/arm.h"
36 
37 /* FIXME: Belongs in global header.  */
38 #ifndef strneq
39 #define strneq(a,b,n)	(strncmp ((a), (b), (n)) == 0)
40 #endif
41 
42 #ifndef NUM_ELEM
43 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
44 #endif
45 
46 struct opcode32
47 {
48   unsigned long arch;		/* Architecture defining this insn.  */
49   unsigned long value, mask;	/* Recognise insn if (op&mask)==value.  */
50   const char *assembler;	/* How to disassemble this insn.  */
51 };
52 
53 struct opcode16
54 {
55   unsigned long arch;		/* Architecture defining this insn.  */
56   unsigned short value, mask;	/* Recognise insn if (op&mask)==value.  */
57   const char *assembler;	/* How to disassemble this insn.  */
58 };
59 
60 /* print_insn_coprocessor recognizes the following format control codes:
61 
62    %%			%
63 
64    %c			print condition code (always bits 28-31)
65    %A			print address for ldc/stc/ldf/stf instruction
66    %I                   print cirrus signed shift immediate: bits 0..3|4..6
67    %F			print the COUNT field of a LFM/SFM instruction.
68    %P			print floating point precision in arithmetic insn
69    %Q			print floating point precision in ldf/stf insn
70    %R			print floating point rounding mode
71 
72    %<bitfield>r		print as an ARM register
73    %<bitfield>d		print the bitfield in decimal
74    %<bitfield>x		print the bitfield in hex
75    %<bitfield>X		print the bitfield as 1 hex digit without leading "0x"
76    %<bitfield>f		print a floating point constant if >7 else a
77 			floating point register
78    %<bitfield>w         print as an iWMMXt width field - [bhwd]ss/us
79    %<bitfield>g         print as an iWMMXt 64-bit register
80    %<bitfield>G         print as an iWMMXt general purpose or control register
81 
82    %<code>y		print a single precision VFP reg.
83 			  Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
84    %<code>z		print a double precision VFP reg
85 			  Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
86    %<bitnum>'c		print specified char iff bit is one
87    %<bitnum>`c		print specified char iff bit is zero
88    %<bitnum>?ab		print a if bit is one else print b
89 
90    %L			print as an iWMMXt N/M width field.
91    %Z			print the Immediate of a WSHUFH instruction.
92    %l			like 'A' except use byte offsets for 'B' & 'H'
93 			versions.  */
94 
95 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
96 
97 static const struct opcode32 coprocessor_opcodes[] =
98 {
99   /* XScale instructions.  */
100   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
101   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
102   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
103   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
104   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
105 
106   /* Intel Wireless MMX technology instructions.  */
107 #define FIRST_IWMMXT_INSN 0x0e130130
108 #define IWMMXT_INSN_COUNT 47
109   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
110   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
111   {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
112   {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
113   {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
114   {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
115   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
116   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
117   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
118   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
119   {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
120   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
121   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
122   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
123   {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
124   {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
125   {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
126   {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
127   {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
128   {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
129   {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
130   {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
131   {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
132   {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
133   {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
134   {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
135   {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
136   {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
137   {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
138   {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
139   {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
140   {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
141   {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
142   {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
143   {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
144   {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
145   {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
146   {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
147   {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
148   {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
149   {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
150   {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
151   {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
152   {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
153   {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
154   {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
155   {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
156   {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
157   {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
158 
159   /* Floating point coprocessor (FPA) instructions */
160   {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
161   {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
162   {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
163   {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
164   {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
165   {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
166   {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
167   {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
168   {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
169   {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
170   {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
171   {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
172   {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
173   {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
174   {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
175   {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
176   {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
177   {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
178   {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
179   {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
180   {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
181   {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
182   {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
183   {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
184   {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
185   {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
186   {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
187   {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
188   {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
189   {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
190   {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
191   {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
192   {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
193   {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
194   {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
195   {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
196   {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
197   {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
198   {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
199   {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
200   {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
201   {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
202   {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
203 
204   /* Floating point coprocessor (VFP) instructions */
205   {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
206   {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
207   {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
208   {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %0y"},
209   {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
210   {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
211   {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
212   {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
213   {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
214   {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
215   {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
216   {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
217   {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
218   {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
219   {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
220   {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
221   {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
222   {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
223   {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
224   {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
225   {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
226   {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
227   {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
228   {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
229   {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
230   {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
231   {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
232   {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
233   {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
234   {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
235   {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
236   {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
237   {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
238   {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
239   {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
240   {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
241   {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
242   {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
243   {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
244   {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
245   {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
246   {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
247   {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
248   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
249   {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
250   {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
251   {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
252   {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
253   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
254   {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
255   {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
256   {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
257   {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
258   {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
259   {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
260   {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
261   {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
262   {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
263   {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
264   {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
265   {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
266   {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
267   {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
268   {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
269   {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
270   {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
271   {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
272   {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
273   {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
274   {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
275   {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
276   {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
277   {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
278 
279   /* Cirrus coprocessor instructions.  */
280   {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
281   {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
282   {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
283   {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
284   {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
285   {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
286   {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
287   {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
288   {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
289   {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
290   {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
291   {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
292   {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
293   {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
294   {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
295   {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
296   {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
297   {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
298   {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
299   {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
300   {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
301   {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
302   {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
303   {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
304   {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
305   {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
306   {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
307   {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
308   {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
309   {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
310   {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
311   {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
312   {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
313   {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
314   {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
315   {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
316   {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
317   {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
318   {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
319   {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
320   {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
321   {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
322   {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
323   {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
324   {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
325   {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
326   {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
327   {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
328   {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
329   {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
330   {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
331   {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
332   {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
333   {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
334   {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
335   {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
336   {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
337   {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
338   {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
339   {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
340   {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
341   {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
342   {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
343   {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
344   {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
345   {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
346   {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
347   {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
348   {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
349   {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
350   {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
351   {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
352   {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
353   {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
354   {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
355   {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
356   {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
357   {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
358   {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
359   {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
360   {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
361   {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
362   {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
363   {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
364 
365   /* Generic coprocessor instructions */
366   {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
367   {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
368   {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
369   {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
370   {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
371   {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
372   {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
373 
374   /* V6 coprocessor instructions */
375   {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
376   {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
377 
378   /* V5 coprocessor instructions */
379   {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
380   {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
381   {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
382   {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
383   {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
384   {0, 0, 0, 0}
385 };
386 
387 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb.  All three are partially
388    ordered: they must be searched linearly from the top to obtain a correct
389    match.  */
390 
391 /* print_insn_arm recognizes the following format control codes:
392 
393    %%			%
394 
395    %a			print address for ldr/str instruction
396    %s                   print address for ldr/str halfword/signextend instruction
397    %b			print branch destination
398    %c			print condition code (always bits 28-31)
399    %m			print register mask for ldm/stm instruction
400    %o			print operand2 (immediate or register + shift)
401    %p			print 'p' iff bits 12-15 are 15
402    %t			print 't' iff bit 21 set and bit 24 clear
403    %B			print arm BLX(1) destination
404    %C			print the PSR sub type.
405    %U			print barrier type.
406    %P			print address for pli instruction.
407 
408    %<bitfield>r		print as an ARM register
409    %<bitfield>d		print the bitfield in decimal
410    %<bitfield>W         print the bitfield plus one in decimal
411    %<bitfield>x		print the bitfield in hex
412    %<bitfield>X		print the bitfield as 1 hex digit without leading "0x"
413 
414    %<bitnum>'c		print specified char iff bit is one
415    %<bitnum>`c		print specified char iff bit is zero
416    %<bitnum>?ab		print a if bit is one else print b
417 
418    %e                   print arm SMI operand (bits 0..7,8..19).
419    %E			print the LSB and WIDTH fields of a BFI or BFC instruction.
420    %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.  */
421 
422 static const struct opcode32 arm_opcodes[] =
423 {
424   /* ARM instructions.  */
425   {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
426   {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
427   {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
428   {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
429   {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
430   {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
431   {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
432 
433   /* V7 instructions.  */
434   {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
435   {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
436   {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
437   {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
438   {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
439 
440   /* ARM V6T2 instructions.  */
441   {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
442   {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
443   {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
444   {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
445   {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
446   {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
447   {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
448   {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
449   {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
450 
451   /* ARM V6Z instructions.  */
452   {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
453 
454   /* ARM V6K instructions.  */
455   {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
456   {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
457   {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
458   {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
459   {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
460   {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
461   {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
462 
463   /* ARM V6K NOP hints.  */
464   {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
465   {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
466   {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
467   {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
468   {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
469 
470   /* ARM V6 instructions. */
471   {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
472   {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
473   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
474   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
475   {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
476   {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
477   {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
478   {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
479   {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
480   {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
481   {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
482   {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
483   {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
484   {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
485   {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
486   {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
487   {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
488   {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
489   {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
490   {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
491   {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
492   {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
493   {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
494   {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
495   {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
496   {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
497   {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
498   {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
499   {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
500   {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
501   {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
502   {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
503   {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
504   {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
505   {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
506   {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
507   {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
508   {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
509   {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
510   {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
511   {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
512   {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
513   {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
514   {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
515   {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
516   {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
517   {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
518   {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
519   {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
520   {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
521   {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
522   {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
523   {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
524   {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
525   {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
526   {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
527   {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
528   {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
529   {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
530   {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
531   {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
532   {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
533   {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
534   {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
535   {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
536   {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
537   {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
538   {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
539   {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
540   {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
541   {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
542   {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
543   {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
544   {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
545   {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
546   {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
547   {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
548   {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
549   {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
550   {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
551   {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
552   {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
553   {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
554   {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
555   {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
556   {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
557   {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
558   {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
559   {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
560   {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
561   {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
562   {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
563   {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
564   {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
565   {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
566   {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
567   {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
568   {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
569   {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
570   {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
571   {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
572   {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
573   {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
574   {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
575   {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
576   {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
577   {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
578   {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
579   {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
580   {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
581   {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
582   {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
583   {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
584   {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
585   {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
586   {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
587   {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
588   {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
589   {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
590   {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
591   {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
592   {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
593 
594   /* V5J instruction.  */
595   {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
596 
597   /* V5 Instructions.  */
598   {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
599   {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
600   {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
601   {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
602 
603   /* V5E "El Segundo" Instructions.  */
604   {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
605   {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
606   {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
607   {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
608   {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
609   {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
610   {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
611 
612   {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
613   {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
614 
615   {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
616   {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
617   {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
618   {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
619 
620   {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
621   {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
622   {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
623   {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
624 
625   {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
626   {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
627 
628   {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0,  "qadd%c\t%12-15r, %0-3r, %16-19r"},
629   {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
630   {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0,  "qsub%c\t%12-15r, %0-3r, %16-19r"},
631   {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
632 
633   /* ARM Instructions.  */
634   {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
635   {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
636   {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
637   {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
638   {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
639   {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
640   {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
641   {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
642   {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
643   {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
644   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
645   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
646   {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
647   {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
648   {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
649   {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
650   {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
651   {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
652   {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
653   {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
654   {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
655   {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
656   {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
657   {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
658   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
659   {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
660   {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
661   {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
662   {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
663 
664   /* The rest.  */
665   {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
666   {0, 0x00000000, 0x00000000, 0}
667 };
668 
669 /* print_insn_thumb16 recognizes the following format control codes:
670 
671    %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
672    %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
673    %<bitfield>I         print bitfield as a signed decimal
674    				(top bit of range being the sign bit)
675    %N                   print Thumb register mask (with LR)
676    %O                   print Thumb register mask (with PC)
677    %M                   print Thumb register mask
678    %b			print CZB's 6-bit unsigned branch destination
679    %s			print Thumb right-shift immediate (6..10; 0 == 32).
680    %<bitfield>r		print bitfield as an ARM register
681    %<bitfield>d		print bitfield as a decimal
682    %<bitfield>H         print (bitfield * 2) as a decimal
683    %<bitfield>W         print (bitfield * 4) as a decimal
684    %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
685    %<bitfield>B         print Thumb branch destination (signed displacement)
686    %<bitfield>c         print bitfield as a condition code
687    %<bitnum>'c		print specified char iff bit is one
688    %<bitnum>?ab		print a if bit is one else print b.  */
689 
690 static const struct opcode16 thumb_opcodes[] =
691 {
692   /* Thumb instructions.  */
693 
694   /* ARM V6K no-argument instructions.  */
695   {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
696   {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
697   {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
698   {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
699   {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
700   {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
701 
702   /* ARM V6T2 instructions.  */
703   {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"},
704   {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"},
705   {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"},
706   {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"},
707   {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"},
708   {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"},
709   {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"},
710   {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"},
711   {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"},
712 
713   /* ARM V6.  */
714   {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
715   {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
716   {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
717   {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
718   {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
719   {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
720   {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
721   {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
722   {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
723   {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
724   {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
725 
726   /* ARM V5 ISA extends Thumb.  */
727   {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
728   /* This is BLX(2).  BLX(1) is a 32-bit instruction.  */
729   {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"},	/* note: 4 bit register number.  */
730   /* ARM V4T ISA (Thumb v1).  */
731   {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
732   /* Format 4.  */
733   {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"},
734   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"},
735   {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"},
736   {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"},
737   {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"},
738   {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"},
739   {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
740   {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
741   {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
742   {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
743   {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
744   {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
745   {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
746   {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"},
747   {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"},
748   {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"},
749   /* format 13 */
750   {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
751   {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
752   /* format 5 */
753   {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
754   {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
755   {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
756   {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
757   /* format 14 */
758   {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
759   {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
760   /* format 2 */
761   {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
762   {ARM_EXT_V4T, 0x1A00, 0xFE00, "subs\t%0-2r, %3-5r, %6-8r"},
763   {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
764   {ARM_EXT_V4T, 0x1E00, 0xFE00, "subs\t%0-2r, %3-5r, #%6-8d"},
765   /* format 8 */
766   {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
767   {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
768   {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
769   /* format 7 */
770   {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
771   {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
772   /* format 1 */
773   {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"},
774   {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"},
775   {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"},
776   /* format 3 */
777   {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
778   {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
779   {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
780   {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
781   /* format 6 */
782   {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
783   /* format 9 */
784   {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
785   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
786   {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
787   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
788   /* format 10 */
789   {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
790   {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
791   /* format 11 */
792   {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
793   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
794   /* format 12 */
795   {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
796   {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
797   /* format 15 */
798   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
799   {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
800   /* format 17 */
801   {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc\t%0-7d"},
802   /* format 16 */
803   {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"},
804   /* format 18 */
805   {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"},
806 
807   /* The E800 .. FFFF range is unconditionally redirected to the
808      32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
809      are processed via that table.  Thus, we can never encounter a
810      bare "second half of BL/BLX(1)" instruction here.  */
811   {ARM_EXT_V1,  0x0000, 0x0000, "undefined"},
812   {0, 0, 0, 0}
813 };
814 
815 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
816    We adopt the convention that hw1 is the high 16 bits of .value and
817    .mask, hw2 the low 16 bits.
818 
819    print_insn_thumb32 recognizes the following format control codes:
820 
821        %%		%
822 
823        %I		print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
824        %M		print a modified 12-bit immediate (same location)
825        %J		print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
826        %K		print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
827        %S		print a possibly-shifted Rm
828 
829        %a		print the address of a plain load/store
830        %w		print the width and signedness of a core load/store
831        %m		print register mask for ldm/stm
832 
833        %E		print the lsb and width fields of a bfc/bfi instruction
834        %F		print the lsb and width fields of a sbfx/ubfx instruction
835        %b		print a conditional branch offset
836        %B		print an unconditional branch offset
837        %s		print the shift field of an SSAT instruction
838        %R		print the rotation field of an SXT instruction
839        %U		print barrier type.
840        %P		print address for pli instruction.
841 
842        %<bitfield>d	print bitfield in decimal
843        %<bitfield>W	print bitfield*4 in decimal
844        %<bitfield>r	print bitfield as an ARM register
845        %<bitfield>c	print bitfield as a condition code
846 
847        %<bitnum>'c	print "c" iff bit is one
848        %<bitnum>`c	print "c" iff bit is zero
849        %<bitnum>?ab	print "a" if bit is one, else "b"
850 
851    With one exception at the bottom (done because BL and BLX(1) need
852    to come dead last), this table was machine-sorted first in
853    decreasing order of number of bits set in the mask, then in
854    increasing numeric order of mask, then in increasing numeric order
855    of opcode.  This order is not the clearest for a human reader, but
856    is guaranteed never to catch a special-case bit pattern with a more
857    general mask, which is important, because this instruction encoding
858    makes heavy use of special-case bit patterns.  */
859 static const struct opcode32 thumb32_opcodes[] =
860 {
861   /* V7 instructions.  */
862   {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"},
863   {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"},
864   {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"},
865   {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"},
866   {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"},
867   {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"},
868   {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"},
869 
870   /* Instructions defined in the basic V6T2 set.  */
871   {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
872   {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
873   {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
874   {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
875   {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
876   {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
877 
878   {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
879   {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
880   {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
881   {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
882   {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
883   {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
884   {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"},
885   {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
886   {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
887   {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
888   {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
889   {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
890   {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
891   {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"},
892   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
893   {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
894   {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
895   {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
896   {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"},
897   {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"},
898   {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"},
899   {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
900   {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
901   {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
902   {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
903   {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
904   {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
905   {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
906   {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"},
907   {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"},
908   {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"},
909   {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"},
910   {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"},
911   {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"},
912   {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"},
913   {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"},
914   {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"},
915   {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"},
916   {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"},
917   {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"},
918   {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"},
919   {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"},
920   {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"},
921   {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"},
922   {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"},
923   {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"},
924   {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"},
925   {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"},
926   {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"},
927   {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"},
928   {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"},
929   {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"},
930   {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"},
931   {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"},
932   {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"},
933   {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"},
934   {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"},
935   {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"},
936   {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"},
937   {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"},
938   {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"},
939   {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"},
940   {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"},
941   {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"},
942   {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"},
943   {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"},
944   {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"},
945   {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"},
946   {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"},
947   {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"},
948   {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"},
949   {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"},
950   {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"},
951   {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"},
952   {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"},
953   {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"},
954   {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"},
955   {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"},
956   {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
957   {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
958   {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
959   {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
960   {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
961   {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
962   {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
963   {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
964   {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
965   {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
966   {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"},
967   {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"},
968   {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"},
969   {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"},
970   {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
971   {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
972   {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
973   {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
974   {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
975   {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
976   {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
977   {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
978   {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
979   {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
980   {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
981   {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
982   {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"},
983   {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"},
984   {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"},
985   {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"},
986   {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"},
987   {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
988   {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
989   {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
990   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
991   {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc\t%K"},
992   {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
993   {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
994   {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
995   {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
996   {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
997   {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
998   {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
999   {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
1000   {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1001   {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1002   {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
1003   {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
1004   {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
1005   {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
1006   {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
1007   {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
1008   {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
1009   {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"},
1010   {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"},
1011   {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"},
1012   {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"},
1013   {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"},
1014   {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"},
1015   {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"},
1016   {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"},
1017   {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"},
1018   {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"},
1019   {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"},
1020   {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"},
1021   {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"},
1022   {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
1023   {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
1024   {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
1025   {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
1026   {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
1027   {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1028   {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"},
1029   {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"},
1030   {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"},
1031   {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
1032   {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
1033   {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
1034   {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
1035   {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
1036   {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
1037   {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
1038   {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
1039   {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
1040   {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
1041   {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
1042   {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
1043   {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
1044   {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1045   {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1046   {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
1047   {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"},
1048 
1049   /* Filter out Bcc with cond=E or F, which are used for other instructions.  */
1050   {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1051   {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1052   {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
1053   {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
1054 
1055   /* These have been 32-bit since the invention of Thumb.  */
1056   {ARM_EXT_V4T,  0xf000c000, 0xf800d000, "blx\t%B"},
1057   {ARM_EXT_V4T,  0xf000d000, 0xf800d000, "bl\t%B"},
1058 
1059   /* Fallback.  */
1060   {ARM_EXT_V1,   0x00000000, 0x00000000, "undefined"},
1061   {0, 0, 0, 0}
1062 };
1063 
1064 static const char *const arm_conditional[] =
1065 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1066  "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1067 
1068 static const char *const arm_fp_const[] =
1069 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1070 
1071 static const char *const arm_shift[] =
1072 {"lsl", "lsr", "asr", "ror"};
1073 
1074 typedef struct
1075 {
1076   const char *name;
1077   const char *description;
1078   const char *reg_names[16];
1079 }
1080 arm_regname;
1081 
1082 static const arm_regname regnames[] =
1083 {
1084   { "raw" , "Select raw register names",
1085     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1086   { "gcc",  "Select register names used by GCC",
1087     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1088   { "std",  "Select register names used in ARM's ISA documentation",
1089     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
1090   { "apcs", "Select register names used in the APCS",
1091     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1092   { "atpcs", "Select register names used in the ATPCS",
1093     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
1094   { "special-atpcs", "Select special register names used in the ATPCS",
1095     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
1096 };
1097 
1098 static const char *const iwmmxt_wwnames[] =
1099 {"b", "h", "w", "d"};
1100 
1101 static const char *const iwmmxt_wwssnames[] =
1102 {"b", "bus", "b", "bss",
1103  "h", "hus", "h", "hss",
1104  "w", "wus", "w", "wss",
1105  "d", "dus", "d", "dss"
1106 };
1107 
1108 static const char *const iwmmxt_regnames[] =
1109 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1110   "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1111 };
1112 
1113 static const char *const iwmmxt_cregnames[] =
1114 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1115   "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1116 };
1117 
1118 /* Default to GCC register name set.  */
1119 static unsigned int regname_selected = 1;
1120 
1121 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1122 #define arm_regnames      regnames[regname_selected].reg_names
1123 
1124 static bfd_boolean force_thumb = FALSE;
1125 
1126 
1127 /* Functions.  */
1128 int
1129 get_arm_regname_num_options (void)
1130 {
1131   return NUM_ARM_REGNAMES;
1132 }
1133 
1134 int
1135 set_arm_regname_option (int option)
1136 {
1137   int old = regname_selected;
1138   regname_selected = option;
1139   return old;
1140 }
1141 
1142 int
1143 get_arm_regnames (int option, const char **setname, const char **setdescription,
1144 		  const char *const **register_names)
1145 {
1146   *setname = regnames[option].name;
1147   *setdescription = regnames[option].description;
1148   *register_names = regnames[option].reg_names;
1149   return 16;
1150 }
1151 
1152 static void
1153 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1154 {
1155   func (stream, "%s", arm_regnames[given & 0xf]);
1156 
1157   if ((given & 0xff0) != 0)
1158     {
1159       if ((given & 0x10) == 0)
1160 	{
1161 	  int amount = (given & 0xf80) >> 7;
1162 	  int shift = (given & 0x60) >> 5;
1163 
1164 	  if (amount == 0)
1165 	    {
1166 	      if (shift == 3)
1167 		{
1168 		  func (stream, ", rrx");
1169 		  return;
1170 		}
1171 
1172 	      amount = 32;
1173 	    }
1174 
1175 	  func (stream, ", %s #%d", arm_shift[shift], amount);
1176 	}
1177       else
1178 	func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1179 	      arm_regnames[(given & 0xf00) >> 8]);
1180     }
1181 }
1182 
1183 /* Print one coprocessor instruction on INFO->STREAM.
1184    Return TRUE if the instuction matched, FALSE if this is not a
1185    recognised coprocessor instruction.  */
1186 
1187 static bfd_boolean
1188 print_insn_coprocessor (struct disassemble_info *info, long given,
1189 			bfd_boolean thumb)
1190 {
1191   const struct opcode32 *insn;
1192   void *stream = info->stream;
1193   fprintf_ftype func = info->fprintf_func;
1194   unsigned long mask;
1195   unsigned long value;
1196 
1197   for (insn = coprocessor_opcodes; insn->assembler; insn++)
1198     {
1199       if (insn->value == FIRST_IWMMXT_INSN
1200 	  && info->mach != bfd_mach_arm_XScale
1201 	  && info->mach != bfd_mach_arm_iWMMXt)
1202 	insn = insn + IWMMXT_INSN_COUNT;
1203 
1204       mask = insn->mask;
1205       value = insn->value;
1206       if (thumb)
1207 	{
1208 	  /* The high 4 bits are 0xe for Arm conditional instructions, and
1209 	     0xe for arm unconditional instructions.  The rest of the
1210 	     encoding is the same.  */
1211 	  mask |= 0xf0000000;
1212 	  value |= 0xe0000000;
1213 	}
1214       else
1215 	{
1216 	  /* Only match unconditional instuctions against unconditional
1217 	     patterns.  */
1218 	  if ((given & 0xf0000000) == 0xf0000000)
1219 	    mask |= 0xf0000000;
1220 	}
1221       if ((given & mask) == value)
1222 	{
1223 	  const char *c;
1224 
1225 	  for (c = insn->assembler; *c; c++)
1226 	    {
1227 	      if (*c == '%')
1228 		{
1229 		  switch (*++c)
1230 		    {
1231 		    case '%':
1232 		      func (stream, "%%");
1233 		      break;
1234 
1235 		    case 'A':
1236 		      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1237 
1238 		      if ((given & (1 << 24)) != 0)
1239 			{
1240 			  int offset = given & 0xff;
1241 
1242 			  if (offset)
1243 			    func (stream, ", #%s%d]%s",
1244 				  ((given & 0x00800000) == 0 ? "-" : ""),
1245 				  offset * 4,
1246 				  ((given & 0x00200000) != 0 ? "!" : ""));
1247 			  else
1248 			    func (stream, "]");
1249 			}
1250 		      else
1251 			{
1252 			  int offset = given & 0xff;
1253 
1254 			  func (stream, "]");
1255 
1256 			  if (given & (1 << 21))
1257 			    {
1258 			      if (offset)
1259 				func (stream, ", #%s%d",
1260 				      ((given & 0x00800000) == 0 ? "-" : ""),
1261 				      offset * 4);
1262 			    }
1263 			  else
1264 			    func (stream, ", {%d}", offset);
1265 			}
1266 		      break;
1267 
1268 		    case 'c':
1269 		      func (stream, "%s",
1270 			    arm_conditional [(given >> 28) & 0xf]);
1271 		      break;
1272 
1273 		    case 'I':
1274 		      /* Print a Cirrus/DSP shift immediate.  */
1275 		      /* Immediates are 7bit signed ints with bits 0..3 in
1276 			 bits 0..3 of opcode and bits 4..6 in bits 5..7
1277 			 of opcode.  */
1278 		      {
1279 			int imm;
1280 
1281 			imm = (given & 0xf) | ((given & 0xe0) >> 1);
1282 
1283 			/* Is ``imm'' a negative number?  */
1284 			if (imm & 0x40)
1285 			  imm |= (-1 << 7);
1286 
1287 			func (stream, "%d", imm);
1288 		      }
1289 
1290 		      break;
1291 
1292 		    case 'F':
1293 		      switch (given & 0x00408000)
1294 			{
1295 			case 0:
1296 			  func (stream, "4");
1297 			  break;
1298 			case 0x8000:
1299 			  func (stream, "1");
1300 			  break;
1301 			case 0x00400000:
1302 			  func (stream, "2");
1303 			  break;
1304 			default:
1305 			  func (stream, "3");
1306 			}
1307 		      break;
1308 
1309 		    case 'P':
1310 		      switch (given & 0x00080080)
1311 			{
1312 			case 0:
1313 			  func (stream, "s");
1314 			  break;
1315 			case 0x80:
1316 			  func (stream, "d");
1317 			  break;
1318 			case 0x00080000:
1319 			  func (stream, "e");
1320 			  break;
1321 			default:
1322 			  func (stream, _("<illegal precision>"));
1323 			  break;
1324 			}
1325 		      break;
1326 		    case 'Q':
1327 		      switch (given & 0x00408000)
1328 			{
1329 			case 0:
1330 			  func (stream, "s");
1331 			  break;
1332 			case 0x8000:
1333 			  func (stream, "d");
1334 			  break;
1335 			case 0x00400000:
1336 			  func (stream, "e");
1337 			  break;
1338 			default:
1339 			  func (stream, "p");
1340 			  break;
1341 			}
1342 		      break;
1343 		    case 'R':
1344 		      switch (given & 0x60)
1345 			{
1346 			case 0:
1347 			  break;
1348 			case 0x20:
1349 			  func (stream, "p");
1350 			  break;
1351 			case 0x40:
1352 			  func (stream, "m");
1353 			  break;
1354 			default:
1355 			  func (stream, "z");
1356 			  break;
1357 			}
1358 		      break;
1359 
1360 		    case '0': case '1': case '2': case '3': case '4':
1361 		    case '5': case '6': case '7': case '8': case '9':
1362 		      {
1363 			int bitstart = *c++ - '0';
1364 			int bitend = 0;
1365 			while (*c >= '0' && *c <= '9')
1366 			  bitstart = (bitstart * 10) + *c++ - '0';
1367 
1368 			switch (*c)
1369 			  {
1370 			  case '-':
1371 			    c++;
1372 
1373 			    while (*c >= '0' && *c <= '9')
1374 			      bitend = (bitend * 10) + *c++ - '0';
1375 
1376 			    if (!bitend)
1377 			      abort ();
1378 
1379 			    switch (*c)
1380 			      {
1381 			      case 'r':
1382 				{
1383 				  long reg;
1384 
1385 				  reg = given >> bitstart;
1386 				  reg &= (2 << (bitend - bitstart)) - 1;
1387 
1388 				  func (stream, "%s", arm_regnames[reg]);
1389 				}
1390 				break;
1391 			      case 'd':
1392 				{
1393 				  long reg;
1394 
1395 				  reg = given >> bitstart;
1396 				  reg &= (2 << (bitend - bitstart)) - 1;
1397 
1398 				  func (stream, "%ld", reg);
1399 				}
1400 				break;
1401 			      case 'f':
1402 				{
1403 				  long reg;
1404 
1405 				  reg = given >> bitstart;
1406 				  reg &= (2 << (bitend - bitstart)) - 1;
1407 
1408 				  if (reg > 7)
1409 				    func (stream, "#%s",
1410 					  arm_fp_const[reg & 7]);
1411 				  else
1412 				    func (stream, "f%ld", reg);
1413 				}
1414 				break;
1415 
1416 			      case 'w':
1417 				{
1418 				  long reg;
1419 
1420 				  if (bitstart != bitend)
1421 				    {
1422 				      reg = given >> bitstart;
1423 				      reg &= (2 << (bitend - bitstart)) - 1;
1424 				      if (bitend - bitstart == 1)
1425 					func (stream, "%s", iwmmxt_wwnames[reg]);
1426 				      else
1427 					func (stream, "%s", iwmmxt_wwssnames[reg]);
1428 				    }
1429 				  else
1430 				    {
1431 				      reg = (((given >> 8)  & 0x1) |
1432 					     ((given >> 22) & 0x1));
1433 				      func (stream, "%s", iwmmxt_wwnames[reg]);
1434 				    }
1435 				}
1436 				break;
1437 
1438 			      case 'g':
1439 				{
1440 				  long reg;
1441 				  reg = given >> bitstart;
1442 				  reg &= (2 << (bitend - bitstart)) - 1;
1443 				  func (stream, "%s", iwmmxt_regnames[reg]);
1444 				}
1445 				break;
1446 
1447 			      case 'G':
1448 				{
1449 				  long reg;
1450 				  reg = given >> bitstart;
1451 				  reg &= (2 << (bitend - bitstart)) - 1;
1452 				  func (stream, "%s", iwmmxt_cregnames[reg]);
1453 				}
1454 				break;
1455 
1456 			      default:
1457 				abort ();
1458 			      }
1459 			    break;
1460 
1461 			  case 'y':
1462 			  case 'z':
1463 			    {
1464 			      int single = *c == 'y';
1465 			      int regno;
1466 
1467 			      switch (bitstart)
1468 				{
1469 				case 4: /* Sm pair */
1470 				  func (stream, "{");
1471 				  /* Fall through.  */
1472 				case 0: /* Sm, Dm */
1473 				  regno = given & 0x0000000f;
1474 				  if (single)
1475 				    {
1476 				      regno <<= 1;
1477 				      regno += (given >> 5) & 1;
1478 				    }
1479 				  break;
1480 
1481 				case 1: /* Sd, Dd */
1482 				  regno = (given >> 12) & 0x0000000f;
1483 				  if (single)
1484 				    {
1485 				      regno <<= 1;
1486 				      regno += (given >> 22) & 1;
1487 				    }
1488 				  break;
1489 
1490 				case 2: /* Sn, Dn */
1491 				  regno = (given >> 16) & 0x0000000f;
1492 				  if (single)
1493 				    {
1494 				      regno <<= 1;
1495 				      regno += (given >> 7) & 1;
1496 				    }
1497 				  break;
1498 
1499 				case 3: /* List */
1500 				  func (stream, "{");
1501 				  regno = (given >> 12) & 0x0000000f;
1502 				  if (single)
1503 				    {
1504 				      regno <<= 1;
1505 				      regno += (given >> 22) & 1;
1506 				    }
1507 				  break;
1508 
1509 
1510 				default:
1511 				  abort ();
1512 				}
1513 
1514 			      func (stream, "%c%d", single ? 's' : 'd', regno);
1515 
1516 			      if (bitstart == 3)
1517 				{
1518 				  int count = given & 0xff;
1519 
1520 				  if (single == 0)
1521 				    count >>= 1;
1522 
1523 				  if (--count)
1524 				    {
1525 				      func (stream, "-%c%d",
1526 					    single ? 's' : 'd',
1527 					    regno + count);
1528 				    }
1529 
1530 				  func (stream, "}");
1531 				}
1532 			      else if (bitstart == 4)
1533 				func (stream, ", %c%d}", single ? 's' : 'd',
1534 				      regno + 1);
1535 
1536 			      break;
1537 			    }
1538 
1539 			    break;
1540 
1541 			  case '`':
1542 			    c++;
1543 			    if ((given & (1 << bitstart)) == 0)
1544 			      func (stream, "%c", *c);
1545 			    break;
1546 			  case '\'':
1547 			    c++;
1548 			    if ((given & (1 << bitstart)) != 0)
1549 			      func (stream, "%c", *c);
1550 			    break;
1551 			  case '?':
1552 			    ++c;
1553 			    if ((given & (1 << bitstart)) != 0)
1554 			      func (stream, "%c", *c++);
1555 			    else
1556 			      func (stream, "%c", *++c);
1557 			    break;
1558 			  default:
1559 			    abort ();
1560 			  }
1561 			break;
1562 
1563 		      case 'L':
1564 			switch (given & 0x00400100)
1565 			  {
1566 			  case 0x00000000: func (stream, "b"); break;
1567 			  case 0x00400000: func (stream, "h"); break;
1568 			  case 0x00000100: func (stream, "w"); break;
1569 			  case 0x00400100: func (stream, "d"); break;
1570 			  default:
1571 			    break;
1572 			  }
1573 			break;
1574 
1575 		      case 'Z':
1576 			{
1577 			  int value;
1578 			  /* given (20, 23) | given (0, 3) */
1579 			  value = ((given >> 16) & 0xf0) | (given & 0xf);
1580 			  func (stream, "%d", value);
1581 			}
1582 			break;
1583 
1584 		      case 'l':
1585 			/* This is like the 'A' operator, except that if
1586 			   the width field "M" is zero, then the offset is
1587 			   *not* multiplied by four.  */
1588 			{
1589 			  int offset = given & 0xff;
1590 			  int multiplier = (given & 0x00000100) ? 4 : 1;
1591 
1592 			  func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1593 
1594 			  if (offset)
1595 			    {
1596 			      if ((given & 0x01000000) != 0)
1597 				func (stream, ", #%s%d]%s",
1598 				      ((given & 0x00800000) == 0 ? "-" : ""),
1599 				      offset * multiplier,
1600 				      ((given & 0x00200000) != 0 ? "!" : ""));
1601 			      else
1602 				func (stream, "], #%s%d",
1603 				      ((given & 0x00800000) == 0 ? "-" : ""),
1604 				      offset * multiplier);
1605 			    }
1606 			  else
1607 			    func (stream, "]");
1608 			}
1609 			break;
1610 
1611 		      default:
1612 			abort ();
1613 		      }
1614 		    }
1615 		}
1616 	      else
1617 		func (stream, "%c", *c);
1618 	    }
1619 	  return TRUE;
1620 	}
1621     }
1622   return FALSE;
1623 }
1624 
1625 static void
1626 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
1627 {
1628   void *stream = info->stream;
1629   fprintf_ftype func = info->fprintf_func;
1630 
1631   if (((given & 0x000f0000) == 0x000f0000)
1632       && ((given & 0x02000000) == 0))
1633     {
1634       int offset = given & 0xfff;
1635 
1636       func (stream, "[pc");
1637 
1638       if (given & 0x01000000)
1639 	{
1640 	  if ((given & 0x00800000) == 0)
1641 	    offset = - offset;
1642 
1643 	  /* Pre-indexed.  */
1644 	  func (stream, ", #%d]", offset);
1645 
1646 	  offset += pc + 8;
1647 
1648 	  /* Cope with the possibility of write-back
1649 	     being used.  Probably a very dangerous thing
1650 	     for the programmer to do, but who are we to
1651 	     argue ?  */
1652 	  if (given & 0x00200000)
1653 	    func (stream, "!");
1654 	}
1655       else
1656 	{
1657 	  /* Post indexed.  */
1658 	  func (stream, "], #%d", offset);
1659 
1660 	  /* ie ignore the offset.  */
1661 	  offset = pc + 8;
1662 	}
1663 
1664       func (stream, "\t; ");
1665       info->print_address_func (offset, info);
1666     }
1667   else
1668     {
1669       func (stream, "[%s",
1670 	    arm_regnames[(given >> 16) & 0xf]);
1671       if ((given & 0x01000000) != 0)
1672 	{
1673 	  if ((given & 0x02000000) == 0)
1674 	    {
1675 	      int offset = given & 0xfff;
1676 	      if (offset)
1677 		func (stream, ", #%s%d",
1678 		      (((given & 0x00800000) == 0)
1679 		       ? "-" : ""), offset);
1680 	    }
1681 	  else
1682 	    {
1683 	      func (stream, ", %s",
1684 		    (((given & 0x00800000) == 0)
1685 		     ? "-" : ""));
1686 	      arm_decode_shift (given, func, stream);
1687 	    }
1688 
1689 	  func (stream, "]%s",
1690 		((given & 0x00200000) != 0) ? "!" : "");
1691 	}
1692       else
1693 	{
1694 	  if ((given & 0x02000000) == 0)
1695 	    {
1696 	      int offset = given & 0xfff;
1697 	      if (offset)
1698 		func (stream, "], #%s%d",
1699 		      (((given & 0x00800000) == 0)
1700 		       ? "-" : ""), offset);
1701 	      else
1702 		func (stream, "]");
1703 	    }
1704 	  else
1705 	    {
1706 	      func (stream, "], %s",
1707 		    (((given & 0x00800000) == 0)
1708 		     ? "-" : ""));
1709 	      arm_decode_shift (given, func, stream);
1710 	    }
1711 	}
1712     }
1713 }
1714 
1715 /* Print one ARM instruction from PC on INFO->STREAM.  */
1716 
1717 static void
1718 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
1719 {
1720   const struct opcode32 *insn;
1721   void *stream = info->stream;
1722   fprintf_ftype func = info->fprintf_func;
1723 
1724   if (print_insn_coprocessor (info, given, FALSE))
1725     return;
1726 
1727   for (insn = arm_opcodes; insn->assembler; insn++)
1728     {
1729       if (insn->value == FIRST_IWMMXT_INSN
1730 	  && info->mach != bfd_mach_arm_XScale
1731 	  && info->mach != bfd_mach_arm_iWMMXt)
1732 	insn = insn + IWMMXT_INSN_COUNT;
1733 
1734       if ((given & insn->mask) == insn->value
1735 	  /* Special case: an instruction with all bits set in the condition field
1736 	     (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
1737 	     or by the catchall at the end of the table.  */
1738 	  && ((given & 0xF0000000) != 0xF0000000
1739 	      || (insn->mask & 0xF0000000) == 0xF0000000
1740 	      || (insn->mask == 0 && insn->value == 0)))
1741 	{
1742 	  const char *c;
1743 
1744 	  for (c = insn->assembler; *c; c++)
1745 	    {
1746 	      if (*c == '%')
1747 		{
1748 		  switch (*++c)
1749 		    {
1750 		    case '%':
1751 		      func (stream, "%%");
1752 		      break;
1753 
1754 		    case 'a':
1755 		      print_arm_address (pc, info, given);
1756 		      break;
1757 
1758 		    case 'P':
1759 		      /* Set P address bit and use normal address
1760 			 printing routine.  */
1761 		      print_arm_address (pc, info, given | (1 << 24));
1762 		      break;
1763 
1764 		    case 's':
1765                       if ((given & 0x004f0000) == 0x004f0000)
1766 			{
1767                           /* PC relative with immediate offset.  */
1768 			  int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1769 
1770 			  if ((given & 0x00800000) == 0)
1771 			    offset = -offset;
1772 
1773 			  func (stream, "[pc, #%d]\t; ", offset);
1774 			  info->print_address_func (offset + pc + 8, info);
1775 			}
1776 		      else
1777 			{
1778 			  func (stream, "[%s",
1779 				arm_regnames[(given >> 16) & 0xf]);
1780 			  if ((given & 0x01000000) != 0)
1781 			    {
1782                               /* Pre-indexed.  */
1783 			      if ((given & 0x00400000) == 0x00400000)
1784 				{
1785                                   /* Immediate.  */
1786                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1787 				  if (offset)
1788 				    func (stream, ", #%s%d",
1789 					  (((given & 0x00800000) == 0)
1790 					   ? "-" : ""), offset);
1791 				}
1792 			      else
1793 				{
1794                                   /* Register.  */
1795 				  func (stream, ", %s%s",
1796 					(((given & 0x00800000) == 0)
1797 					 ? "-" : ""),
1798                                         arm_regnames[given & 0xf]);
1799 				}
1800 
1801 			      func (stream, "]%s",
1802 				    ((given & 0x00200000) != 0) ? "!" : "");
1803 			    }
1804 			  else
1805 			    {
1806                               /* Post-indexed.  */
1807 			      if ((given & 0x00400000) == 0x00400000)
1808 				{
1809                                   /* Immediate.  */
1810                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1811 				  if (offset)
1812 				    func (stream, "], #%s%d",
1813 					  (((given & 0x00800000) == 0)
1814 					   ? "-" : ""), offset);
1815 				  else
1816 				    func (stream, "]");
1817 				}
1818 			      else
1819 				{
1820                                   /* Register.  */
1821 				  func (stream, "], %s%s",
1822 					(((given & 0x00800000) == 0)
1823 					 ? "-" : ""),
1824                                         arm_regnames[given & 0xf]);
1825 				}
1826 			    }
1827 			}
1828 		      break;
1829 
1830 		    case 'b':
1831 		      {
1832 			int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
1833 			info->print_address_func (disp*4 + pc + 8, info);
1834 		      }
1835 		      break;
1836 
1837 		    case 'c':
1838 		      func (stream, "%s",
1839 			    arm_conditional [(given >> 28) & 0xf]);
1840 		      break;
1841 
1842 		    case 'm':
1843 		      {
1844 			int started = 0;
1845 			int reg;
1846 
1847 			func (stream, "{");
1848 			for (reg = 0; reg < 16; reg++)
1849 			  if ((given & (1 << reg)) != 0)
1850 			    {
1851 			      if (started)
1852 				func (stream, ", ");
1853 			      started = 1;
1854 			      func (stream, "%s", arm_regnames[reg]);
1855 			    }
1856 			func (stream, "}");
1857 		      }
1858 		      break;
1859 
1860 		    case 'o':
1861 		      if ((given & 0x02000000) != 0)
1862 			{
1863 			  int rotate = (given & 0xf00) >> 7;
1864 			  int immed = (given & 0xff);
1865 			  immed = (((immed << (32 - rotate))
1866 				    | (immed >> rotate)) & 0xffffffff);
1867 			  func (stream, "#%d\t; 0x%x", immed, immed);
1868 			}
1869 		      else
1870 			arm_decode_shift (given, func, stream);
1871 		      break;
1872 
1873 		    case 'p':
1874 		      if ((given & 0x0000f000) == 0x0000f000)
1875 			func (stream, "p");
1876 		      break;
1877 
1878 		    case 't':
1879 		      if ((given & 0x01200000) == 0x00200000)
1880 			func (stream, "t");
1881 		      break;
1882 
1883 		    case 'A':
1884 		      func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1885 
1886 		      if ((given & (1 << 24)) != 0)
1887 			{
1888 			  int offset = given & 0xff;
1889 
1890 			  if (offset)
1891 			    func (stream, ", #%s%d]%s",
1892 				  ((given & 0x00800000) == 0 ? "-" : ""),
1893 				  offset * 4,
1894 				  ((given & 0x00200000) != 0 ? "!" : ""));
1895 			  else
1896 			    func (stream, "]");
1897 			}
1898 		      else
1899 			{
1900 			  int offset = given & 0xff;
1901 
1902 			  func (stream, "]");
1903 
1904 			  if (given & (1 << 21))
1905 			    {
1906 			      if (offset)
1907 				func (stream, ", #%s%d",
1908 				      ((given & 0x00800000) == 0 ? "-" : ""),
1909 				      offset * 4);
1910 			    }
1911 			  else
1912 			    func (stream, ", {%d}", offset);
1913 			}
1914 		      break;
1915 
1916 		    case 'B':
1917 		      /* Print ARM V5 BLX(1) address: pc+25 bits.  */
1918 		      {
1919 			bfd_vma address;
1920 			bfd_vma offset = 0;
1921 
1922 			if (given & 0x00800000)
1923 			  /* Is signed, hi bits should be ones.  */
1924 			  offset = (-1) ^ 0x00ffffff;
1925 
1926 			/* Offset is (SignExtend(offset field)<<2).  */
1927 			offset += given & 0x00ffffff;
1928 			offset <<= 2;
1929 			address = offset + pc + 8;
1930 
1931 			if (given & 0x01000000)
1932 			  /* H bit allows addressing to 2-byte boundaries.  */
1933 			  address += 2;
1934 
1935 		        info->print_address_func (address, info);
1936 		      }
1937 		      break;
1938 
1939 		    case 'C':
1940 		      func (stream, "_");
1941 		      if (given & 0x80000)
1942 			func (stream, "f");
1943 		      if (given & 0x40000)
1944 			func (stream, "s");
1945 		      if (given & 0x20000)
1946 			func (stream, "x");
1947 		      if (given & 0x10000)
1948 			func (stream, "c");
1949 		      break;
1950 
1951 		    case 'U':
1952 		      switch (given & 0xf)
1953 			{
1954 			case 0xf: func(stream, "sy"); break;
1955 			case 0x7: func(stream, "un"); break;
1956 			case 0xe: func(stream, "st"); break;
1957 			case 0x6: func(stream, "unst"); break;
1958 			default:
1959 			  func(stream, "#%d", (int)given & 0xf);
1960 			  break;
1961 			}
1962 		      break;
1963 
1964 		    case '0': case '1': case '2': case '3': case '4':
1965 		    case '5': case '6': case '7': case '8': case '9':
1966 		      {
1967 			int bitstart = *c++ - '0';
1968 			int bitend = 0;
1969 			while (*c >= '0' && *c <= '9')
1970 			  bitstart = (bitstart * 10) + *c++ - '0';
1971 
1972 			switch (*c)
1973 			  {
1974 			  case '-':
1975 			    c++;
1976 
1977 			    while (*c >= '0' && *c <= '9')
1978 			      bitend = (bitend * 10) + *c++ - '0';
1979 
1980 			    if (!bitend)
1981 			      abort ();
1982 
1983 			    switch (*c)
1984 			      {
1985 			      case 'r':
1986 				{
1987 				  long reg;
1988 
1989 				  reg = given >> bitstart;
1990 				  reg &= (2 << (bitend - bitstart)) - 1;
1991 
1992 				  func (stream, "%s", arm_regnames[reg]);
1993 				}
1994 				break;
1995 			      case 'd':
1996 				{
1997 				  long reg;
1998 
1999 				  reg = given >> bitstart;
2000 				  reg &= (2 << (bitend - bitstart)) - 1;
2001 
2002 				  func (stream, "%ld", reg);
2003 				}
2004 				break;
2005 			      case 'W':
2006 				{
2007 				  long reg;
2008 
2009 				  reg = given >> bitstart;
2010 				  reg &= (2 << (bitend - bitstart)) - 1;
2011 
2012 				  func (stream, "%ld", reg + 1);
2013 				}
2014 				break;
2015 			      case 'x':
2016 				{
2017 				  long reg;
2018 
2019 				  reg = given >> bitstart;
2020 				  reg &= (2 << (bitend - bitstart)) - 1;
2021 
2022 				  func (stream, "0x%08lx", reg);
2023 
2024 				  /* Some SWI instructions have special
2025 				     meanings.  */
2026 				  if ((given & 0x0fffffff) == 0x0FF00000)
2027 				    func (stream, "\t; IMB");
2028 				  else if ((given & 0x0fffffff) == 0x0FF00001)
2029 				    func (stream, "\t; IMBRange");
2030 				}
2031 				break;
2032 			      case 'X':
2033 				{
2034 				  long reg;
2035 
2036 				  reg = given >> bitstart;
2037 				  reg &= (2 << (bitend - bitstart)) - 1;
2038 
2039 				  func (stream, "%01lx", reg & 0xf);
2040 				}
2041 				break;
2042 			      default:
2043 				abort ();
2044 			      }
2045 			    break;
2046 
2047 			  case '`':
2048 			    c++;
2049 			    if ((given & (1 << bitstart)) == 0)
2050 			      func (stream, "%c", *c);
2051 			    break;
2052 			  case '\'':
2053 			    c++;
2054 			    if ((given & (1 << bitstart)) != 0)
2055 			      func (stream, "%c", *c);
2056 			    break;
2057 			  case '?':
2058 			    ++c;
2059 			    if ((given & (1 << bitstart)) != 0)
2060 			      func (stream, "%c", *c++);
2061 			    else
2062 			      func (stream, "%c", *++c);
2063 			    break;
2064 			  default:
2065 			    abort ();
2066 			  }
2067 			break;
2068 
2069 		      case 'e':
2070 			{
2071 			  int imm;
2072 
2073 			  imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2074 			  func (stream, "%d", imm);
2075 			}
2076 			break;
2077 
2078 		      case 'E':
2079 			/* LSB and WIDTH fields of BFI or BFC.  The machine-
2080 			   language instruction encodes LSB and MSB.  */
2081 			{
2082 			  long msb = (given & 0x001f0000) >> 16;
2083 			  long lsb = (given & 0x00000f80) >> 7;
2084 
2085 			  long width = msb - lsb + 1;
2086 			  if (width > 0)
2087 			    func (stream, "#%lu, #%lu", lsb, width);
2088 			  else
2089 			    func (stream, "(invalid: %lu:%lu)", lsb, msb);
2090 			}
2091 			break;
2092 
2093 		      case 'V':
2094 			/* 16-bit unsigned immediate from a MOVT or MOVW
2095 			   instruction, encoded in bits 0:11 and 15:19.  */
2096 			{
2097 			  long hi = (given & 0x000f0000) >> 4;
2098 			  long lo = (given & 0x00000fff);
2099 			  long imm16 = hi | lo;
2100 			  func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2101 			}
2102 			break;
2103 
2104 		      default:
2105 			abort ();
2106 		      }
2107 		    }
2108 		}
2109 	      else
2110 		func (stream, "%c", *c);
2111 	    }
2112 	  return;
2113 	}
2114     }
2115   abort ();
2116 }
2117 
2118 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
2119 
2120 static void
2121 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2122 {
2123   const struct opcode16 *insn;
2124   void *stream = info->stream;
2125   fprintf_ftype func = info->fprintf_func;
2126 
2127   for (insn = thumb_opcodes; insn->assembler; insn++)
2128     if ((given & insn->mask) == insn->value)
2129       {
2130 	const char *c = insn->assembler;
2131 	for (; *c; c++)
2132 	  {
2133 	    int domaskpc = 0;
2134 	    int domasklr = 0;
2135 
2136 	    if (*c != '%')
2137 	      {
2138 		func (stream, "%c", *c);
2139 		continue;
2140 	      }
2141 
2142 	    switch (*++c)
2143 	      {
2144 	      case '%':
2145 		func (stream, "%%");
2146 		break;
2147 
2148 	      case 'S':
2149 		{
2150 		  long reg;
2151 
2152 		  reg = (given >> 3) & 0x7;
2153 		  if (given & (1 << 6))
2154 		    reg += 8;
2155 
2156 		  func (stream, "%s", arm_regnames[reg]);
2157 		}
2158 		break;
2159 
2160 	      case 'D':
2161 		{
2162 		  long reg;
2163 
2164 		  reg = given & 0x7;
2165 		  if (given & (1 << 7))
2166 		    reg += 8;
2167 
2168 		  func (stream, "%s", arm_regnames[reg]);
2169 		}
2170 		break;
2171 
2172 	      case 'N':
2173 		if (given & (1 << 8))
2174 		  domasklr = 1;
2175 		/* Fall through.  */
2176 	      case 'O':
2177 		if (*c == 'O' && (given & (1 << 8)))
2178 		  domaskpc = 1;
2179 		/* Fall through.  */
2180 	      case 'M':
2181 		{
2182 		  int started = 0;
2183 		  int reg;
2184 
2185 		  func (stream, "{");
2186 
2187 		  /* It would be nice if we could spot
2188 		     ranges, and generate the rS-rE format: */
2189 		  for (reg = 0; (reg < 8); reg++)
2190 		    if ((given & (1 << reg)) != 0)
2191 		      {
2192 			if (started)
2193 			  func (stream, ", ");
2194 			started = 1;
2195 			func (stream, "%s", arm_regnames[reg]);
2196 		      }
2197 
2198 		  if (domasklr)
2199 		    {
2200 		      if (started)
2201 			func (stream, ", ");
2202 		      started = 1;
2203 		      func (stream, arm_regnames[14] /* "lr" */);
2204 		    }
2205 
2206 		  if (domaskpc)
2207 		    {
2208 		      if (started)
2209 			func (stream, ", ");
2210 		      func (stream, arm_regnames[15] /* "pc" */);
2211 		    }
2212 
2213 		  func (stream, "}");
2214 		}
2215 		break;
2216 
2217 	      case 'b':
2218 		/* Print ARM V6T2 CZB address: pc+4+6 bits.  */
2219 		{
2220 		  bfd_vma address = (pc + 4
2221 				     + ((given & 0x00f8) >> 2)
2222 				     + ((given & 0x0200) >> 3));
2223 		  info->print_address_func (address, info);
2224 		}
2225 		break;
2226 
2227 	      case 's':
2228 		/* Right shift immediate -- bits 6..10; 1-31 print
2229 		   as themselves, 0 prints as 32.  */
2230 		{
2231 		  long imm = (given & 0x07c0) >> 6;
2232 		  if (imm == 0)
2233 		    imm = 32;
2234 		  func (stream, "#%ld", imm);
2235 		}
2236 		break;
2237 
2238 	      case '0': case '1': case '2': case '3': case '4':
2239 	      case '5': case '6': case '7': case '8': case '9':
2240 		{
2241 		  int bitstart = *c++ - '0';
2242 		  int bitend = 0;
2243 
2244 		  while (*c >= '0' && *c <= '9')
2245 		    bitstart = (bitstart * 10) + *c++ - '0';
2246 
2247 		  switch (*c)
2248 		    {
2249 		    case '-':
2250 		      {
2251 			long reg;
2252 
2253 			c++;
2254 			while (*c >= '0' && *c <= '9')
2255 			  bitend = (bitend * 10) + *c++ - '0';
2256 			if (!bitend)
2257 			  abort ();
2258 			reg = given >> bitstart;
2259 			reg &= (2 << (bitend - bitstart)) - 1;
2260 			switch (*c)
2261 			  {
2262 			  case 'r':
2263 			    func (stream, "%s", arm_regnames[reg]);
2264 			    break;
2265 
2266 			  case 'd':
2267 			    func (stream, "%ld", reg);
2268 			    break;
2269 
2270 			  case 'H':
2271 			    func (stream, "%ld", reg << 1);
2272 			    break;
2273 
2274 			  case 'W':
2275 			    func (stream, "%ld", reg << 2);
2276 			    break;
2277 
2278 			  case 'a':
2279 			    /* PC-relative address -- the bottom two
2280 			       bits of the address are dropped
2281 			       before the calculation.  */
2282 			    info->print_address_func
2283 			      (((pc + 4) & ~3) + (reg << 2), info);
2284 			    break;
2285 
2286 			  case 'x':
2287 			    func (stream, "0x%04lx", reg);
2288 			    break;
2289 
2290 			  case 'B':
2291 			    reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2292 			    info->print_address_func (reg * 2 + pc + 4, info);
2293 			    break;
2294 
2295 			  case 'c':
2296 			    {
2297 			      /* Must print 0xE as 'al' to distinguish
2298 				 unconditional B from conditional BAL.  */
2299 			      if (reg == 0xE)
2300 				func (stream, "al");
2301 			      else
2302 				func (stream, "%s", arm_conditional [reg]);
2303 			    }
2304 			    break;
2305 
2306 			  default:
2307 			    abort ();
2308 			  }
2309 		      }
2310 		      break;
2311 
2312 		    case '\'':
2313 		      c++;
2314 		      if ((given & (1 << bitstart)) != 0)
2315 			func (stream, "%c", *c);
2316 		      break;
2317 
2318 		    case '?':
2319 		      ++c;
2320 		      if ((given & (1 << bitstart)) != 0)
2321 			func (stream, "%c", *c++);
2322 		      else
2323 			func (stream, "%c", *++c);
2324 		      break;
2325 
2326 		    default:
2327 		      abort ();
2328 		    }
2329 		}
2330 		break;
2331 
2332 	      default:
2333 		abort ();
2334 	      }
2335 	  }
2336 	return;
2337       }
2338 
2339   /* No match.  */
2340   abort ();
2341 }
2342 
2343 /* Return the name of an V7M special register.  */
2344 static const char *
2345 psr_name (int regno)
2346 {
2347   switch (regno)
2348     {
2349     case 0: return "APSR";
2350     case 1: return "IAPSR";
2351     case 2: return "EAPSR";
2352     case 3: return "PSR";
2353     case 5: return "IPSR";
2354     case 6: return "EPSR";
2355     case 7: return "IEPSR";
2356     case 8: return "MSP";
2357     case 9: return "PSP";
2358     case 16: return "PRIMASK";
2359     case 17: return "BASEPRI";
2360     case 18: return "BASEPRI_MASK";
2361     case 19: return "FAULTMASK";
2362     case 20: return "CONTROL";
2363     default: return "<unknown>";
2364     }
2365 }
2366 
2367 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
2368 
2369 static void
2370 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
2371 {
2372   const struct opcode32 *insn;
2373   void *stream = info->stream;
2374   fprintf_ftype func = info->fprintf_func;
2375 
2376   if (print_insn_coprocessor (info, given, TRUE))
2377     return;
2378 
2379   for (insn = thumb32_opcodes; insn->assembler; insn++)
2380     if ((given & insn->mask) == insn->value)
2381       {
2382 	const char *c = insn->assembler;
2383 	for (; *c; c++)
2384 	  {
2385 	    if (*c != '%')
2386 	      {
2387 		func (stream, "%c", *c);
2388 		continue;
2389 	      }
2390 
2391 	    switch (*++c)
2392 	      {
2393 	      case '%':
2394 		func (stream, "%%");
2395 		break;
2396 
2397 	      case 'I':
2398 		{
2399 		  unsigned int imm12 = 0;
2400 		  imm12 |= (given & 0x000000ffu);
2401 		  imm12 |= (given & 0x00007000u) >> 4;
2402 		  imm12 |= (given & 0x04000000u) >> 15;
2403 		  func (stream, "#%u\t; 0x%x", imm12, imm12);
2404 		}
2405 		break;
2406 
2407 	      case 'M':
2408 		{
2409 		  unsigned int bits = 0, imm, imm8, mod;
2410 		  bits |= (given & 0x000000ffu);
2411 		  bits |= (given & 0x00007000u) >> 4;
2412 		  bits |= (given & 0x04000000u) >> 15;
2413 		  imm8 = (bits & 0x0ff);
2414 		  mod = (bits & 0xf00) >> 8;
2415 		  switch (mod)
2416 		    {
2417 		    case 0: imm = imm8; break;
2418 		    case 1: imm = ((imm8<<16) | imm8); break;
2419 		    case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
2420 		    case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
2421 		    default:
2422 		      mod  = (bits & 0xf80) >> 7;
2423 		      imm8 = (bits & 0x07f) | 0x80;
2424 		      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
2425 		    }
2426 		  func (stream, "#%u\t; 0x%x", imm, imm);
2427 		}
2428 		break;
2429 
2430 	      case 'J':
2431 		{
2432 		  unsigned int imm = 0;
2433 		  imm |= (given & 0x000000ffu);
2434 		  imm |= (given & 0x00007000u) >> 4;
2435 		  imm |= (given & 0x04000000u) >> 15;
2436 		  imm |= (given & 0x000f0000u) >> 4;
2437 		  func (stream, "#%u\t; 0x%x", imm, imm);
2438 		}
2439 		break;
2440 
2441 	      case 'K':
2442 		{
2443 		  unsigned int imm = 0;
2444 		  imm |= (given & 0x000f0000u) >> 16;
2445 		  imm |= (given & 0x00000ff0u) >> 0;
2446 		  imm |= (given & 0x0000000fu) << 12;
2447 		  func (stream, "#%u\t; 0x%x", imm, imm);
2448 		}
2449 		break;
2450 
2451 	      case 'S':
2452 		{
2453 		  unsigned int reg = (given & 0x0000000fu);
2454 		  unsigned int stp = (given & 0x00000030u) >> 4;
2455 		  unsigned int imm = 0;
2456 		  imm |= (given & 0x000000c0u) >> 6;
2457 		  imm |= (given & 0x00007000u) >> 10;
2458 
2459 		  func (stream, "%s", arm_regnames[reg]);
2460 		  switch (stp)
2461 		    {
2462 		    case 0:
2463 		      if (imm > 0)
2464 			func (stream, ", lsl #%u", imm);
2465 		      break;
2466 
2467 		    case 1:
2468 		      if (imm == 0)
2469 			imm = 32;
2470 		      func (stream, ", lsr #%u", imm);
2471 		      break;
2472 
2473 		    case 2:
2474 		      if (imm == 0)
2475 			imm = 32;
2476 		      func (stream, ", asr #%u", imm);
2477 		      break;
2478 
2479 		    case 3:
2480 		      if (imm == 0)
2481 			func (stream, ", rrx");
2482 		      else
2483 			func (stream, ", ror #%u", imm);
2484 		    }
2485 		}
2486 		break;
2487 
2488 	      case 'a':
2489 		{
2490 		  unsigned int Rn  = (given & 0x000f0000) >> 16;
2491 		  unsigned int U   = (given & 0x00800000) >> 23;
2492 		  unsigned int op  = (given & 0x00000f00) >> 8;
2493 		  unsigned int i12 = (given & 0x00000fff);
2494 		  unsigned int i8  = (given & 0x000000ff);
2495 		  bfd_boolean writeback = FALSE, postind = FALSE;
2496 		  int offset = 0;
2497 
2498 		  func (stream, "[%s", arm_regnames[Rn]);
2499 		  if (U) /* 12-bit positive immediate offset */
2500 		    offset = i12;
2501 		  else if (Rn == 15) /* 12-bit negative immediate offset */
2502 		    offset = -(int)i12;
2503 		  else if (op == 0x0) /* shifted register offset */
2504 		    {
2505 		      unsigned int Rm = (i8 & 0x0f);
2506 		      unsigned int sh = (i8 & 0x30) >> 4;
2507 		      func (stream, ", %s", arm_regnames[Rm]);
2508 		      if (sh)
2509 			func (stream, ", lsl #%u", sh);
2510 		      func (stream, "]");
2511 		      break;
2512 		    }
2513 		  else switch (op)
2514 		    {
2515 		    case 0xE:  /* 8-bit positive immediate offset */
2516 		      offset = i8;
2517 		      break;
2518 
2519 		    case 0xC:  /* 8-bit negative immediate offset */
2520 		      offset = -i8;
2521 		      break;
2522 
2523 		    case 0xF:  /* 8-bit + preindex with wb */
2524 		      offset = i8;
2525 		      writeback = TRUE;
2526 		      break;
2527 
2528 		    case 0xD:  /* 8-bit - preindex with wb */
2529 		      offset = -i8;
2530 		      writeback = TRUE;
2531 		      break;
2532 
2533 		    case 0xB:  /* 8-bit + postindex */
2534 		      offset = i8;
2535 		      postind = TRUE;
2536 		      break;
2537 
2538 		    case 0x9:  /* 8-bit - postindex */
2539 		      offset = -i8;
2540 		      postind = TRUE;
2541 		      break;
2542 
2543 		    default:
2544 		      func (stream, ", <undefined>]");
2545 		      goto skip;
2546 		    }
2547 
2548 		  if (postind)
2549 		    func (stream, "], #%d", offset);
2550 		  else
2551 		    {
2552 		      if (offset)
2553 			func (stream, ", #%d", offset);
2554 		      func (stream, writeback ? "]!" : "]");
2555 		    }
2556 
2557 		  if (Rn == 15)
2558 		    {
2559 		      func (stream, "\t; ");
2560 		      info->print_address_func (((pc + 4) & ~3) + offset, info);
2561 		    }
2562 		}
2563 	      skip:
2564 		break;
2565 
2566 	      case 'A':
2567 		{
2568 		  unsigned int P   = (given & 0x01000000) >> 24;
2569 		  unsigned int U   = (given & 0x00800000) >> 23;
2570 		  unsigned int W   = (given & 0x00400000) >> 21;
2571 		  unsigned int Rn  = (given & 0x000f0000) >> 16;
2572 		  unsigned int off = (given & 0x000000ff);
2573 
2574 		  func (stream, "[%s", arm_regnames[Rn]);
2575 		  if (P)
2576 		    {
2577 		      if (off || !U)
2578 			func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2579 		      func (stream, "]");
2580 		      if (W)
2581 			func (stream, "!");
2582 		    }
2583 		  else
2584 		    {
2585 		      func (stream, "], ");
2586 		      if (W)
2587 			func (stream, "#%c%u", U ? '+' : '-', off * 4);
2588 		      else
2589 			func (stream, "{%u}", off);
2590 		    }
2591 		}
2592 		break;
2593 
2594 	      case 'w':
2595 		{
2596 		  unsigned int Sbit = (given & 0x01000000) >> 24;
2597 		  unsigned int type = (given & 0x00600000) >> 21;
2598 		  switch (type)
2599 		    {
2600 		    case 0: func (stream, Sbit ? "sb" : "b"); break;
2601 		    case 1: func (stream, Sbit ? "sh" : "h"); break;
2602 		    case 2:
2603 		      if (Sbit)
2604 			func (stream, "??");
2605 		      break;
2606 		    case 3:
2607 		      func (stream, "??");
2608 		      break;
2609 		    }
2610 		}
2611 		break;
2612 
2613 	      case 'm':
2614 		{
2615 		  int started = 0;
2616 		  int reg;
2617 
2618 		  func (stream, "{");
2619 		  for (reg = 0; reg < 16; reg++)
2620 		    if ((given & (1 << reg)) != 0)
2621 		      {
2622 			if (started)
2623 			  func (stream, ", ");
2624 			started = 1;
2625 			func (stream, "%s", arm_regnames[reg]);
2626 		      }
2627 		  func (stream, "}");
2628 		}
2629 		break;
2630 
2631 	      case 'E':
2632 		{
2633 		  unsigned int msb = (given & 0x0000001f);
2634 		  unsigned int lsb = 0;
2635 		  lsb |= (given & 0x000000c0u) >> 6;
2636 		  lsb |= (given & 0x00007000u) >> 10;
2637 		  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
2638 		}
2639 		break;
2640 
2641 	      case 'F':
2642 		{
2643 		  unsigned int width = (given & 0x0000001f) + 1;
2644 		  unsigned int lsb = 0;
2645 		  lsb |= (given & 0x000000c0u) >> 6;
2646 		  lsb |= (given & 0x00007000u) >> 10;
2647 		  func (stream, "#%u, #%u", lsb, width);
2648 		}
2649 		break;
2650 
2651 	      case 'b':
2652 		{
2653 		  unsigned int S = (given & 0x04000000u) >> 26;
2654 		  unsigned int J1 = (given & 0x00002000u) >> 13;
2655 		  unsigned int J2 = (given & 0x00000800u) >> 11;
2656 		  int offset = 0;
2657 
2658 		  offset |= !S << 20;
2659 		  offset |= J2 << 19;
2660 		  offset |= J1 << 18;
2661 		  offset |= (given & 0x003f0000) >> 4;
2662 		  offset |= (given & 0x000007ff) << 1;
2663 		  offset -= (1 << 20);
2664 
2665 		  info->print_address_func (pc + 4 + offset, info);
2666 		}
2667 		break;
2668 
2669 	      case 'B':
2670 		{
2671 		  unsigned int S = (given & 0x04000000u) >> 26;
2672 		  unsigned int I1 = (given & 0x00002000u) >> 13;
2673 		  unsigned int I2 = (given & 0x00000800u) >> 11;
2674 		  int offset = 0;
2675 
2676 		  offset |= !S << 24;
2677 		  offset |= !(I1 ^ S) << 23;
2678 		  offset |= !(I2 ^ S) << 22;
2679 		  offset |= (given & 0x03ff0000u) >> 4;
2680 		  offset |= (given & 0x000007ffu) << 1;
2681 		  offset -= (1 << 24);
2682 		  offset += pc + 4;
2683 
2684 		  /* BLX target addresses are always word aligned.  */
2685 		  if ((given & 0x00001000u) == 0)
2686 		      offset &= ~2u;
2687 
2688 		  info->print_address_func (offset, info);
2689 		}
2690 		break;
2691 
2692 	      case 's':
2693 		{
2694 		  unsigned int shift = 0;
2695 		  shift |= (given & 0x000000c0u) >> 6;
2696 		  shift |= (given & 0x00007000u) >> 10;
2697 		  if (given & 0x00200000u)
2698 		    func (stream, ", asr #%u", shift);
2699 		  else if (shift)
2700 		    func (stream, ", lsl #%u", shift);
2701 		  /* else print nothing - lsl #0 */
2702 		}
2703 		break;
2704 
2705 	      case 'R':
2706 		{
2707 		  unsigned int rot = (given & 0x00000030) >> 4;
2708 		  if (rot)
2709 		    func (stream, ", ror #%u", rot * 8);
2710 		}
2711 		break;
2712 
2713 	      case 'U':
2714 		switch (given & 0xf)
2715 		  {
2716 		  case 0xf: func(stream, "sy"); break;
2717 		  case 0x7: func(stream, "un"); break;
2718 		  case 0xe: func(stream, "st"); break;
2719 		  case 0x6: func(stream, "unst"); break;
2720 		  default:
2721 		    func(stream, "#%d", (int)given & 0xf);
2722 		    break;
2723 		  }
2724 		break;
2725 
2726 	      case 'C':
2727 		if ((given & 0xff) == 0)
2728 		  {
2729 		    func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
2730 		    if (given & 0x800)
2731 		      func (stream, "f");
2732 		    if (given & 0x400)
2733 		      func (stream, "s");
2734 		    if (given & 0x200)
2735 		      func (stream, "x");
2736 		    if (given & 0x100)
2737 		      func (stream, "c");
2738 		  }
2739 		else
2740 		  {
2741 		    func (stream, psr_name (given & 0xff));
2742 		  }
2743 		break;
2744 
2745 	      case 'D':
2746 		if ((given & 0xff) == 0)
2747 		  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
2748 		else
2749 		  func (stream, psr_name (given & 0xff));
2750 		break;
2751 
2752 	      case '0': case '1': case '2': case '3': case '4':
2753 	      case '5': case '6': case '7': case '8': case '9':
2754 		{
2755 		  int bitstart = *c++ - '0';
2756 		  int bitend = 0;
2757 		  unsigned int val;
2758 		  while (*c >= '0' && *c <= '9')
2759 		    bitstart = (bitstart * 10) + *c++ - '0';
2760 
2761 		  if (*c == '-')
2762 		    {
2763 		      c++;
2764 		      while (*c >= '0' && *c <= '9')
2765 			bitend = (bitend * 10) + *c++ - '0';
2766 		      if (!bitend)
2767 			abort ();
2768 
2769 		      val = given >> bitstart;
2770 		      val &= (2 << (bitend - bitstart)) - 1;
2771 		    }
2772 		  else
2773 		    val = (given >> bitstart) & 1;
2774 
2775 		  switch (*c)
2776 		    {
2777 		    case 'd': func (stream, "%u", val); break;
2778 		    case 'W': func (stream, "%u", val * 4); break;
2779 		    case 'r': func (stream, "%s", arm_regnames[val]); break;
2780 
2781 		    case 'c':
2782 		      if (val == 0xE)
2783 			func (stream, "al");
2784 		      else
2785 			func (stream, "%s", arm_conditional[val]);
2786 		      break;
2787 
2788 		    case '\'':
2789 		      if (val)
2790 			func (stream, "%c", c[1]);
2791 		      c++;
2792 		      break;
2793 
2794 		    case '`':
2795 		      if (!val)
2796 			func (stream, "%c", c[1]);
2797 		      c++;
2798 		      break;
2799 
2800 		    case '?':
2801 		      func (stream, "%c", val ? c[1] : c[2]);
2802 		      c += 2;
2803 		      break;
2804 
2805 		    default:
2806 		      abort ();
2807 		    }
2808 		}
2809 		break;
2810 
2811 	      default:
2812 		abort ();
2813 	      }
2814 	  }
2815 	return;
2816       }
2817 
2818   /* No match.  */
2819   abort ();
2820 }
2821 
2822 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2823    being displayed in symbol relative addresses.  */
2824 
2825 bfd_boolean
2826 arm_symbol_is_valid (asymbol * sym,
2827 		     struct disassemble_info * info ATTRIBUTE_UNUSED)
2828 {
2829   const char * name;
2830 
2831   if (sym == NULL)
2832     return FALSE;
2833 
2834   name = bfd_asymbol_name (sym);
2835 
2836   return (name && *name != '$');
2837 }
2838 
2839 /* Parse an individual disassembler option.  */
2840 
2841 void
2842 parse_arm_disassembler_option (char *option)
2843 {
2844   if (option == NULL)
2845     return;
2846 
2847   if (strneq (option, "reg-names-", 10))
2848     {
2849       int i;
2850 
2851       option += 10;
2852 
2853       for (i = NUM_ARM_REGNAMES; i--;)
2854 	if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2855 	  {
2856 	    regname_selected = i;
2857 	    break;
2858 	  }
2859 
2860       if (i < 0)
2861 	/* XXX - should break 'option' at following delimiter.  */
2862 	fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2863     }
2864   else if (strneq (option, "force-thumb", 11))
2865     force_thumb = 1;
2866   else if (strneq (option, "no-force-thumb", 14))
2867     force_thumb = 0;
2868   else
2869     /* XXX - should break 'option' at following delimiter.  */
2870     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2871 
2872   return;
2873 }
2874 
2875 /* Parse the string of disassembler options, spliting it at whitespaces
2876    or commas.  (Whitespace separators supported for backwards compatibility).  */
2877 
2878 static void
2879 parse_disassembler_options (char *options)
2880 {
2881   if (options == NULL)
2882     return;
2883 
2884   while (*options)
2885     {
2886       parse_arm_disassembler_option (options);
2887 
2888       /* Skip forward to next seperator.  */
2889       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2890 	++ options;
2891       /* Skip forward past seperators.  */
2892       while (ISSPACE (*options) || (*options == ','))
2893 	++ options;
2894     }
2895 }
2896 
2897 /* NOTE: There are no checks in these routines that
2898    the relevant number of data bytes exist.  */
2899 
2900 static int
2901 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
2902 {
2903   unsigned char b[4];
2904   long		given;
2905   int           status;
2906   int           is_thumb;
2907   int		size;
2908   void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
2909 
2910   if (info->disassembler_options)
2911     {
2912       parse_disassembler_options (info->disassembler_options);
2913 
2914       /* To avoid repeated parsing of these options, we remove them here.  */
2915       info->disassembler_options = NULL;
2916     }
2917 
2918   is_thumb = force_thumb;
2919 
2920   if (!is_thumb && info->symbols != NULL)
2921     {
2922       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2923 	{
2924 	  coff_symbol_type * cs;
2925 
2926 	  cs = coffsymbol (*info->symbols);
2927 	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
2928 		      || cs->native->u.syment.n_sclass == C_THUMBSTAT
2929 		      || cs->native->u.syment.n_sclass == C_THUMBLABEL
2930 		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2931 		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2932 	}
2933       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2934 	{
2935 	  elf_symbol_type *  es;
2936 	  unsigned int       type;
2937 
2938 	  es = *(elf_symbol_type **)(info->symbols);
2939 	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2940 
2941 	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2942 	}
2943     }
2944 
2945   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2946   info->bytes_per_line = 4;
2947 
2948   if (!is_thumb)
2949     {
2950       /* In ARM mode endianness is a straightforward issue: the instruction
2951 	 is four bytes long and is either ordered 0123 or 3210.  */
2952       printer = print_insn_arm;
2953       info->bytes_per_chunk = 4;
2954       size = 4;
2955 
2956       status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2957       if (little)
2958 	given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2959       else
2960 	given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2961     }
2962   else
2963     {
2964       /* In Thumb mode we have the additional wrinkle of two
2965 	 instruction lengths.  Fortunately, the bits that determine
2966 	 the length of the current instruction are always to be found
2967 	 in the first two bytes.  */
2968       printer = print_insn_thumb16;
2969       info->bytes_per_chunk = 2;
2970       size = 2;
2971 
2972       status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2973       if (little)
2974 	given = (b[0]) | (b[1] << 8);
2975       else
2976 	given = (b[1]) | (b[0] << 8);
2977 
2978       if (!status)
2979 	{
2980 	  /* These bit patterns signal a four-byte Thumb
2981 	     instruction.  */
2982 	  if ((given & 0xF800) == 0xF800
2983 	      || (given & 0xF800) == 0xF000
2984 	      || (given & 0xF800) == 0xE800)
2985 	    {
2986 	      status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2987 	      if (little)
2988 		given = (b[0]) | (b[1] << 8) | (given << 16);
2989 	      else
2990 		given = (b[1]) | (b[0] << 8) | (given << 16);
2991 
2992 	      printer = print_insn_thumb32;
2993 	      size = 4;
2994 	    }
2995 	}
2996     }
2997 
2998   if (status)
2999     {
3000       info->memory_error_func (status, pc, info);
3001       return -1;
3002     }
3003   if (info->flags & INSN_HAS_RELOC)
3004     /* If the instruction has a reloc associated with it, then
3005        the offset field in the instruction will actually be the
3006        addend for the reloc.  (We are using REL type relocs).
3007        In such cases, we can ignore the pc when computing
3008        addresses, since the addend is not currently pc-relative.  */
3009     pc = 0;
3010 
3011   printer (pc, info, given);
3012   return size;
3013 }
3014 
3015 int
3016 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3017 {
3018   return print_insn (pc, info, FALSE);
3019 }
3020 
3021 int
3022 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3023 {
3024   return print_insn (pc, info, TRUE);
3025 }
3026 
3027 void
3028 print_arm_disassembler_options (FILE *stream)
3029 {
3030   int i;
3031 
3032   fprintf (stream, _("\n\
3033 The following ARM specific disassembler options are supported for use with\n\
3034 the -M switch:\n"));
3035 
3036   for (i = NUM_ARM_REGNAMES; i--;)
3037     fprintf (stream, "  reg-names-%s %*c%s\n",
3038 	     regnames[i].name,
3039 	     (int)(14 - strlen (regnames[i].name)), ' ',
3040 	     regnames[i].description);
3041 
3042   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
3043   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
3044 }
3045