2006-02-24 Paul Brook <paul@codesourcery.com>
[external/binutils.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3    Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5    Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7    This file is part of libopcodes.
8
9    This program is free software; you can redistribute it and/or modify it under
10    the terms of the GNU General Public License as published by the Free
11    Software Foundation; either version 2 of the License, or (at your option)
12    any later version.
13
14    This program is distributed in the hope that it will be useful, but WITHOUT
15    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
17    more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.  */
22
23 #include "sysdep.h"
24
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
29
30 /* FIXME: This shouldn't be done here.  */
31 #include "coff/internal.h"
32 #include "libcoff.h"
33 #include "elf-bfd.h"
34 #include "elf/internal.h"
35 #include "elf/arm.h"
36
37 /* FIXME: Belongs in global header.  */
38 #ifndef strneq
39 #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
40 #endif
41
42 #ifndef NUM_ELEM
43 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
44 #endif
45
46 struct opcode32
47 {
48   unsigned long arch;           /* Architecture defining this insn.  */
49   unsigned long value, mask;    /* Recognise insn if (op&mask)==value.  */
50   const char *assembler;        /* How to disassemble this insn.  */
51 };
52
53 struct opcode16
54 {
55   unsigned long arch;           /* Architecture defining this insn.  */
56   unsigned short value, mask;   /* Recognise insn if (op&mask)==value.  */
57   const char *assembler;        /* How to disassemble this insn.  */
58 };
59
60 /* 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    %U                   print barrier type.
406    %P                   print address for pli instruction.
407
408    %<bitfield>r         print as an ARM register
409    %<bitfield>d         print the bitfield in decimal
410    %<bitfield>W         print the bitfield plus one in decimal 
411    %<bitfield>x         print the bitfield in hex
412    %<bitfield>X         print the bitfield as 1 hex digit without leading "0x"
413
414    %<bitnum>'c          print specified char iff bit is one
415    %<bitnum>`c          print specified char iff bit is zero
416    %<bitnum>?ab         print a if bit is one else print b
417
418    %e                   print arm SMI operand (bits 0..7,8..19).
419    %E                   print the LSB and WIDTH fields of a BFI or BFC instruction.
420    %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.  */
421
422 static const struct opcode32 arm_opcodes[] =
423 {
424   /* ARM instructions.  */
425   {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
426   {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
427   {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
428   {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
429   {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
430   {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
431   {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
432
433   /* V7 instructions.  */
434   {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
435   {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
436   {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
437   {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
438   {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
439
440   /* ARM V6T2 instructions.  */
441   {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
442   {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
443   {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
444   {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
445   {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
446   {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
447   {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
448   {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
449   {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
450
451   /* ARM V6Z instructions.  */
452   {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
453
454   /* ARM V6K instructions.  */
455   {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
456   {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
457   {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
458   {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
459   {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
460   {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
461   {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
462
463   /* ARM V6K NOP hints.  */
464   {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
465   {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
466   {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
467   {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
468   {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
469
470   /* ARM V6 instructions. */
471   {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
472   {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
473   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
474   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
475   {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
476   {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
477   {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
478   {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
479   {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
480   {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
481   {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
482   {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
483   {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
484   {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
485   {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
486   {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
487   {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
488   {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
489   {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
490   {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
491   {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
492   {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
493   {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
494   {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
495   {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
496   {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
497   {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
498   {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
499   {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
500   {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
501   {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
502   {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
503   {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
504   {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
505   {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
506   {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
507   {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
508   {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
509   {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
510   {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
511   {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
512   {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
513   {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
514   {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
515   {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
516   {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
517   {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
518   {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
519   {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
520   {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
521   {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
522   {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
523   {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
524   {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
525   {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
526   {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
527   {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
528   {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
529   {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
530   {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
531   {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
532   {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
533   {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
534   {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
535   {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
536   {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
537   {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
538   {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
539   {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
540   {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
541   {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
542   {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
543   {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
544   {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
545   {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
546   {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
547   {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
548   {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
549   {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
550   {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
551   {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
552   {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
553   {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
554   {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
555   {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
556   {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
557   {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
558   {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
559   {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
560   {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
561   {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
562   {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
563   {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
564   {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
565   {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
566   {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
567   {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
568   {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
569   {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
570   {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
571   {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
572   {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
573   {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
574   {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
575   {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
576   {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
577   {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
578   {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
579   {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
580   {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
581   {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
582   {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
583   {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
584   {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
585   {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
586   {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
587   {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
588   {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
589   {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
590   {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
591   {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
592   {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
593
594   /* V5J instruction.  */
595   {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
596
597   /* V5 Instructions.  */
598   {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
599   {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
600   {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
601   {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
602
603   /* V5E "El Segundo" Instructions.  */    
604   {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
605   {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
606   {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
607   {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
608   {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
609   {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
610   {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
611
612   {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
613   {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
614
615   {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
616   {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
617   {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
618   {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
619
620   {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
621   {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
622   {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
623   {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
624
625   {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
626   {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
627
628   {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0,  "qadd%c\t%12-15r, %0-3r, %16-19r"},
629   {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
630   {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0,  "qsub%c\t%12-15r, %0-3r, %16-19r"},
631   {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
632
633   /* ARM Instructions.  */
634   {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
635   {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
636   {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
637   {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
638   {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
639   {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
640   {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
641   {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
642   {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
643   {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
644   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
645   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
646   {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
647   {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
648   {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
649   {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
650   {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
651   {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
652   {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
653   {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
654   {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
655   {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
656   {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
657   {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
658   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
659   {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
660   {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
661   {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
662   {ARM_EXT_V1, 0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
663
664   /* The rest.  */
665   {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
666   {0, 0x00000000, 0x00000000, 0}
667 };
668
669 /* print_insn_thumb16 recognizes the following format control codes:
670
671    %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
672    %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
673    %<bitfield>I         print bitfield as a signed decimal
674                                 (top bit of range being the sign bit)
675    %N                   print Thumb register mask (with LR)
676    %O                   print Thumb register mask (with PC)
677    %M                   print Thumb register mask
678    %b                   print CZB's 6-bit unsigned branch destination
679    %s                   print Thumb right-shift immediate (6..10; 0 == 32).
680    %<bitfield>r         print bitfield as an ARM register
681    %<bitfield>d         print bitfield as a decimal
682    %<bitfield>H         print (bitfield * 2) as a decimal
683    %<bitfield>W         print (bitfield * 4) as a decimal
684    %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
685    %<bitfield>B         print Thumb branch destination (signed displacement)
686    %<bitfield>c         print bitfield as a condition code
687    %<bitnum>'c          print specified char iff bit is one
688    %<bitnum>?ab         print a if bit is one else print b.  */
689
690 static const struct opcode16 thumb_opcodes[] =
691 {
692   /* Thumb instructions.  */
693
694   /* ARM V6K no-argument instructions.  */
695   {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
696   {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
697   {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
698   {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
699   {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
700   {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
701
702   /* ARM V6T2 instructions.  */
703   {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"},
704   {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"},
705   {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"},
706   {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"},
707   {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"},
708   {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"},
709   {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"},
710   {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"},
711   {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"},
712
713   /* ARM V6.  */
714   {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
715   {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
716   {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
717   {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
718   {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
719   {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
720   {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
721   {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
722   {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
723   {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
724   {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
725
726   /* ARM V5 ISA extends Thumb.  */
727   {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
728   /* This is BLX(2).  BLX(1) is a 32-bit instruction.  */
729   {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"},  /* note: 4 bit register number.  */
730   /* ARM V4T ISA (Thumb v1).  */
731   {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
732   /* Format 4.  */
733   {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"},
734   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"},
735   {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"},
736   {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"},
737   {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"},
738   {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"},
739   {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
740   {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
741   {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
742   {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
743   {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
744   {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
745   {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
746   {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"},
747   {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"},
748   {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"},
749   /* format 13 */
750   {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
751   {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
752   /* format 5 */
753   {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
754   {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
755   {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
756   {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
757   /* format 14 */
758   {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
759   {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
760   /* format 2 */
761   {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
762   {ARM_EXT_V4T, 0x1A00, 0xFE00, "subs\t%0-2r, %3-5r, %6-8r"},
763   {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
764   {ARM_EXT_V4T, 0x1E00, 0xFE00, "subs\t%0-2r, %3-5r, #%6-8d"},
765   /* format 8 */
766   {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
767   {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
768   {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
769   /* format 7 */
770   {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
771   {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
772   /* format 1 */
773   {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"},
774   {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"},
775   {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"},
776   /* format 3 */
777   {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
778   {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
779   {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
780   {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
781   /* format 6 */
782   {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
783   /* format 9 */
784   {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
785   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
786   {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
787   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
788   /* format 10 */
789   {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
790   {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
791   /* format 11 */
792   {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
793   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
794   /* format 12 */
795   {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
796   {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
797   /* format 15 */
798   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
799   {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
800   /* format 17 */
801   {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
802   /* format 16 */
803   {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"},
804   /* format 18 */
805   {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"},
806
807   /* The E800 .. FFFF range is unconditionally redirected to the
808      32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
809      are processed via that table.  Thus, we can never encounter a
810      bare "second half of BL/BLX(1)" instruction here.  */
811   {ARM_EXT_V1,  0x0000, 0x0000, "undefined"},
812   {0, 0, 0, 0}
813 };
814
815 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
816    We adopt the convention that hw1 is the high 16 bits of .value and
817    .mask, hw2 the low 16 bits.
818
819    print_insn_thumb32 recognizes the following format control codes:
820
821        %%               %
822
823        %I               print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
824        %M               print a modified 12-bit immediate (same location)
825        %J               print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
826        %K               print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
827        %S               print a possibly-shifted Rm
828
829        %a               print the address of a plain load/store
830        %w               print the width and signedness of a core load/store
831        %m               print register mask for ldm/stm
832
833        %E               print the lsb and width fields of a bfc/bfi instruction
834        %F               print the lsb and width fields of a sbfx/ubfx instruction
835        %b               print a conditional branch offset
836        %B               print an unconditional branch offset
837        %s               print the shift field of an SSAT instruction
838        %R               print the rotation field of an SXT instruction
839        %U               print barrier type.
840        %P               print address for pli instruction.
841
842        %<bitfield>d     print bitfield in decimal
843        %<bitfield>W     print bitfield*4 in decimal
844        %<bitfield>r     print bitfield as an ARM register
845        %<bitfield>c     print bitfield as a condition code
846
847        %<bitnum>'c      print "c" iff bit is one
848        %<bitnum>`c      print "c" iff bit is zero
849        %<bitnum>?ab     print "a" if bit is one, else "b"
850
851    With one exception at the bottom (done because BL and BLX(1) need
852    to come dead last), this table was machine-sorted first in
853    decreasing order of number of bits set in the mask, then in
854    increasing numeric order of mask, then in increasing numeric order
855    of opcode.  This order is not the clearest for a human reader, but
856    is guaranteed never to catch a special-case bit pattern with a more
857    general mask, which is important, because this instruction encoding
858    makes heavy use of special-case bit patterns.  */
859 static const struct opcode32 thumb32_opcodes[] =
860 {
861   /* V7 instructions.  */
862   {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"},
863   {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"},
864   {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"},
865   {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"},
866   {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"},
867   {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"},
868   {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"},
869
870   /* Instructions defined in the basic V6T2 set.  */
871   {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
872   {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
873   {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
874   {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
875   {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
876   {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
877
878   {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
879   {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
880   {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
881   {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
882   {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
883   {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
884   {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"},
885   {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
886   {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
887   {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
888   {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
889   {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
890   {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
891   {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"},
892   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
893   {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
894   {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
895   {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
896   {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"},
897   {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"},
898   {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"},
899   {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
900   {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
901   {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
902   {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
903   {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
904   {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
905   {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
906   {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"},
907   {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"},
908   {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"},
909   {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"},
910   {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"},
911   {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"},
912   {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"},
913   {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"},
914   {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"},
915   {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"},
916   {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"},
917   {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"},
918   {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"},
919   {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"},
920   {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"},
921   {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"},
922   {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"},
923   {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"},
924   {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"},
925   {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"},
926   {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"},
927   {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"},
928   {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"},
929   {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"},
930   {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"},
931   {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"},
932   {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"},
933   {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"},
934   {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"},
935   {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"},
936   {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"},
937   {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"},
938   {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"},
939   {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"},
940   {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"},
941   {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"},
942   {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"},
943   {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"},
944   {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"},
945   {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"},
946   {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"},
947   {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"},
948   {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"},
949   {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"},
950   {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"},
951   {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"},
952   {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"},
953   {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"},
954   {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"},
955   {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"},
956   {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
957   {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
958   {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
959   {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
960   {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
961   {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
962   {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
963   {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
964   {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
965   {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
966   {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"},
967   {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"},
968   {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"},
969   {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"},
970   {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
971   {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
972   {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
973   {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
974   {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
975   {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
976   {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
977   {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
978   {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
979   {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
980   {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
981   {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
982   {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"},
983   {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"},
984   {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"},
985   {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"},
986   {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"},
987   {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
988   {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
989   {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
990   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
991   {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc\t%K"},
992   {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
993   {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
994   {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
995   {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
996   {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
997   {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
998   {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
999   {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
1000   {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1001   {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1002   {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
1003   {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
1004   {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
1005   {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
1006   {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
1007   {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
1008   {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
1009   {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"},
1010   {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"},
1011   {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"},
1012   {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"},
1013   {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"},
1014   {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"},
1015   {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"},
1016   {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"},
1017   {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"},
1018   {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"},
1019   {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"},
1020   {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"},
1021   {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"},
1022   {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
1023   {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
1024   {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
1025   {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
1026   {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
1027   {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1028   {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"},
1029   {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"},
1030   {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"},
1031   {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
1032   {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
1033   {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
1034   {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
1035   {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
1036   {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
1037   {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
1038   {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
1039   {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
1040   {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
1041   {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
1042   {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
1043   {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
1044   {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1045   {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1046   {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
1047   {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"},
1048
1049   /* Filter out Bcc with cond=E or F, which are used for other instructions.  */
1050   {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1051   {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1052   {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
1053   {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
1054
1055   /* These have been 32-bit since the invention of Thumb.  */
1056   {ARM_EXT_V4T,  0xf000c000, 0xf800d000, "blx\t%B"},
1057   {ARM_EXT_V4T,  0xf000d000, 0xf800d000, "bl\t%B"},
1058
1059   /* Fallback.  */
1060   {ARM_EXT_V1,   0x00000000, 0x00000000, "undefined"},
1061   {0, 0, 0, 0}
1062 };
1063    
1064 static const char *const arm_conditional[] =
1065 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1066  "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1067
1068 static const char *const arm_fp_const[] =
1069 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1070
1071 static const char *const arm_shift[] =
1072 {"lsl", "lsr", "asr", "ror"};
1073
1074 typedef struct
1075 {
1076   const char *name;
1077   const char *description;
1078   const char *reg_names[16];
1079 }
1080 arm_regname;
1081
1082 static const arm_regname regnames[] =
1083 {
1084   { "raw" , "Select raw register names",
1085     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1086   { "gcc",  "Select register names used by GCC",
1087     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1088   { "std",  "Select register names used in ARM's ISA documentation",
1089     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
1090   { "apcs", "Select register names used in the APCS",
1091     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1092   { "atpcs", "Select register names used in the ATPCS",
1093     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
1094   { "special-atpcs", "Select special register names used in the ATPCS",
1095     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
1096 };
1097
1098 static const char *const iwmmxt_wwnames[] =
1099 {"b", "h", "w", "d"};
1100
1101 static const char *const iwmmxt_wwssnames[] =
1102 {"b", "bus", "b", "bss",
1103  "h", "hus", "h", "hss",
1104  "w", "wus", "w", "wss",
1105  "d", "dus", "d", "dss"
1106 };
1107
1108 static const char *const iwmmxt_regnames[] =
1109 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1110   "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1111 };
1112
1113 static const char *const iwmmxt_cregnames[] =
1114 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1115   "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1116 };
1117
1118 /* Default to GCC register name set.  */
1119 static unsigned int regname_selected = 1;
1120
1121 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1122 #define arm_regnames      regnames[regname_selected].reg_names
1123
1124 static bfd_boolean force_thumb = FALSE;
1125
1126 \f
1127 /* Functions.  */
1128 int
1129 get_arm_regname_num_options (void)
1130 {
1131   return NUM_ARM_REGNAMES;
1132 }
1133
1134 int
1135 set_arm_regname_option (int option)
1136 {
1137   int old = regname_selected;
1138   regname_selected = option;
1139   return old;
1140 }
1141
1142 int
1143 get_arm_regnames (int option, const char **setname, const char **setdescription,
1144                   const char *const **register_names)
1145 {
1146   *setname = regnames[option].name;
1147   *setdescription = regnames[option].description;
1148   *register_names = regnames[option].reg_names;
1149   return 16;
1150 }
1151
1152 static void
1153 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1154 {
1155   func (stream, "%s", arm_regnames[given & 0xf]);
1156
1157   if ((given & 0xff0) != 0)
1158     {
1159       if ((given & 0x10) == 0)
1160         {
1161           int amount = (given & 0xf80) >> 7;
1162           int shift = (given & 0x60) >> 5;
1163
1164           if (amount == 0)
1165             {
1166               if (shift == 3)
1167                 {
1168                   func (stream, ", rrx");
1169                   return;
1170                 }
1171
1172               amount = 32;
1173             }
1174
1175           func (stream, ", %s #%d", arm_shift[shift], amount);
1176         }
1177       else
1178         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1179               arm_regnames[(given & 0xf00) >> 8]);
1180     }
1181 }
1182
1183 /* Print one coprocessor instruction on INFO->STREAM.
1184    Return TRUE if the instuction matched, FALSE if this is not a
1185    recognised coprocessor instruction.  */
1186
1187 static bfd_boolean
1188 print_insn_coprocessor (struct disassemble_info *info, long given,
1189                         bfd_boolean thumb)
1190 {
1191   const struct opcode32 *insn;
1192   void *stream = info->stream;
1193   fprintf_ftype func = info->fprintf_func;
1194   unsigned long mask;
1195   unsigned long value;
1196
1197   for (insn = coprocessor_opcodes; insn->assembler; insn++)
1198     {
1199       if (insn->value == FIRST_IWMMXT_INSN
1200           && info->mach != bfd_mach_arm_XScale
1201           && info->mach != bfd_mach_arm_iWMMXt)
1202         insn = insn + IWMMXT_INSN_COUNT;
1203
1204       mask = insn->mask;
1205       value = insn->value;
1206       if (thumb)
1207         {
1208           /* The high 4 bits are 0xe for Arm conditional instructions, and
1209              0xe for arm unconditional instructions.  The rest of the
1210              encoding is the same.  */
1211           mask |= 0xf0000000;
1212           value |= 0xe0000000;
1213         }
1214       else
1215         {
1216           /* Only match unconditional instuctions against unconditional
1217              patterns.  */
1218           if ((given & 0xf0000000) == 0xf0000000)
1219             mask |= 0xf0000000;
1220         }
1221       if ((given & mask) == value)
1222         {
1223           const char *c;
1224
1225           for (c = insn->assembler; *c; c++)
1226             {
1227               if (*c == '%')
1228                 {
1229                   switch (*++c)
1230                     {
1231                     case '%':
1232                       func (stream, "%%");
1233                       break;
1234
1235                     case 'A':
1236                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1237
1238                       if ((given & (1 << 24)) != 0)
1239                         {
1240                           int offset = given & 0xff;
1241
1242                           if (offset)
1243                             func (stream, ", #%s%d]%s",
1244                                   ((given & 0x00800000) == 0 ? "-" : ""),
1245                                   offset * 4,
1246                                   ((given & 0x00200000) != 0 ? "!" : ""));
1247                           else
1248                             func (stream, "]");
1249                         }
1250                       else
1251                         {
1252                           int offset = given & 0xff;
1253
1254                           func (stream, "]");
1255
1256                           if (given & (1 << 21))
1257                             {
1258                               if (offset)
1259                                 func (stream, ", #%s%d",
1260                                       ((given & 0x00800000) == 0 ? "-" : ""),
1261                                       offset * 4);
1262                             }
1263                           else
1264                             func (stream, ", {%d}", offset);
1265                         }
1266                       break;
1267
1268                     case 'c':
1269                       func (stream, "%s",
1270                             arm_conditional [(given >> 28) & 0xf]);
1271                       break;
1272
1273                     case 'I':
1274                       /* Print a Cirrus/DSP shift immediate.  */
1275                       /* Immediates are 7bit signed ints with bits 0..3 in
1276                          bits 0..3 of opcode and bits 4..6 in bits 5..7
1277                          of opcode.  */
1278                       {
1279                         int imm;
1280
1281                         imm = (given & 0xf) | ((given & 0xe0) >> 1);
1282
1283                         /* Is ``imm'' a negative number?  */
1284                         if (imm & 0x40)
1285                           imm |= (-1 << 7);
1286
1287                         func (stream, "%d", imm);
1288                       }
1289
1290                       break;
1291
1292                     case 'F':
1293                       switch (given & 0x00408000)
1294                         {
1295                         case 0:
1296                           func (stream, "4");
1297                           break;
1298                         case 0x8000:
1299                           func (stream, "1");
1300                           break;
1301                         case 0x00400000:
1302                           func (stream, "2");
1303                           break;
1304                         default:
1305                           func (stream, "3");
1306                         }
1307                       break;
1308
1309                     case 'P':
1310                       switch (given & 0x00080080)
1311                         {
1312                         case 0:
1313                           func (stream, "s");
1314                           break;
1315                         case 0x80:
1316                           func (stream, "d");
1317                           break;
1318                         case 0x00080000:
1319                           func (stream, "e");
1320                           break;
1321                         default:
1322                           func (stream, _("<illegal precision>"));
1323                           break;
1324                         }
1325                       break;
1326                     case 'Q':
1327                       switch (given & 0x00408000)
1328                         {
1329                         case 0:
1330                           func (stream, "s");
1331                           break;
1332                         case 0x8000:
1333                           func (stream, "d");
1334                           break;
1335                         case 0x00400000:
1336                           func (stream, "e");
1337                           break;
1338                         default:
1339                           func (stream, "p");
1340                           break;
1341                         }
1342                       break;
1343                     case 'R':
1344                       switch (given & 0x60)
1345                         {
1346                         case 0:
1347                           break;
1348                         case 0x20:
1349                           func (stream, "p");
1350                           break;
1351                         case 0x40:
1352                           func (stream, "m");
1353                           break;
1354                         default:
1355                           func (stream, "z");
1356                           break;
1357                         }
1358                       break;
1359
1360                     case '0': case '1': case '2': case '3': case '4':
1361                     case '5': case '6': case '7': case '8': case '9':
1362                       {
1363                         int bitstart = *c++ - '0';
1364                         int bitend = 0;
1365                         while (*c >= '0' && *c <= '9')
1366                           bitstart = (bitstart * 10) + *c++ - '0';
1367
1368                         switch (*c)
1369                           {
1370                           case '-':
1371                             c++;
1372
1373                             while (*c >= '0' && *c <= '9')
1374                               bitend = (bitend * 10) + *c++ - '0';
1375
1376                             if (!bitend)
1377                               abort ();
1378
1379                             switch (*c)
1380                               {
1381                               case 'r':
1382                                 {
1383                                   long reg;
1384
1385                                   reg = given >> bitstart;
1386                                   reg &= (2 << (bitend - bitstart)) - 1;
1387
1388                                   func (stream, "%s", arm_regnames[reg]);
1389                                 }
1390                                 break;
1391                               case 'd':
1392                                 {
1393                                   long reg;
1394
1395                                   reg = given >> bitstart;
1396                                   reg &= (2 << (bitend - bitstart)) - 1;
1397
1398                                   func (stream, "%ld", reg);
1399                                 }
1400                                 break;
1401                               case 'f':
1402                                 {
1403                                   long reg;
1404
1405                                   reg = given >> bitstart;
1406                                   reg &= (2 << (bitend - bitstart)) - 1;
1407
1408                                   if (reg > 7)
1409                                     func (stream, "#%s",
1410                                           arm_fp_const[reg & 7]);
1411                                   else
1412                                     func (stream, "f%ld", reg);
1413                                 }
1414                                 break;
1415
1416                               case 'w':
1417                                 {
1418                                   long reg;
1419
1420                                   if (bitstart != bitend)
1421                                     {
1422                                       reg = given >> bitstart;
1423                                       reg &= (2 << (bitend - bitstart)) - 1;
1424                                       if (bitend - bitstart == 1)
1425                                         func (stream, "%s", iwmmxt_wwnames[reg]);
1426                                       else
1427                                         func (stream, "%s", iwmmxt_wwssnames[reg]);
1428                                     }
1429                                   else
1430                                     {
1431                                       reg = (((given >> 8)  & 0x1) |
1432                                              ((given >> 22) & 0x1));
1433                                       func (stream, "%s", iwmmxt_wwnames[reg]);
1434                                     }
1435                                 }
1436                                 break;
1437
1438                               case 'g':
1439                                 {
1440                                   long reg;
1441                                   reg = given >> bitstart;
1442                                   reg &= (2 << (bitend - bitstart)) - 1;
1443                                   func (stream, "%s", iwmmxt_regnames[reg]);
1444                                 }
1445                                 break;
1446
1447                               case 'G':
1448                                 {
1449                                   long reg;
1450                                   reg = given >> bitstart;
1451                                   reg &= (2 << (bitend - bitstart)) - 1;
1452                                   func (stream, "%s", iwmmxt_cregnames[reg]);
1453                                 }
1454                                 break;
1455
1456                               default:
1457                                 abort ();
1458                               }
1459                             break;
1460
1461                           case 'y':
1462                           case 'z':
1463                             {
1464                               int single = *c == 'y';
1465                               int regno;
1466
1467                               switch (bitstart)
1468                                 {
1469                                 case 4: /* Sm pair */
1470                                   func (stream, "{");
1471                                   /* Fall through.  */
1472                                 case 0: /* Sm, Dm */
1473                                   regno = given & 0x0000000f;
1474                                   if (single)
1475                                     {
1476                                       regno <<= 1;
1477                                       regno += (given >> 5) & 1;
1478                                     }
1479                                   break;
1480
1481                                 case 1: /* Sd, Dd */
1482                                   regno = (given >> 12) & 0x0000000f;
1483                                   if (single)
1484                                     {
1485                                       regno <<= 1;
1486                                       regno += (given >> 22) & 1;
1487                                     }
1488                                   break;
1489
1490                                 case 2: /* Sn, Dn */
1491                                   regno = (given >> 16) & 0x0000000f;
1492                                   if (single)
1493                                     {
1494                                       regno <<= 1;
1495                                       regno += (given >> 7) & 1;
1496                                     }
1497                                   break;
1498
1499                                 case 3: /* List */
1500                                   func (stream, "{");
1501                                   regno = (given >> 12) & 0x0000000f;
1502                                   if (single)
1503                                     {
1504                                       regno <<= 1;
1505                                       regno += (given >> 22) & 1;
1506                                     }
1507                                   break;
1508
1509
1510                                 default:
1511                                   abort ();
1512                                 }
1513
1514                               func (stream, "%c%d", single ? 's' : 'd', regno);
1515
1516                               if (bitstart == 3)
1517                                 {
1518                                   int count = given & 0xff;
1519
1520                                   if (single == 0)
1521                                     count >>= 1;
1522
1523                                   if (--count)
1524                                     {
1525                                       func (stream, "-%c%d",
1526                                             single ? 's' : 'd',
1527                                             regno + count);
1528                                     }
1529
1530                                   func (stream, "}");
1531                                 }
1532                               else if (bitstart == 4)
1533                                 func (stream, ", %c%d}", single ? 's' : 'd',
1534                                       regno + 1);
1535
1536                               break;
1537                             }
1538
1539                             break;
1540
1541                           case '`':
1542                             c++;
1543                             if ((given & (1 << bitstart)) == 0)
1544                               func (stream, "%c", *c);
1545                             break;
1546                           case '\'':
1547                             c++;
1548                             if ((given & (1 << bitstart)) != 0)
1549                               func (stream, "%c", *c);
1550                             break;
1551                           case '?':
1552                             ++c;
1553                             if ((given & (1 << bitstart)) != 0)
1554                               func (stream, "%c", *c++);
1555                             else
1556                               func (stream, "%c", *++c);
1557                             break;
1558                           default:
1559                             abort ();
1560                           }
1561                         break;
1562
1563                       case 'L':
1564                         switch (given & 0x00400100)
1565                           {
1566                           case 0x00000000: func (stream, "b"); break;
1567                           case 0x00400000: func (stream, "h"); break;
1568                           case 0x00000100: func (stream, "w"); break;
1569                           case 0x00400100: func (stream, "d"); break;
1570                           default:
1571                             break;
1572                           }
1573                         break;
1574
1575                       case 'Z':
1576                         {
1577                           int value;
1578                           /* given (20, 23) | given (0, 3) */
1579                           value = ((given >> 16) & 0xf0) | (given & 0xf);
1580                           func (stream, "%d", value);
1581                         }
1582                         break;
1583
1584                       case 'l':
1585                         /* This is like the 'A' operator, except that if
1586                            the width field "M" is zero, then the offset is
1587                            *not* multiplied by four.  */
1588                         {
1589                           int offset = given & 0xff;
1590                           int multiplier = (given & 0x00000100) ? 4 : 1;
1591
1592                           func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1593
1594                           if (offset)
1595                             {
1596                               if ((given & 0x01000000) != 0)
1597                                 func (stream, ", #%s%d]%s",
1598                                       ((given & 0x00800000) == 0 ? "-" : ""),
1599                                       offset * multiplier,
1600                                       ((given & 0x00200000) != 0 ? "!" : ""));
1601                               else
1602                                 func (stream, "], #%s%d",
1603                                       ((given & 0x00800000) == 0 ? "-" : ""),
1604                                       offset * multiplier);
1605                             }
1606                           else
1607                             func (stream, "]");
1608                         }
1609                         break;
1610
1611                       default:
1612                         abort ();
1613                       }
1614                     }
1615                 }
1616               else
1617                 func (stream, "%c", *c);
1618             }
1619           return TRUE;
1620         }
1621     }
1622   return FALSE;
1623 }
1624
1625 static void
1626 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
1627 {
1628   void *stream = info->stream;
1629   fprintf_ftype func = info->fprintf_func;
1630
1631   if (((given & 0x000f0000) == 0x000f0000)
1632       && ((given & 0x02000000) == 0))
1633     {
1634       int offset = given & 0xfff;
1635
1636       func (stream, "[pc");
1637
1638       if (given & 0x01000000)
1639         {
1640           if ((given & 0x00800000) == 0)
1641             offset = - offset;
1642
1643           /* Pre-indexed.  */
1644           func (stream, ", #%d]", offset);
1645
1646           offset += pc + 8;
1647
1648           /* Cope with the possibility of write-back
1649              being used.  Probably a very dangerous thing
1650              for the programmer to do, but who are we to
1651              argue ?  */
1652           if (given & 0x00200000)
1653             func (stream, "!");
1654         }
1655       else
1656         {
1657           /* Post indexed.  */
1658           func (stream, "], #%d", offset);
1659
1660           /* ie ignore the offset.  */
1661           offset = pc + 8;
1662         }
1663
1664       func (stream, "\t; ");
1665       info->print_address_func (offset, info);
1666     }
1667   else
1668     {
1669       func (stream, "[%s",
1670             arm_regnames[(given >> 16) & 0xf]);
1671       if ((given & 0x01000000) != 0)
1672         {
1673           if ((given & 0x02000000) == 0)
1674             {
1675               int offset = given & 0xfff;
1676               if (offset)
1677                 func (stream, ", #%s%d",
1678                       (((given & 0x00800000) == 0)
1679                        ? "-" : ""), offset);
1680             }
1681           else
1682             {
1683               func (stream, ", %s",
1684                     (((given & 0x00800000) == 0)
1685                      ? "-" : ""));
1686               arm_decode_shift (given, func, stream);
1687             }
1688
1689           func (stream, "]%s",
1690                 ((given & 0x00200000) != 0) ? "!" : "");
1691         }
1692       else
1693         {
1694           if ((given & 0x02000000) == 0)
1695             {
1696               int offset = given & 0xfff;
1697               if (offset)
1698                 func (stream, "], #%s%d",
1699                       (((given & 0x00800000) == 0)
1700                        ? "-" : ""), offset);
1701               else
1702                 func (stream, "]");
1703             }
1704           else
1705             {
1706               func (stream, "], %s",
1707                     (((given & 0x00800000) == 0)
1708                      ? "-" : ""));
1709               arm_decode_shift (given, func, stream);
1710             }
1711         }
1712     }
1713 }
1714
1715 /* Print one ARM instruction from PC on INFO->STREAM.  */
1716
1717 static void
1718 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
1719 {
1720   const struct opcode32 *insn;
1721   void *stream = info->stream;
1722   fprintf_ftype func = info->fprintf_func;
1723
1724   if (print_insn_coprocessor (info, given, FALSE))
1725     return;
1726
1727   for (insn = arm_opcodes; insn->assembler; insn++)
1728     {
1729       if (insn->value == FIRST_IWMMXT_INSN
1730           && info->mach != bfd_mach_arm_XScale
1731           && info->mach != bfd_mach_arm_iWMMXt)
1732         insn = insn + IWMMXT_INSN_COUNT;
1733
1734       if ((given & insn->mask) == insn->value
1735           /* Special case: an instruction with all bits set in the condition field
1736              (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
1737              or by the catchall at the end of the table.  */
1738           && ((given & 0xF0000000) != 0xF0000000
1739               || (insn->mask & 0xF0000000) == 0xF0000000
1740               || (insn->mask == 0 && insn->value == 0)))
1741         {
1742           const char *c;
1743
1744           for (c = insn->assembler; *c; c++)
1745             {
1746               if (*c == '%')
1747                 {
1748                   switch (*++c)
1749                     {
1750                     case '%':
1751                       func (stream, "%%");
1752                       break;
1753
1754                     case 'a':
1755                       print_arm_address (pc, info, given);
1756                       break;
1757
1758                     case 'P':
1759                       /* Set P address bit and use normal address
1760                          printing routine.  */
1761                       print_arm_address (pc, info, given | (1 << 24));
1762                       break;
1763
1764                     case 's':
1765                       if ((given & 0x004f0000) == 0x004f0000)
1766                         {
1767                           /* PC relative with immediate offset.  */
1768                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1769
1770                           if ((given & 0x00800000) == 0)
1771                             offset = -offset;
1772
1773                           func (stream, "[pc, #%d]\t; ", offset);
1774                           info->print_address_func (offset + pc + 8, info);
1775                         }
1776                       else
1777                         {
1778                           func (stream, "[%s",
1779                                 arm_regnames[(given >> 16) & 0xf]);
1780                           if ((given & 0x01000000) != 0)
1781                             {
1782                               /* Pre-indexed.  */
1783                               if ((given & 0x00400000) == 0x00400000)
1784                                 {
1785                                   /* Immediate.  */
1786                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1787                                   if (offset)
1788                                     func (stream, ", #%s%d",
1789                                           (((given & 0x00800000) == 0)
1790                                            ? "-" : ""), offset);
1791                                 }
1792                               else
1793                                 {
1794                                   /* Register.  */
1795                                   func (stream, ", %s%s",
1796                                         (((given & 0x00800000) == 0)
1797                                          ? "-" : ""),
1798                                         arm_regnames[given & 0xf]);
1799                                 }
1800
1801                               func (stream, "]%s",
1802                                     ((given & 0x00200000) != 0) ? "!" : "");
1803                             }
1804                           else
1805                             {
1806                               /* Post-indexed.  */
1807                               if ((given & 0x00400000) == 0x00400000)
1808                                 {
1809                                   /* Immediate.  */
1810                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1811                                   if (offset)
1812                                     func (stream, "], #%s%d",
1813                                           (((given & 0x00800000) == 0)
1814                                            ? "-" : ""), offset);
1815                                   else
1816                                     func (stream, "]");
1817                                 }
1818                               else
1819                                 {
1820                                   /* Register.  */
1821                                   func (stream, "], %s%s",
1822                                         (((given & 0x00800000) == 0)
1823                                          ? "-" : ""),
1824                                         arm_regnames[given & 0xf]);
1825                                 }
1826                             }
1827                         }
1828                       break;
1829
1830                     case 'b':
1831                       {
1832                         int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
1833                         info->print_address_func (disp*4 + pc + 8, info);
1834                       }
1835                       break;
1836
1837                     case 'c':
1838                       func (stream, "%s",
1839                             arm_conditional [(given >> 28) & 0xf]);
1840                       break;
1841
1842                     case 'm':
1843                       {
1844                         int started = 0;
1845                         int reg;
1846
1847                         func (stream, "{");
1848                         for (reg = 0; reg < 16; reg++)
1849                           if ((given & (1 << reg)) != 0)
1850                             {
1851                               if (started)
1852                                 func (stream, ", ");
1853                               started = 1;
1854                               func (stream, "%s", arm_regnames[reg]);
1855                             }
1856                         func (stream, "}");
1857                       }
1858                       break;
1859
1860                     case 'o':
1861                       if ((given & 0x02000000) != 0)
1862                         {
1863                           int rotate = (given & 0xf00) >> 7;
1864                           int immed = (given & 0xff);
1865                           immed = (((immed << (32 - rotate))
1866                                     | (immed >> rotate)) & 0xffffffff);
1867                           func (stream, "#%d\t; 0x%x", immed, immed);
1868                         }
1869                       else
1870                         arm_decode_shift (given, func, stream);
1871                       break;
1872
1873                     case 'p':
1874                       if ((given & 0x0000f000) == 0x0000f000)
1875                         func (stream, "p");
1876                       break;
1877
1878                     case 't':
1879                       if ((given & 0x01200000) == 0x00200000)
1880                         func (stream, "t");
1881                       break;
1882
1883                     case 'A':
1884                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1885
1886                       if ((given & (1 << 24)) != 0)
1887                         {
1888                           int offset = given & 0xff;
1889
1890                           if (offset)
1891                             func (stream, ", #%s%d]%s",
1892                                   ((given & 0x00800000) == 0 ? "-" : ""),
1893                                   offset * 4,
1894                                   ((given & 0x00200000) != 0 ? "!" : ""));
1895                           else
1896                             func (stream, "]");
1897                         }
1898                       else
1899                         {
1900                           int offset = given & 0xff;
1901
1902                           func (stream, "]");
1903
1904                           if (given & (1 << 21))
1905                             {
1906                               if (offset)
1907                                 func (stream, ", #%s%d",
1908                                       ((given & 0x00800000) == 0 ? "-" : ""),
1909                                       offset * 4);
1910                             }
1911                           else
1912                             func (stream, ", {%d}", offset);
1913                         }
1914                       break;
1915
1916                     case 'B':
1917                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
1918                       {
1919                         bfd_vma address;
1920                         bfd_vma offset = 0;
1921
1922                         if (given & 0x00800000)
1923                           /* Is signed, hi bits should be ones.  */
1924                           offset = (-1) ^ 0x00ffffff;
1925
1926                         /* Offset is (SignExtend(offset field)<<2).  */
1927                         offset += given & 0x00ffffff;
1928                         offset <<= 2;
1929                         address = offset + pc + 8;
1930
1931                         if (given & 0x01000000)
1932                           /* H bit allows addressing to 2-byte boundaries.  */
1933                           address += 2;
1934
1935                         info->print_address_func (address, info);
1936                       }
1937                       break;
1938
1939                     case 'C':
1940                       func (stream, "_");
1941                       if (given & 0x80000)
1942                         func (stream, "f");
1943                       if (given & 0x40000)
1944                         func (stream, "s");
1945                       if (given & 0x20000)
1946                         func (stream, "x");
1947                       if (given & 0x10000)
1948                         func (stream, "c");
1949                       break;
1950
1951                     case 'U':
1952                       switch (given & 0xf)
1953                         {
1954                         case 0xf: func(stream, "sy"); break;
1955                         case 0x7: func(stream, "un"); break;
1956                         case 0xe: func(stream, "st"); break;
1957                         case 0x6: func(stream, "unst"); break;
1958                         default:
1959                           func(stream, "#%d", (int)given & 0xf);
1960                           break;
1961                         }
1962                       break;
1963
1964                     case '0': case '1': case '2': case '3': case '4':
1965                     case '5': case '6': case '7': case '8': case '9':
1966                       {
1967                         int bitstart = *c++ - '0';
1968                         int bitend = 0;
1969                         while (*c >= '0' && *c <= '9')
1970                           bitstart = (bitstart * 10) + *c++ - '0';
1971
1972                         switch (*c)
1973                           {
1974                           case '-':
1975                             c++;
1976
1977                             while (*c >= '0' && *c <= '9')
1978                               bitend = (bitend * 10) + *c++ - '0';
1979
1980                             if (!bitend)
1981                               abort ();
1982
1983                             switch (*c)
1984                               {
1985                               case 'r':
1986                                 {
1987                                   long reg;
1988
1989                                   reg = given >> bitstart;
1990                                   reg &= (2 << (bitend - bitstart)) - 1;
1991
1992                                   func (stream, "%s", arm_regnames[reg]);
1993                                 }
1994                                 break;
1995                               case 'd':
1996                                 {
1997                                   long reg;
1998
1999                                   reg = given >> bitstart;
2000                                   reg &= (2 << (bitend - bitstart)) - 1;
2001
2002                                   func (stream, "%ld", reg);
2003                                 }
2004                                 break;
2005                               case 'W':
2006                                 {
2007                                   long reg;
2008                                   
2009                                   reg = given >> bitstart;
2010                                   reg &= (2 << (bitend - bitstart)) - 1;
2011                                   
2012                                   func (stream, "%ld", reg + 1);
2013                                 }
2014                                 break;
2015                               case 'x':
2016                                 {
2017                                   long reg;
2018
2019                                   reg = given >> bitstart;
2020                                   reg &= (2 << (bitend - bitstart)) - 1;
2021
2022                                   func (stream, "0x%08lx", reg);
2023
2024                                   /* Some SWI instructions have special
2025                                      meanings.  */
2026                                   if ((given & 0x0fffffff) == 0x0FF00000)
2027                                     func (stream, "\t; IMB");
2028                                   else if ((given & 0x0fffffff) == 0x0FF00001)
2029                                     func (stream, "\t; IMBRange");
2030                                 }
2031                                 break;
2032                               case 'X':
2033                                 {
2034                                   long reg;
2035
2036                                   reg = given >> bitstart;
2037                                   reg &= (2 << (bitend - bitstart)) - 1;
2038
2039                                   func (stream, "%01lx", reg & 0xf);
2040                                 }
2041                                 break;
2042                               default:
2043                                 abort ();
2044                               }
2045                             break;
2046
2047                           case '`':
2048                             c++;
2049                             if ((given & (1 << bitstart)) == 0)
2050                               func (stream, "%c", *c);
2051                             break;
2052                           case '\'':
2053                             c++;
2054                             if ((given & (1 << bitstart)) != 0)
2055                               func (stream, "%c", *c);
2056                             break;
2057                           case '?':
2058                             ++c;
2059                             if ((given & (1 << bitstart)) != 0)
2060                               func (stream, "%c", *c++);
2061                             else
2062                               func (stream, "%c", *++c);
2063                             break;
2064                           default:
2065                             abort ();
2066                           }
2067                         break;
2068
2069                       case 'e':
2070                         {
2071                           int imm;
2072
2073                           imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2074                           func (stream, "%d", imm);
2075                         }
2076                         break;
2077
2078                       case 'E':
2079                         /* LSB and WIDTH fields of BFI or BFC.  The machine-
2080                            language instruction encodes LSB and MSB.  */
2081                         {
2082                           long msb = (given & 0x001f0000) >> 16;
2083                           long lsb = (given & 0x00000f80) >> 7;
2084
2085                           long width = msb - lsb + 1;
2086                           if (width > 0)
2087                             func (stream, "#%lu, #%lu", lsb, width);
2088                           else
2089                             func (stream, "(invalid: %lu:%lu)", lsb, msb);
2090                         }
2091                         break;
2092
2093                       case 'V':
2094                         /* 16-bit unsigned immediate from a MOVT or MOVW
2095                            instruction, encoded in bits 0:11 and 15:19.  */
2096                         {
2097                           long hi = (given & 0x000f0000) >> 4;
2098                           long lo = (given & 0x00000fff);
2099                           long imm16 = hi | lo;
2100                           func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2101                         }
2102                         break;
2103
2104                       default:
2105                         abort ();
2106                       }
2107                     }
2108                 }
2109               else
2110                 func (stream, "%c", *c);
2111             }
2112           return;
2113         }
2114     }
2115   abort ();
2116 }
2117
2118 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
2119
2120 static void
2121 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2122 {
2123   const struct opcode16 *insn;
2124   void *stream = info->stream;
2125   fprintf_ftype func = info->fprintf_func;
2126
2127   for (insn = thumb_opcodes; insn->assembler; insn++)
2128     if ((given & insn->mask) == insn->value)
2129       {
2130         const char *c = insn->assembler;
2131         for (; *c; c++)
2132           {
2133             int domaskpc = 0;
2134             int domasklr = 0;
2135
2136             if (*c != '%')
2137               {
2138                 func (stream, "%c", *c);
2139                 continue;
2140               }
2141
2142             switch (*++c)
2143               {
2144               case '%':
2145                 func (stream, "%%");
2146                 break;
2147
2148               case 'S':
2149                 {
2150                   long reg;
2151
2152                   reg = (given >> 3) & 0x7;
2153                   if (given & (1 << 6))
2154                     reg += 8;
2155
2156                   func (stream, "%s", arm_regnames[reg]);
2157                 }
2158                 break;
2159
2160               case 'D':
2161                 {
2162                   long reg;
2163
2164                   reg = given & 0x7;
2165                   if (given & (1 << 7))
2166                     reg += 8;
2167
2168                   func (stream, "%s", arm_regnames[reg]);
2169                 }
2170                 break;
2171
2172               case 'N':
2173                 if (given & (1 << 8))
2174                   domasklr = 1;
2175                 /* Fall through.  */
2176               case 'O':
2177                 if (*c == 'O' && (given & (1 << 8)))
2178                   domaskpc = 1;
2179                 /* Fall through.  */
2180               case 'M':
2181                 {
2182                   int started = 0;
2183                   int reg;
2184
2185                   func (stream, "{");
2186
2187                   /* It would be nice if we could spot
2188                      ranges, and generate the rS-rE format: */
2189                   for (reg = 0; (reg < 8); reg++)
2190                     if ((given & (1 << reg)) != 0)
2191                       {
2192                         if (started)
2193                           func (stream, ", ");
2194                         started = 1;
2195                         func (stream, "%s", arm_regnames[reg]);
2196                       }
2197
2198                   if (domasklr)
2199                     {
2200                       if (started)
2201                         func (stream, ", ");
2202                       started = 1;
2203                       func (stream, arm_regnames[14] /* "lr" */);
2204                     }
2205
2206                   if (domaskpc)
2207                     {
2208                       if (started)
2209                         func (stream, ", ");
2210                       func (stream, arm_regnames[15] /* "pc" */);
2211                     }
2212
2213                   func (stream, "}");
2214                 }
2215                 break;
2216
2217               case 'b':
2218                 /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
2219                 {
2220                   bfd_vma address = (pc + 4
2221                                      + ((given & 0x00f8) >> 2)
2222                                      + ((given & 0x0200) >> 3));
2223                   info->print_address_func (address, info);
2224                 }
2225                 break;
2226
2227               case 's':
2228                 /* Right shift immediate -- bits 6..10; 1-31 print
2229                    as themselves, 0 prints as 32.  */
2230                 {
2231                   long imm = (given & 0x07c0) >> 6;
2232                   if (imm == 0)
2233                     imm = 32;
2234                   func (stream, "#%ld", imm);
2235                 }
2236                 break;
2237
2238               case '0': case '1': case '2': case '3': case '4':
2239               case '5': case '6': case '7': case '8': case '9':
2240                 {
2241                   int bitstart = *c++ - '0';
2242                   int bitend = 0;
2243
2244                   while (*c >= '0' && *c <= '9')
2245                     bitstart = (bitstart * 10) + *c++ - '0';
2246
2247                   switch (*c)
2248                     {
2249                     case '-':
2250                       {
2251                         long reg;
2252
2253                         c++;
2254                         while (*c >= '0' && *c <= '9')
2255                           bitend = (bitend * 10) + *c++ - '0';
2256                         if (!bitend)
2257                           abort ();
2258                         reg = given >> bitstart;
2259                         reg &= (2 << (bitend - bitstart)) - 1;
2260                         switch (*c)
2261                           {
2262                           case 'r':
2263                             func (stream, "%s", arm_regnames[reg]);
2264                             break;
2265
2266                           case 'd':
2267                             func (stream, "%ld", reg);
2268                             break;
2269
2270                           case 'H':
2271                             func (stream, "%ld", reg << 1);
2272                             break;
2273
2274                           case 'W':
2275                             func (stream, "%ld", reg << 2);
2276                             break;
2277
2278                           case 'a':
2279                             /* PC-relative address -- the bottom two
2280                                bits of the address are dropped
2281                                before the calculation.  */
2282                             info->print_address_func
2283                               (((pc + 4) & ~3) + (reg << 2), info);
2284                             break;
2285
2286                           case 'x':
2287                             func (stream, "0x%04lx", reg);
2288                             break;
2289
2290                           case 'B':
2291                             reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2292                             info->print_address_func (reg * 2 + pc + 4, info);
2293                             break;
2294
2295                           case 'c':
2296                             {
2297                               /* Must print 0xE as 'al' to distinguish
2298                                  unconditional B from conditional BAL.  */
2299                               if (reg == 0xE)
2300                                 func (stream, "al");
2301                               else
2302                                 func (stream, "%s", arm_conditional [reg]);
2303                             }
2304                             break;
2305
2306                           default:
2307                             abort ();
2308                           }
2309                       }
2310                       break;
2311
2312                     case '\'':
2313                       c++;
2314                       if ((given & (1 << bitstart)) != 0)
2315                         func (stream, "%c", *c);
2316                       break;
2317
2318                     case '?':
2319                       ++c;
2320                       if ((given & (1 << bitstart)) != 0)
2321                         func (stream, "%c", *c++);
2322                       else
2323                         func (stream, "%c", *++c);
2324                       break;
2325
2326                     default:
2327                       abort ();
2328                     }
2329                 }
2330                 break;
2331
2332               default:
2333                 abort ();
2334               }
2335           }
2336         return;
2337       }
2338
2339   /* No match.  */
2340   abort ();
2341 }
2342
2343 /* Return the name of an V7M special register.  */
2344 static const char *
2345 psr_name (int regno)
2346 {
2347   switch (regno)
2348     {
2349     case 0: return "APSR";
2350     case 1: return "IAPSR";
2351     case 2: return "EAPSR";
2352     case 3: return "PSR";
2353     case 5: return "IPSR";
2354     case 6: return "EPSR";
2355     case 7: return "IEPSR";
2356     case 8: return "MSP";
2357     case 9: return "PSP";
2358     case 16: return "PRIMASK";
2359     case 17: return "BASEPRI";
2360     case 18: return "BASEPRI_MASK";
2361     case 19: return "FAULTMASK";
2362     case 20: return "CONTROL";
2363     default: return "<unknown>";
2364     }
2365 }
2366
2367 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
2368
2369 static void
2370 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
2371 {
2372   const struct opcode32 *insn;
2373   void *stream = info->stream;
2374   fprintf_ftype func = info->fprintf_func;
2375
2376   if (print_insn_coprocessor (info, given, TRUE))
2377     return;
2378
2379   for (insn = thumb32_opcodes; insn->assembler; insn++)
2380     if ((given & insn->mask) == insn->value)
2381       {
2382         const char *c = insn->assembler;
2383         for (; *c; c++)
2384           {
2385             if (*c != '%')
2386               {
2387                 func (stream, "%c", *c);
2388                 continue;
2389               }
2390
2391             switch (*++c)
2392               {
2393               case '%':
2394                 func (stream, "%%");
2395                 break;
2396
2397               case 'I':
2398                 {
2399                   unsigned int imm12 = 0;
2400                   imm12 |= (given & 0x000000ffu);
2401                   imm12 |= (given & 0x00007000u) >> 4;
2402                   imm12 |= (given & 0x04000000u) >> 15;
2403                   func (stream, "#%u\t; 0x%x", imm12, imm12);
2404                 }
2405                 break;
2406
2407               case 'M':
2408                 {
2409                   unsigned int bits = 0, imm, imm8, mod;
2410                   bits |= (given & 0x000000ffu);
2411                   bits |= (given & 0x00007000u) >> 4;
2412                   bits |= (given & 0x04000000u) >> 15;
2413                   imm8 = (bits & 0x0ff);
2414                   mod = (bits & 0xf00) >> 8;
2415                   switch (mod)
2416                     {
2417                     case 0: imm = imm8; break;
2418                     case 1: imm = ((imm8<<16) | imm8); break;
2419                     case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
2420                     case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
2421                     default:
2422                       mod  = (bits & 0xf80) >> 7;
2423                       imm8 = (bits & 0x07f) | 0x80;
2424                       imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
2425                     }
2426                   func (stream, "#%u\t; 0x%x", imm, imm);
2427                 }
2428                 break;
2429                   
2430               case 'J':
2431                 {
2432                   unsigned int imm = 0;
2433                   imm |= (given & 0x000000ffu);
2434                   imm |= (given & 0x00007000u) >> 4;
2435                   imm |= (given & 0x04000000u) >> 15;
2436                   imm |= (given & 0x000f0000u) >> 4;
2437                   func (stream, "#%u\t; 0x%x", imm, imm);
2438                 }
2439                 break;
2440
2441               case 'K':
2442                 {
2443                   unsigned int imm = 0;
2444                   imm |= (given & 0x000f0000u) >> 16;
2445                   imm |= (given & 0x00000ff0u) >> 0;
2446                   imm |= (given & 0x0000000fu) << 12;
2447                   func (stream, "#%u\t; 0x%x", imm, imm);
2448                 }
2449                 break;
2450
2451               case 'S':
2452                 {
2453                   unsigned int reg = (given & 0x0000000fu);
2454                   unsigned int stp = (given & 0x00000030u) >> 4;
2455                   unsigned int imm = 0;
2456                   imm |= (given & 0x000000c0u) >> 6;
2457                   imm |= (given & 0x00007000u) >> 10;
2458
2459                   func (stream, "%s", arm_regnames[reg]);
2460                   switch (stp)
2461                     {
2462                     case 0:
2463                       if (imm > 0)
2464                         func (stream, ", lsl #%u", imm);
2465                       break;
2466
2467                     case 1:
2468                       if (imm == 0)
2469                         imm = 32;
2470                       func (stream, ", lsr #%u", imm);
2471                       break;
2472
2473                     case 2:
2474                       if (imm == 0)
2475                         imm = 32;
2476                       func (stream, ", asr #%u", imm);
2477                       break;
2478
2479                     case 3:
2480                       if (imm == 0)
2481                         func (stream, ", rrx");
2482                       else
2483                         func (stream, ", ror #%u", imm);
2484                     }
2485                 }
2486                 break;
2487
2488               case 'a':
2489                 {
2490                   unsigned int Rn  = (given & 0x000f0000) >> 16;
2491                   unsigned int U   = (given & 0x00800000) >> 23;
2492                   unsigned int op  = (given & 0x00000f00) >> 8;
2493                   unsigned int i12 = (given & 0x00000fff);
2494                   unsigned int i8  = (given & 0x000000ff);
2495                   bfd_boolean writeback = FALSE, postind = FALSE;
2496                   int offset = 0;
2497
2498                   func (stream, "[%s", arm_regnames[Rn]);
2499                   if (U) /* 12-bit positive immediate offset */
2500                     offset = i12;
2501                   else if (Rn == 15) /* 12-bit negative immediate offset */
2502                     offset = -(int)i12;
2503                   else if (op == 0x0) /* shifted register offset */
2504                     {
2505                       unsigned int Rm = (i8 & 0x0f);
2506                       unsigned int sh = (i8 & 0x30) >> 4;
2507                       func (stream, ", %s", arm_regnames[Rm]);
2508                       if (sh)
2509                         func (stream, ", lsl #%u", sh);
2510                       func (stream, "]");
2511                       break;
2512                     }
2513                   else switch (op)
2514                     {
2515                     case 0xE:  /* 8-bit positive immediate offset */
2516                       offset = i8;
2517                       break;
2518
2519                     case 0xC:  /* 8-bit negative immediate offset */
2520                       offset = -i8;
2521                       break;
2522
2523                     case 0xF:  /* 8-bit + preindex with wb */
2524                       offset = i8;
2525                       writeback = TRUE;
2526                       break;
2527
2528                     case 0xD:  /* 8-bit - preindex with wb */
2529                       offset = -i8;
2530                       writeback = TRUE;
2531                       break;
2532
2533                     case 0xB:  /* 8-bit + postindex */
2534                       offset = i8;
2535                       postind = TRUE;
2536                       break;
2537
2538                     case 0x9:  /* 8-bit - postindex */
2539                       offset = -i8;
2540                       postind = TRUE;
2541                       break;
2542
2543                     default:
2544                       func (stream, ", <undefined>]");
2545                       goto skip;
2546                     }
2547
2548                   if (postind)
2549                     func (stream, "], #%d", offset);
2550                   else
2551                     {
2552                       if (offset)
2553                         func (stream, ", #%d", offset);
2554                       func (stream, writeback ? "]!" : "]");
2555                     }
2556
2557                   if (Rn == 15)
2558                     {
2559                       func (stream, "\t; ");
2560                       info->print_address_func (((pc + 4) & ~3) + offset, info);
2561                     }
2562                 }
2563               skip:
2564                 break;
2565
2566               case 'A':
2567                 {
2568                   unsigned int P   = (given & 0x01000000) >> 24;
2569                   unsigned int U   = (given & 0x00800000) >> 23;
2570                   unsigned int W   = (given & 0x00400000) >> 21;
2571                   unsigned int Rn  = (given & 0x000f0000) >> 16;
2572                   unsigned int off = (given & 0x000000ff);
2573
2574                   func (stream, "[%s", arm_regnames[Rn]);
2575                   if (P)
2576                     {
2577                       if (off || !U)
2578                         func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2579                       func (stream, "]");
2580                       if (W)
2581                         func (stream, "!");
2582                     }
2583                   else
2584                     {
2585                       func (stream, "], ");
2586                       if (W)
2587                         func (stream, "#%c%u", U ? '+' : '-', off * 4);
2588                       else
2589                         func (stream, "{%u}", off);
2590                     }
2591                 }
2592                 break;
2593
2594               case 'w':
2595                 {
2596                   unsigned int Sbit = (given & 0x01000000) >> 24;
2597                   unsigned int type = (given & 0x00600000) >> 21;
2598                   switch (type)
2599                     {
2600                     case 0: func (stream, Sbit ? "sb" : "b"); break;
2601                     case 1: func (stream, Sbit ? "sh" : "h"); break;
2602                     case 2:
2603                       if (Sbit)
2604                         func (stream, "??");
2605                       break;
2606                     case 3:
2607                       func (stream, "??");
2608                       break;
2609                     }
2610                 }
2611                 break;
2612
2613               case 'm':
2614                 {
2615                   int started = 0;
2616                   int reg;
2617
2618                   func (stream, "{");
2619                   for (reg = 0; reg < 16; reg++)
2620                     if ((given & (1 << reg)) != 0)
2621                       {
2622                         if (started)
2623                           func (stream, ", ");
2624                         started = 1;
2625                         func (stream, "%s", arm_regnames[reg]);
2626                       }
2627                   func (stream, "}");
2628                 }
2629                 break;
2630
2631               case 'E':
2632                 {
2633                   unsigned int msb = (given & 0x0000001f);
2634                   unsigned int lsb = 0;
2635                   lsb |= (given & 0x000000c0u) >> 6;
2636                   lsb |= (given & 0x00007000u) >> 10;
2637                   func (stream, "#%u, #%u", lsb, msb - lsb + 1);
2638                 }
2639                 break;
2640
2641               case 'F':
2642                 {
2643                   unsigned int width = (given & 0x0000001f) + 1;
2644                   unsigned int lsb = 0;
2645                   lsb |= (given & 0x000000c0u) >> 6;
2646                   lsb |= (given & 0x00007000u) >> 10;
2647                   func (stream, "#%u, #%u", lsb, width);
2648                 }
2649                 break;
2650
2651               case 'b':
2652                 {
2653                   unsigned int S = (given & 0x04000000u) >> 26;
2654                   unsigned int J1 = (given & 0x00002000u) >> 13;
2655                   unsigned int J2 = (given & 0x00000800u) >> 11;
2656                   int offset = 0;
2657
2658                   offset |= !S << 20;
2659                   offset |= J2 << 19;
2660                   offset |= J1 << 18;
2661                   offset |= (given & 0x003f0000) >> 4;
2662                   offset |= (given & 0x000007ff) << 1;
2663                   offset -= (1 << 20);
2664
2665                   info->print_address_func (pc + 4 + offset, info);
2666                 }
2667                 break;
2668
2669               case 'B':
2670                 {
2671                   unsigned int S = (given & 0x04000000u) >> 26;
2672                   unsigned int I1 = (given & 0x00002000u) >> 13;
2673                   unsigned int I2 = (given & 0x00000800u) >> 11;
2674                   int offset = 0;
2675
2676                   offset |= !S << 24;
2677                   offset |= !(I1 ^ S) << 23;
2678                   offset |= !(I2 ^ S) << 22;
2679                   offset |= (given & 0x03ff0000u) >> 4;
2680                   offset |= (given & 0x000007ffu) << 1;
2681                   offset -= (1 << 24);
2682                   offset += pc + 4;
2683
2684                   /* BLX target addresses are always word aligned.  */
2685                   if ((given & 0x00001000u) == 0)
2686                       offset &= ~2u;
2687
2688                   info->print_address_func (offset, info);
2689                 }
2690                 break;
2691
2692               case 's':
2693                 {
2694                   unsigned int shift = 0;
2695                   shift |= (given & 0x000000c0u) >> 6;
2696                   shift |= (given & 0x00007000u) >> 10;
2697                   if (given & 0x00200000u)
2698                     func (stream, ", asr #%u", shift);
2699                   else if (shift)
2700                     func (stream, ", lsl #%u", shift);
2701                   /* else print nothing - lsl #0 */
2702                 }
2703                 break;
2704
2705               case 'R':
2706                 {
2707                   unsigned int rot = (given & 0x00000030) >> 4;
2708                   if (rot)
2709                     func (stream, ", ror #%u", rot * 8);
2710                 }
2711                 break;
2712
2713               case 'U':
2714                 switch (given & 0xf)
2715                   {
2716                   case 0xf: func(stream, "sy"); break;
2717                   case 0x7: func(stream, "un"); break;
2718                   case 0xe: func(stream, "st"); break;
2719                   case 0x6: func(stream, "unst"); break;
2720                   default:
2721                     func(stream, "#%d", (int)given & 0xf);
2722                     break;
2723                   }
2724                 break;
2725
2726               case 'C':
2727                 if ((given & 0xff) == 0)
2728                   {
2729                     func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
2730                     if (given & 0x800)
2731                       func (stream, "f");
2732                     if (given & 0x400)
2733                       func (stream, "s");
2734                     if (given & 0x200)
2735                       func (stream, "x");
2736                     if (given & 0x100)
2737                       func (stream, "c");
2738                   }
2739                 else
2740                   {
2741                     func (stream, psr_name (given & 0xff));
2742                   }
2743                 break;
2744
2745               case 'D':
2746                 if ((given & 0xff) == 0)
2747                   func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
2748                 else
2749                   func (stream, psr_name (given & 0xff));
2750                 break;
2751
2752               case '0': case '1': case '2': case '3': case '4':
2753               case '5': case '6': case '7': case '8': case '9':
2754                 {
2755                   int bitstart = *c++ - '0';
2756                   int bitend = 0;
2757                   unsigned int val;
2758                   while (*c >= '0' && *c <= '9')
2759                     bitstart = (bitstart * 10) + *c++ - '0';
2760
2761                   if (*c == '-')
2762                     {
2763                       c++;
2764                       while (*c >= '0' && *c <= '9')
2765                         bitend = (bitend * 10) + *c++ - '0';
2766                       if (!bitend)
2767                         abort ();
2768
2769                       val = given >> bitstart;
2770                       val &= (2 << (bitend - bitstart)) - 1;
2771                     }
2772                   else
2773                     val = (given >> bitstart) & 1;
2774
2775                   switch (*c)
2776                     {
2777                     case 'd': func (stream, "%u", val); break;
2778                     case 'W': func (stream, "%u", val * 4); break;
2779                     case 'r': func (stream, "%s", arm_regnames[val]); break;
2780
2781                     case 'c':
2782                       if (val == 0xE)
2783                         func (stream, "al");
2784                       else
2785                         func (stream, "%s", arm_conditional[val]);
2786                       break;
2787
2788                     case '\'':
2789                       if (val)
2790                         func (stream, "%c", c[1]);
2791                       c++;
2792                       break;
2793                       
2794                     case '`':
2795                       if (!val)
2796                         func (stream, "%c", c[1]);
2797                       c++;
2798                       break;
2799
2800                     case '?':
2801                       func (stream, "%c", val ? c[1] : c[2]);
2802                       c += 2;
2803                       break;
2804
2805                     default:
2806                       abort ();
2807                     }
2808                 }
2809                 break;
2810
2811               default:
2812                 abort ();
2813               }
2814           }
2815         return;
2816       }
2817
2818   /* No match.  */
2819   abort ();
2820 }
2821
2822 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2823    being displayed in symbol relative addresses.  */
2824
2825 bfd_boolean
2826 arm_symbol_is_valid (asymbol * sym,
2827                      struct disassemble_info * info ATTRIBUTE_UNUSED)
2828 {
2829   const char * name;
2830   
2831   if (sym == NULL)
2832     return FALSE;
2833
2834   name = bfd_asymbol_name (sym);
2835
2836   return (name && *name != '$');
2837 }
2838
2839 /* Parse an individual disassembler option.  */
2840
2841 void
2842 parse_arm_disassembler_option (char *option)
2843 {
2844   if (option == NULL)
2845     return;
2846
2847   if (strneq (option, "reg-names-", 10))
2848     {
2849       int i;
2850
2851       option += 10;
2852
2853       for (i = NUM_ARM_REGNAMES; i--;)
2854         if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2855           {
2856             regname_selected = i;
2857             break;
2858           }
2859
2860       if (i < 0)
2861         /* XXX - should break 'option' at following delimiter.  */
2862         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2863     }
2864   else if (strneq (option, "force-thumb", 11))
2865     force_thumb = 1;
2866   else if (strneq (option, "no-force-thumb", 14))
2867     force_thumb = 0;
2868   else
2869     /* XXX - should break 'option' at following delimiter.  */
2870     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2871
2872   return;
2873 }
2874
2875 /* Parse the string of disassembler options, spliting it at whitespaces
2876    or commas.  (Whitespace separators supported for backwards compatibility).  */
2877
2878 static void
2879 parse_disassembler_options (char *options)
2880 {
2881   if (options == NULL)
2882     return;
2883
2884   while (*options)
2885     {
2886       parse_arm_disassembler_option (options);
2887
2888       /* Skip forward to next seperator.  */
2889       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2890         ++ options;
2891       /* Skip forward past seperators.  */
2892       while (ISSPACE (*options) || (*options == ','))
2893         ++ options;      
2894     }
2895 }
2896
2897 /* NOTE: There are no checks in these routines that
2898    the relevant number of data bytes exist.  */
2899
2900 static int
2901 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
2902 {
2903   unsigned char b[4];
2904   long          given;
2905   int           status;
2906   int           is_thumb;
2907   int           size;
2908   void          (*printer) (bfd_vma, struct disassemble_info *, long);
2909
2910   if (info->disassembler_options)
2911     {
2912       parse_disassembler_options (info->disassembler_options);
2913
2914       /* To avoid repeated parsing of these options, we remove them here.  */
2915       info->disassembler_options = NULL;
2916     }
2917
2918   is_thumb = force_thumb;
2919
2920   if (!is_thumb && info->symbols != NULL)
2921     {
2922       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2923         {
2924           coff_symbol_type * cs;
2925
2926           cs = coffsymbol (*info->symbols);
2927           is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
2928                       || cs->native->u.syment.n_sclass == C_THUMBSTAT
2929                       || cs->native->u.syment.n_sclass == C_THUMBLABEL
2930                       || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2931                       || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2932         }
2933       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2934         {
2935           elf_symbol_type *  es;
2936           unsigned int       type;
2937
2938           es = *(elf_symbol_type **)(info->symbols);
2939           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2940
2941           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2942         }
2943     }
2944
2945   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2946   info->bytes_per_line = 4;
2947
2948   if (!is_thumb)
2949     {
2950       /* In ARM mode endianness is a straightforward issue: the instruction
2951          is four bytes long and is either ordered 0123 or 3210.  */
2952       printer = print_insn_arm;
2953       info->bytes_per_chunk = 4;
2954       size = 4;
2955
2956       status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2957       if (little)
2958         given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2959       else
2960         given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2961     }
2962   else
2963     {
2964       /* In Thumb mode we have the additional wrinkle of two
2965          instruction lengths.  Fortunately, the bits that determine
2966          the length of the current instruction are always to be found
2967          in the first two bytes.  */
2968       printer = print_insn_thumb16;
2969       info->bytes_per_chunk = 2;
2970       size = 2;
2971
2972       status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2973       if (little)
2974         given = (b[0]) | (b[1] << 8);
2975       else
2976         given = (b[1]) | (b[0] << 8);
2977
2978       if (!status)
2979         {
2980           /* These bit patterns signal a four-byte Thumb
2981              instruction.  */
2982           if ((given & 0xF800) == 0xF800
2983               || (given & 0xF800) == 0xF000
2984               || (given & 0xF800) == 0xE800)
2985             {
2986               status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2987               if (little)
2988                 given = (b[0]) | (b[1] << 8) | (given << 16);
2989               else
2990                 given = (b[1]) | (b[0] << 8) | (given << 16);
2991
2992               printer = print_insn_thumb32;
2993               size = 4;
2994             }
2995         }
2996     }
2997
2998   if (status)
2999     {
3000       info->memory_error_func (status, pc, info);
3001       return -1;
3002     }
3003   if (info->flags & INSN_HAS_RELOC)
3004     /* If the instruction has a reloc associated with it, then
3005        the offset field in the instruction will actually be the
3006        addend for the reloc.  (We are using REL type relocs).
3007        In such cases, we can ignore the pc when computing
3008        addresses, since the addend is not currently pc-relative.  */
3009     pc = 0;
3010
3011   printer (pc, info, given);
3012   return size;
3013 }
3014
3015 int
3016 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3017 {
3018   return print_insn (pc, info, FALSE);
3019 }
3020
3021 int
3022 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3023 {
3024   return print_insn (pc, info, TRUE);
3025 }
3026
3027 void
3028 print_arm_disassembler_options (FILE *stream)
3029 {
3030   int i;
3031
3032   fprintf (stream, _("\n\
3033 The following ARM specific disassembler options are supported for use with\n\
3034 the -M switch:\n"));
3035
3036   for (i = NUM_ARM_REGNAMES; i--;)
3037     fprintf (stream, "  reg-names-%s %*c%s\n",
3038              regnames[i].name,
3039              (int)(14 - strlen (regnames[i].name)), ' ',
3040              regnames[i].description);
3041
3042   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
3043   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
3044 }