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