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
get_arm_regname_num_options(void)1129 get_arm_regname_num_options (void)
1130 {
1131   return NUM_ARM_REGNAMES;
1132 }
1133 
1134 int
set_arm_regname_option(int option)1135 set_arm_regname_option (int option)
1136 {
1137   int old = regname_selected;
1138   regname_selected = option;
1139   return old;
1140 }
1141 
1142 int
get_arm_regnames(int option,const char ** setname,const char ** setdescription,const char * const ** register_names)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
arm_decode_shift(long given,fprintf_ftype func,void * stream)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
print_insn_coprocessor(struct disassemble_info * info,long given,bfd_boolean thumb)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
print_arm_address(bfd_vma pc,struct disassemble_info * info,long given)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
print_insn_arm(bfd_vma pc,struct disassemble_info * info,long given)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 0x2: func(stream, "oshst"); break;
1955 			case 0x3: func(stream, "osh"); break;
1956 			case 0x6: func(stream, "nshst"); break;
1957 			case 0x7: func(stream, "nsh"); break;
1958 			case 0xa: func(stream, "ishst"); break;
1959 			case 0xb: func(stream, "ish"); break;
1960 			case 0xe: func(stream, "st"); break;
1961 			case 0xf: func(stream, "sy"); break;
1962 			default:
1963 			  func(stream, "#%d", (int)given & 0xf);
1964 			  break;
1965 			}
1966 		      break;
1967 
1968 		    case '0': case '1': case '2': case '3': case '4':
1969 		    case '5': case '6': case '7': case '8': case '9':
1970 		      {
1971 			int bitstart = *c++ - '0';
1972 			int bitend = 0;
1973 			while (*c >= '0' && *c <= '9')
1974 			  bitstart = (bitstart * 10) + *c++ - '0';
1975 
1976 			switch (*c)
1977 			  {
1978 			  case '-':
1979 			    c++;
1980 
1981 			    while (*c >= '0' && *c <= '9')
1982 			      bitend = (bitend * 10) + *c++ - '0';
1983 
1984 			    if (!bitend)
1985 			      abort ();
1986 
1987 			    switch (*c)
1988 			      {
1989 			      case 'r':
1990 				{
1991 				  long reg;
1992 
1993 				  reg = given >> bitstart;
1994 				  reg &= (2 << (bitend - bitstart)) - 1;
1995 
1996 				  func (stream, "%s", arm_regnames[reg]);
1997 				}
1998 				break;
1999 			      case 'd':
2000 				{
2001 				  long reg;
2002 
2003 				  reg = given >> bitstart;
2004 				  reg &= (2 << (bitend - bitstart)) - 1;
2005 
2006 				  func (stream, "%ld", reg);
2007 				}
2008 				break;
2009 			      case 'W':
2010 				{
2011 				  long reg;
2012 
2013 				  reg = given >> bitstart;
2014 				  reg &= (2 << (bitend - bitstart)) - 1;
2015 
2016 				  func (stream, "%ld", reg + 1);
2017 				}
2018 				break;
2019 			      case 'x':
2020 				{
2021 				  long reg;
2022 
2023 				  reg = given >> bitstart;
2024 				  reg &= (2 << (bitend - bitstart)) - 1;
2025 
2026 				  func (stream, "0x%08lx", reg);
2027 
2028 				  /* Some SWI instructions have special
2029 				     meanings.  */
2030 				  if ((given & 0x0fffffff) == 0x0FF00000)
2031 				    func (stream, "\t; IMB");
2032 				  else if ((given & 0x0fffffff) == 0x0FF00001)
2033 				    func (stream, "\t; IMBRange");
2034 				}
2035 				break;
2036 			      case 'X':
2037 				{
2038 				  long reg;
2039 
2040 				  reg = given >> bitstart;
2041 				  reg &= (2 << (bitend - bitstart)) - 1;
2042 
2043 				  func (stream, "%01lx", reg & 0xf);
2044 				}
2045 				break;
2046 			      default:
2047 				abort ();
2048 			      }
2049 			    break;
2050 
2051 			  case '`':
2052 			    c++;
2053 			    if ((given & (1 << bitstart)) == 0)
2054 			      func (stream, "%c", *c);
2055 			    break;
2056 			  case '\'':
2057 			    c++;
2058 			    if ((given & (1 << bitstart)) != 0)
2059 			      func (stream, "%c", *c);
2060 			    break;
2061 			  case '?':
2062 			    ++c;
2063 			    if ((given & (1 << bitstart)) != 0)
2064 			      func (stream, "%c", *c++);
2065 			    else
2066 			      func (stream, "%c", *++c);
2067 			    break;
2068 			  default:
2069 			    abort ();
2070 			  }
2071 			break;
2072 
2073 		      case 'e':
2074 			{
2075 			  int imm;
2076 
2077 			  imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2078 			  func (stream, "%d", imm);
2079 			}
2080 			break;
2081 
2082 		      case 'E':
2083 			/* LSB and WIDTH fields of BFI or BFC.  The machine-
2084 			   language instruction encodes LSB and MSB.  */
2085 			{
2086 			  long msb = (given & 0x001f0000) >> 16;
2087 			  long lsb = (given & 0x00000f80) >> 7;
2088 
2089 			  long width = msb - lsb + 1;
2090 			  if (width > 0)
2091 			    func (stream, "#%lu, #%lu", lsb, width);
2092 			  else
2093 			    func (stream, "(invalid: %lu:%lu)", lsb, msb);
2094 			}
2095 			break;
2096 
2097 		      case 'V':
2098 			/* 16-bit unsigned immediate from a MOVT or MOVW
2099 			   instruction, encoded in bits 0:11 and 15:19.  */
2100 			{
2101 			  long hi = (given & 0x000f0000) >> 4;
2102 			  long lo = (given & 0x00000fff);
2103 			  long imm16 = hi | lo;
2104 			  func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2105 			}
2106 			break;
2107 
2108 		      default:
2109 			abort ();
2110 		      }
2111 		    }
2112 		}
2113 	      else
2114 		func (stream, "%c", *c);
2115 	    }
2116 	  return;
2117 	}
2118     }
2119   abort ();
2120 }
2121 
2122 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
2123 
2124 static void
print_insn_thumb16(bfd_vma pc,struct disassemble_info * info,long given)2125 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2126 {
2127   const struct opcode16 *insn;
2128   void *stream = info->stream;
2129   fprintf_ftype func = info->fprintf_func;
2130 
2131   for (insn = thumb_opcodes; insn->assembler; insn++)
2132     if ((given & insn->mask) == insn->value)
2133       {
2134 	const char *c = insn->assembler;
2135 	for (; *c; c++)
2136 	  {
2137 	    int domaskpc = 0;
2138 	    int domasklr = 0;
2139 
2140 	    if (*c != '%')
2141 	      {
2142 		func (stream, "%c", *c);
2143 		continue;
2144 	      }
2145 
2146 	    switch (*++c)
2147 	      {
2148 	      case '%':
2149 		func (stream, "%%");
2150 		break;
2151 
2152 	      case 'S':
2153 		{
2154 		  long reg;
2155 
2156 		  reg = (given >> 3) & 0x7;
2157 		  if (given & (1 << 6))
2158 		    reg += 8;
2159 
2160 		  func (stream, "%s", arm_regnames[reg]);
2161 		}
2162 		break;
2163 
2164 	      case 'D':
2165 		{
2166 		  long reg;
2167 
2168 		  reg = given & 0x7;
2169 		  if (given & (1 << 7))
2170 		    reg += 8;
2171 
2172 		  func (stream, "%s", arm_regnames[reg]);
2173 		}
2174 		break;
2175 
2176 	      case 'N':
2177 		if (given & (1 << 8))
2178 		  domasklr = 1;
2179 		/* Fall through.  */
2180 	      case 'O':
2181 		if (*c == 'O' && (given & (1 << 8)))
2182 		  domaskpc = 1;
2183 		/* Fall through.  */
2184 	      case 'M':
2185 		{
2186 		  int started = 0;
2187 		  int reg;
2188 
2189 		  func (stream, "{");
2190 
2191 		  /* It would be nice if we could spot
2192 		     ranges, and generate the rS-rE format: */
2193 		  for (reg = 0; (reg < 8); reg++)
2194 		    if ((given & (1 << reg)) != 0)
2195 		      {
2196 			if (started)
2197 			  func (stream, ", ");
2198 			started = 1;
2199 			func (stream, "%s", arm_regnames[reg]);
2200 		      }
2201 
2202 		  if (domasklr)
2203 		    {
2204 		      if (started)
2205 			func (stream, ", ");
2206 		      started = 1;
2207 		      func (stream, arm_regnames[14] /* "lr" */);
2208 		    }
2209 
2210 		  if (domaskpc)
2211 		    {
2212 		      if (started)
2213 			func (stream, ", ");
2214 		      func (stream, arm_regnames[15] /* "pc" */);
2215 		    }
2216 
2217 		  func (stream, "}");
2218 		}
2219 		break;
2220 
2221 	      case 'b':
2222 		/* Print ARM V6T2 CZB address: pc+4+6 bits.  */
2223 		{
2224 		  bfd_vma address = (pc + 4
2225 				     + ((given & 0x00f8) >> 2)
2226 				     + ((given & 0x0200) >> 3));
2227 		  info->print_address_func (address, info);
2228 		}
2229 		break;
2230 
2231 	      case 's':
2232 		/* Right shift immediate -- bits 6..10; 1-31 print
2233 		   as themselves, 0 prints as 32.  */
2234 		{
2235 		  long imm = (given & 0x07c0) >> 6;
2236 		  if (imm == 0)
2237 		    imm = 32;
2238 		  func (stream, "#%ld", imm);
2239 		}
2240 		break;
2241 
2242 	      case '0': case '1': case '2': case '3': case '4':
2243 	      case '5': case '6': case '7': case '8': case '9':
2244 		{
2245 		  int bitstart = *c++ - '0';
2246 		  int bitend = 0;
2247 
2248 		  while (*c >= '0' && *c <= '9')
2249 		    bitstart = (bitstart * 10) + *c++ - '0';
2250 
2251 		  switch (*c)
2252 		    {
2253 		    case '-':
2254 		      {
2255 			long reg;
2256 
2257 			c++;
2258 			while (*c >= '0' && *c <= '9')
2259 			  bitend = (bitend * 10) + *c++ - '0';
2260 			if (!bitend)
2261 			  abort ();
2262 			reg = given >> bitstart;
2263 			reg &= (2 << (bitend - bitstart)) - 1;
2264 			switch (*c)
2265 			  {
2266 			  case 'r':
2267 			    func (stream, "%s", arm_regnames[reg]);
2268 			    break;
2269 
2270 			  case 'd':
2271 			    func (stream, "%ld", reg);
2272 			    break;
2273 
2274 			  case 'H':
2275 			    func (stream, "%ld", reg << 1);
2276 			    break;
2277 
2278 			  case 'W':
2279 			    func (stream, "%ld", reg << 2);
2280 			    break;
2281 
2282 			  case 'a':
2283 			    /* PC-relative address -- the bottom two
2284 			       bits of the address are dropped
2285 			       before the calculation.  */
2286 			    info->print_address_func
2287 			      (((pc + 4) & ~3) + (reg << 2), info);
2288 			    break;
2289 
2290 			  case 'x':
2291 			    func (stream, "0x%04lx", reg);
2292 			    break;
2293 
2294 			  case 'B':
2295 			    reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2296 			    info->print_address_func (reg * 2 + pc + 4, info);
2297 			    break;
2298 
2299 			  case 'c':
2300 			    {
2301 			      /* Must print 0xE as 'al' to distinguish
2302 				 unconditional B from conditional BAL.  */
2303 			      if (reg == 0xE)
2304 				func (stream, "al");
2305 			      else
2306 				func (stream, "%s", arm_conditional [reg]);
2307 			    }
2308 			    break;
2309 
2310 			  default:
2311 			    abort ();
2312 			  }
2313 		      }
2314 		      break;
2315 
2316 		    case '\'':
2317 		      c++;
2318 		      if ((given & (1 << bitstart)) != 0)
2319 			func (stream, "%c", *c);
2320 		      break;
2321 
2322 		    case '?':
2323 		      ++c;
2324 		      if ((given & (1 << bitstart)) != 0)
2325 			func (stream, "%c", *c++);
2326 		      else
2327 			func (stream, "%c", *++c);
2328 		      break;
2329 
2330 		    default:
2331 		      abort ();
2332 		    }
2333 		}
2334 		break;
2335 
2336 	      default:
2337 		abort ();
2338 	      }
2339 	  }
2340 	return;
2341       }
2342 
2343   /* No match.  */
2344   abort ();
2345 }
2346 
2347 /* Return the name of an V7M special register.  */
2348 static const char *
psr_name(int regno)2349 psr_name (int regno)
2350 {
2351   switch (regno)
2352     {
2353     case 0: return "APSR";
2354     case 1: return "IAPSR";
2355     case 2: return "EAPSR";
2356     case 3: return "PSR";
2357     case 5: return "IPSR";
2358     case 6: return "EPSR";
2359     case 7: return "IEPSR";
2360     case 8: return "MSP";
2361     case 9: return "PSP";
2362     case 16: return "PRIMASK";
2363     case 17: return "BASEPRI";
2364     case 18: return "BASEPRI_MASK";
2365     case 19: return "FAULTMASK";
2366     case 20: return "CONTROL";
2367     default: return "<unknown>";
2368     }
2369 }
2370 
2371 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
2372 
2373 static void
print_insn_thumb32(bfd_vma pc,struct disassemble_info * info,long given)2374 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
2375 {
2376   const struct opcode32 *insn;
2377   void *stream = info->stream;
2378   fprintf_ftype func = info->fprintf_func;
2379 
2380   if (print_insn_coprocessor (info, given, TRUE))
2381     return;
2382 
2383   for (insn = thumb32_opcodes; insn->assembler; insn++)
2384     if ((given & insn->mask) == insn->value)
2385       {
2386 	const char *c = insn->assembler;
2387 	for (; *c; c++)
2388 	  {
2389 	    if (*c != '%')
2390 	      {
2391 		func (stream, "%c", *c);
2392 		continue;
2393 	      }
2394 
2395 	    switch (*++c)
2396 	      {
2397 	      case '%':
2398 		func (stream, "%%");
2399 		break;
2400 
2401 	      case 'I':
2402 		{
2403 		  unsigned int imm12 = 0;
2404 		  imm12 |= (given & 0x000000ffu);
2405 		  imm12 |= (given & 0x00007000u) >> 4;
2406 		  imm12 |= (given & 0x04000000u) >> 15;
2407 		  func (stream, "#%u\t; 0x%x", imm12, imm12);
2408 		}
2409 		break;
2410 
2411 	      case 'M':
2412 		{
2413 		  unsigned int bits = 0, imm, imm8, mod;
2414 		  bits |= (given & 0x000000ffu);
2415 		  bits |= (given & 0x00007000u) >> 4;
2416 		  bits |= (given & 0x04000000u) >> 15;
2417 		  imm8 = (bits & 0x0ff);
2418 		  mod = (bits & 0xf00) >> 8;
2419 		  switch (mod)
2420 		    {
2421 		    case 0: imm = imm8; break;
2422 		    case 1: imm = ((imm8<<16) | imm8); break;
2423 		    case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
2424 		    case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
2425 		    default:
2426 		      mod  = (bits & 0xf80) >> 7;
2427 		      imm8 = (bits & 0x07f) | 0x80;
2428 		      imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
2429 		    }
2430 		  func (stream, "#%u\t; 0x%x", imm, imm);
2431 		}
2432 		break;
2433 
2434 	      case 'J':
2435 		{
2436 		  unsigned int imm = 0;
2437 		  imm |= (given & 0x000000ffu);
2438 		  imm |= (given & 0x00007000u) >> 4;
2439 		  imm |= (given & 0x04000000u) >> 15;
2440 		  imm |= (given & 0x000f0000u) >> 4;
2441 		  func (stream, "#%u\t; 0x%x", imm, imm);
2442 		}
2443 		break;
2444 
2445 	      case 'K':
2446 		{
2447 		  unsigned int imm = 0;
2448 		  imm |= (given & 0x000f0000u) >> 16;
2449 		  imm |= (given & 0x00000ff0u) >> 0;
2450 		  imm |= (given & 0x0000000fu) << 12;
2451 		  func (stream, "#%u\t; 0x%x", imm, imm);
2452 		}
2453 		break;
2454 
2455 	      case 'S':
2456 		{
2457 		  unsigned int reg = (given & 0x0000000fu);
2458 		  unsigned int stp = (given & 0x00000030u) >> 4;
2459 		  unsigned int imm = 0;
2460 		  imm |= (given & 0x000000c0u) >> 6;
2461 		  imm |= (given & 0x00007000u) >> 10;
2462 
2463 		  func (stream, "%s", arm_regnames[reg]);
2464 		  switch (stp)
2465 		    {
2466 		    case 0:
2467 		      if (imm > 0)
2468 			func (stream, ", lsl #%u", imm);
2469 		      break;
2470 
2471 		    case 1:
2472 		      if (imm == 0)
2473 			imm = 32;
2474 		      func (stream, ", lsr #%u", imm);
2475 		      break;
2476 
2477 		    case 2:
2478 		      if (imm == 0)
2479 			imm = 32;
2480 		      func (stream, ", asr #%u", imm);
2481 		      break;
2482 
2483 		    case 3:
2484 		      if (imm == 0)
2485 			func (stream, ", rrx");
2486 		      else
2487 			func (stream, ", ror #%u", imm);
2488 		    }
2489 		}
2490 		break;
2491 
2492 	      case 'a':
2493 		{
2494 		  unsigned int Rn  = (given & 0x000f0000) >> 16;
2495 		  unsigned int U   = (given & 0x00800000) >> 23;
2496 		  unsigned int op  = (given & 0x00000f00) >> 8;
2497 		  unsigned int i12 = (given & 0x00000fff);
2498 		  unsigned int i8  = (given & 0x000000ff);
2499 		  bfd_boolean writeback = FALSE, postind = FALSE;
2500 		  int offset = 0;
2501 
2502 		  func (stream, "[%s", arm_regnames[Rn]);
2503 		  if (U) /* 12-bit positive immediate offset */
2504 		    offset = i12;
2505 		  else if (Rn == 15) /* 12-bit negative immediate offset */
2506 		    offset = -(int)i12;
2507 		  else if (op == 0x0) /* shifted register offset */
2508 		    {
2509 		      unsigned int Rm = (i8 & 0x0f);
2510 		      unsigned int sh = (i8 & 0x30) >> 4;
2511 		      func (stream, ", %s", arm_regnames[Rm]);
2512 		      if (sh)
2513 			func (stream, ", lsl #%u", sh);
2514 		      func (stream, "]");
2515 		      break;
2516 		    }
2517 		  else switch (op)
2518 		    {
2519 		    case 0xE:  /* 8-bit positive immediate offset */
2520 		      offset = i8;
2521 		      break;
2522 
2523 		    case 0xC:  /* 8-bit negative immediate offset */
2524 		      offset = -i8;
2525 		      break;
2526 
2527 		    case 0xF:  /* 8-bit + preindex with wb */
2528 		      offset = i8;
2529 		      writeback = TRUE;
2530 		      break;
2531 
2532 		    case 0xD:  /* 8-bit - preindex with wb */
2533 		      offset = -i8;
2534 		      writeback = TRUE;
2535 		      break;
2536 
2537 		    case 0xB:  /* 8-bit + postindex */
2538 		      offset = i8;
2539 		      postind = TRUE;
2540 		      break;
2541 
2542 		    case 0x9:  /* 8-bit - postindex */
2543 		      offset = -i8;
2544 		      postind = TRUE;
2545 		      break;
2546 
2547 		    default:
2548 		      func (stream, ", <undefined>]");
2549 		      goto skip;
2550 		    }
2551 
2552 		  if (postind)
2553 		    func (stream, "], #%d", offset);
2554 		  else
2555 		    {
2556 		      if (offset)
2557 			func (stream, ", #%d", offset);
2558 		      func (stream, writeback ? "]!" : "]");
2559 		    }
2560 
2561 		  if (Rn == 15)
2562 		    {
2563 		      func (stream, "\t; ");
2564 		      info->print_address_func (((pc + 4) & ~3) + offset, info);
2565 		    }
2566 		}
2567 	      skip:
2568 		break;
2569 
2570 	      case 'A':
2571 		{
2572 		  unsigned int P   = (given & 0x01000000) >> 24;
2573 		  unsigned int U   = (given & 0x00800000) >> 23;
2574 		  unsigned int W   = (given & 0x00400000) >> 21;
2575 		  unsigned int Rn  = (given & 0x000f0000) >> 16;
2576 		  unsigned int off = (given & 0x000000ff);
2577 
2578 		  func (stream, "[%s", arm_regnames[Rn]);
2579 		  if (P)
2580 		    {
2581 		      if (off || !U)
2582 			func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2583 		      func (stream, "]");
2584 		      if (W)
2585 			func (stream, "!");
2586 		    }
2587 		  else
2588 		    {
2589 		      func (stream, "], ");
2590 		      if (W)
2591 			func (stream, "#%c%u", U ? '+' : '-', off * 4);
2592 		      else
2593 			func (stream, "{%u}", off);
2594 		    }
2595 		}
2596 		break;
2597 
2598 	      case 'w':
2599 		{
2600 		  unsigned int Sbit = (given & 0x01000000) >> 24;
2601 		  unsigned int type = (given & 0x00600000) >> 21;
2602 		  switch (type)
2603 		    {
2604 		    case 0: func (stream, Sbit ? "sb" : "b"); break;
2605 		    case 1: func (stream, Sbit ? "sh" : "h"); break;
2606 		    case 2:
2607 		      if (Sbit)
2608 			func (stream, "??");
2609 		      break;
2610 		    case 3:
2611 		      func (stream, "??");
2612 		      break;
2613 		    }
2614 		}
2615 		break;
2616 
2617 	      case 'm':
2618 		{
2619 		  int started = 0;
2620 		  int reg;
2621 
2622 		  func (stream, "{");
2623 		  for (reg = 0; reg < 16; reg++)
2624 		    if ((given & (1 << reg)) != 0)
2625 		      {
2626 			if (started)
2627 			  func (stream, ", ");
2628 			started = 1;
2629 			func (stream, "%s", arm_regnames[reg]);
2630 		      }
2631 		  func (stream, "}");
2632 		}
2633 		break;
2634 
2635 	      case 'E':
2636 		{
2637 		  unsigned int msb = (given & 0x0000001f);
2638 		  unsigned int lsb = 0;
2639 		  lsb |= (given & 0x000000c0u) >> 6;
2640 		  lsb |= (given & 0x00007000u) >> 10;
2641 		  func (stream, "#%u, #%u", lsb, msb - lsb + 1);
2642 		}
2643 		break;
2644 
2645 	      case 'F':
2646 		{
2647 		  unsigned int width = (given & 0x0000001f) + 1;
2648 		  unsigned int lsb = 0;
2649 		  lsb |= (given & 0x000000c0u) >> 6;
2650 		  lsb |= (given & 0x00007000u) >> 10;
2651 		  func (stream, "#%u, #%u", lsb, width);
2652 		}
2653 		break;
2654 
2655 	      case 'b':
2656 		{
2657 		  unsigned int S = (given & 0x04000000u) >> 26;
2658 		  unsigned int J1 = (given & 0x00002000u) >> 13;
2659 		  unsigned int J2 = (given & 0x00000800u) >> 11;
2660 		  int offset = 0;
2661 
2662 		  offset |= !S << 20;
2663 		  offset |= J2 << 19;
2664 		  offset |= J1 << 18;
2665 		  offset |= (given & 0x003f0000) >> 4;
2666 		  offset |= (given & 0x000007ff) << 1;
2667 		  offset -= (1 << 20);
2668 
2669 		  info->print_address_func (pc + 4 + offset, info);
2670 		}
2671 		break;
2672 
2673 	      case 'B':
2674 		{
2675 		  unsigned int S = (given & 0x04000000u) >> 26;
2676 		  unsigned int I1 = (given & 0x00002000u) >> 13;
2677 		  unsigned int I2 = (given & 0x00000800u) >> 11;
2678 		  int offset = 0;
2679 
2680 		  offset |= !S << 24;
2681 		  offset |= !(I1 ^ S) << 23;
2682 		  offset |= !(I2 ^ S) << 22;
2683 		  offset |= (given & 0x03ff0000u) >> 4;
2684 		  offset |= (given & 0x000007ffu) << 1;
2685 		  offset -= (1 << 24);
2686 		  offset += pc + 4;
2687 
2688 		  /* BLX target addresses are always word aligned.  */
2689 		  if ((given & 0x00001000u) == 0)
2690 		      offset &= ~2u;
2691 
2692 		  info->print_address_func (offset, info);
2693 		}
2694 		break;
2695 
2696 	      case 's':
2697 		{
2698 		  unsigned int shift = 0;
2699 		  shift |= (given & 0x000000c0u) >> 6;
2700 		  shift |= (given & 0x00007000u) >> 10;
2701 		  if (given & 0x00200000u)
2702 		    func (stream, ", asr #%u", shift);
2703 		  else if (shift)
2704 		    func (stream, ", lsl #%u", shift);
2705 		  /* else print nothing - lsl #0 */
2706 		}
2707 		break;
2708 
2709 	      case 'R':
2710 		{
2711 		  unsigned int rot = (given & 0x00000030) >> 4;
2712 		  if (rot)
2713 		    func (stream, ", ror #%u", rot * 8);
2714 		}
2715 		break;
2716 
2717 	      case 'U':
2718 		switch (given & 0xf)
2719 		  {
2720 		  case 0x2: func(stream, "oshst"); break;
2721 		  case 0x3: func(stream, "osh"); break;
2722 		  case 0x6: func(stream, "nshst"); break;
2723 		  case 0x7: func(stream, "nsh"); break;
2724 		  case 0xa: func(stream, "ishst"); break;
2725 		  case 0xb: func(stream, "ish"); break;
2726 		  case 0xe: func(stream, "st"); break;
2727 		  case 0xf: func(stream, "sy"); break;
2728 		  default:
2729 		    func(stream, "#%d", (int)given & 0xf);
2730 		    break;
2731 		  }
2732 		break;
2733 
2734 	      case 'C':
2735 		if ((given & 0xff) == 0)
2736 		  {
2737 		    func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
2738 		    if (given & 0x800)
2739 		      func (stream, "f");
2740 		    if (given & 0x400)
2741 		      func (stream, "s");
2742 		    if (given & 0x200)
2743 		      func (stream, "x");
2744 		    if (given & 0x100)
2745 		      func (stream, "c");
2746 		  }
2747 		else
2748 		  {
2749 		    func (stream, psr_name (given & 0xff));
2750 		  }
2751 		break;
2752 
2753 	      case 'D':
2754 		if ((given & 0xff) == 0)
2755 		  func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
2756 		else
2757 		  func (stream, psr_name (given & 0xff));
2758 		break;
2759 
2760 	      case '0': case '1': case '2': case '3': case '4':
2761 	      case '5': case '6': case '7': case '8': case '9':
2762 		{
2763 		  int bitstart = *c++ - '0';
2764 		  int bitend = 0;
2765 		  unsigned int val;
2766 		  while (*c >= '0' && *c <= '9')
2767 		    bitstart = (bitstart * 10) + *c++ - '0';
2768 
2769 		  if (*c == '-')
2770 		    {
2771 		      c++;
2772 		      while (*c >= '0' && *c <= '9')
2773 			bitend = (bitend * 10) + *c++ - '0';
2774 		      if (!bitend)
2775 			abort ();
2776 
2777 		      val = given >> bitstart;
2778 		      val &= (2 << (bitend - bitstart)) - 1;
2779 		    }
2780 		  else
2781 		    val = (given >> bitstart) & 1;
2782 
2783 		  switch (*c)
2784 		    {
2785 		    case 'd': func (stream, "%u", val); break;
2786 		    case 'W': func (stream, "%u", val * 4); break;
2787 		    case 'r': func (stream, "%s", arm_regnames[val]); break;
2788 
2789 		    case 'c':
2790 		      if (val == 0xE)
2791 			func (stream, "al");
2792 		      else
2793 			func (stream, "%s", arm_conditional[val]);
2794 		      break;
2795 
2796 		    case '\'':
2797 		      if (val)
2798 			func (stream, "%c", c[1]);
2799 		      c++;
2800 		      break;
2801 
2802 		    case '`':
2803 		      if (!val)
2804 			func (stream, "%c", c[1]);
2805 		      c++;
2806 		      break;
2807 
2808 		    case '?':
2809 		      func (stream, "%c", val ? c[1] : c[2]);
2810 		      c += 2;
2811 		      break;
2812 
2813 		    default:
2814 		      abort ();
2815 		    }
2816 		}
2817 		break;
2818 
2819 	      default:
2820 		abort ();
2821 	      }
2822 	  }
2823 	return;
2824       }
2825 
2826   /* No match.  */
2827   abort ();
2828 }
2829 
2830 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2831    being displayed in symbol relative addresses.  */
2832 
2833 bfd_boolean
arm_symbol_is_valid(asymbol * sym,struct disassemble_info * info ATTRIBUTE_UNUSED)2834 arm_symbol_is_valid (asymbol * sym,
2835 		     struct disassemble_info * info ATTRIBUTE_UNUSED)
2836 {
2837   const char * name;
2838 
2839   if (sym == NULL)
2840     return FALSE;
2841 
2842   name = bfd_asymbol_name (sym);
2843 
2844   return (name && *name != '$');
2845 }
2846 
2847 /* Parse an individual disassembler option.  */
2848 
2849 void
parse_arm_disassembler_option(char * option)2850 parse_arm_disassembler_option (char *option)
2851 {
2852   if (option == NULL)
2853     return;
2854 
2855   if (strneq (option, "reg-names-", 10))
2856     {
2857       int i;
2858 
2859       option += 10;
2860 
2861       for (i = NUM_ARM_REGNAMES; i--;)
2862 	if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2863 	  {
2864 	    regname_selected = i;
2865 	    break;
2866 	  }
2867 
2868       if (i < 0)
2869 	/* XXX - should break 'option' at following delimiter.  */
2870 	fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2871     }
2872   else if (strneq (option, "force-thumb", 11))
2873     force_thumb = 1;
2874   else if (strneq (option, "no-force-thumb", 14))
2875     force_thumb = 0;
2876   else
2877     /* XXX - should break 'option' at following delimiter.  */
2878     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2879 
2880   return;
2881 }
2882 
2883 /* Parse the string of disassembler options, spliting it at whitespaces
2884    or commas.  (Whitespace separators supported for backwards compatibility).  */
2885 
2886 static void
parse_disassembler_options(char * options)2887 parse_disassembler_options (char *options)
2888 {
2889   if (options == NULL)
2890     return;
2891 
2892   while (*options)
2893     {
2894       parse_arm_disassembler_option (options);
2895 
2896       /* Skip forward to next seperator.  */
2897       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2898 	++ options;
2899       /* Skip forward past seperators.  */
2900       while (ISSPACE (*options) || (*options == ','))
2901 	++ options;
2902     }
2903 }
2904 
2905 /* NOTE: There are no checks in these routines that
2906    the relevant number of data bytes exist.  */
2907 
2908 static int
print_insn(bfd_vma pc,struct disassemble_info * info,bfd_boolean little)2909 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
2910 {
2911   unsigned char b[4];
2912   long		given;
2913   int           status;
2914   int           is_thumb;
2915   int		size;
2916   void	 	(*printer) (bfd_vma, struct disassemble_info *, long);
2917 
2918   if (info->disassembler_options)
2919     {
2920       parse_disassembler_options (info->disassembler_options);
2921 
2922       /* To avoid repeated parsing of these options, we remove them here.  */
2923       info->disassembler_options = NULL;
2924     }
2925 
2926   is_thumb = force_thumb;
2927 
2928   if (!is_thumb && info->symbols != NULL)
2929     {
2930       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2931 	{
2932 	  coff_symbol_type * cs;
2933 
2934 	  cs = coffsymbol (*info->symbols);
2935 	  is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
2936 		      || cs->native->u.syment.n_sclass == C_THUMBSTAT
2937 		      || cs->native->u.syment.n_sclass == C_THUMBLABEL
2938 		      || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2939 		      || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2940 	}
2941       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2942 	{
2943 	  elf_symbol_type *  es;
2944 	  unsigned int       type;
2945 
2946 	  es = *(elf_symbol_type **)(info->symbols);
2947 	  type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2948 
2949 	  is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2950 	}
2951     }
2952 
2953   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2954   info->bytes_per_line = 4;
2955 
2956   if (!is_thumb)
2957     {
2958       /* In ARM mode endianness is a straightforward issue: the instruction
2959 	 is four bytes long and is either ordered 0123 or 3210.  */
2960       printer = print_insn_arm;
2961       info->bytes_per_chunk = 4;
2962       size = 4;
2963 
2964       status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2965       if (little)
2966 	given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2967       else
2968 	given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2969     }
2970   else
2971     {
2972       /* In Thumb mode we have the additional wrinkle of two
2973 	 instruction lengths.  Fortunately, the bits that determine
2974 	 the length of the current instruction are always to be found
2975 	 in the first two bytes.  */
2976       printer = print_insn_thumb16;
2977       info->bytes_per_chunk = 2;
2978       size = 2;
2979 
2980       status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2981       if (little)
2982 	given = (b[0]) | (b[1] << 8);
2983       else
2984 	given = (b[1]) | (b[0] << 8);
2985 
2986       if (!status)
2987 	{
2988 	  /* These bit patterns signal a four-byte Thumb
2989 	     instruction.  */
2990 	  if ((given & 0xF800) == 0xF800
2991 	      || (given & 0xF800) == 0xF000
2992 	      || (given & 0xF800) == 0xE800)
2993 	    {
2994 	      status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2995 	      if (little)
2996 		given = (b[0]) | (b[1] << 8) | (given << 16);
2997 	      else
2998 		given = (b[1]) | (b[0] << 8) | (given << 16);
2999 
3000 	      printer = print_insn_thumb32;
3001 	      size = 4;
3002 	    }
3003 	}
3004     }
3005 
3006   if (status)
3007     {
3008       info->memory_error_func (status, pc, info);
3009       return -1;
3010     }
3011   if (info->flags & INSN_HAS_RELOC)
3012     /* If the instruction has a reloc associated with it, then
3013        the offset field in the instruction will actually be the
3014        addend for the reloc.  (We are using REL type relocs).
3015        In such cases, we can ignore the pc when computing
3016        addresses, since the addend is not currently pc-relative.  */
3017     pc = 0;
3018 
3019   printer (pc, info, given);
3020   return size;
3021 }
3022 
3023 int
print_insn_big_arm(bfd_vma pc,struct disassemble_info * info)3024 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3025 {
3026   return print_insn (pc, info, FALSE);
3027 }
3028 
3029 int
print_insn_little_arm(bfd_vma pc,struct disassemble_info * info)3030 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3031 {
3032   return print_insn (pc, info, TRUE);
3033 }
3034 
3035 void
print_arm_disassembler_options(FILE * stream)3036 print_arm_disassembler_options (FILE *stream)
3037 {
3038   int i;
3039 
3040   fprintf (stream, _("\n\
3041 The following ARM specific disassembler options are supported for use with\n\
3042 the -M switch:\n"));
3043 
3044   for (i = NUM_ARM_REGNAMES; i--;)
3045     fprintf (stream, "  reg-names-%s %*c%s\n",
3046 	     regnames[i].name,
3047 	     (int)(14 - strlen (regnames[i].name)), ' ',
3048 	     regnames[i].description);
3049 
3050   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
3051   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
3052 }
3053