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