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