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