* arm-opc.h (arm_opcode, thumb_opcode): Add extra field for the
[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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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 /* Format of the assembler string :
53    
54    %%                   %
55    %<bitfield>d         print the bitfield in decimal
56    %<bitfield>x         print the bitfield in hex
57    %<bitfield>X         print the bitfield as 1 hex digit without leading "0x"
58    %<bitfield>W         print the bitfield plus one in decimal 
59    %<bitfield>r         print as an ARM register
60    %<bitfield>f         print a floating point constant if >7 else a
61                         floating point register
62    %<code>y             print a single precision VFP reg.
63                           Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
64    %<code>z             print a double precision VFP reg
65                           Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
66    %c                   print condition code (always bits 28-31)
67    %P                   print floating point precision in arithmetic insn
68    %Q                   print floating point precision in ldf/stf insn
69    %R                   print floating point rounding mode
70    %<bitnum>'c          print specified char iff bit is one
71    %<bitnum>`c          print specified char iff bit is zero
72    %<bitnum>?ab         print a if bit is one else print b
73    %p                   print 'p' iff bits 12-15 are 15
74    %t                   print 't' iff bit 21 set and bit 24 clear
75    %o                   print operand2 (immediate or register + shift)
76    %a                   print address for ldr/str instruction
77    %s                   print address for ldr/str halfword/signextend instruction
78    %b                   print branch destination
79    %B                   print arm BLX(1) destination
80    %A                   print address for ldc/stc/ldf/stf instruction
81    %m                   print register mask for ldm/stm instruction
82    %C                   print the PSR sub type.
83    %F                   print the COUNT field of a LFM/SFM instruction.
84 IWMMXT specific format options:
85    %<bitfield>g         print as an iWMMXt 64-bit register
86    %<bitfield>G         print as an iWMMXt general purpose or control register
87    %<bitfield>w         print as an iWMMXt width field - [bhwd]ss/us
88    %Z                   print the Immediate of a WSHUFH instruction.
89    %L                   print as an iWMMXt N/M width field.
90    %l                   like 'A' except use byte offsets for 'B' & 'H' versions
91 Thumb specific format options:
92    %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
93    %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
94    %<bitfield>I         print bitfield as a signed decimal
95                                 (top bit of range being the sign bit)
96    %M                   print Thumb register mask
97    %N                   print Thumb register mask (with LR)
98    %O                   print Thumb register mask (with PC)
99    %T                   print Thumb condition code (always bits 8-11)
100    %I                   print cirrus signed shift immediate: bits 0..3|4..6
101    %<bitfield>B         print Thumb branch destination (signed displacement)
102    %<bitfield>W         print (bitfield * 4) as a decimal
103    %<bitfield>H         print (bitfield * 2) as a decimal
104    %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
105    %e                   print arm SMI operand (bits 0..7,8..19).  */
106
107 /* Note: There is a partial ordering in this table - it must be searched from
108    the top to obtain a correct match.  */
109
110 static const struct arm_opcode arm_opcodes[] =
111 {
112   /* ARM instructions.  */
113   {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
114   {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
115   {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
116   {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
117   {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
118   {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
119   {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
120
121   /* ARM V6Z instructions.  */
122   {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
123
124   /* ARM V6K instructions.  */
125   {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
126   {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
127   {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
128   {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
129   {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
130   {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
131   {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
132
133   /* ARM V6K NOP hints.  */
134   {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
135   {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
136   {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
137   {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
138   {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
139
140   /* ARM V6 instructions. */
141   {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
142   {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
143   {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
144   {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
145   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
146   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
147   {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
148   {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
149   {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
150   {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
151   {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
152   {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
153   {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
154   {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
155   {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
156   {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
157   {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
158   {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
159   {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
160   {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
161   {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
162   {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
163   {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
164   {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
165   {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
166   {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
167   {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
168   {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
169   {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
170   {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
171   {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
172   {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
173   {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
174   {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
175   {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
176   {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
177   {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
178   {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
179   {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
180   {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
181   {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
182   {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
183   {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
184   {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
185   {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
186   {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
187   {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
188   {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
189   {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
190   {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
191   {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
192   {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
193   {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
194   {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
195   {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
196   {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
197   {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
198   {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
199   {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
200   {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
201   {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
202   {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
203   {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
204   {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
205   {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
206   {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
207   {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
208   {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
209   {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
210   {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
211   {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
212   {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
213   {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
214   {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
215   {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
216   {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
217   {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
218   {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
219   {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
220   {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
221   {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
222   {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
223   {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
224   {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
225   {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
226   {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
227   {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
228   {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
229   {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
230   {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
231   {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
232   {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
233   {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
234   {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
235   {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
236   {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
237   {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
238   {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
239   {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
240   {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
241   {ARM_EXT_V6, 0x068000b0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
242   {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
243   {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
244   {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
245   {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
246   {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
247   {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
248   {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
249   {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
250   {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
251   {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
252   {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
253   {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
254   {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
255   {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
256   {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
257   {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
258   {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
259   {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
260   {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
261   {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
262   {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
263   {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
264   {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
265
266   /* V5J instruction.  */
267   {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
268
269   /* XScale instructions.  */
270   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
271   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
272   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
273   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
274   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
275     
276   /* Intel Wireless MMX technology instructions.  */
277 #define FIRST_IWMMXT_INSN 0x0e130130
278 #define IWMMXT_INSN_COUNT 47
279   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
280   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
281   {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
282   {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
283   {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
284   {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
285   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
286   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
287   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
288   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
289   {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
290   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
291   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
292   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
293   {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
294   {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
295   {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
296   {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
297   {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
298   {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
299   {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
300   {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
301   {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
302   {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
303   {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
304   {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
305   {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
306   {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
307   {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
308   {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
309   {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
310   {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
311   {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
312   {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
313   {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
314   {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
315   {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
316   {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
317   {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
318   {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
319   {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
320   {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
321   {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
322   {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
323   {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
324   {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
325   {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
326   {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
327   {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
328
329   /* V5 Instructions.  */
330   {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
331   {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
332   {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
333   {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
334   {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
335   {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
336   {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
337   {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
338   {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
339
340   /* V5E "El Segundo" Instructions.  */    
341   {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
342   {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
343   {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
344   {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
345   {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
346   {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
347   {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
348
349   {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
350   {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
351
352   {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
353   {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
354   {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
355   {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
356
357   {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
358   {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
359   {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
360   {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
361
362   {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
363   {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
364
365   {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0,  "qadd%c\t%12-15r, %0-3r, %16-19r"},
366   {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
367   {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0,  "qsub%c\t%12-15r, %0-3r, %16-19r"},
368   {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
369
370   /* ARM Instructions.  */
371   {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
372   {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
373   {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
374   {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
375   {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
376   {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
377   {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
378   {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
379   {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
380   {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
381   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
382   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
383   {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
384   {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
385   {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
386   {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
387   {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
388   {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
389   {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
390   {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
391   {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
392   {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
393   {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
394   {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
395   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
396   {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
397   {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
398   {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
399   {ARM_EXT_V1, 0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
400
401   /* Floating point coprocessor (FPA) instructions */
402   {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
403   {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
404   {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
405   {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
406   {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
407   {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
408   {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
409   {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
410   {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
411   {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
412   {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
413   {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
414   {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
415   {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
416   {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
417   {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
418   {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
419   {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
420   {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
421   {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
422   {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
423   {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
424   {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
425   {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
426   {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
427   {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
428   {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
429   {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
430   {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
431   {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
432   {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
433   {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
434   {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
435   {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
436   {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
437   {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
438   {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
439   {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
440   {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
441   {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
442   {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
443   {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
444   {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
445
446   /* Floating point coprocessor (VFP) instructions */
447   {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
448   {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
449   {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
450   {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"},
451   {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
452   {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
453   {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
454   {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
455   {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
456   {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
457   {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
458   {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
459   {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
460   {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
461   {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
462   {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
463   {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
464   {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
465   {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
466   {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
467   {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
468   {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
469   {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
470   {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
471   {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
472   {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
473   {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
474   {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
475   {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
476   {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
477   {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
478   {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
479   {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
480   {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
481   {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
482   {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
483   {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
484   {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
485   {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
486   {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
487   {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
488   {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
489   {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
490   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
491   {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
492   {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
493   {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
494   {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
495   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
496   {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
497   {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
498   {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
499   {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
500   {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
501   {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
502   {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
503   {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
504   {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
505   {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
506   {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
507   {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
508   {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
509   {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
510   {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
511   {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
512   {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
513   {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
514   {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
515   {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
516   {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
517   {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
518   {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
519   {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
520
521   /* Cirrus coprocessor instructions.  */
522   {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
523   {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
524   {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
525   {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 
526   {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
527   {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
528   {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
529   {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
530   {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
531   {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
532   {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
533   {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
534   {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
535   {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
536   {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
537   {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
538   {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
539   {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
540   {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
541   {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
542   {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
543   {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
544   {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
545   {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
546   {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
547   {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
548   {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
549   {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
550   {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
551   {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
552   {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
553   {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
554   {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
555   {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
556   {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
557   {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
558   {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
559   {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
560   {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
561   {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
562   {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
563   {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
564   {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
565   {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
566   {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
567   {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
568   {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
569   {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
570   {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
571   {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
572   {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
573   {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
574   {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
575   {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
576   {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
577   {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
578   {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
579   {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
580   {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
581   {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
582   {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
583   {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
584   {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
585   {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
586   {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
587   {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
588   {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
589   {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
590   {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
591   {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
592   {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
593   {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
594   {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
595   {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
596   {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
597   {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
598   {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
599   {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
600   {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
601   {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
602   {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
603   {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
604   {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
605   {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
606
607   /* Generic coprocessor instructions */
608   {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
609   {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
610   {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
611   {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
612   {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
613   {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
614   {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
615
616   /* The rest.  */
617   {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
618   {0, 0x00000000, 0x00000000, 0}
619 };
620
621 static const struct thumb_opcode thumb_opcodes[] =
622 {
623   /* Thumb instructions.  */
624
625   /* ARM V6.  */
626   {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
627   {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
628   {ARM_EXT_V6, 0x4600, 0xffc0, "cpy\t%0-2r, %3-5r"},
629   {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
630   {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
631   {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
632   {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
633   {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
634   {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
635   {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
636   {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
637
638   /* ARM V5 ISA extends Thumb.  */
639   {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
640   /* Note: this is BLX(2).  BLX(1) is done in arm-dis.c/print_insn_thumb()
641      as an extension of the special processing there for Thumb BL.
642      BL and BLX(1) involve 2 successive 16-bit instructions, which must
643      always appear together in the correct order.  So, the empty
644      string is put in this table, and the string interpreter takes <empty>
645      to mean it has a pair of BL-ish instructions.  */
646   {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"},  /* note: 4 bit register number.  */
647   /* ARM V4T ISA (Thumb v1).  */
648   {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
649   /* Format 5 instructions do not update the PSR.  */
650   {ARM_EXT_V4T, 0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
651   /* Format 4.  */
652   {ARM_EXT_V4T, 0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
653   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
654   {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
655   {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
656   {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
657   {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
658   {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
659   {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
660   {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
661   {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
662   {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
663   {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
664   {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
665   {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
666   {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
667   {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
668   /* format 13 */
669   {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
670   {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
671   /* format 5 */
672   {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
673   {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
674   {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
675   {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
676   /* format 14 */
677   {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
678   {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
679   /* format 2 */
680   {ARM_EXT_V4T, 0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
681   {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
682   {ARM_EXT_V4T, 0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
683   {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
684   /* format 8 */
685   {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
686   {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
687   {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
688   /* format 7 */
689   {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
690   {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
691   /* format 1 */
692   {ARM_EXT_V4T, 0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
693   {ARM_EXT_V4T, 0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
694   {ARM_EXT_V4T, 0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
695   /* format 3 */
696   {ARM_EXT_V4T, 0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
697   {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
698   {ARM_EXT_V4T, 0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
699   {ARM_EXT_V4T, 0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
700   /* format 6 */
701   {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
702   /* format 9 */
703   {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
704   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
705   {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
706   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
707   /* format 10 */
708   {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
709   {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
710   /* format 11 */
711   {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
712   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
713   /* format 12 */
714   {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
715   {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
716   /* format 15 */
717   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!,%M"},
718   {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
719   /* format 18 */
720   {ARM_EXT_V4T, 0xE000, 0xF800, "b\t%0-10B"},
721   {ARM_EXT_V4T, 0xE800, 0xF800, "undefined"},
722   /* format 19 */
723   {ARM_EXT_V4T, 0xF000, 0xF800, ""}, /* special processing required in disassembler */
724   {ARM_EXT_V4T, 0xF800, 0xF800, "second half of BL instruction %0-15x"},
725   /* format 16 */
726   {ARM_EXT_V4T, 0xD000, 0xFF00, "beq\t%0-7B"},
727   {ARM_EXT_V4T, 0xD100, 0xFF00, "bne\t%0-7B"},
728   {ARM_EXT_V4T, 0xD200, 0xFF00, "bcs\t%0-7B"},
729   {ARM_EXT_V4T, 0xD300, 0xFF00, "bcc\t%0-7B"},
730   {ARM_EXT_V4T, 0xD400, 0xFF00, "bmi\t%0-7B"},
731   {ARM_EXT_V4T, 0xD500, 0xFF00, "bpl\t%0-7B"},
732   {ARM_EXT_V4T, 0xD600, 0xFF00, "bvs\t%0-7B"},
733   {ARM_EXT_V4T, 0xD700, 0xFF00, "bvc\t%0-7B"},
734   {ARM_EXT_V4T, 0xD800, 0xFF00, "bhi\t%0-7B"},
735   {ARM_EXT_V4T, 0xD900, 0xFF00, "bls\t%0-7B"},
736   {ARM_EXT_V4T, 0xDA00, 0xFF00, "bge\t%0-7B"},
737   {ARM_EXT_V4T, 0xDB00, 0xFF00, "blt\t%0-7B"},
738   {ARM_EXT_V4T, 0xDC00, 0xFF00, "bgt\t%0-7B"},
739   {ARM_EXT_V4T, 0xDD00, 0xFF00, "ble\t%0-7B"},
740   /* format 17 */
741   {ARM_EXT_V4T, 0xDE00, 0xFF00, "bal\t%0-7B"},
742   {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
743   /* format 9 */
744   {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
745   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
746   {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
747   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
748   /* the rest */
749   {ARM_EXT_V1, 0x0000, 0x0000, "undefined instruction %0-15x"},
750   {0, 0x0000, 0x0000, 0}
751 };
752
753 static char * arm_conditional[] =
754 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
755  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
756
757 typedef struct
758 {
759   const char * name;
760   const char * description;
761   const char * reg_names[16];
762 }
763 arm_regname;
764
765 static arm_regname regnames[] =
766 {
767   { "raw" , "Select raw register names",
768     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
769   { "gcc",  "Select register names used by GCC",
770     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
771   { "std",  "Select register names used in ARM's ISA documentation",
772     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
773   { "apcs", "Select register names used in the APCS",
774     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
775   { "atpcs", "Select register names used in the ATPCS",
776     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
777   { "special-atpcs", "Select special register names used in the ATPCS",
778     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
779   { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
780     { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
781   { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
782     {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
783 };
784
785 static char * iwmmxt_wwnames[] =
786 {"b", "h", "w", "d"};
787
788 static char * iwmmxt_wwssnames[] =
789 {"b", "bus", "b", "bss",
790  "h", "hus", "h", "hss",
791  "w", "wus", "w", "wss",
792  "d", "dus", "d", "dss"
793 };
794
795 /* Default to GCC register name set.  */
796 static unsigned int regname_selected = 1;
797
798 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
799 #define arm_regnames      regnames[regname_selected].reg_names
800
801 static bfd_boolean force_thumb = FALSE;
802
803 static char * arm_fp_const[] =
804 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
805
806 static char * arm_shift[] =
807 {"lsl", "lsr", "asr", "ror"};
808 \f
809 /* Forward declarations.  */
810 static void arm_decode_shift
811   PARAMS ((long, fprintf_ftype, void *));
812 static int  print_insn_arm
813   PARAMS ((bfd_vma, struct disassemble_info *, long));
814 static int  print_insn_thumb
815   PARAMS ((bfd_vma, struct disassemble_info *, long));
816 static void parse_disassembler_options
817   PARAMS ((char *));
818 static int  print_insn
819   PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
820 static int set_iwmmxt_regnames
821   PARAMS ((void));
822
823 int get_arm_regname_num_options
824   PARAMS ((void));
825 int set_arm_regname_option
826   PARAMS ((int));
827 int get_arm_regnames
828   PARAMS ((int, const char **, const char **, const char ***));
829 \f
830 /* Functions.  */
831 int
832 get_arm_regname_num_options ()
833 {
834   return NUM_ARM_REGNAMES;
835 }
836
837 int
838 set_arm_regname_option (option)
839      int option;
840 {
841   int old = regname_selected;
842   regname_selected = option;
843   return old;
844 }
845
846 int
847 get_arm_regnames (option, setname, setdescription, register_names)
848      int option;
849      const char **setname;
850      const char **setdescription;
851      const char ***register_names;
852 {
853   *setname = regnames[option].name;
854   *setdescription = regnames[option].description;
855   *register_names = regnames[option].reg_names;
856   return 16;
857 }
858
859 static void
860 arm_decode_shift (given, func, stream)
861      long given;
862      fprintf_ftype func;
863      void * stream;
864 {
865   func (stream, "%s", arm_regnames[given & 0xf]);
866
867   if ((given & 0xff0) != 0)
868     {
869       if ((given & 0x10) == 0)
870         {
871           int amount = (given & 0xf80) >> 7;
872           int shift = (given & 0x60) >> 5;
873
874           if (amount == 0)
875             {
876               if (shift == 3)
877                 {
878                   func (stream, ", rrx");
879                   return;
880                 }
881
882               amount = 32;
883             }
884
885           func (stream, ", %s #%d", arm_shift[shift], amount);
886         }
887       else
888         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
889               arm_regnames[(given & 0xf00) >> 8]);
890     }
891 }
892
893 static int
894 set_iwmmxt_regnames ()
895 {
896   const char * setname;
897   const char * setdesc;
898   const char ** regnames;
899   int iwmmxt_regnames = 0;
900   int num_regnames = get_arm_regname_num_options ();
901
902   get_arm_regnames (iwmmxt_regnames, &setname,
903                     &setdesc, &regnames);
904   while ((strcmp ("iwmmxt_regnames", setname))
905          && (iwmmxt_regnames < num_regnames))
906     get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
907
908   return iwmmxt_regnames;
909 }
910                           
911 /* Print one instruction from PC on INFO->STREAM.
912    Return the size of the instruction (always 4 on ARM). */
913
914 static int
915 print_insn_arm (pc, info, given)
916      bfd_vma pc;
917      struct disassemble_info *info;
918      long given;
919 {
920   const struct arm_opcode *insn;
921   void *stream = info->stream;
922   fprintf_ftype func   = info->fprintf_func;
923   static int iwmmxt_regnames = 0;
924
925   for (insn = arm_opcodes; insn->assembler; insn++)
926     {
927       if (insn->value == FIRST_IWMMXT_INSN
928           && info->mach != bfd_mach_arm_XScale
929           && info->mach != bfd_mach_arm_iWMMXt)
930         insn = insn + IWMMXT_INSN_COUNT;
931
932       if ((given & insn->mask) == insn->value)
933         {
934           char * c;
935
936           for (c = insn->assembler; *c; c++)
937             {
938               if (*c == '%')
939                 {
940                   switch (*++c)
941                     {
942                     case '%':
943                       func (stream, "%%");
944                       break;
945
946                     case 'a':
947                       if (((given & 0x000f0000) == 0x000f0000)
948                           && ((given & 0x02000000) == 0))
949                         {
950                           int offset = given & 0xfff;
951
952                           func (stream, "[pc");
953
954                           if (given & 0x01000000)
955                             {
956                               if ((given & 0x00800000) == 0)
957                                 offset = - offset;
958
959                               /* Pre-indexed.  */
960                               func (stream, ", #%d]", offset);
961
962                               offset += pc + 8;
963
964                               /* Cope with the possibility of write-back
965                                  being used.  Probably a very dangerous thing
966                                  for the programmer to do, but who are we to
967                                  argue ?  */
968                               if (given & 0x00200000)
969                                 func (stream, "!");
970                             }
971                           else
972                             {
973                               /* Post indexed.  */
974                               func (stream, "], #%d", offset);
975
976                               /* ie ignore the offset.  */
977                               offset = pc + 8;
978                             }
979
980                           func (stream, "\t; ");
981                           info->print_address_func (offset, info);
982                         }
983                       else
984                         {
985                           func (stream, "[%s",
986                                 arm_regnames[(given >> 16) & 0xf]);
987                           if ((given & 0x01000000) != 0)
988                             {
989                               if ((given & 0x02000000) == 0)
990                                 {
991                                   int offset = given & 0xfff;
992                                   if (offset)
993                                     func (stream, ", #%s%d",
994                                           (((given & 0x00800000) == 0)
995                                            ? "-" : ""), offset);
996                                 }
997                               else
998                                 {
999                                   func (stream, ", %s",
1000                                         (((given & 0x00800000) == 0)
1001                                          ? "-" : ""));
1002                                   arm_decode_shift (given, func, stream);
1003                                 }
1004
1005                               func (stream, "]%s",
1006                                     ((given & 0x00200000) != 0) ? "!" : "");
1007                             }
1008                           else
1009                             {
1010                               if ((given & 0x02000000) == 0)
1011                                 {
1012                                   int offset = given & 0xfff;
1013                                   if (offset)
1014                                     func (stream, "], #%s%d",
1015                                           (((given & 0x00800000) == 0)
1016                                            ? "-" : ""), offset);
1017                                   else
1018                                     func (stream, "]");
1019                                 }
1020                               else
1021                                 {
1022                                   func (stream, "], %s",
1023                                         (((given & 0x00800000) == 0)
1024                                          ? "-" : ""));
1025                                   arm_decode_shift (given, func, stream);
1026                                 }
1027                             }
1028                         }
1029                       break;
1030
1031                     case 's':
1032                       if ((given & 0x004f0000) == 0x004f0000)
1033                         {
1034                           /* PC relative with immediate offset.  */
1035                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1036
1037                           if ((given & 0x00800000) == 0)
1038                             offset = -offset;
1039
1040                           func (stream, "[pc, #%d]\t; ", offset);
1041
1042                           (*info->print_address_func)
1043                             (offset + pc + 8, info);
1044                         }
1045                       else
1046                         {
1047                           func (stream, "[%s",
1048                                 arm_regnames[(given >> 16) & 0xf]);
1049                           if ((given & 0x01000000) != 0)
1050                             {
1051                               /* Pre-indexed.  */
1052                               if ((given & 0x00400000) == 0x00400000)
1053                                 {
1054                                   /* Immediate.  */
1055                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1056                                   if (offset)
1057                                     func (stream, ", #%s%d",
1058                                           (((given & 0x00800000) == 0)
1059                                            ? "-" : ""), offset);
1060                                 }
1061                               else
1062                                 {
1063                                   /* Register.  */
1064                                   func (stream, ", %s%s",
1065                                         (((given & 0x00800000) == 0)
1066                                          ? "-" : ""),
1067                                         arm_regnames[given & 0xf]);
1068                                 }
1069
1070                               func (stream, "]%s",
1071                                     ((given & 0x00200000) != 0) ? "!" : "");
1072                             }
1073                           else
1074                             {
1075                               /* Post-indexed.  */
1076                               if ((given & 0x00400000) == 0x00400000)
1077                                 {
1078                                   /* Immediate.  */
1079                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1080                                   if (offset)
1081                                     func (stream, "], #%s%d",
1082                                           (((given & 0x00800000) == 0)
1083                                            ? "-" : ""), offset);
1084                                   else
1085                                     func (stream, "]");
1086                                 }
1087                               else
1088                                 {
1089                                   /* Register.  */
1090                                   func (stream, "], %s%s",
1091                                         (((given & 0x00800000) == 0)
1092                                          ? "-" : ""),
1093                                         arm_regnames[given & 0xf]);
1094                                 }
1095                             }
1096                         }
1097                       break;
1098
1099                     case 'b':
1100                       (*info->print_address_func)
1101                         (BDISP (given) * 4 + pc + 8, info);
1102                       break;
1103
1104                     case 'c':
1105                       func (stream, "%s",
1106                             arm_conditional [(given >> 28) & 0xf]);
1107                       break;
1108
1109                     case 'm':
1110                       {
1111                         int started = 0;
1112                         int reg;
1113
1114                         func (stream, "{");
1115                         for (reg = 0; reg < 16; reg++)
1116                           if ((given & (1 << reg)) != 0)
1117                             {
1118                               if (started)
1119                                 func (stream, ", ");
1120                               started = 1;
1121                               func (stream, "%s", arm_regnames[reg]);
1122                             }
1123                         func (stream, "}");
1124                       }
1125                       break;
1126
1127                     case 'o':
1128                       if ((given & 0x02000000) != 0)
1129                         {
1130                           int rotate = (given & 0xf00) >> 7;
1131                           int immed = (given & 0xff);
1132                           immed = (((immed << (32 - rotate))
1133                                     | (immed >> rotate)) & 0xffffffff);
1134                           func (stream, "#%d\t; 0x%x", immed, immed);
1135                         }
1136                       else
1137                         arm_decode_shift (given, func, stream);
1138                       break;
1139
1140                     case 'p':
1141                       if ((given & 0x0000f000) == 0x0000f000)
1142                         func (stream, "p");
1143                       break;
1144
1145                     case 't':
1146                       if ((given & 0x01200000) == 0x00200000)
1147                         func (stream, "t");
1148                       break;
1149
1150                     case 'A':
1151                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1152
1153                       if ((given & (1 << 24)) != 0)
1154                         {
1155                           int offset = given & 0xff;
1156
1157                           if (offset)
1158                             func (stream, ", #%s%d]%s",
1159                                   ((given & 0x00800000) == 0 ? "-" : ""),
1160                                   offset * 4,
1161                                   ((given & 0x00200000) != 0 ? "!" : ""));
1162                           else
1163                             func (stream, "]");
1164                         }
1165                       else
1166                         {
1167                           int offset = given & 0xff;
1168
1169                           func (stream, "]");
1170
1171                           if (given & (1 << 21))
1172                             {
1173                               if (offset)
1174                                 func (stream, ", #%s%d",
1175                                       ((given & 0x00800000) == 0 ? "-" : ""),
1176                                       offset * 4);
1177                             }
1178                           else
1179                             func (stream, ", {%d}", offset);
1180                         }
1181                       break;
1182
1183                     case 'B':
1184                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
1185                       {
1186                         bfd_vma address;
1187                         bfd_vma offset = 0;
1188
1189                         if (given & 0x00800000)
1190                           /* Is signed, hi bits should be ones.  */
1191                           offset = (-1) ^ 0x00ffffff;
1192
1193                         /* Offset is (SignExtend(offset field)<<2).  */
1194                         offset += given & 0x00ffffff;
1195                         offset <<= 2;
1196                         address = offset + pc + 8;
1197
1198                         if (given & 0x01000000)
1199                           /* H bit allows addressing to 2-byte boundaries.  */
1200                           address += 2;
1201
1202                         info->print_address_func (address, info);
1203                       }
1204                       break;
1205
1206                     case 'I':
1207                       /* Print a Cirrus/DSP shift immediate.  */
1208                       /* Immediates are 7bit signed ints with bits 0..3 in
1209                          bits 0..3 of opcode and bits 4..6 in bits 5..7
1210                          of opcode.  */
1211                       {
1212                         int imm;
1213
1214                         imm = (given & 0xf) | ((given & 0xe0) >> 1);
1215
1216                         /* Is ``imm'' a negative number?  */
1217                         if (imm & 0x40)
1218                           imm |= (-1 << 7);
1219
1220                         func (stream, "%d", imm);
1221                       }
1222
1223                       break;
1224
1225                     case 'C':
1226                       func (stream, "_");
1227                       if (given & 0x80000)
1228                         func (stream, "f");
1229                       if (given & 0x40000)
1230                         func (stream, "s");
1231                       if (given & 0x20000)
1232                         func (stream, "x");
1233                       if (given & 0x10000)
1234                         func (stream, "c");
1235                       break;
1236
1237                     case 'F':
1238                       switch (given & 0x00408000)
1239                         {
1240                         case 0:
1241                           func (stream, "4");
1242                           break;
1243                         case 0x8000:
1244                           func (stream, "1");
1245                           break;
1246                         case 0x00400000:
1247                           func (stream, "2");
1248                           break;
1249                         default:
1250                           func (stream, "3");
1251                         }
1252                       break;
1253
1254                     case 'P':
1255                       switch (given & 0x00080080)
1256                         {
1257                         case 0:
1258                           func (stream, "s");
1259                           break;
1260                         case 0x80:
1261                           func (stream, "d");
1262                           break;
1263                         case 0x00080000:
1264                           func (stream, "e");
1265                           break;
1266                         default:
1267                           func (stream, _("<illegal precision>"));
1268                           break;
1269                         }
1270                       break;
1271                     case 'Q':
1272                       switch (given & 0x00408000)
1273                         {
1274                         case 0:
1275                           func (stream, "s");
1276                           break;
1277                         case 0x8000:
1278                           func (stream, "d");
1279                           break;
1280                         case 0x00400000:
1281                           func (stream, "e");
1282                           break;
1283                         default:
1284                           func (stream, "p");
1285                           break;
1286                         }
1287                       break;
1288                     case 'R':
1289                       switch (given & 0x60)
1290                         {
1291                         case 0:
1292                           break;
1293                         case 0x20:
1294                           func (stream, "p");
1295                           break;
1296                         case 0x40:
1297                           func (stream, "m");
1298                           break;
1299                         default:
1300                           func (stream, "z");
1301                           break;
1302                         }
1303                       break;
1304
1305                     case '0': case '1': case '2': case '3': case '4':
1306                     case '5': case '6': case '7': case '8': case '9':
1307                       {
1308                         int bitstart = *c++ - '0';
1309                         int bitend = 0;
1310                         while (*c >= '0' && *c <= '9')
1311                           bitstart = (bitstart * 10) + *c++ - '0';
1312
1313                         switch (*c)
1314                           {
1315                           case '-':
1316                             c++;
1317
1318                             while (*c >= '0' && *c <= '9')
1319                               bitend = (bitend * 10) + *c++ - '0';
1320
1321                             if (!bitend)
1322                               abort ();
1323
1324                             switch (*c)
1325                               {
1326                               case 'r':
1327                                 {
1328                                   long reg;
1329
1330                                   reg = given >> bitstart;
1331                                   reg &= (2 << (bitend - bitstart)) - 1;
1332
1333                                   func (stream, "%s", arm_regnames[reg]);
1334                                 }
1335                                 break;
1336                               case 'd':
1337                                 {
1338                                   long reg;
1339
1340                                   reg = given >> bitstart;
1341                                   reg &= (2 << (bitend - bitstart)) - 1;
1342
1343                                   func (stream, "%d", reg);
1344                                 }
1345                                 break;
1346                               case 'W':
1347                                 {
1348                                   long reg;
1349                                   
1350                                   reg = given >> bitstart;
1351                                   reg &= (2 << (bitend - bitstart)) - 1;
1352                                   
1353                                   func (stream, "%d", reg + 1);
1354                                 }
1355                                 break;
1356                               case 'x':
1357                                 {
1358                                   long reg;
1359
1360                                   reg = given >> bitstart;
1361                                   reg &= (2 << (bitend - bitstart)) - 1;
1362
1363                                   func (stream, "0x%08x", reg);
1364
1365                                   /* Some SWI instructions have special
1366                                      meanings.  */
1367                                   if ((given & 0x0fffffff) == 0x0FF00000)
1368                                     func (stream, "\t; IMB");
1369                                   else if ((given & 0x0fffffff) == 0x0FF00001)
1370                                     func (stream, "\t; IMBRange");
1371                                 }
1372                                 break;
1373                               case 'X':
1374                                 {
1375                                   long reg;
1376
1377                                   reg = given >> bitstart;
1378                                   reg &= (2 << (bitend - bitstart)) - 1;
1379
1380                                   func (stream, "%01x", reg & 0xf);
1381                                 }
1382                                 break;
1383                               case 'f':
1384                                 {
1385                                   long reg;
1386
1387                                   reg = given >> bitstart;
1388                                   reg &= (2 << (bitend - bitstart)) - 1;
1389
1390                                   if (reg > 7)
1391                                     func (stream, "#%s",
1392                                           arm_fp_const[reg & 7]);
1393                                   else
1394                                     func (stream, "f%d", reg);
1395                                 }
1396                                 break;
1397
1398                               case 'w':
1399                                 {
1400                                   long reg;
1401
1402                                   if (bitstart != bitend)
1403                                     {
1404                                       reg = given >> bitstart;
1405                                       reg &= (2 << (bitend - bitstart)) - 1;
1406                                       if (bitend - bitstart == 1)
1407                                         func (stream, "%s", iwmmxt_wwnames[reg]);
1408                                       else
1409                                         func (stream, "%s", iwmmxt_wwssnames[reg]);
1410                                     }
1411                                   else
1412                                     {
1413                                       reg = (((given >> 8)  & 0x1) |
1414                                              ((given >> 22) & 0x1));
1415                                       func (stream, "%s", iwmmxt_wwnames[reg]);
1416                                     }
1417                                 }
1418                                 break;
1419
1420                               case 'g':
1421                                 {
1422                                   long reg;
1423                                   int current_regnames;
1424
1425                                   if (! iwmmxt_regnames)
1426                                     iwmmxt_regnames = set_iwmmxt_regnames ();
1427                                   current_regnames = set_arm_regname_option
1428                                     (iwmmxt_regnames);
1429
1430                                   reg = given >> bitstart;
1431                                   reg &= (2 << (bitend - bitstart)) - 1;
1432                                   func (stream, "%s", arm_regnames[reg]);
1433                                   set_arm_regname_option (current_regnames);
1434                                 }
1435                                 break;
1436
1437                               case 'G':
1438                                 {
1439                                   long reg;
1440                                   int current_regnames;
1441
1442                                   if (! iwmmxt_regnames)
1443                                     iwmmxt_regnames = set_iwmmxt_regnames ();
1444                                   current_regnames = set_arm_regname_option
1445                                     (iwmmxt_regnames + 1);
1446
1447                                   reg = given >> bitstart;
1448                                   reg &= (2 << (bitend - bitstart)) - 1;
1449                                   func (stream, "%s", arm_regnames[reg]);
1450                                   set_arm_regname_option (current_regnames);
1451                                 }
1452                                 break;
1453
1454                               default:
1455                                 abort ();
1456                               }
1457                             break;
1458
1459                           case 'y':
1460                           case 'z':
1461                             {
1462                               int single = *c == 'y';
1463                               int regno;
1464
1465                               switch (bitstart)
1466                                 {
1467                                 case 4: /* Sm pair */
1468                                   func (stream, "{");
1469                                   /* Fall through.  */
1470                                 case 0: /* Sm, Dm */
1471                                   regno = given & 0x0000000f;
1472                                   if (single)
1473                                     {
1474                                       regno <<= 1;
1475                                       regno += (given >> 5) & 1;
1476                                     }
1477                                   break;
1478
1479                                 case 1: /* Sd, Dd */
1480                                   regno = (given >> 12) & 0x0000000f;
1481                                   if (single)
1482                                     {
1483                                       regno <<= 1;
1484                                       regno += (given >> 22) & 1;
1485                                     }
1486                                   break;
1487
1488                                 case 2: /* Sn, Dn */
1489                                   regno = (given >> 16) & 0x0000000f;
1490                                   if (single)
1491                                     {
1492                                       regno <<= 1;
1493                                       regno += (given >> 7) & 1;
1494                                     }
1495                                   break;
1496
1497                                 case 3: /* List */
1498                                   func (stream, "{");
1499                                   regno = (given >> 12) & 0x0000000f;
1500                                   if (single)
1501                                     {
1502                                       regno <<= 1;
1503                                       regno += (given >> 22) & 1;
1504                                     }
1505                                   break;
1506
1507
1508                                 default:
1509                                   abort ();
1510                                 }
1511
1512                               func (stream, "%c%d", single ? 's' : 'd', regno);
1513
1514                               if (bitstart == 3)
1515                                 {
1516                                   int count = given & 0xff;
1517
1518                                   if (single == 0)
1519                                     count >>= 1;
1520
1521                                   if (--count)
1522                                     {
1523                                       func (stream, "-%c%d",
1524                                             single ? 's' : 'd',
1525                                             regno + count);
1526                                     }
1527
1528                                   func (stream, "}");
1529                                 }
1530                               else if (bitstart == 4)
1531                                 func (stream, ", %c%d}", single ? 's' : 'd',
1532                                       regno + 1);
1533
1534                               break;
1535                             }
1536
1537                           case '`':
1538                             c++;
1539                             if ((given & (1 << bitstart)) == 0)
1540                               func (stream, "%c", *c);
1541                             break;
1542                           case '\'':
1543                             c++;
1544                             if ((given & (1 << bitstart)) != 0)
1545                               func (stream, "%c", *c);
1546                             break;
1547                           case '?':
1548                             ++c;
1549                             if ((given & (1 << bitstart)) != 0)
1550                               func (stream, "%c", *c++);
1551                             else
1552                               func (stream, "%c", *++c);
1553                             break;
1554                           default:
1555                             abort ();
1556                           }
1557                         break;
1558
1559                       case 'L':
1560                         switch (given & 0x00400100)
1561                           {
1562                           case 0x00000000: func (stream, "b"); break;
1563                           case 0x00400000: func (stream, "h"); break;
1564                           case 0x00000100: func (stream, "w"); break;
1565                           case 0x00400100: func (stream, "d"); break;
1566                           default:
1567                             break;
1568                           }
1569                         break;
1570
1571                       case 'Z':
1572                         {
1573                           int value;
1574                           /* given (20, 23) | given (0, 3) */
1575                           value = ((given >> 16) & 0xf0) | (given & 0xf);
1576                           func (stream, "%d", value);
1577                         }
1578                         break;
1579
1580                       case 'l':
1581                         /* This is like the 'A' operator, except that if
1582                            the width field "M" is zero, then the offset is
1583                            *not* multiplied by four.  */
1584                         {
1585                           int offset = given & 0xff;
1586                           int multiplier = (given & 0x00000100) ? 4 : 1;
1587
1588                           func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1589
1590                           if (offset)
1591                             {
1592                               if ((given & 0x01000000) != 0)
1593                                 func (stream, ", #%s%d]%s",
1594                                       ((given & 0x00800000) == 0 ? "-" : ""),
1595                                       offset * multiplier,
1596                                       ((given & 0x00200000) != 0 ? "!" : ""));
1597                               else
1598                                 func (stream, "], #%s%d",
1599                                       ((given & 0x00800000) == 0 ? "-" : ""),
1600                                       offset * multiplier);
1601                             }
1602                           else
1603                             func (stream, "]");
1604                         }
1605                         break;
1606
1607                       case 'e':
1608                         {
1609                           int imm;
1610
1611                           imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1612                           func (stream, "%d", imm);
1613                         }
1614                         break;
1615
1616                       default:
1617                         abort ();
1618                       }
1619                     }
1620                 }
1621               else
1622                 func (stream, "%c", *c);
1623             }
1624           return 4;
1625         }
1626     }
1627   abort ();
1628 }
1629
1630 /* Print one instruction from PC on INFO->STREAM.
1631    Return the size of the instruction. */
1632
1633 static int
1634 print_insn_thumb (pc, info, given)
1635      bfd_vma pc;
1636      struct disassemble_info *info;
1637      long given;
1638 {
1639   const struct thumb_opcode *insn;
1640   void *stream = info->stream;
1641   fprintf_ftype func = info->fprintf_func;
1642
1643   for (insn = thumb_opcodes; insn->assembler; insn++)
1644     {
1645       if ((given & insn->mask) == insn->value)
1646         {
1647           char * c = insn->assembler;
1648
1649           /* Special processing for Thumb 2 instruction BL sequence:  */
1650           if (!*c) /* Check for empty (not NULL) assembler string.  */
1651             {
1652               long offset;
1653
1654               info->bytes_per_chunk = 4;
1655               info->bytes_per_line  = 4;
1656
1657               offset = BDISP23 (given);
1658               offset = offset * 2 + pc + 4;
1659
1660               if ((given & 0x10000000) == 0)
1661                 {
1662                   func (stream, "blx\t");
1663                   offset &= 0xfffffffc;
1664                 }
1665               else
1666                 func (stream, "bl\t");
1667
1668               info->print_address_func (offset, info);
1669               return 4;
1670             }
1671           else
1672             {
1673               info->bytes_per_chunk = 2;
1674               info->bytes_per_line  = 4;
1675
1676               given &= 0xffff;
1677
1678               for (; *c; c++)
1679                 {
1680                   if (*c == '%')
1681                     {
1682                       int domaskpc = 0;
1683                       int domasklr = 0;
1684
1685                       switch (*++c)
1686                         {
1687                         case '%':
1688                           func (stream, "%%");
1689                           break;
1690
1691                         case 'S':
1692                           {
1693                             long reg;
1694
1695                             reg = (given >> 3) & 0x7;
1696                             if (given & (1 << 6))
1697                               reg += 8;
1698
1699                             func (stream, "%s", arm_regnames[reg]);
1700                           }
1701                           break;
1702
1703                         case 'D':
1704                           {
1705                             long reg;
1706
1707                             reg = given & 0x7;
1708                             if (given & (1 << 7))
1709                              reg += 8;
1710
1711                             func (stream, "%s", arm_regnames[reg]);
1712                           }
1713                           break;
1714
1715                         case 'T':
1716                           func (stream, "%s",
1717                                 arm_conditional [(given >> 8) & 0xf]);
1718                           break;
1719
1720                         case 'N':
1721                           if (given & (1 << 8))
1722                             domasklr = 1;
1723                           /* Fall through.  */
1724                         case 'O':
1725                           if (*c == 'O' && (given & (1 << 8)))
1726                             domaskpc = 1;
1727                           /* Fall through.  */
1728                         case 'M':
1729                           {
1730                             int started = 0;
1731                             int reg;
1732
1733                             func (stream, "{");
1734
1735                             /* It would be nice if we could spot
1736                                ranges, and generate the rS-rE format: */
1737                             for (reg = 0; (reg < 8); reg++)
1738                               if ((given & (1 << reg)) != 0)
1739                                 {
1740                                   if (started)
1741                                     func (stream, ", ");
1742                                   started = 1;
1743                                   func (stream, "%s", arm_regnames[reg]);
1744                                 }
1745
1746                             if (domasklr)
1747                               {
1748                                 if (started)
1749                                   func (stream, ", ");
1750                                 started = 1;
1751                                 func (stream, arm_regnames[14] /* "lr" */);
1752                               }
1753
1754                             if (domaskpc)
1755                               {
1756                                 if (started)
1757                                   func (stream, ", ");
1758                                 func (stream, arm_regnames[15] /* "pc" */);
1759                               }
1760
1761                             func (stream, "}");
1762                           }
1763                           break;
1764
1765
1766                         case '0': case '1': case '2': case '3': case '4':
1767                         case '5': case '6': case '7': case '8': case '9':
1768                           {
1769                             int bitstart = *c++ - '0';
1770                             int bitend = 0;
1771
1772                             while (*c >= '0' && *c <= '9')
1773                               bitstart = (bitstart * 10) + *c++ - '0';
1774
1775                             switch (*c)
1776                               {
1777                               case '-':
1778                                 {
1779                                   long reg;
1780
1781                                   c++;
1782                                   while (*c >= '0' && *c <= '9')
1783                                     bitend = (bitend * 10) + *c++ - '0';
1784                                   if (!bitend)
1785                                     abort ();
1786                                   reg = given >> bitstart;
1787                                   reg &= (2 << (bitend - bitstart)) - 1;
1788                                   switch (*c)
1789                                     {
1790                                     case 'r':
1791                                       func (stream, "%s", arm_regnames[reg]);
1792                                       break;
1793
1794                                     case 'd':
1795                                       func (stream, "%d", reg);
1796                                       break;
1797
1798                                     case 'H':
1799                                       func (stream, "%d", reg << 1);
1800                                       break;
1801
1802                                     case 'W':
1803                                       func (stream, "%d", reg << 2);
1804                                       break;
1805
1806                                     case 'a':
1807                                       /* PC-relative address -- the bottom two
1808                                          bits of the address are dropped
1809                                          before the calculation.  */
1810                                       info->print_address_func
1811                                         (((pc + 4) & ~3) + (reg << 2), info);
1812                                       break;
1813
1814                                     case 'x':
1815                                       func (stream, "0x%04x", reg);
1816                                       break;
1817
1818                                     case 'I':
1819                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1820                                       func (stream, "%d", reg);
1821                                       break;
1822
1823                                     case 'B':
1824                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1825                                       (*info->print_address_func)
1826                                         (reg * 2 + pc + 4, info);
1827                                       break;
1828
1829                                     default:
1830                                       abort ();
1831                                     }
1832                                 }
1833                                 break;
1834
1835                               case '\'':
1836                                 c++;
1837                                 if ((given & (1 << bitstart)) != 0)
1838                                   func (stream, "%c", *c);
1839                                 break;
1840
1841                               case '?':
1842                                 ++c;
1843                                 if ((given & (1 << bitstart)) != 0)
1844                                   func (stream, "%c", *c++);
1845                                 else
1846                                   func (stream, "%c", *++c);
1847                                 break;
1848
1849                               default:
1850                                  abort ();
1851                               }
1852                           }
1853                           break;
1854
1855                         default:
1856                           abort ();
1857                         }
1858                     }
1859                   else
1860                     func (stream, "%c", *c);
1861                 }
1862              }
1863           return 2;
1864        }
1865     }
1866
1867   /* No match.  */
1868   abort ();
1869 }
1870
1871 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1872    being displayed in symbol relative addresses.  */
1873
1874 bfd_boolean
1875 arm_symbol_is_valid (asymbol * sym,
1876                      struct disassemble_info * info ATTRIBUTE_UNUSED)
1877 {
1878   const char * name;
1879   
1880   if (sym == NULL)
1881     return FALSE;
1882
1883   name = bfd_asymbol_name (sym);
1884
1885   return (name && *name != '$');
1886 }
1887
1888 /* Parse an individual disassembler option.  */
1889
1890 void
1891 parse_arm_disassembler_option (option)
1892      char * option;
1893 {
1894   if (option == NULL)
1895     return;
1896
1897   if (strneq (option, "reg-names-", 10))
1898     {
1899       int i;
1900
1901       option += 10;
1902
1903       for (i = NUM_ARM_REGNAMES; i--;)
1904         if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1905           {
1906             regname_selected = i;
1907             break;
1908           }
1909
1910       if (i < 0)
1911         /* XXX - should break 'option' at following delimiter.  */
1912         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1913     }
1914   else if (strneq (option, "force-thumb", 11))
1915     force_thumb = 1;
1916   else if (strneq (option, "no-force-thumb", 14))
1917     force_thumb = 0;
1918   else
1919     /* XXX - should break 'option' at following delimiter.  */
1920     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1921
1922   return;
1923 }
1924
1925 /* Parse the string of disassembler options, spliting it at whitespaces
1926    or commas.  (Whitespace separators supported for backwards compatibility).  */
1927
1928 static void
1929 parse_disassembler_options (options)
1930      char * options;
1931 {
1932   if (options == NULL)
1933     return;
1934
1935   while (*options)
1936     {
1937       parse_arm_disassembler_option (options);
1938
1939       /* Skip forward to next seperator.  */
1940       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1941         ++ options;
1942       /* Skip forward past seperators.  */
1943       while (ISSPACE (*options) || (*options == ','))
1944         ++ options;      
1945     }
1946 }
1947
1948 /* NOTE: There are no checks in these routines that
1949    the relevant number of data bytes exist.  */
1950
1951 static int
1952 print_insn (pc, info, little)
1953      bfd_vma pc;
1954      struct disassemble_info * info;
1955      bfd_boolean little;
1956 {
1957   unsigned char      b[4];
1958   long               given;
1959   int                status;
1960   int                is_thumb, second_half_valid = 1;
1961
1962   if (info->disassembler_options)
1963     {
1964       parse_disassembler_options (info->disassembler_options);
1965
1966       /* To avoid repeated parsing of these options, we remove them here.  */
1967       info->disassembler_options = NULL;
1968     }
1969
1970   is_thumb = force_thumb;
1971
1972   if (!is_thumb && info->symbols != NULL)
1973     {
1974       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1975         {
1976           coff_symbol_type * cs;
1977
1978           cs = coffsymbol (*info->symbols);
1979           is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
1980                       || cs->native->u.syment.n_sclass == C_THUMBSTAT
1981                       || cs->native->u.syment.n_sclass == C_THUMBLABEL
1982                       || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1983                       || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1984         }
1985       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1986         {
1987           elf_symbol_type *  es;
1988           unsigned int       type;
1989
1990           es = *(elf_symbol_type **)(info->symbols);
1991           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1992
1993           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1994         }
1995     }
1996
1997   info->bytes_per_chunk = 4;
1998   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1999
2000   if (little)
2001     {
2002       status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
2003       if (status != 0 && is_thumb)
2004         {
2005           info->bytes_per_chunk = 2;
2006           second_half_valid = 0;
2007
2008           status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
2009           b[3] = b[2] = 0;
2010         }
2011
2012       if (status != 0)
2013         {
2014           info->memory_error_func (status, pc, info);
2015           return -1;
2016         }
2017
2018       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2019     }
2020   else
2021     {
2022       status = info->read_memory_func
2023         (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
2024       if (status != 0)
2025         {
2026           info->memory_error_func (status, WORD_ADDRESS (pc), info);
2027           return -1;
2028         }
2029
2030       if (is_thumb)
2031         {
2032           if (pc & 0x2)
2033             {
2034               given = (b[2] << 8) | b[3];
2035
2036               status = info->read_memory_func
2037                 (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info);
2038               if (status != 0)
2039                 second_half_valid = 0;
2040               else
2041                 given |= (b[0] << 24) | (b[1] << 16);
2042             }
2043           else
2044             given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
2045         }
2046       else
2047         given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
2048     }
2049
2050   if (info->flags & INSN_HAS_RELOC)
2051     /* If the instruction has a reloc associated with it, then
2052        the offset field in the instruction will actually be the
2053        addend for the reloc.  (We are using REL type relocs).
2054        In such cases, we can ignore the pc when computing
2055        addresses, since the addend is not currently pc-relative.  */
2056     pc = 0;
2057
2058   if (is_thumb)
2059     status = print_insn_thumb (pc, info, given);
2060   else
2061     status = print_insn_arm (pc, info, given);
2062
2063   if (is_thumb && status == 4 && second_half_valid == 0)
2064     {
2065       info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
2066       return -1;
2067     }
2068
2069   return status;
2070 }
2071
2072 int
2073 print_insn_big_arm (pc, info)
2074      bfd_vma pc;
2075      struct disassemble_info * info;
2076 {
2077   return print_insn (pc, info, FALSE);
2078 }
2079
2080 int
2081 print_insn_little_arm (pc, info)
2082      bfd_vma pc;
2083      struct disassemble_info * info;
2084 {
2085   return print_insn (pc, info, TRUE);
2086 }
2087
2088 void
2089 print_arm_disassembler_options (FILE * stream)
2090 {
2091   int i;
2092
2093   fprintf (stream, _("\n\
2094 The following ARM specific disassembler options are supported for use with\n\
2095 the -M switch:\n"));
2096
2097   for (i = NUM_ARM_REGNAMES; i--;)
2098     fprintf (stream, "  reg-names-%s %*c%s\n",
2099              regnames[i].name,
2100              (int)(14 - strlen (regnames[i].name)), ' ',
2101              regnames[i].description);
2102
2103   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
2104   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
2105 }