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