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