OSDN Git Service

Revert accidental commit of V6K ops
[pf3gnuchains/pf3gnuchains4x.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5    Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7    This file is part of libopcodes.
8
9    This program is free software; you can redistribute it and/or modify it under
10    the terms of the GNU General Public License as published by the Free
11    Software Foundation; either version 2 of the License, or (at your option)
12    any later version.
13
14    This program is distributed in the hope that it will be useful, but WITHOUT
15    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17    more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
22
23 #include "sysdep.h"
24
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "arm-opc.h"
28 #include "coff/internal.h"
29 #include "libcoff.h"
30 #include "opintl.h"
31 #include "safe-ctype.h"
32
33 /* FIXME: This shouldn't be done here.  */
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
37
38 #ifndef streq
39 #define streq(a,b)      (strcmp ((a), (b)) == 0)
40 #endif
41
42 #ifndef strneq
43 #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
44 #endif
45
46 #ifndef NUM_ELEM
47 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
48 #endif
49
50 #define WORD_ADDRESS(pc) ((pc) & ~0x3)
51
52 /* Format of the 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 V6.  */
639   {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
640   {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
641   {ARM_EXT_V6, 0x4600, 0xffc0, "cpy\t%0-2r, %3-5r"},
642   {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
643   {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
644   {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
645   {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
646   {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
647   {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
648   {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
649   {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
650
651   /* ARM V5 ISA extends Thumb.  */
652   {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
653   /* Note: this is BLX(2).  BLX(1) is done in arm-dis.c/print_insn_thumb()
654      as an extension of the special processing there for Thumb BL.
655      BL and BLX(1) involve 2 successive 16-bit instructions, which must
656      always appear together in the correct order.  So, the empty
657      string is put in this table, and the string interpreter takes <empty>
658      to mean it has a pair of BL-ish instructions.  */
659   {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"},  /* note: 4 bit register number.  */
660   /* ARM V4T ISA (Thumb v1).  */
661   {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
662   /* Format 5 instructions do not update the PSR.  */
663   {ARM_EXT_V4T, 0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
664   /* Format 4.  */
665   {ARM_EXT_V4T, 0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
666   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
667   {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
668   {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
669   {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
670   {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
671   {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
672   {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
673   {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
674   {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
675   {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
676   {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
677   {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
678   {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
679   {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
680   {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
681   /* format 13 */
682   {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
683   {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
684   /* format 5 */
685   {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
686   {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
687   {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
688   {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
689   /* format 14 */
690   {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
691   {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
692   /* format 2 */
693   {ARM_EXT_V4T, 0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
694   {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
695   {ARM_EXT_V4T, 0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
696   {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
697   /* format 8 */
698   {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
699   {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
700   {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
701   /* format 7 */
702   {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
703   {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
704   /* format 1 */
705   {ARM_EXT_V4T, 0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
706   {ARM_EXT_V4T, 0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
707   {ARM_EXT_V4T, 0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
708   /* format 3 */
709   {ARM_EXT_V4T, 0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
710   {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
711   {ARM_EXT_V4T, 0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
712   {ARM_EXT_V4T, 0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
713   /* format 6 */
714   {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
715   /* format 9 */
716   {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
717   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
718   {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
719   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
720   /* format 10 */
721   {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
722   {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
723   /* format 11 */
724   {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
725   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
726   /* format 12 */
727   {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
728   {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
729   /* format 15 */
730   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!,%M"},
731   {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
732   /* format 18 */
733   {ARM_EXT_V4T, 0xE000, 0xF800, "b\t%0-10B"},
734   {ARM_EXT_V4T, 0xE800, 0xF800, "undefined"},
735   /* format 19 */
736   {ARM_EXT_V4T, 0xF000, 0xF800, ""}, /* special processing required in disassembler */
737   {ARM_EXT_V4T, 0xF800, 0xF800, "second half of BL instruction %0-15x"},
738   /* format 16 */
739   {ARM_EXT_V4T, 0xD000, 0xFF00, "beq\t%0-7B"},
740   {ARM_EXT_V4T, 0xD100, 0xFF00, "bne\t%0-7B"},
741   {ARM_EXT_V4T, 0xD200, 0xFF00, "bcs\t%0-7B"},
742   {ARM_EXT_V4T, 0xD300, 0xFF00, "bcc\t%0-7B"},
743   {ARM_EXT_V4T, 0xD400, 0xFF00, "bmi\t%0-7B"},
744   {ARM_EXT_V4T, 0xD500, 0xFF00, "bpl\t%0-7B"},
745   {ARM_EXT_V4T, 0xD600, 0xFF00, "bvs\t%0-7B"},
746   {ARM_EXT_V4T, 0xD700, 0xFF00, "bvc\t%0-7B"},
747   {ARM_EXT_V4T, 0xD800, 0xFF00, "bhi\t%0-7B"},
748   {ARM_EXT_V4T, 0xD900, 0xFF00, "bls\t%0-7B"},
749   {ARM_EXT_V4T, 0xDA00, 0xFF00, "bge\t%0-7B"},
750   {ARM_EXT_V4T, 0xDB00, 0xFF00, "blt\t%0-7B"},
751   {ARM_EXT_V4T, 0xDC00, 0xFF00, "bgt\t%0-7B"},
752   {ARM_EXT_V4T, 0xDD00, 0xFF00, "ble\t%0-7B"},
753   /* format 17 */
754   {ARM_EXT_V4T, 0xDE00, 0xFF00, "bal\t%0-7B"},
755   {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
756   /* format 9 */
757   {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
758   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
759   {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
760   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
761   /* the rest */
762   {ARM_EXT_V1, 0x0000, 0x0000, "undefined instruction %0-15x"},
763   {0, 0x0000, 0x0000, 0}
764 };
765
766 static char * arm_conditional[] =
767 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
768  "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
769
770 typedef struct
771 {
772   const char * name;
773   const char * description;
774   const char * reg_names[16];
775 }
776 arm_regname;
777
778 static arm_regname regnames[] =
779 {
780   { "raw" , "Select raw register names",
781     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
782   { "gcc",  "Select register names used by GCC",
783     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
784   { "std",  "Select register names used in ARM's ISA documentation",
785     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
786   { "apcs", "Select register names used in the APCS",
787     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
788   { "atpcs", "Select register names used in the ATPCS",
789     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
790   { "special-atpcs", "Select special register names used in the ATPCS",
791     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
792   { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
793     { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
794   { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
795     {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
796 };
797
798 static char * iwmmxt_wwnames[] =
799 {"b", "h", "w", "d"};
800
801 static char * iwmmxt_wwssnames[] =
802 {"b", "bus", "b", "bss",
803  "h", "hus", "h", "hss",
804  "w", "wus", "w", "wss",
805  "d", "dus", "d", "dss"
806 };
807
808 /* Default to GCC register name set.  */
809 static unsigned int regname_selected = 1;
810
811 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
812 #define arm_regnames      regnames[regname_selected].reg_names
813
814 static bfd_boolean force_thumb = FALSE;
815
816 static char * arm_fp_const[] =
817 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
818
819 static char * arm_shift[] =
820 {"lsl", "lsr", "asr", "ror"};
821 \f
822 /* Forward declarations.  */
823 static void arm_decode_shift
824   PARAMS ((long, fprintf_ftype, void *));
825 static int  print_insn_arm
826   PARAMS ((bfd_vma, struct disassemble_info *, long));
827 static int  print_insn_thumb
828   PARAMS ((bfd_vma, struct disassemble_info *, long));
829 static void parse_disassembler_options
830   PARAMS ((char *));
831 static int  print_insn
832   PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
833 static int set_iwmmxt_regnames
834   PARAMS ((void));
835
836 int get_arm_regname_num_options
837   PARAMS ((void));
838 int set_arm_regname_option
839   PARAMS ((int));
840 int get_arm_regnames
841   PARAMS ((int, const char **, const char **, const char ***));
842 \f
843 /* Functions.  */
844 int
845 get_arm_regname_num_options ()
846 {
847   return NUM_ARM_REGNAMES;
848 }
849
850 int
851 set_arm_regname_option (option)
852      int option;
853 {
854   int old = regname_selected;
855   regname_selected = option;
856   return old;
857 }
858
859 int
860 get_arm_regnames (option, setname, setdescription, register_names)
861      int option;
862      const char **setname;
863      const char **setdescription;
864      const char ***register_names;
865 {
866   *setname = regnames[option].name;
867   *setdescription = regnames[option].description;
868   *register_names = regnames[option].reg_names;
869   return 16;
870 }
871
872 static void
873 arm_decode_shift (given, func, stream)
874      long given;
875      fprintf_ftype func;
876      void * stream;
877 {
878   func (stream, "%s", arm_regnames[given & 0xf]);
879
880   if ((given & 0xff0) != 0)
881     {
882       if ((given & 0x10) == 0)
883         {
884           int amount = (given & 0xf80) >> 7;
885           int shift = (given & 0x60) >> 5;
886
887           if (amount == 0)
888             {
889               if (shift == 3)
890                 {
891                   func (stream, ", rrx");
892                   return;
893                 }
894
895               amount = 32;
896             }
897
898           func (stream, ", %s #%d", arm_shift[shift], amount);
899         }
900       else
901         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
902               arm_regnames[(given & 0xf00) >> 8]);
903     }
904 }
905
906 static int
907 set_iwmmxt_regnames ()
908 {
909   const char * setname;
910   const char * setdesc;
911   const char ** regnames;
912   int iwmmxt_regnames = 0;
913   int num_regnames = get_arm_regname_num_options ();
914
915   get_arm_regnames (iwmmxt_regnames, &setname,
916                     &setdesc, &regnames);
917   while ((strcmp ("iwmmxt_regnames", setname))
918          && (iwmmxt_regnames < num_regnames))
919     get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
920
921   return iwmmxt_regnames;
922 }
923                           
924 /* Print one instruction from PC on INFO->STREAM.
925    Return the size of the instruction (always 4 on ARM). */
926
927 static int
928 print_insn_arm (pc, info, given)
929      bfd_vma pc;
930      struct disassemble_info *info;
931      long given;
932 {
933   const struct arm_opcode *insn;
934   void *stream = info->stream;
935   fprintf_ftype func   = info->fprintf_func;
936   static int iwmmxt_regnames = 0;
937
938   for (insn = arm_opcodes; insn->assembler; insn++)
939     {
940       if (insn->value == FIRST_IWMMXT_INSN
941           && info->mach != bfd_mach_arm_XScale
942           && info->mach != bfd_mach_arm_iWMMXt)
943         insn = insn + IWMMXT_INSN_COUNT;
944
945       if ((given & insn->mask) == insn->value
946           /* Special case: an instruction with all bits set in the condition field
947              (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
948              or by the catchall at the end of the table.  */
949           && ((given & 0xF0000000) != 0xF0000000
950               || (insn->mask & 0xF0000000) == 0xF0000000
951               || (insn->mask == 0 && insn->value == 0)))
952         {
953           char * c;
954
955           for (c = insn->assembler; *c; c++)
956             {
957               if (*c == '%')
958                 {
959                   switch (*++c)
960                     {
961                     case '%':
962                       func (stream, "%%");
963                       break;
964
965                     case 'a':
966                       if (((given & 0x000f0000) == 0x000f0000)
967                           && ((given & 0x02000000) == 0))
968                         {
969                           int offset = given & 0xfff;
970
971                           func (stream, "[pc");
972
973                           if (given & 0x01000000)
974                             {
975                               if ((given & 0x00800000) == 0)
976                                 offset = - offset;
977
978                               /* Pre-indexed.  */
979                               func (stream, ", #%d]", offset);
980
981                               offset += pc + 8;
982
983                               /* Cope with the possibility of write-back
984                                  being used.  Probably a very dangerous thing
985                                  for the programmer to do, but who are we to
986                                  argue ?  */
987                               if (given & 0x00200000)
988                                 func (stream, "!");
989                             }
990                           else
991                             {
992                               /* Post indexed.  */
993                               func (stream, "], #%d", offset);
994
995                               /* ie ignore the offset.  */
996                               offset = pc + 8;
997                             }
998
999                           func (stream, "\t; ");
1000                           info->print_address_func (offset, info);
1001                         }
1002                       else
1003                         {
1004                           func (stream, "[%s",
1005                                 arm_regnames[(given >> 16) & 0xf]);
1006                           if ((given & 0x01000000) != 0)
1007                             {
1008                               if ((given & 0x02000000) == 0)
1009                                 {
1010                                   int offset = given & 0xfff;
1011                                   if (offset)
1012                                     func (stream, ", #%s%d",
1013                                           (((given & 0x00800000) == 0)
1014                                            ? "-" : ""), offset);
1015                                 }
1016                               else
1017                                 {
1018                                   func (stream, ", %s",
1019                                         (((given & 0x00800000) == 0)
1020                                          ? "-" : ""));
1021                                   arm_decode_shift (given, func, stream);
1022                                 }
1023
1024                               func (stream, "]%s",
1025                                     ((given & 0x00200000) != 0) ? "!" : "");
1026                             }
1027                           else
1028                             {
1029                               if ((given & 0x02000000) == 0)
1030                                 {
1031                                   int offset = given & 0xfff;
1032                                   if (offset)
1033                                     func (stream, "], #%s%d",
1034                                           (((given & 0x00800000) == 0)
1035                                            ? "-" : ""), offset);
1036                                   else
1037                                     func (stream, "]");
1038                                 }
1039                               else
1040                                 {
1041                                   func (stream, "], %s",
1042                                         (((given & 0x00800000) == 0)
1043                                          ? "-" : ""));
1044                                   arm_decode_shift (given, func, stream);
1045                                 }
1046                             }
1047                         }
1048                       break;
1049
1050                     case 's':
1051                       if ((given & 0x004f0000) == 0x004f0000)
1052                         {
1053                           /* PC relative with immediate offset.  */
1054                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1055
1056                           if ((given & 0x00800000) == 0)
1057                             offset = -offset;
1058
1059                           func (stream, "[pc, #%d]\t; ", offset);
1060
1061                           (*info->print_address_func)
1062                             (offset + pc + 8, info);
1063                         }
1064                       else
1065                         {
1066                           func (stream, "[%s",
1067                                 arm_regnames[(given >> 16) & 0xf]);
1068                           if ((given & 0x01000000) != 0)
1069                             {
1070                               /* Pre-indexed.  */
1071                               if ((given & 0x00400000) == 0x00400000)
1072                                 {
1073                                   /* Immediate.  */
1074                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1075                                   if (offset)
1076                                     func (stream, ", #%s%d",
1077                                           (((given & 0x00800000) == 0)
1078                                            ? "-" : ""), offset);
1079                                 }
1080                               else
1081                                 {
1082                                   /* Register.  */
1083                                   func (stream, ", %s%s",
1084                                         (((given & 0x00800000) == 0)
1085                                          ? "-" : ""),
1086                                         arm_regnames[given & 0xf]);
1087                                 }
1088
1089                               func (stream, "]%s",
1090                                     ((given & 0x00200000) != 0) ? "!" : "");
1091                             }
1092                           else
1093                             {
1094                               /* Post-indexed.  */
1095                               if ((given & 0x00400000) == 0x00400000)
1096                                 {
1097                                   /* Immediate.  */
1098                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1099                                   if (offset)
1100                                     func (stream, "], #%s%d",
1101                                           (((given & 0x00800000) == 0)
1102                                            ? "-" : ""), offset);
1103                                   else
1104                                     func (stream, "]");
1105                                 }
1106                               else
1107                                 {
1108                                   /* Register.  */
1109                                   func (stream, "], %s%s",
1110                                         (((given & 0x00800000) == 0)
1111                                          ? "-" : ""),
1112                                         arm_regnames[given & 0xf]);
1113                                 }
1114                             }
1115                         }
1116                       break;
1117
1118                     case 'b':
1119                       (*info->print_address_func)
1120                         (BDISP (given) * 4 + pc + 8, info);
1121                       break;
1122
1123                     case 'c':
1124                       func (stream, "%s",
1125                             arm_conditional [(given >> 28) & 0xf]);
1126                       break;
1127
1128                     case 'm':
1129                       {
1130                         int started = 0;
1131                         int reg;
1132
1133                         func (stream, "{");
1134                         for (reg = 0; reg < 16; reg++)
1135                           if ((given & (1 << reg)) != 0)
1136                             {
1137                               if (started)
1138                                 func (stream, ", ");
1139                               started = 1;
1140                               func (stream, "%s", arm_regnames[reg]);
1141                             }
1142                         func (stream, "}");
1143                       }
1144                       break;
1145
1146                     case 'o':
1147                       if ((given & 0x02000000) != 0)
1148                         {
1149                           int rotate = (given & 0xf00) >> 7;
1150                           int immed = (given & 0xff);
1151                           immed = (((immed << (32 - rotate))
1152                                     | (immed >> rotate)) & 0xffffffff);
1153                           func (stream, "#%d\t; 0x%x", immed, immed);
1154                         }
1155                       else
1156                         arm_decode_shift (given, func, stream);
1157                       break;
1158
1159                     case 'p':
1160                       if ((given & 0x0000f000) == 0x0000f000)
1161                         func (stream, "p");
1162                       break;
1163
1164                     case 't':
1165                       if ((given & 0x01200000) == 0x00200000)
1166                         func (stream, "t");
1167                       break;
1168
1169                     case 'A':
1170                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1171
1172                       if ((given & (1 << 24)) != 0)
1173                         {
1174                           int offset = given & 0xff;
1175
1176                           if (offset)
1177                             func (stream, ", #%s%d]%s",
1178                                   ((given & 0x00800000) == 0 ? "-" : ""),
1179                                   offset * 4,
1180                                   ((given & 0x00200000) != 0 ? "!" : ""));
1181                           else
1182                             func (stream, "]");
1183                         }
1184                       else
1185                         {
1186                           int offset = given & 0xff;
1187
1188                           func (stream, "]");
1189
1190                           if (given & (1 << 21))
1191                             {
1192                               if (offset)
1193                                 func (stream, ", #%s%d",
1194                                       ((given & 0x00800000) == 0 ? "-" : ""),
1195                                       offset * 4);
1196                             }
1197                           else
1198                             func (stream, ", {%d}", offset);
1199                         }
1200                       break;
1201
1202                     case 'B':
1203                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
1204                       {
1205                         bfd_vma address;
1206                         bfd_vma offset = 0;
1207
1208                         if (given & 0x00800000)
1209                           /* Is signed, hi bits should be ones.  */
1210                           offset = (-1) ^ 0x00ffffff;
1211
1212                         /* Offset is (SignExtend(offset field)<<2).  */
1213                         offset += given & 0x00ffffff;
1214                         offset <<= 2;
1215                         address = offset + pc + 8;
1216
1217                         if (given & 0x01000000)
1218                           /* H bit allows addressing to 2-byte boundaries.  */
1219                           address += 2;
1220
1221                         info->print_address_func (address, info);
1222                       }
1223                       break;
1224
1225                     case 'I':
1226                       /* Print a Cirrus/DSP shift immediate.  */
1227                       /* Immediates are 7bit signed ints with bits 0..3 in
1228                          bits 0..3 of opcode and bits 4..6 in bits 5..7
1229                          of opcode.  */
1230                       {
1231                         int imm;
1232
1233                         imm = (given & 0xf) | ((given & 0xe0) >> 1);
1234
1235                         /* Is ``imm'' a negative number?  */
1236                         if (imm & 0x40)
1237                           imm |= (-1 << 7);
1238
1239                         func (stream, "%d", imm);
1240                       }
1241
1242                       break;
1243
1244                     case 'C':
1245                       func (stream, "_");
1246                       if (given & 0x80000)
1247                         func (stream, "f");
1248                       if (given & 0x40000)
1249                         func (stream, "s");
1250                       if (given & 0x20000)
1251                         func (stream, "x");
1252                       if (given & 0x10000)
1253                         func (stream, "c");
1254                       break;
1255
1256                     case 'F':
1257                       switch (given & 0x00408000)
1258                         {
1259                         case 0:
1260                           func (stream, "4");
1261                           break;
1262                         case 0x8000:
1263                           func (stream, "1");
1264                           break;
1265                         case 0x00400000:
1266                           func (stream, "2");
1267                           break;
1268                         default:
1269                           func (stream, "3");
1270                         }
1271                       break;
1272
1273                     case 'P':
1274                       switch (given & 0x00080080)
1275                         {
1276                         case 0:
1277                           func (stream, "s");
1278                           break;
1279                         case 0x80:
1280                           func (stream, "d");
1281                           break;
1282                         case 0x00080000:
1283                           func (stream, "e");
1284                           break;
1285                         default:
1286                           func (stream, _("<illegal precision>"));
1287                           break;
1288                         }
1289                       break;
1290                     case 'Q':
1291                       switch (given & 0x00408000)
1292                         {
1293                         case 0:
1294                           func (stream, "s");
1295                           break;
1296                         case 0x8000:
1297                           func (stream, "d");
1298                           break;
1299                         case 0x00400000:
1300                           func (stream, "e");
1301                           break;
1302                         default:
1303                           func (stream, "p");
1304                           break;
1305                         }
1306                       break;
1307                     case 'R':
1308                       switch (given & 0x60)
1309                         {
1310                         case 0:
1311                           break;
1312                         case 0x20:
1313                           func (stream, "p");
1314                           break;
1315                         case 0x40:
1316                           func (stream, "m");
1317                           break;
1318                         default:
1319                           func (stream, "z");
1320                           break;
1321                         }
1322                       break;
1323
1324                     case '0': case '1': case '2': case '3': case '4':
1325                     case '5': case '6': case '7': case '8': case '9':
1326                       {
1327                         int bitstart = *c++ - '0';
1328                         int bitend = 0;
1329                         while (*c >= '0' && *c <= '9')
1330                           bitstart = (bitstart * 10) + *c++ - '0';
1331
1332                         switch (*c)
1333                           {
1334                           case '-':
1335                             c++;
1336
1337                             while (*c >= '0' && *c <= '9')
1338                               bitend = (bitend * 10) + *c++ - '0';
1339
1340                             if (!bitend)
1341                               abort ();
1342
1343                             switch (*c)
1344                               {
1345                               case 'r':
1346                                 {
1347                                   long reg;
1348
1349                                   reg = given >> bitstart;
1350                                   reg &= (2 << (bitend - bitstart)) - 1;
1351
1352                                   func (stream, "%s", arm_regnames[reg]);
1353                                 }
1354                                 break;
1355                               case 'd':
1356                                 {
1357                                   long reg;
1358
1359                                   reg = given >> bitstart;
1360                                   reg &= (2 << (bitend - bitstart)) - 1;
1361
1362                                   func (stream, "%d", reg);
1363                                 }
1364                                 break;
1365                               case 'W':
1366                                 {
1367                                   long reg;
1368                                   
1369                                   reg = given >> bitstart;
1370                                   reg &= (2 << (bitend - bitstart)) - 1;
1371                                   
1372                                   func (stream, "%d", reg + 1);
1373                                 }
1374                                 break;
1375                               case 'x':
1376                                 {
1377                                   long reg;
1378
1379                                   reg = given >> bitstart;
1380                                   reg &= (2 << (bitend - bitstart)) - 1;
1381
1382                                   func (stream, "0x%08x", reg);
1383
1384                                   /* Some SWI instructions have special
1385                                      meanings.  */
1386                                   if ((given & 0x0fffffff) == 0x0FF00000)
1387                                     func (stream, "\t; IMB");
1388                                   else if ((given & 0x0fffffff) == 0x0FF00001)
1389                                     func (stream, "\t; IMBRange");
1390                                 }
1391                                 break;
1392                               case 'X':
1393                                 {
1394                                   long reg;
1395
1396                                   reg = given >> bitstart;
1397                                   reg &= (2 << (bitend - bitstart)) - 1;
1398
1399                                   func (stream, "%01x", reg & 0xf);
1400                                 }
1401                                 break;
1402                               case 'f':
1403                                 {
1404                                   long reg;
1405
1406                                   reg = given >> bitstart;
1407                                   reg &= (2 << (bitend - bitstart)) - 1;
1408
1409                                   if (reg > 7)
1410                                     func (stream, "#%s",
1411                                           arm_fp_const[reg & 7]);
1412                                   else
1413                                     func (stream, "f%d", reg);
1414                                 }
1415                                 break;
1416
1417                               case 'w':
1418                                 {
1419                                   long reg;
1420
1421                                   if (bitstart != bitend)
1422                                     {
1423                                       reg = given >> bitstart;
1424                                       reg &= (2 << (bitend - bitstart)) - 1;
1425                                       if (bitend - bitstart == 1)
1426                                         func (stream, "%s", iwmmxt_wwnames[reg]);
1427                                       else
1428                                         func (stream, "%s", iwmmxt_wwssnames[reg]);
1429                                     }
1430                                   else
1431                                     {
1432                                       reg = (((given >> 8)  & 0x1) |
1433                                              ((given >> 22) & 0x1));
1434                                       func (stream, "%s", iwmmxt_wwnames[reg]);
1435                                     }
1436                                 }
1437                                 break;
1438
1439                               case 'g':
1440                                 {
1441                                   long reg;
1442                                   int current_regnames;
1443
1444                                   if (! iwmmxt_regnames)
1445                                     iwmmxt_regnames = set_iwmmxt_regnames ();
1446                                   current_regnames = set_arm_regname_option
1447                                     (iwmmxt_regnames);
1448
1449                                   reg = given >> bitstart;
1450                                   reg &= (2 << (bitend - bitstart)) - 1;
1451                                   func (stream, "%s", arm_regnames[reg]);
1452                                   set_arm_regname_option (current_regnames);
1453                                 }
1454                                 break;
1455
1456                               case 'G':
1457                                 {
1458                                   long reg;
1459                                   int current_regnames;
1460
1461                                   if (! iwmmxt_regnames)
1462                                     iwmmxt_regnames = set_iwmmxt_regnames ();
1463                                   current_regnames = set_arm_regname_option
1464                                     (iwmmxt_regnames + 1);
1465
1466                                   reg = given >> bitstart;
1467                                   reg &= (2 << (bitend - bitstart)) - 1;
1468                                   func (stream, "%s", arm_regnames[reg]);
1469                                   set_arm_regname_option (current_regnames);
1470                                 }
1471                                 break;
1472
1473                               default:
1474                                 abort ();
1475                               }
1476                             break;
1477
1478                           case 'y':
1479                           case 'z':
1480                             {
1481                               int single = *c == 'y';
1482                               int regno;
1483
1484                               switch (bitstart)
1485                                 {
1486                                 case 4: /* Sm pair */
1487                                   func (stream, "{");
1488                                   /* Fall through.  */
1489                                 case 0: /* Sm, Dm */
1490                                   regno = given & 0x0000000f;
1491                                   if (single)
1492                                     {
1493                                       regno <<= 1;
1494                                       regno += (given >> 5) & 1;
1495                                     }
1496                                   break;
1497
1498                                 case 1: /* Sd, Dd */
1499                                   regno = (given >> 12) & 0x0000000f;
1500                                   if (single)
1501                                     {
1502                                       regno <<= 1;
1503                                       regno += (given >> 22) & 1;
1504                                     }
1505                                   break;
1506
1507                                 case 2: /* Sn, Dn */
1508                                   regno = (given >> 16) & 0x0000000f;
1509                                   if (single)
1510                                     {
1511                                       regno <<= 1;
1512                                       regno += (given >> 7) & 1;
1513                                     }
1514                                   break;
1515
1516                                 case 3: /* List */
1517                                   func (stream, "{");
1518                                   regno = (given >> 12) & 0x0000000f;
1519                                   if (single)
1520                                     {
1521                                       regno <<= 1;
1522                                       regno += (given >> 22) & 1;
1523                                     }
1524                                   break;
1525
1526
1527                                 default:
1528                                   abort ();
1529                                 }
1530
1531                               func (stream, "%c%d", single ? 's' : 'd', regno);
1532
1533                               if (bitstart == 3)
1534                                 {
1535                                   int count = given & 0xff;
1536
1537                                   if (single == 0)
1538                                     count >>= 1;
1539
1540                                   if (--count)
1541                                     {
1542                                       func (stream, "-%c%d",
1543                                             single ? 's' : 'd',
1544                                             regno + count);
1545                                     }
1546
1547                                   func (stream, "}");
1548                                 }
1549                               else if (bitstart == 4)
1550                                 func (stream, ", %c%d}", single ? 's' : 'd',
1551                                       regno + 1);
1552
1553                               break;
1554                             }
1555
1556                           case '`':
1557                             c++;
1558                             if ((given & (1 << bitstart)) == 0)
1559                               func (stream, "%c", *c);
1560                             break;
1561                           case '\'':
1562                             c++;
1563                             if ((given & (1 << bitstart)) != 0)
1564                               func (stream, "%c", *c);
1565                             break;
1566                           case '?':
1567                             ++c;
1568                             if ((given & (1 << bitstart)) != 0)
1569                               func (stream, "%c", *c++);
1570                             else
1571                               func (stream, "%c", *++c);
1572                             break;
1573                           default:
1574                             abort ();
1575                           }
1576                         break;
1577
1578                       case 'L':
1579                         switch (given & 0x00400100)
1580                           {
1581                           case 0x00000000: func (stream, "b"); break;
1582                           case 0x00400000: func (stream, "h"); break;
1583                           case 0x00000100: func (stream, "w"); break;
1584                           case 0x00400100: func (stream, "d"); break;
1585                           default:
1586                             break;
1587                           }
1588                         break;
1589
1590                       case 'Z':
1591                         {
1592                           int value;
1593                           /* given (20, 23) | given (0, 3) */
1594                           value = ((given >> 16) & 0xf0) | (given & 0xf);
1595                           func (stream, "%d", value);
1596                         }
1597                         break;
1598
1599                       case 'l':
1600                         /* This is like the 'A' operator, except that if
1601                            the width field "M" is zero, then the offset is
1602                            *not* multiplied by four.  */
1603                         {
1604                           int offset = given & 0xff;
1605                           int multiplier = (given & 0x00000100) ? 4 : 1;
1606
1607                           func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1608
1609                           if (offset)
1610                             {
1611                               if ((given & 0x01000000) != 0)
1612                                 func (stream, ", #%s%d]%s",
1613                                       ((given & 0x00800000) == 0 ? "-" : ""),
1614                                       offset * multiplier,
1615                                       ((given & 0x00200000) != 0 ? "!" : ""));
1616                               else
1617                                 func (stream, "], #%s%d",
1618                                       ((given & 0x00800000) == 0 ? "-" : ""),
1619                                       offset * multiplier);
1620                             }
1621                           else
1622                             func (stream, "]");
1623                         }
1624                         break;
1625
1626                       case 'e':
1627                         {
1628                           int imm;
1629
1630                           imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1631                           func (stream, "%d", imm);
1632                         }
1633                         break;
1634
1635                       case 'E':
1636                         /* LSB and WIDTH fields of BFI or BFC.  The machine-
1637                            language instruction encodes LSB and MSB.  */
1638                         {
1639                           long msb = (given & 0x001f0000) >> 16;
1640                           long lsb = (given & 0x00000f80) >> 7;
1641
1642                           long width = msb - lsb + 1;
1643                           if (width > 0)
1644                             func (stream, "#%lu, #%lu", lsb, width);
1645                           else
1646                             func (stream, "(invalid: %lu:%lu)", lsb, msb);
1647                         }
1648                         break;
1649
1650                       case 'V':
1651                         /* 16-bit unsigned immediate from a MOVT or MOVW
1652                            instruction, encoded in bits 0:11 and 15:19.  */
1653                         {
1654                           long hi = (given & 0x000f0000) >> 4;
1655                           long lo = (given & 0x00000fff);
1656                           long imm16 = hi | lo;
1657                           func (stream, "#%lu\t; 0x%lx", imm16, imm16);
1658                         }
1659                         break;
1660
1661                       default:
1662                         abort ();
1663                       }
1664                     }
1665                 }
1666               else
1667                 func (stream, "%c", *c);
1668             }
1669           return 4;
1670         }
1671     }
1672   abort ();
1673 }
1674
1675 /* Print one instruction from PC on INFO->STREAM.
1676    Return the size of the instruction. */
1677
1678 static int
1679 print_insn_thumb (pc, info, given)
1680      bfd_vma pc;
1681      struct disassemble_info *info;
1682      long given;
1683 {
1684   const struct thumb_opcode *insn;
1685   void *stream = info->stream;
1686   fprintf_ftype func = info->fprintf_func;
1687
1688   for (insn = thumb_opcodes; insn->assembler; insn++)
1689     {
1690       if ((given & insn->mask) == insn->value)
1691         {
1692           char * c = insn->assembler;
1693
1694           /* Special processing for Thumb 2 instruction BL sequence:  */
1695           if (!*c) /* Check for empty (not NULL) assembler string.  */
1696             {
1697               long offset;
1698
1699               info->bytes_per_chunk = 4;
1700               info->bytes_per_line  = 4;
1701
1702               offset = BDISP23 (given);
1703               offset = offset * 2 + pc + 4;
1704
1705               if ((given & 0x10000000) == 0)
1706                 {
1707                   func (stream, "blx\t");
1708                   offset &= 0xfffffffc;
1709                 }
1710               else
1711                 func (stream, "bl\t");
1712
1713               info->print_address_func (offset, info);
1714               return 4;
1715             }
1716           else
1717             {
1718               info->bytes_per_chunk = 2;
1719               info->bytes_per_line  = 4;
1720
1721               given &= 0xffff;
1722
1723               for (; *c; c++)
1724                 {
1725                   if (*c == '%')
1726                     {
1727                       int domaskpc = 0;
1728                       int domasklr = 0;
1729
1730                       switch (*++c)
1731                         {
1732                         case '%':
1733                           func (stream, "%%");
1734                           break;
1735
1736                         case 'S':
1737                           {
1738                             long reg;
1739
1740                             reg = (given >> 3) & 0x7;
1741                             if (given & (1 << 6))
1742                               reg += 8;
1743
1744                             func (stream, "%s", arm_regnames[reg]);
1745                           }
1746                           break;
1747
1748                         case 'D':
1749                           {
1750                             long reg;
1751
1752                             reg = given & 0x7;
1753                             if (given & (1 << 7))
1754                              reg += 8;
1755
1756                             func (stream, "%s", arm_regnames[reg]);
1757                           }
1758                           break;
1759
1760                         case 'T':
1761                           func (stream, "%s",
1762                                 arm_conditional [(given >> 8) & 0xf]);
1763                           break;
1764
1765                         case 'N':
1766                           if (given & (1 << 8))
1767                             domasklr = 1;
1768                           /* Fall through.  */
1769                         case 'O':
1770                           if (*c == 'O' && (given & (1 << 8)))
1771                             domaskpc = 1;
1772                           /* Fall through.  */
1773                         case 'M':
1774                           {
1775                             int started = 0;
1776                             int reg;
1777
1778                             func (stream, "{");
1779
1780                             /* It would be nice if we could spot
1781                                ranges, and generate the rS-rE format: */
1782                             for (reg = 0; (reg < 8); reg++)
1783                               if ((given & (1 << reg)) != 0)
1784                                 {
1785                                   if (started)
1786                                     func (stream, ", ");
1787                                   started = 1;
1788                                   func (stream, "%s", arm_regnames[reg]);
1789                                 }
1790
1791                             if (domasklr)
1792                               {
1793                                 if (started)
1794                                   func (stream, ", ");
1795                                 started = 1;
1796                                 func (stream, arm_regnames[14] /* "lr" */);
1797                               }
1798
1799                             if (domaskpc)
1800                               {
1801                                 if (started)
1802                                   func (stream, ", ");
1803                                 func (stream, arm_regnames[15] /* "pc" */);
1804                               }
1805
1806                             func (stream, "}");
1807                           }
1808                           break;
1809
1810
1811                         case '0': case '1': case '2': case '3': case '4':
1812                         case '5': case '6': case '7': case '8': case '9':
1813                           {
1814                             int bitstart = *c++ - '0';
1815                             int bitend = 0;
1816
1817                             while (*c >= '0' && *c <= '9')
1818                               bitstart = (bitstart * 10) + *c++ - '0';
1819
1820                             switch (*c)
1821                               {
1822                               case '-':
1823                                 {
1824                                   long reg;
1825
1826                                   c++;
1827                                   while (*c >= '0' && *c <= '9')
1828                                     bitend = (bitend * 10) + *c++ - '0';
1829                                   if (!bitend)
1830                                     abort ();
1831                                   reg = given >> bitstart;
1832                                   reg &= (2 << (bitend - bitstart)) - 1;
1833                                   switch (*c)
1834                                     {
1835                                     case 'r':
1836                                       func (stream, "%s", arm_regnames[reg]);
1837                                       break;
1838
1839                                     case 'd':
1840                                       func (stream, "%d", reg);
1841                                       break;
1842
1843                                     case 'H':
1844                                       func (stream, "%d", reg << 1);
1845                                       break;
1846
1847                                     case 'W':
1848                                       func (stream, "%d", reg << 2);
1849                                       break;
1850
1851                                     case 'a':
1852                                       /* PC-relative address -- the bottom two
1853                                          bits of the address are dropped
1854                                          before the calculation.  */
1855                                       info->print_address_func
1856                                         (((pc + 4) & ~3) + (reg << 2), info);
1857                                       break;
1858
1859                                     case 'x':
1860                                       func (stream, "0x%04x", reg);
1861                                       break;
1862
1863                                     case 'I':
1864                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1865                                       func (stream, "%d", reg);
1866                                       break;
1867
1868                                     case 'B':
1869                                       reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1870                                       (*info->print_address_func)
1871                                         (reg * 2 + pc + 4, info);
1872                                       break;
1873
1874                                     default:
1875                                       abort ();
1876                                     }
1877                                 }
1878                                 break;
1879
1880                               case '\'':
1881                                 c++;
1882                                 if ((given & (1 << bitstart)) != 0)
1883                                   func (stream, "%c", *c);
1884                                 break;
1885
1886                               case '?':
1887                                 ++c;
1888                                 if ((given & (1 << bitstart)) != 0)
1889                                   func (stream, "%c", *c++);
1890                                 else
1891                                   func (stream, "%c", *++c);
1892                                 break;
1893
1894                               default:
1895                                  abort ();
1896                               }
1897                           }
1898                           break;
1899
1900                         default:
1901                           abort ();
1902                         }
1903                     }
1904                   else
1905                     func (stream, "%c", *c);
1906                 }
1907              }
1908           return 2;
1909        }
1910     }
1911
1912   /* No match.  */
1913   abort ();
1914 }
1915
1916 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1917    being displayed in symbol relative addresses.  */
1918
1919 bfd_boolean
1920 arm_symbol_is_valid (asymbol * sym,
1921                      struct disassemble_info * info ATTRIBUTE_UNUSED)
1922 {
1923   const char * name;
1924   
1925   if (sym == NULL)
1926     return FALSE;
1927
1928   name = bfd_asymbol_name (sym);
1929
1930   return (name && *name != '$');
1931 }
1932
1933 /* Parse an individual disassembler option.  */
1934
1935 void
1936 parse_arm_disassembler_option (option)
1937      char * option;
1938 {
1939   if (option == NULL)
1940     return;
1941
1942   if (strneq (option, "reg-names-", 10))
1943     {
1944       int i;
1945
1946       option += 10;
1947
1948       for (i = NUM_ARM_REGNAMES; i--;)
1949         if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1950           {
1951             regname_selected = i;
1952             break;
1953           }
1954
1955       if (i < 0)
1956         /* XXX - should break 'option' at following delimiter.  */
1957         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1958     }
1959   else if (strneq (option, "force-thumb", 11))
1960     force_thumb = 1;
1961   else if (strneq (option, "no-force-thumb", 14))
1962     force_thumb = 0;
1963   else
1964     /* XXX - should break 'option' at following delimiter.  */
1965     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1966
1967   return;
1968 }
1969
1970 /* Parse the string of disassembler options, spliting it at whitespaces
1971    or commas.  (Whitespace separators supported for backwards compatibility).  */
1972
1973 static void
1974 parse_disassembler_options (options)
1975      char * options;
1976 {
1977   if (options == NULL)
1978     return;
1979
1980   while (*options)
1981     {
1982       parse_arm_disassembler_option (options);
1983
1984       /* Skip forward to next seperator.  */
1985       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1986         ++ options;
1987       /* Skip forward past seperators.  */
1988       while (ISSPACE (*options) || (*options == ','))
1989         ++ options;      
1990     }
1991 }
1992
1993 /* NOTE: There are no checks in these routines that
1994    the relevant number of data bytes exist.  */
1995
1996 static int
1997 print_insn (pc, info, little)
1998      bfd_vma pc;
1999      struct disassemble_info * info;
2000      bfd_boolean little;
2001 {
2002   unsigned char      b[4];
2003   long               given;
2004   int                status;
2005   int                is_thumb, second_half_valid = 1;
2006
2007   if (info->disassembler_options)
2008     {
2009       parse_disassembler_options (info->disassembler_options);
2010
2011       /* To avoid repeated parsing of these options, we remove them here.  */
2012       info->disassembler_options = NULL;
2013     }
2014
2015   is_thumb = force_thumb;
2016
2017   if (!is_thumb && info->symbols != NULL)
2018     {
2019       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2020         {
2021           coff_symbol_type * cs;
2022
2023           cs = coffsymbol (*info->symbols);
2024           is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
2025                       || cs->native->u.syment.n_sclass == C_THUMBSTAT
2026                       || cs->native->u.syment.n_sclass == C_THUMBLABEL
2027                       || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2028                       || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2029         }
2030       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2031         {
2032           elf_symbol_type *  es;
2033           unsigned int       type;
2034
2035           es = *(elf_symbol_type **)(info->symbols);
2036           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2037
2038           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2039         }
2040     }
2041
2042   info->bytes_per_chunk = 4;
2043   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2044
2045   if (little)
2046     {
2047       status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
2048       if (status != 0 && is_thumb)
2049         {
2050           info->bytes_per_chunk = 2;
2051           second_half_valid = 0;
2052
2053           status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
2054           b[3] = b[2] = 0;
2055         }
2056
2057       if (status != 0)
2058         {
2059           info->memory_error_func (status, pc, info);
2060           return -1;
2061         }
2062
2063       given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2064     }
2065   else
2066     {
2067       status = info->read_memory_func
2068         (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
2069       if (status != 0)
2070         {
2071           info->memory_error_func (status, WORD_ADDRESS (pc), info);
2072           return -1;
2073         }
2074
2075       if (is_thumb)
2076         {
2077           if (pc & 0x2)
2078             {
2079               given = (b[2] << 8) | b[3];
2080
2081               status = info->read_memory_func
2082                 (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info);
2083               if (status != 0)
2084                 second_half_valid = 0;
2085               else
2086                 given |= (b[0] << 24) | (b[1] << 16);
2087             }
2088           else
2089             given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
2090         }
2091       else
2092         given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
2093     }
2094
2095   if (info->flags & INSN_HAS_RELOC)
2096     /* If the instruction has a reloc associated with it, then
2097        the offset field in the instruction will actually be the
2098        addend for the reloc.  (We are using REL type relocs).
2099        In such cases, we can ignore the pc when computing
2100        addresses, since the addend is not currently pc-relative.  */
2101     pc = 0;
2102
2103   if (is_thumb)
2104     status = print_insn_thumb (pc, info, given);
2105   else
2106     status = print_insn_arm (pc, info, given);
2107
2108   if (is_thumb && status == 4 && second_half_valid == 0)
2109     {
2110       info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
2111       return -1;
2112     }
2113
2114   return status;
2115 }
2116
2117 int
2118 print_insn_big_arm (pc, info)
2119      bfd_vma pc;
2120      struct disassemble_info * info;
2121 {
2122   return print_insn (pc, info, FALSE);
2123 }
2124
2125 int
2126 print_insn_little_arm (pc, info)
2127      bfd_vma pc;
2128      struct disassemble_info * info;
2129 {
2130   return print_insn (pc, info, TRUE);
2131 }
2132
2133 void
2134 print_arm_disassembler_options (FILE * stream)
2135 {
2136   int i;
2137
2138   fprintf (stream, _("\n\
2139 The following ARM specific disassembler options are supported for use with\n\
2140 the -M switch:\n"));
2141
2142   for (i = NUM_ARM_REGNAMES; i--;)
2143     fprintf (stream, "  reg-names-%s %*c%s\n",
2144              regnames[i].name,
2145              (int)(14 - strlen (regnames[i].name)), ' ',
2146              regnames[i].description);
2147
2148   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
2149   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
2150 }