* arm-dis.c (print_insn_neon): Disassemble 32-bit immediates as signed
[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 #include "floatformat.h"
30
31 /* FIXME: This shouldn't be done here.  */
32 #include "coff/internal.h"
33 #include "libcoff.h"
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
37
38 /* FIXME: Belongs in global header.  */
39 #ifndef strneq
40 #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
41 #endif
42
43 #ifndef NUM_ELEM
44 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
45 #endif
46
47 struct opcode32
48 {
49   unsigned long arch;           /* Architecture defining this insn.  */
50   unsigned long value, mask;    /* Recognise insn if (op&mask)==value.  */
51   const char *assembler;        /* How to disassemble this insn.  */
52 };
53
54 struct opcode16
55 {
56   unsigned long arch;           /* Architecture defining this insn.  */
57   unsigned short value, mask;   /* Recognise insn if (op&mask)==value.  */
58   const char *assembler;        /* How to disassemble this insn.  */
59 };
60
61 /* print_insn_coprocessor recognizes the following format control codes:
62
63    %%                   %
64
65    %c                   print condition code (always bits 28-31 in ARM mode)
66    %u                   print condition code (unconditional in ARM mode)
67    %A                   print address for ldc/stc/ldf/stf instruction
68    %B                   print vstm/vldm register list
69    %C                   print vstr/vldr address operand
70    %I                   print cirrus signed shift immediate: bits 0..3|4..6
71    %F                   print the COUNT field of a LFM/SFM instruction.
72    %P                   print floating point precision in arithmetic insn
73    %Q                   print floating point precision in ldf/stf insn
74    %R                   print floating point rounding mode
75
76    %<bitfield>r         print as an ARM register
77    %<bitfield>d         print the bitfield in decimal
78    %<bitfield>k         print immediate for VFPv3 conversion instruction
79    %<bitfield>x         print the bitfield in hex
80    %<bitfield>X         print the bitfield as 1 hex digit without leading "0x"
81    %<bitfield>f         print a floating point constant if >7 else a
82                         floating point register
83    %<bitfield>w         print as an iWMMXt width field - [bhwd]ss/us
84    %<bitfield>g         print as an iWMMXt 64-bit register
85    %<bitfield>G         print as an iWMMXt general purpose or control register
86    %<bitfield>D         print as a NEON D register
87    %<bitfield>Q         print as a NEON Q register
88
89    %y<code>             print a single precision VFP reg.
90                           Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
91    %z<code>             print a double precision VFP reg
92                           Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
93
94    %<bitfield>'c        print specified char iff bitfield is all ones
95    %<bitfield>`c        print specified char iff bitfield is all zeroes
96    %<bitfield>?ab...    select from array of values in big endian order
97    
98    %L                   print as an iWMMXt N/M width field.
99    %Z                   print the Immediate of a WSHUFH instruction.
100    %l                   like 'A' except use byte offsets for 'B' & 'H'
101                         versions.  */
102
103 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
104
105 static const struct opcode32 coprocessor_opcodes[] =
106 {
107   /* XScale instructions.  */
108   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
109   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
110   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
111   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
112   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
113     
114   /* Intel Wireless MMX technology instructions.  */
115 #define FIRST_IWMMXT_INSN 0x0e130130
116 #define IWMMXT_INSN_COUNT 47
117   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
118   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
119   {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
120   {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
121   {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
122   {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
123   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
124   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
125   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
126   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
127   {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
128   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
129   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
130   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
131   {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
132   {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
133   {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
134   {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
135   {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
136   {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
137   {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
138   {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
139   {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
140   {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
141   {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
142   {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
143   {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
144   {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
145   {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
146   {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
147   {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
148   {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
149   {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
150   {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
151   {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
152   {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
153   {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
154   {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
155   {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
156   {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
157   {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
158   {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
159   {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
160   {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
161   {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
162   {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
163   {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
164   {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
165   {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
166
167   /* Floating point coprocessor (FPA) instructions */
168   {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
169   {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
170   {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
171   {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
172   {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
173   {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
174   {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
175   {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
176   {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
177   {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
178   {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
179   {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
180   {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
181   {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
182   {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
183   {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
184   {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
185   {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
186   {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
187   {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
188   {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
189   {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
190   {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
191   {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
192   {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
193   {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
194   {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
195   {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
196   {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
197   {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
198   {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
199   {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
200   {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
201   {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
202   {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
203   {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
204   {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
205   {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
206   {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
207   {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
208   {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
209   {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
210   {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
211
212   /* Register load/store */
213   {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
214   {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
215   {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
216   {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
217   {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
218   {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
219
220   /* Data transfer between ARM and NEON registers */
221   {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
222   {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
223   {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
224   {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
225   {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
226   {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
227   {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
228   {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
229   {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
230   {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
231   {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
232   {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
233   {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
234   {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
235
236   /* Floating point coprocessor (VFP) instructions */
237   {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
238   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
239   {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
240   {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
241   {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
242   {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
243   {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
244   {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
245   {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
246   {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
247   {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
248   {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
249   {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
250   {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
251   {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
252   {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
253   {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
254   {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
255   {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
256   {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
257   {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
258   {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
259   {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
260   {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
261   {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
262   {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
263   {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
264   {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
265   {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
266   {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
267   {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
268   {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
269   {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
270   {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
271   {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
272   {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
273   {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
274   {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
275   {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
276   {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
277   {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
278   {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
279   {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
280   {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
281   {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%16-19,0-3d"},
282   {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%16-19,0-3d"},
283   {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %y4"},
284   {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
285   {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
286   {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
287   {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
288   {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
289   {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
290   {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
291   {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
292   {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
293   {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
294   {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
295   {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
296   {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
297   {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
298   {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
299   {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
300   {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
301   {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
302   {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
303   {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
304   {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
305   {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
306   {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
307   {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
308   {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
309   {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
310   {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
311   {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
312   {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
313   {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
314   {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
315   {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
316
317   /* Cirrus coprocessor instructions.  */
318   {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
319   {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
320   {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
321   {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"}, 
322   {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
323   {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
324   {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
325   {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
326   {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
327   {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
328   {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
329   {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
330   {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
331   {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
332   {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
333   {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
334   {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
335   {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
336   {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
337   {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
338   {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
339   {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
340   {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
341   {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
342   {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
343   {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
344   {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
345   {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
346   {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
347   {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
348   {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
349   {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
350   {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
351   {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
352   {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
353   {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
354   {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
355   {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
356   {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
357   {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
358   {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
359   {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
360   {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
361   {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
362   {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
363   {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
364   {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
365   {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
366   {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
367   {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
368   {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
369   {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
370   {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
371   {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
372   {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
373   {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
374   {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
375   {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
376   {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
377   {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
378   {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
379   {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
380   {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
381   {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
382   {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
383   {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
384   {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
385   {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
386   {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
387   {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
388   {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
389   {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
390   {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
391   {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
392   {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
393   {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
394   {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
395   {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
396   {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
397   {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
398   {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
399   {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
400   {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
401   {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
402
403   /* Generic coprocessor instructions */
404   {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
405   {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
406   {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
407   {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
408   {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
409   {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
410   {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
411
412   /* V6 coprocessor instructions */
413   {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
414   {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
415
416   /* V5 coprocessor instructions */
417   {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
418   {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
419   {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
420   {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
421   {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
422
423   {0, 0, 0, 0}
424 };
425
426 /* Neon opcode table:  This does not encode the top byte -- that is
427    checked by the print_insn_neon routine, as it depends on whether we are
428    doing thumb32 or arm32 disassembly.  */
429
430 /* print_insn_neon recognizes the following format control codes:
431
432    %%                   %
433
434    %c                   print condition code
435    %A                   print v{st,ld}[1234] operands
436    %B                   print v{st,ld}[1234] any one operands
437    %C                   print v{st,ld}[1234] single->all operands
438    %D                   print scalar
439    %E                   print vmov, vmvn, vorr, vbic encoded constant
440    %F                   print vtbl,vtbx register list
441
442    %<bitfield>r         print as an ARM register
443    %<bitfield>d         print the bitfield in decimal
444    %<bitfield>e         print the 2^N - bitfield in decimal
445    %<bitfield>D         print as a NEON D register
446    %<bitfield>Q         print as a NEON Q register
447    %<bitfield>R         print as a NEON D or Q register
448    %<bitfield>Sn        print byte scaled width limited by n
449    %<bitfield>Tn        print short scaled width limited by n
450    %<bitfield>Un        print long scaled width limited by n
451    
452    %<bitfield>'c        print specified char iff bitfield is all ones
453    %<bitfield>`c        print specified char iff bitfield is all zeroes
454    %<bitfield>?ab...    select from array of values in big endian order  */
455
456 static const struct opcode32 neon_opcodes[] =
457 {
458   /* Extract */
459   {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
460   {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
461
462   /* Move data element to all lanes */
463   {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
464   {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
465   {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
466
467   /* Table lookup */
468   {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
469   {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
470   
471   /* Two registers, miscellaneous */
472   {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
473   {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
474   {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
475   {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
476   {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
477   {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
478   {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19S2\t%12-15,22D, %0-3,5Q"},
479   {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
480   {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
481   {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
482   {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
483   {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
484   {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
485   {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
486   {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
487   {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
488   {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
489   {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
490   {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
491   {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
492   {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
493   {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
494   {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
495   {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
496   {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
497   {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
498   {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
499   {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
500   {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
501   {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
502   {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
503   {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
504   {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
505
506   /* Three registers of the same length */
507   {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
508   {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
509   {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
510   {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
511   {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
512   {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
513   {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
514   {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
515   {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
516   {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
517   {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
518   {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
519   {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
520   {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
521   {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
522   {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
523   {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
524   {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
525   {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
526   {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
527   {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
528   {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
529   {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
530   {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
531   {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
532   {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
533   {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
534   {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
535   {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
536   {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
537   {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
538   {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
539   {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
540   {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
541   {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
542   {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
543   {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
544   {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
545   {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
546   {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
547   {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
548   {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
549   {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
550   {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
551   {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
552   {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
553   {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
554   {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
555   {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
556   {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
557   {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
558   {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
559   {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
560
561   /* One register and an immediate value */
562   {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
563   {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
564   {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
565   {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
566   {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
567   {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
568   {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
569   {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
570   {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
571   {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
572   {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
573   {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
574   {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
575
576   /* Two registers and a shift amount */
577   {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
578   {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
579   {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
580   {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
581   {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
582   {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
583   {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
584   {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
585   {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
586   {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
587   {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
588   {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
589   {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
590   {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
591   {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
592   {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
593   {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
594   {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
595   {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
596   {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
597   {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
598   {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
599   {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
600   {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
601   {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
602   {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
603   {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
604   {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
605   {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
606   {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
607   {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
608   {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
609   {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
610   {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
611   {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
612   {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
613   {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
614   {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
615   {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
616   {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
617   {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
618   {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
619   {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
620   {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
621   {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
622   {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
623   {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
624   {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
625   {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
626   {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
627   {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
628   {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
629   {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
630   {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
631   {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
632   {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
633   {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
634   {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
635
636   /* Three registers of different lengths */
637   {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
638   {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
639   {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
640   {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
641   {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
642   {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
643   {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
644   {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
645   {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
646   {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
647   {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
648   {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
649   {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
650   {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
651   {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
652   {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
653   {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
654
655   /* Two registers and a scalar */
656   {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
657   {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
658   {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
659   {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
660   {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
661   {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
662   {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
663   {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
664   {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
665   {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
666   {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
667   {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
668   {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
669   {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
670   {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
671   {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
672   {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
673   {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
674   {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
675   {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
676   {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
677   {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
678
679   /* Element and structure load/store */
680   {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
681   {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
682   {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
683   {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
684   {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
685   {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
686   {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
687   {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
688   {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
689   {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
690   {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
691   {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
692   {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
693   {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
694   {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
695   {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
696   {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
697   {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
698   {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
699
700   {0,0 ,0, 0}
701 };
702
703 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb.  All three are partially
704    ordered: they must be searched linearly from the top to obtain a correct
705    match.  */
706
707 /* print_insn_arm recognizes the following format control codes:
708
709    %%                   %
710
711    %a                   print address for ldr/str instruction
712    %s                   print address for ldr/str halfword/signextend instruction
713    %b                   print branch destination
714    %c                   print condition code (always bits 28-31)
715    %m                   print register mask for ldm/stm instruction
716    %o                   print operand2 (immediate or register + shift)
717    %p                   print 'p' iff bits 12-15 are 15
718    %t                   print 't' iff bit 21 set and bit 24 clear
719    %B                   print arm BLX(1) destination
720    %C                   print the PSR sub type.
721    %U                   print barrier type.
722    %P                   print address for pli instruction.
723
724    %<bitfield>r         print as an ARM register
725    %<bitfield>d         print the bitfield in decimal
726    %<bitfield>W         print the bitfield plus one in decimal 
727    %<bitfield>x         print the bitfield in hex
728    %<bitfield>X         print the bitfield as 1 hex digit without leading "0x"
729    
730    %<bitfield>'c        print specified char iff bitfield is all ones
731    %<bitfield>`c        print specified char iff bitfield is all zeroes
732    %<bitfield>?ab...    select from array of values in big endian order
733
734    %e                   print arm SMI operand (bits 0..7,8..19).
735    %E                   print the LSB and WIDTH fields of a BFI or BFC instruction.
736    %V                   print the 16-bit immediate field of a MOVT or MOVW instruction.  */
737
738 static const struct opcode32 arm_opcodes[] =
739 {
740   /* ARM instructions.  */
741   {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
742   {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
743   {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
744   {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
745   {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
746   {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
747   {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
748
749   /* V7 instructions.  */
750   {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
751   {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
752   {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
753   {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
754   {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
755
756   /* ARM V6T2 instructions.  */
757   {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
758   {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
759   {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
760   {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
761   {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
762   {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
763   {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
764   {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
765   {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
766
767   /* ARM V6Z instructions.  */
768   {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
769
770   /* ARM V6K instructions.  */
771   {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
772   {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
773   {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
774   {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
775   {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
776   {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
777   {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
778
779   /* ARM V6K NOP hints.  */
780   {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
781   {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
782   {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
783   {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
784   {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
785
786   /* ARM V6 instructions. */
787   {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
788   {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
789   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
790   {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
791   {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
792   {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
793   {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
794   {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
795   {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
796   {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
797   {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
798   {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
799   {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
800   {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
801   {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
802   {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
803   {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
804   {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
805   {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
806   {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
807   {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
808   {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
809   {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
810   {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
811   {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
812   {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
813   {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
814   {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
815   {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
816   {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
817   {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
818   {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
819   {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
820   {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
821   {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
822   {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
823   {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
824   {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
825   {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
826   {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
827   {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
828   {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
829   {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
830   {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
831   {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
832   {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
833   {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
834   {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
835   {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
836   {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
837   {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
838   {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
839   {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
840   {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
841   {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
842   {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
843   {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
844   {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
845   {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
846   {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
847   {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
848   {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
849   {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
850   {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
851   {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
852   {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
853   {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
854   {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
855   {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
856   {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
857   {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
858   {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
859   {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
860   {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
861   {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
862   {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
863   {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
864   {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
865   {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
866   {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
867   {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
868   {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
869   {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
870   {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
871   {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
872   {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
873   {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
874   {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
875   {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
876   {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
877   {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
878   {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
879   {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
880   {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
881   {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
882   {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
883   {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
884   {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
885   {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
886   {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
887   {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
888   {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
889   {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
890   {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
891   {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
892   {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
893   {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
894   {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
895   {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
896   {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
897   {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
898   {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
899   {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
900   {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
901   {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
902   {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
903   {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
904   {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
905   {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
906   {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
907   {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
908   {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
909
910   /* V5J instruction.  */
911   {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
912
913   /* V5 Instructions.  */
914   {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
915   {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
916   {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
917   {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
918
919   /* V5E "El Segundo" Instructions.  */    
920   {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
921   {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
922   {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
923   {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
924   {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
925   {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
926   {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
927
928   {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
929   {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
930
931   {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
932   {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
933   {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
934   {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
935
936   {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
937   {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
938   {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
939   {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
940
941   {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
942   {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
943
944   {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0,  "qadd%c\t%12-15r, %0-3r, %16-19r"},
945   {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
946   {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0,  "qsub%c\t%12-15r, %0-3r, %16-19r"},
947   {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
948
949   /* ARM Instructions.  */
950   {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
951   {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
952   {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
953   {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
954   {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
955   {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
956   {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
957   {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
958   {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
959   {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
960   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
961   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
962   {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
963   {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
964   {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
965   {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
966   {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
967   {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
968   {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
969   {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
970   {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
971   {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
972   {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
973   {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
974   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
975   {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
976   {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
977   {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
978   {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
979
980   /* The rest.  */
981   {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
982   {0, 0x00000000, 0x00000000, 0}
983 };
984
985 /* print_insn_thumb16 recognizes the following format control codes:
986
987    %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
988    %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
989    %<bitfield>I         print bitfield as a signed decimal
990                                 (top bit of range being the sign bit)
991    %N                   print Thumb register mask (with LR)
992    %O                   print Thumb register mask (with PC)
993    %M                   print Thumb register mask
994    %b                   print CZB's 6-bit unsigned branch destination
995    %s                   print Thumb right-shift immediate (6..10; 0 == 32).
996    %c                   print the condition code
997    %C                   print the condition code, or "s" if not conditional
998    %x                   print warning if conditional an not at end of IT block"
999    %X                   print "\t; unpredictable <IT:code>" if conditional
1000    %I                   print IT instruction suffix and operands
1001    %<bitfield>r         print bitfield as an ARM register
1002    %<bitfield>d         print bitfield as a decimal
1003    %<bitfield>H         print (bitfield * 2) as a decimal
1004    %<bitfield>W         print (bitfield * 4) as a decimal
1005    %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
1006    %<bitfield>B         print Thumb branch destination (signed displacement)
1007    %<bitfield>c         print bitfield as a condition code
1008    %<bitnum>'c          print specified char iff bit is one
1009    %<bitnum>?ab         print a if bit is one else print b.  */
1010
1011 static const struct opcode16 thumb_opcodes[] =
1012 {
1013   /* Thumb instructions.  */
1014
1015   /* ARM V6K no-argument instructions.  */
1016   {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1017   {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1018   {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1019   {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1020   {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1021   {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1022
1023   /* ARM V6T2 instructions.  */
1024   {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1025   {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1026   {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1027
1028   /* ARM V6.  */
1029   {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1030   {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1031   {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1032   {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1033   {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1034   {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1035   {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1036   {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1037   {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1038   {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1039   {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1040
1041   /* ARM V5 ISA extends Thumb.  */
1042   {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional.  */
1043   /* This is BLX(2).  BLX(1) is a 32-bit instruction.  */
1044   {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"},      /* note: 4 bit register number.  */
1045   /* ARM V4T ISA (Thumb v1).  */
1046   {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
1047   /* Format 4.  */
1048   {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1049   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1050   {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1051   {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1052   {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1053   {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1054   {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1055   {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1056   {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1057   {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1058   {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1059   {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1060   {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1061   {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1062   {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1063   {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1064   /* format 13 */
1065   {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1066   {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1067   /* format 5 */
1068   {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1069   {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1070   {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1071   {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1072   /* format 14 */
1073   {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1074   {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1075   /* format 2 */
1076   {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1077   {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1078   {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1079   {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1080   /* format 8 */
1081   {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1082   {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1083   {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1084   /* format 7 */
1085   {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1086   {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1087   /* format 1 */
1088   {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1089   {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1090   {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1091   /* format 3 */
1092   {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1093   {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1094   {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1095   {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1096   /* format 6 */
1097   {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1098   /* format 9 */
1099   {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1100   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1101   {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1102   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1103   /* format 10 */
1104   {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1105   {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1106   /* format 11 */
1107   {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1108   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1109   /* format 12 */
1110   {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
1111   {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1112   /* format 15 */
1113   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1114   {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1115   /* format 17 */
1116   {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1117   /* format 16 */
1118   {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1119   /* format 18 */
1120   {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1121
1122   /* The E800 .. FFFF range is unconditionally redirected to the
1123      32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1124      are processed via that table.  Thus, we can never encounter a
1125      bare "second half of BL/BLX(1)" instruction here.  */
1126   {ARM_EXT_V1,  0x0000, 0x0000, "undefined"},
1127   {0, 0, 0, 0}
1128 };
1129
1130 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1131    We adopt the convention that hw1 is the high 16 bits of .value and
1132    .mask, hw2 the low 16 bits.
1133
1134    print_insn_thumb32 recognizes the following format control codes:
1135
1136        %%               %
1137
1138        %I               print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1139        %M               print a modified 12-bit immediate (same location)
1140        %J               print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1141        %K               print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1142        %S               print a possibly-shifted Rm
1143
1144        %a               print the address of a plain load/store
1145        %w               print the width and signedness of a core load/store
1146        %m               print register mask for ldm/stm
1147
1148        %E               print the lsb and width fields of a bfc/bfi instruction
1149        %F               print the lsb and width fields of a sbfx/ubfx instruction
1150        %b               print a conditional branch offset
1151        %B               print an unconditional branch offset
1152        %s               print the shift field of an SSAT instruction
1153        %R               print the rotation field of an SXT instruction
1154        %U               print barrier type.
1155        %P               print address for pli instruction.
1156        %c               print the condition code
1157        %x               print warning if conditional an not at end of IT block"
1158        %X               print "\t; unpredictable <IT:code>" if conditional
1159
1160        %<bitfield>d     print bitfield in decimal
1161        %<bitfield>W     print bitfield*4 in decimal
1162        %<bitfield>r     print bitfield as an ARM register
1163        %<bitfield>c     print bitfield as a condition code
1164
1165        %<bitfield>'c    print specified char iff bitfield is all ones
1166        %<bitfield>`c    print specified char iff bitfield is all zeroes
1167        %<bitfield>?ab... select from array of values in big endian order
1168
1169    With one exception at the bottom (done because BL and BLX(1) need
1170    to come dead last), this table was machine-sorted first in
1171    decreasing order of number of bits set in the mask, then in
1172    increasing numeric order of mask, then in increasing numeric order
1173    of opcode.  This order is not the clearest for a human reader, but
1174    is guaranteed never to catch a special-case bit pattern with a more
1175    general mask, which is important, because this instruction encoding
1176    makes heavy use of special-case bit patterns.  */
1177 static const struct opcode32 thumb32_opcodes[] =
1178 {
1179   /* V7 instructions.  */
1180   {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1181   {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1182   {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1183   {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1184   {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1185   {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1186   {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1187
1188   /* Instructions defined in the basic V6T2 set.  */
1189   {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1190   {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1191   {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1192   {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1193   {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"},
1194   {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1195
1196   {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1197   {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1198   {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1199   {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1200   {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1201   {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1202   {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1203   {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1204   {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1205   {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1206   {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1207   {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1208   {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1209   {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1210   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1211   {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1212   {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t#%0-4d%21'!"},
1213   {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t#%0-4d%21'!"},
1214   {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1215   {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1216   {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1217   {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1218   {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1219   {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1220   {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1221   {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1222   {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1223   {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1224   {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1225   {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1226   {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1227   {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1228   {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1229   {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1230   {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1231   {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1232   {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1233   {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1234   {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1235   {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1236   {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1237   {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1238   {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1239   {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1240   {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1241   {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1242   {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1243   {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1244   {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1245   {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1246   {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1247   {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1248   {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1249   {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1250   {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1251   {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1252   {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1253   {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1254   {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1255   {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1256   {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1257   {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1258   {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1259   {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1260   {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1261   {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1262   {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1263   {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1264   {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1265   {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1266   {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1267   {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1268   {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1269   {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1270   {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1271   {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1272   {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1273   {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1274   {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1275   {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1276   {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1277   {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1278   {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1279   {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1280   {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1281   {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1282   {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1283   {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1284   {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1285   {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1286   {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1287   {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1288   {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1289   {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1290   {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1291   {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1292   {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1293   {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1294   {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1295   {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1296   {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1297   {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1298   {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1299   {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1300   {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1301   {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1302   {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1303   {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1304   {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1305   {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1306   {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1307   {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1308   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1309   {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1310   {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1311   {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1312   {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1313   {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1314   {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1315   {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1316   {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1317   {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1318   {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1319   {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1320   {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1321   {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1322   {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1323   {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1324   {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1325   {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1326   {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1327   {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1328   {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1329   {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1330   {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1331   {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1332   {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1333   {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1334   {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1335   {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1336   {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1337   {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1338   {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1339   {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1340   {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1341   {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1342   {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1343   {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1344   {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1345   {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1346   {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1347   {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1348   {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1349   {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1350   {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1351   {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1352   {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1353   {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1354   {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1355   {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1356   {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1357   {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1358   {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1359   {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1360   {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1361   {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1362   {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1363   {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1364   {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1365   {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1366
1367   /* Filter out Bcc with cond=E or F, which are used for other instructions.  */
1368   {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1369   {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1370   {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1371   {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1372
1373   /* These have been 32-bit since the invention of Thumb.  */
1374   {ARM_EXT_V4T,  0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1375   {ARM_EXT_V4T,  0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1376
1377   /* Fallback.  */
1378   {ARM_EXT_V1,   0x00000000, 0x00000000, "undefined"},
1379   {0, 0, 0, 0}
1380 };
1381    
1382 static const char *const arm_conditional[] =
1383 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1384  "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1385
1386 static const char *const arm_fp_const[] =
1387 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1388
1389 static const char *const arm_shift[] =
1390 {"lsl", "lsr", "asr", "ror"};
1391
1392 typedef struct
1393 {
1394   const char *name;
1395   const char *description;
1396   const char *reg_names[16];
1397 }
1398 arm_regname;
1399
1400 static const arm_regname regnames[] =
1401 {
1402   { "raw" , "Select raw register names",
1403     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1404   { "gcc",  "Select register names used by GCC",
1405     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1406   { "std",  "Select register names used in ARM's ISA documentation",
1407     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
1408   { "apcs", "Select register names used in the APCS",
1409     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1410   { "atpcs", "Select register names used in the ATPCS",
1411     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
1412   { "special-atpcs", "Select special register names used in the ATPCS",
1413     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
1414 };
1415
1416 static const char *const iwmmxt_wwnames[] =
1417 {"b", "h", "w", "d"};
1418
1419 static const char *const iwmmxt_wwssnames[] =
1420 {"b", "bus", "b", "bss",
1421  "h", "hus", "h", "hss",
1422  "w", "wus", "w", "wss",
1423  "d", "dus", "d", "dss"
1424 };
1425
1426 static const char *const iwmmxt_regnames[] =
1427 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1428   "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1429 };
1430
1431 static const char *const iwmmxt_cregnames[] =
1432 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1433   "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1434 };
1435
1436 /* Default to GCC register name set.  */
1437 static unsigned int regname_selected = 1;
1438
1439 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1440 #define arm_regnames      regnames[regname_selected].reg_names
1441
1442 static bfd_boolean force_thumb = FALSE;
1443
1444 /* Current IT instruction state.  This contains the same state as the IT
1445    bits in the CPSR.  */
1446 static unsigned int ifthen_state;
1447 /* IT state for the next instruction.  */
1448 static unsigned int ifthen_next_state;
1449 /* The address of the insn for which the IT state is valid.  */
1450 static bfd_vma ifthen_address;
1451 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1452
1453 \f
1454 /* Functions.  */
1455 int
1456 get_arm_regname_num_options (void)
1457 {
1458   return NUM_ARM_REGNAMES;
1459 }
1460
1461 int
1462 set_arm_regname_option (int option)
1463 {
1464   int old = regname_selected;
1465   regname_selected = option;
1466   return old;
1467 }
1468
1469 int
1470 get_arm_regnames (int option, const char **setname, const char **setdescription,
1471                   const char *const **register_names)
1472 {
1473   *setname = regnames[option].name;
1474   *setdescription = regnames[option].description;
1475   *register_names = regnames[option].reg_names;
1476   return 16;
1477 }
1478
1479 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1480    Returns pointer to following character of the format string and
1481    fills in *VALUEP and *WIDTHP with the extracted value and number of
1482    bits extracted.  WIDTHP can be NULL. */
1483
1484 static const char *
1485 arm_decode_bitfield (const char *ptr, unsigned long insn,
1486                      unsigned long *valuep, int *widthp)
1487 {
1488   unsigned long value = 0;
1489   int width = 0;
1490   
1491   do 
1492     {
1493       int start, end;
1494       int bits;
1495
1496       for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1497         start = start * 10 + *ptr - '0';
1498       if (*ptr == '-')
1499         for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1500           end = end * 10 + *ptr - '0';
1501       else
1502         end = start;
1503       bits = end - start;
1504       if (bits < 0)
1505         abort ();
1506       value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1507       width += bits + 1;
1508     }
1509   while (*ptr++ == ',');
1510   *valuep = value;
1511   if (widthp)
1512     *widthp = width;
1513   return ptr - 1;
1514 }
1515
1516 static void
1517 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1518 {
1519   func (stream, "%s", arm_regnames[given & 0xf]);
1520
1521   if ((given & 0xff0) != 0)
1522     {
1523       if ((given & 0x10) == 0)
1524         {
1525           int amount = (given & 0xf80) >> 7;
1526           int shift = (given & 0x60) >> 5;
1527
1528           if (amount == 0)
1529             {
1530               if (shift == 3)
1531                 {
1532                   func (stream, ", rrx");
1533                   return;
1534                 }
1535
1536               amount = 32;
1537             }
1538
1539           func (stream, ", %s #%d", arm_shift[shift], amount);
1540         }
1541       else
1542         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1543               arm_regnames[(given & 0xf00) >> 8]);
1544     }
1545 }
1546
1547 /* Print one coprocessor instruction on INFO->STREAM.
1548    Return TRUE if the instuction matched, FALSE if this is not a
1549    recognised coprocessor instruction.  */
1550
1551 static bfd_boolean
1552 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1553                         bfd_boolean thumb)
1554 {
1555   const struct opcode32 *insn;
1556   void *stream = info->stream;
1557   fprintf_ftype func = info->fprintf_func;
1558   unsigned long mask;
1559   unsigned long value;
1560   int cond;
1561
1562   for (insn = coprocessor_opcodes; insn->assembler; insn++)
1563     {
1564       if (insn->value == FIRST_IWMMXT_INSN
1565           && info->mach != bfd_mach_arm_XScale
1566           && info->mach != bfd_mach_arm_iWMMXt)
1567         insn = insn + IWMMXT_INSN_COUNT;
1568
1569       mask = insn->mask;
1570       value = insn->value;
1571       if (thumb)
1572         {
1573           /* The high 4 bits are 0xe for Arm conditional instructions, and
1574              0xe for arm unconditional instructions.  The rest of the
1575              encoding is the same.  */
1576           mask |= 0xf0000000;
1577           value |= 0xe0000000;
1578           if (ifthen_state)
1579             cond = IFTHEN_COND;
1580           else
1581             cond = 16;
1582         }
1583       else
1584         {
1585           /* Only match unconditional instuctions against unconditional
1586              patterns.  */
1587           if ((given & 0xf0000000) == 0xf0000000)
1588             {
1589               mask |= 0xf0000000;
1590               cond = 16;
1591             }
1592           else
1593             {
1594               cond = (given >> 28) & 0xf;
1595               if (cond == 0xe)
1596                 cond = 16;
1597             }
1598         }
1599       if ((given & mask) == value)
1600         {
1601           const char *c;
1602
1603           for (c = insn->assembler; *c; c++)
1604             {
1605               if (*c == '%')
1606                 {
1607                   switch (*++c)
1608                     {
1609                     case '%':
1610                       func (stream, "%%");
1611                       break;
1612
1613                     case 'A':
1614                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1615
1616                       if ((given & (1 << 24)) != 0)
1617                         {
1618                           int offset = given & 0xff;
1619
1620                           if (offset)
1621                             func (stream, ", #%s%d]%s",
1622                                   ((given & 0x00800000) == 0 ? "-" : ""),
1623                                   offset * 4,
1624                                   ((given & 0x00200000) != 0 ? "!" : ""));
1625                           else
1626                             func (stream, "]");
1627                         }
1628                       else
1629                         {
1630                           int offset = given & 0xff;
1631
1632                           func (stream, "]");
1633
1634                           if (given & (1 << 21))
1635                             {
1636                               if (offset)
1637                                 func (stream, ", #%s%d",
1638                                       ((given & 0x00800000) == 0 ? "-" : ""),
1639                                       offset * 4);
1640                             }
1641                           else
1642                             func (stream, ", {%d}", offset);
1643                         }
1644                       break;
1645
1646                     case 'B':
1647                       {
1648                         int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1649                         int offset = (given >> 1) & 0x3f;
1650                         
1651                         if (offset == 1)
1652                           func (stream, "{d%d}", regno);
1653                         else if (regno + offset > 32)
1654                           func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1655                         else
1656                           func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1657                       }
1658                       break;
1659                       
1660                     case 'C':
1661                       {
1662                         int rn = (given >> 16) & 0xf;
1663                         int offset = (given & 0xff) * 4;
1664                         int add = (given >> 23) & 1;
1665                         
1666                         func (stream, "[%s", arm_regnames[rn]);
1667                         
1668                         if (offset)
1669                           {
1670                             if (!add)
1671                               offset = -offset;
1672                             func (stream, ", #%d", offset);
1673                           }
1674                         func (stream, "]");
1675                         if (rn == 15)
1676                           {
1677                             func (stream, "\t; ");
1678                             /* FIXME: Unsure if info->bytes_per_chunk is the
1679                                right thing to use here.  */
1680                             info->print_address_func (offset + pc
1681                               + info->bytes_per_chunk * 2, info);
1682                           }
1683                       }
1684                       break;
1685
1686                     case 'c':
1687                       func (stream, "%s", arm_conditional[cond]);
1688                       break;
1689
1690                     case 'I':
1691                       /* Print a Cirrus/DSP shift immediate.  */
1692                       /* Immediates are 7bit signed ints with bits 0..3 in
1693                          bits 0..3 of opcode and bits 4..6 in bits 5..7
1694                          of opcode.  */
1695                       {
1696                         int imm;
1697
1698                         imm = (given & 0xf) | ((given & 0xe0) >> 1);
1699
1700                         /* Is ``imm'' a negative number?  */
1701                         if (imm & 0x40)
1702                           imm |= (-1 << 7);
1703
1704                         func (stream, "%d", imm);
1705                       }
1706
1707                       break;
1708
1709                     case 'F':
1710                       switch (given & 0x00408000)
1711                         {
1712                         case 0:
1713                           func (stream, "4");
1714                           break;
1715                         case 0x8000:
1716                           func (stream, "1");
1717                           break;
1718                         case 0x00400000:
1719                           func (stream, "2");
1720                           break;
1721                         default:
1722                           func (stream, "3");
1723                         }
1724                       break;
1725
1726                     case 'P':
1727                       switch (given & 0x00080080)
1728                         {
1729                         case 0:
1730                           func (stream, "s");
1731                           break;
1732                         case 0x80:
1733                           func (stream, "d");
1734                           break;
1735                         case 0x00080000:
1736                           func (stream, "e");
1737                           break;
1738                         default:
1739                           func (stream, _("<illegal precision>"));
1740                           break;
1741                         }
1742                       break;
1743                     case 'Q':
1744                       switch (given & 0x00408000)
1745                         {
1746                         case 0:
1747                           func (stream, "s");
1748                           break;
1749                         case 0x8000:
1750                           func (stream, "d");
1751                           break;
1752                         case 0x00400000:
1753                           func (stream, "e");
1754                           break;
1755                         default:
1756                           func (stream, "p");
1757                           break;
1758                         }
1759                       break;
1760                     case 'R':
1761                       switch (given & 0x60)
1762                         {
1763                         case 0:
1764                           break;
1765                         case 0x20:
1766                           func (stream, "p");
1767                           break;
1768                         case 0x40:
1769                           func (stream, "m");
1770                           break;
1771                         default:
1772                           func (stream, "z");
1773                           break;
1774                         }
1775                       break;
1776
1777                     case '0': case '1': case '2': case '3': case '4':
1778                     case '5': case '6': case '7': case '8': case '9':
1779                       {
1780                         int width;
1781                         unsigned long value;
1782
1783                         c = arm_decode_bitfield (c, given, &value, &width);
1784
1785                         switch (*c)
1786                           {
1787                           case 'r':
1788                             func (stream, "%s", arm_regnames[value]);
1789                             break;
1790                           case 'D':
1791                             func (stream, "d%ld", value);
1792                             break;
1793                           case 'Q':
1794                             if (value & 1)
1795                               func (stream, "<illegal reg q%ld.5>", value >> 1);
1796                             else
1797                               func (stream, "q%ld", value >> 1);
1798                             break;
1799                           case 'd':
1800                             func (stream, "%ld", value);
1801                             break;
1802                           case 'k':
1803                             {
1804                               int from = (given & (1 << 7)) ? 32 : 16;
1805                               func (stream, "%ld", from - value);
1806                             }
1807                             break;
1808                             
1809                           case 'f':
1810                             if (value > 7)
1811                               func (stream, "#%s", arm_fp_const[value & 7]);
1812                             else
1813                               func (stream, "f%ld", value);
1814                             break;
1815
1816                           case 'w':
1817                             if (width == 2)
1818                               func (stream, "%s", iwmmxt_wwnames[value]);
1819                             else
1820                               func (stream, "%s", iwmmxt_wwssnames[value]);
1821                             break;
1822
1823                           case 'g':
1824                             func (stream, "%s", iwmmxt_regnames[value]);
1825                             break;
1826                           case 'G':
1827                             func (stream, "%s", iwmmxt_cregnames[value]);
1828                             break;
1829                           case '`':
1830                             c++;
1831                             if (value == 0)
1832                               func (stream, "%c", *c);
1833                             break;
1834                           case '\'':
1835                             c++;
1836                             if (value == ((1ul << width) - 1))
1837                               func (stream, "%c", *c);
1838                             break;
1839                           case '?':
1840                             func (stream, "%c", c[(1 << width) - (int)value]);
1841                             c += 1 << width;
1842                             break;
1843                           default:
1844                             abort ();
1845                           }
1846                         break;
1847
1848                       case 'y':
1849                       case 'z':
1850                         {
1851                           int single = *c++ == 'y';
1852                           int regno;
1853                           
1854                           switch (*c)
1855                             {
1856                             case '4': /* Sm pair */
1857                               func (stream, "{");
1858                               /* Fall through.  */
1859                             case '0': /* Sm, Dm */
1860                               regno = given & 0x0000000f;
1861                               if (single)
1862                                 {
1863                                   regno <<= 1;
1864                                   regno += (given >> 5) & 1;
1865                                 }
1866                               else
1867                                 regno += ((given >> 5) & 1) << 4;
1868                               break;
1869
1870                             case '1': /* Sd, Dd */
1871                               regno = (given >> 12) & 0x0000000f;
1872                               if (single)
1873                                 {
1874                                   regno <<= 1;
1875                                   regno += (given >> 22) & 1;
1876                                 }
1877                               else
1878                                 regno += ((given >> 22) & 1) << 4;
1879                               break;
1880
1881                             case '2': /* Sn, Dn */
1882                               regno = (given >> 16) & 0x0000000f;
1883                               if (single)
1884                                 {
1885                                   regno <<= 1;
1886                                   regno += (given >> 7) & 1;
1887                                 }
1888                               else
1889                                 regno += ((given >> 7) & 1) << 4;
1890                               break;
1891                               
1892                             case '3': /* List */
1893                               func (stream, "{");
1894                               regno = (given >> 12) & 0x0000000f;
1895                               if (single)
1896                                 {
1897                                   regno <<= 1;
1898                                   regno += (given >> 22) & 1;
1899                                 }
1900                               else
1901                                 regno += ((given >> 22) & 1) << 4;
1902                               break;
1903                               
1904                             default:
1905                               abort ();
1906                             }
1907
1908                           func (stream, "%c%d", single ? 's' : 'd', regno);
1909
1910                           if (*c == '3')
1911                             {
1912                               int count = given & 0xff;
1913                               
1914                               if (single == 0)
1915                                 count >>= 1;
1916                               
1917                               if (--count)
1918                                 {
1919                                   func (stream, "-%c%d",
1920                                         single ? 's' : 'd',
1921                                         regno + count);
1922                                 }
1923                               
1924                               func (stream, "}");
1925                             }
1926                           else if (*c == '4')
1927                             func (stream, ", %c%d}", single ? 's' : 'd',
1928                                   regno + 1);
1929                         }
1930                         break;
1931                             
1932                       case 'L':
1933                         switch (given & 0x00400100)
1934                           {
1935                           case 0x00000000: func (stream, "b"); break;
1936                           case 0x00400000: func (stream, "h"); break;
1937                           case 0x00000100: func (stream, "w"); break;
1938                           case 0x00400100: func (stream, "d"); break;
1939                           default:
1940                             break;
1941                           }
1942                         break;
1943
1944                       case 'Z':
1945                         {
1946                           int value;
1947                           /* given (20, 23) | given (0, 3) */
1948                           value = ((given >> 16) & 0xf0) | (given & 0xf);
1949                           func (stream, "%d", value);
1950                         }
1951                         break;
1952
1953                       case 'l':
1954                         /* This is like the 'A' operator, except that if
1955                            the width field "M" is zero, then the offset is
1956                            *not* multiplied by four.  */
1957                         {
1958                           int offset = given & 0xff;
1959                           int multiplier = (given & 0x00000100) ? 4 : 1;
1960
1961                           func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1962
1963                           if (offset)
1964                             {
1965                               if ((given & 0x01000000) != 0)
1966                                 func (stream, ", #%s%d]%s",
1967                                       ((given & 0x00800000) == 0 ? "-" : ""),
1968                                       offset * multiplier,
1969                                       ((given & 0x00200000) != 0 ? "!" : ""));
1970                               else
1971                                 func (stream, "], #%s%d",
1972                                       ((given & 0x00800000) == 0 ? "-" : ""),
1973                                       offset * multiplier);
1974                             }
1975                           else
1976                             func (stream, "]");
1977                         }
1978                         break;
1979
1980                       default:
1981                         abort ();
1982                       }
1983                     }
1984                 }
1985               else
1986                 func (stream, "%c", *c);
1987             }
1988           return TRUE;
1989         }
1990     }
1991   return FALSE;
1992 }
1993
1994 static void
1995 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
1996 {
1997   void *stream = info->stream;
1998   fprintf_ftype func = info->fprintf_func;
1999
2000   if (((given & 0x000f0000) == 0x000f0000)
2001       && ((given & 0x02000000) == 0))
2002     {
2003       int offset = given & 0xfff;
2004
2005       func (stream, "[pc");
2006
2007       if (given & 0x01000000)
2008         {
2009           if ((given & 0x00800000) == 0)
2010             offset = - offset;
2011
2012           /* Pre-indexed.  */
2013           func (stream, ", #%d]", offset);
2014
2015           offset += pc + 8;
2016
2017           /* Cope with the possibility of write-back
2018              being used.  Probably a very dangerous thing
2019              for the programmer to do, but who are we to
2020              argue ?  */
2021           if (given & 0x00200000)
2022             func (stream, "!");
2023         }
2024       else
2025         {
2026           /* Post indexed.  */
2027           func (stream, "], #%d", offset);
2028
2029           /* ie ignore the offset.  */
2030           offset = pc + 8;
2031         }
2032
2033       func (stream, "\t; ");
2034       info->print_address_func (offset, info);
2035     }
2036   else
2037     {
2038       func (stream, "[%s",
2039             arm_regnames[(given >> 16) & 0xf]);
2040       if ((given & 0x01000000) != 0)
2041         {
2042           if ((given & 0x02000000) == 0)
2043             {
2044               int offset = given & 0xfff;
2045               if (offset)
2046                 func (stream, ", #%s%d",
2047                       (((given & 0x00800000) == 0)
2048                        ? "-" : ""), offset);
2049             }
2050           else
2051             {
2052               func (stream, ", %s",
2053                     (((given & 0x00800000) == 0)
2054                      ? "-" : ""));
2055               arm_decode_shift (given, func, stream);
2056             }
2057
2058           func (stream, "]%s",
2059                 ((given & 0x00200000) != 0) ? "!" : "");
2060         }
2061       else
2062         {
2063           if ((given & 0x02000000) == 0)
2064             {
2065               int offset = given & 0xfff;
2066               if (offset)
2067                 func (stream, "], #%s%d",
2068                       (((given & 0x00800000) == 0)
2069                        ? "-" : ""), offset);
2070               else
2071                 func (stream, "]");
2072             }
2073           else
2074             {
2075               func (stream, "], %s",
2076                     (((given & 0x00800000) == 0)
2077                      ? "-" : ""));
2078               arm_decode_shift (given, func, stream);
2079             }
2080         }
2081     }
2082 }
2083
2084 /* Print one neon instruction on INFO->STREAM.
2085    Return TRUE if the instuction matched, FALSE if this is not a
2086    recognised neon instruction.  */
2087
2088 static bfd_boolean
2089 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2090 {
2091   const struct opcode32 *insn;
2092   void *stream = info->stream;
2093   fprintf_ftype func = info->fprintf_func;
2094
2095   if (thumb)
2096     {
2097       if ((given & 0xef000000) == 0xef000000)
2098         {
2099           /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
2100           unsigned long bit28 = given & (1 << 28);
2101
2102           given &= 0x00ffffff;
2103           if (bit28)
2104             given |= 0xf3000000;
2105           else
2106             given |= 0xf2000000;
2107         }
2108       else if ((given & 0xff000000) == 0xf9000000)
2109         given ^= 0xf9000000 ^ 0xf4000000;
2110       else
2111         return FALSE;
2112     }
2113   
2114   for (insn = neon_opcodes; insn->assembler; insn++)
2115     {
2116       if ((given & insn->mask) == insn->value)
2117         {
2118           const char *c;
2119
2120           for (c = insn->assembler; *c; c++)
2121             {
2122               if (*c == '%')
2123                 {
2124                   switch (*++c)
2125                     {
2126                     case '%':
2127                       func (stream, "%%");
2128                       break;
2129
2130                     case 'c':
2131                       if (thumb && ifthen_state)
2132                         func (stream, "%s", arm_conditional[IFTHEN_COND]);
2133                       break;
2134
2135                     case 'A':
2136                       {
2137                         static const unsigned char enc[16] = 
2138                         {
2139                           0x4, 0x14, /* st4 0,1 */
2140                           0x4, /* st1 2 */
2141                           0x4, /* st2 3 */
2142                           0x3, /* st3 4 */
2143                           0x13, /* st3 5 */
2144                           0x3, /* st1 6 */
2145                           0x1, /* st1 7 */
2146                           0x2, /* st2 8 */
2147                           0x12, /* st2 9 */
2148                           0x2, /* st1 10 */
2149                           0, 0, 0, 0, 0
2150                         };
2151                         int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2152                         int rn = ((given >> 16) & 0xf);
2153                         int rm = ((given >> 0) & 0xf);
2154                         int align = ((given >> 4) & 0x3);
2155                         int type = ((given >> 8) & 0xf);
2156                         int n = enc[type] & 0xf;
2157                         int stride = (enc[type] >> 4) + 1;
2158                         int ix;
2159                         
2160                         func (stream, "{");
2161                         if (stride > 1)
2162                           for (ix = 0; ix != n; ix++)
2163                             func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2164                         else if (n == 1)
2165                           func (stream, "d%d", rd);
2166                         else
2167                           func (stream, "d%d-d%d", rd, rd + n - 1);
2168                         func (stream, "}, [%s", arm_regnames[rn]);
2169                         if (align)
2170                           func (stream, ", :%d", 32 << align);
2171                         func (stream, "]");
2172                         if (rm == 0xd)
2173                           func (stream, "!");
2174                         else if (rm != 0xf)
2175                           func (stream, ", %s", arm_regnames[rm]);
2176                       }
2177                       break;
2178                       
2179                     case 'B':
2180                       {
2181                         int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2182                         int rn = ((given >> 16) & 0xf);
2183                         int rm = ((given >> 0) & 0xf);
2184                         int idx_align = ((given >> 4) & 0xf);
2185                         int align = 0;
2186                         int size = ((given >> 10) & 0x3);
2187                         int idx = idx_align >> (size + 1);
2188                         int length = ((given >> 8) & 3) + 1;
2189                         int stride = 1;
2190                         int i;
2191
2192                         if (length > 1 && size > 0)
2193                           stride = (idx_align & (1 << size)) ? 2 : 1;
2194                         
2195                         switch (length)
2196                           {
2197                           case 1:
2198                             {
2199                               int amask = (1 << size) - 1;
2200                               if ((idx_align & (1 << size)) != 0)
2201                                 return FALSE;
2202                               if (size > 0)
2203                                 {
2204                                   if ((idx_align & amask) == amask)
2205                                     align = 8 << size;
2206                                   else if ((idx_align & amask) != 0)
2207                                     return FALSE;
2208                                 }
2209                               }
2210                             break;
2211                           
2212                           case 2:
2213                             if (size == 2 && (idx_align & 2) != 0)
2214                               return FALSE;
2215                             align = (idx_align & 1) ? 16 << size : 0;
2216                             break;
2217                           
2218                           case 3:
2219                             if ((size == 2 && (idx_align & 3) != 0)
2220                                 || (idx_align & 1) != 0)
2221                               return FALSE;
2222                             break;
2223                           
2224                           case 4:
2225                             if (size == 2)
2226                               {
2227                                 if ((idx_align & 3) == 3)
2228                                   return FALSE;
2229                                 align = (idx_align & 3) * 64;
2230                               }
2231                             else
2232                               align = (idx_align & 1) ? 32 << size : 0;
2233                             break;
2234                           
2235                           default:
2236                             abort ();
2237                           }
2238                                 
2239                         func (stream, "{");
2240                         for (i = 0; i < length; i++)
2241                           func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2242                             rd + i * stride, idx);
2243                         func (stream, "}, [%s", arm_regnames[rn]);
2244                         if (align)
2245                           func (stream, ", :%d", align);
2246                         func (stream, "]");
2247                         if (rm == 0xd)
2248                           func (stream, "!");
2249                         else if (rm != 0xf)
2250                           func (stream, ", %s", arm_regnames[rm]);
2251                       }
2252                       break;
2253                       
2254                     case 'C':
2255                       {
2256                         int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2257                         int rn = ((given >> 16) & 0xf);
2258                         int rm = ((given >> 0) & 0xf);
2259                         int align = ((given >> 4) & 0x1);
2260                         int size = ((given >> 6) & 0x3);
2261                         int type = ((given >> 8) & 0x3);
2262                         int n = type + 1;
2263                         int stride = ((given >> 5) & 0x1);
2264                         int ix;
2265                         
2266                         if (stride && (n == 1))
2267                           n++;
2268                         else
2269                           stride++;
2270                         
2271                         func (stream, "{");
2272                         if (stride > 1)
2273                           for (ix = 0; ix != n; ix++)
2274                             func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2275                         else if (n == 1)
2276                           func (stream, "d%d[]", rd);
2277                         else
2278                           func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2279                         func (stream, "}, [%s", arm_regnames[rn]);
2280                         if (align)
2281                           {
2282                             int align = (8 * (type + 1)) << size;
2283                             if (type == 3)
2284                               align = (size > 1) ? align >> 1 : align;
2285                             if (type == 2 || (type == 0 && !size))
2286                               func (stream, ", :<bad align %d>", align);
2287                             else
2288                               func (stream, ", :%d", align);
2289                           }
2290                         func (stream, "]");
2291                         if (rm == 0xd)
2292                           func (stream, "!");
2293                         else if (rm != 0xf)
2294                           func (stream, ", %s", arm_regnames[rm]);
2295                       }
2296                       break;
2297                       
2298                     case 'D':
2299                       {
2300                         int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2301                         int size = (given >> 20) & 3;
2302                         int reg = raw_reg & ((4 << size) - 1);
2303                         int ix = raw_reg >> size >> 2;
2304                         
2305                         func (stream, "d%d[%d]", reg, ix);
2306                       }
2307                       break;
2308                       
2309                     case 'E':
2310                       /* Neon encoded constant for mov, mvn, vorr, vbic */
2311                       {
2312                         int bits = 0;
2313                         int cmode = (given >> 8) & 0xf;
2314                         int op = (given >> 5) & 0x1;
2315                         unsigned long value = 0, hival = 0;
2316                         unsigned shift;
2317                         int size = 0;
2318                         int isfloat = 0;
2319                         
2320                         bits |= ((given >> 24) & 1) << 7;
2321                         bits |= ((given >> 16) & 7) << 4;
2322                         bits |= ((given >> 0) & 15) << 0;
2323                         
2324                         if (cmode < 8)
2325                           {
2326                             shift = (cmode >> 1) & 3;
2327                             value = (unsigned long)bits << (8 * shift);
2328                             size = 32;
2329                           }
2330                         else if (cmode < 12)
2331                           {
2332                             shift = (cmode >> 1) & 1;
2333                             value = (unsigned long)bits << (8 * shift);
2334                             size = 16;
2335                           }
2336                         else if (cmode < 14)
2337                           {
2338                             shift = (cmode & 1) + 1;
2339                             value = (unsigned long)bits << (8 * shift);
2340                             value |= (1ul << (8 * shift)) - 1;
2341                             size = 32;
2342                           }
2343                         else if (cmode == 14)
2344                           {
2345                             if (op)
2346                               {
2347                                 /* bit replication into bytes */
2348                                 int ix;
2349                                 unsigned long mask;
2350                                 
2351                                 value = 0;
2352                                 hival = 0;
2353                                 for (ix = 7; ix >= 0; ix--)
2354                                   {
2355                                     mask = ((bits >> ix) & 1) ? 0xff : 0;
2356                                     if (ix <= 3)
2357                                       value = (value << 8) | mask;
2358                                     else
2359                                       hival = (hival << 8) | mask;
2360                                   }
2361                                 size = 64;
2362                               }
2363                             else
2364                               {
2365                                 /* byte replication */
2366                                 value = (unsigned long)bits;
2367                                 size = 8;
2368                               }
2369                           }
2370                         else if (!op)
2371                           {
2372                             /* floating point encoding */
2373                             int tmp;
2374                             
2375                             value = (unsigned long)(bits & 0x7f) << 19;
2376                             value |= (unsigned long)(bits & 0x80) << 24;
2377                             tmp = bits & 0x40 ? 0x3c : 0x40;
2378                             value |= (unsigned long)tmp << 24;
2379                             size = 32;
2380                             isfloat = 1;
2381                           }
2382                         else
2383                           {
2384                             func (stream, "<illegal constant %.8x:%x:%x>",
2385                                   bits, cmode, op);
2386                             size = 32;
2387                             break;
2388                           }
2389                         switch (size)
2390                           {
2391                           case 8:
2392                             func (stream, "#%ld\t; 0x%.2lx", value, value);
2393                             break;
2394                           
2395                           case 16:
2396                             func (stream, "#%ld\t; 0x%.4lx", value, value);
2397                             break;
2398
2399                           case 32:
2400                             if (isfloat)
2401                               {
2402                                 unsigned char valbytes[4];
2403                                 double fvalue;
2404                                 
2405                                 /* Do this a byte at a time so we don't have to
2406                                    worry about the host's endianness.  */
2407                                 valbytes[0] = value & 0xff;
2408                                 valbytes[1] = (value >> 8) & 0xff;
2409                                 valbytes[2] = (value >> 16) & 0xff;
2410                                 valbytes[3] = (value >> 24) & 0xff;
2411                                 
2412                                 floatformat_to_double 
2413                                   (&floatformat_ieee_single_little, valbytes,
2414                                   &fvalue);
2415                                                                 
2416                                 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2417                                       value);
2418                               }
2419                             else
2420                               func (stream, "#%ld\t; 0x%.8lx",
2421                                 (long) ((value & 0x80000000)
2422                                         ? value | ~0xffffffffl : value), value);
2423                             break;
2424
2425                           case 64:
2426                             func (stream, "#0x%.8lx%.8lx", hival, value);
2427                             break;
2428                           
2429                           default:
2430                             abort ();
2431                           }
2432                       }
2433                       break;
2434                       
2435                     case 'F':
2436                       {
2437                         int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2438                         int num = (given >> 8) & 0x3;
2439                         
2440                         if (!num)
2441                           func (stream, "{d%d}", regno);
2442                         else if (num + regno >= 32)
2443                           func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2444                         else
2445                           func (stream, "{d%d-d%d}", regno, regno + num);
2446                       }
2447                       break;
2448       
2449
2450                     case '0': case '1': case '2': case '3': case '4':
2451                     case '5': case '6': case '7': case '8': case '9':
2452                       {
2453                         int width;
2454                         unsigned long value;
2455
2456                         c = arm_decode_bitfield (c, given, &value, &width);
2457                         
2458                         switch (*c)
2459                           {
2460                           case 'r':
2461                             func (stream, "%s", arm_regnames[value]);
2462                             break;
2463                           case 'd':
2464                             func (stream, "%ld", value);
2465                             break;
2466                           case 'e':
2467                             func (stream, "%ld", (1ul << width) - value);
2468                             break;
2469                             
2470                           case 'S':
2471                           case 'T':
2472                           case 'U':
2473                             /* various width encodings */
2474                             {
2475                               int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2476                               int limit;
2477                               unsigned low, high;
2478
2479                               c++;
2480                               if (*c >= '0' && *c <= '9')
2481                                 limit = *c - '0';
2482                               else if (*c >= 'a' && *c <= 'f')
2483                                 limit = *c - 'a' + 10;
2484                               else
2485                                 abort ();
2486                               low = limit >> 2;
2487                               high = limit & 3;
2488
2489                               if (value < low || value > high)
2490                                 func (stream, "<illegal width %d>", base << value);
2491                               else
2492                                 func (stream, "%d", base << value);
2493                             }
2494                             break;
2495                           case 'R':
2496                             if (given & (1 << 6))
2497                               goto Q;
2498                             /* FALLTHROUGH */
2499                           case 'D':
2500                             func (stream, "d%ld", value);
2501                             break;
2502                           case 'Q':
2503                           Q:
2504                             if (value & 1)
2505                               func (stream, "<illegal reg q%ld.5>", value >> 1);
2506                             else
2507                               func (stream, "q%ld", value >> 1);
2508                             break;
2509                             
2510                           case '`':
2511                             c++;
2512                             if (value == 0)
2513                               func (stream, "%c", *c);
2514                             break;
2515                           case '\'':
2516                             c++;
2517                             if (value == ((1ul << width) - 1))
2518                               func (stream, "%c", *c);
2519                             break;
2520                           case '?':
2521                             func (stream, "%c", c[(1 << width) - (int)value]);
2522                             c += 1 << width;
2523                             break;
2524                           default:
2525                             abort ();
2526                           }
2527                         break;
2528
2529                       default:
2530                         abort ();
2531                       }
2532                     }
2533                 }
2534               else
2535                 func (stream, "%c", *c);
2536             }
2537           return TRUE;
2538         }
2539     }
2540   return FALSE;
2541 }
2542
2543 /* Print one ARM instruction from PC on INFO->STREAM.  */
2544
2545 static void
2546 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2547 {
2548   const struct opcode32 *insn;
2549   void *stream = info->stream;
2550   fprintf_ftype func = info->fprintf_func;
2551
2552   if (print_insn_coprocessor (pc, info, given, FALSE))
2553     return;
2554
2555   if (print_insn_neon (info, given, FALSE))
2556     return;
2557
2558   for (insn = arm_opcodes; insn->assembler; insn++)
2559     {
2560       if (insn->value == FIRST_IWMMXT_INSN
2561           && info->mach != bfd_mach_arm_XScale
2562           && info->mach != bfd_mach_arm_iWMMXt)
2563         insn = insn + IWMMXT_INSN_COUNT;
2564
2565       if ((given & insn->mask) == insn->value
2566           /* Special case: an instruction with all bits set in the condition field
2567              (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2568              or by the catchall at the end of the table.  */
2569           && ((given & 0xF0000000) != 0xF0000000
2570               || (insn->mask & 0xF0000000) == 0xF0000000
2571               || (insn->mask == 0 && insn->value == 0)))
2572         {
2573           const char *c;
2574
2575           for (c = insn->assembler; *c; c++)
2576             {
2577               if (*c == '%')
2578                 {
2579                   switch (*++c)
2580                     {
2581                     case '%':
2582                       func (stream, "%%");
2583                       break;
2584
2585                     case 'a':
2586                       print_arm_address (pc, info, given);
2587                       break;
2588
2589                     case 'P':
2590                       /* Set P address bit and use normal address
2591                          printing routine.  */
2592                       print_arm_address (pc, info, given | (1 << 24));
2593                       break;
2594
2595                     case 's':
2596                       if ((given & 0x004f0000) == 0x004f0000)
2597                         {
2598                           /* PC relative with immediate offset.  */
2599                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2600
2601                           if ((given & 0x00800000) == 0)
2602                             offset = -offset;
2603
2604                           func (stream, "[pc, #%d]\t; ", offset);
2605                           info->print_address_func (offset + pc + 8, info);
2606                         }
2607                       else
2608                         {
2609                           func (stream, "[%s",
2610                                 arm_regnames[(given >> 16) & 0xf]);
2611                           if ((given & 0x01000000) != 0)
2612                             {
2613                               /* Pre-indexed.  */
2614                               if ((given & 0x00400000) == 0x00400000)
2615                                 {
2616                                   /* Immediate.  */
2617                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2618                                   if (offset)
2619                                     func (stream, ", #%s%d",
2620                                           (((given & 0x00800000) == 0)
2621                                            ? "-" : ""), offset);
2622                                 }
2623                               else
2624                                 {
2625                                   /* Register.  */
2626                                   func (stream, ", %s%s",
2627                                         (((given & 0x00800000) == 0)
2628                                          ? "-" : ""),
2629                                         arm_regnames[given & 0xf]);
2630                                 }
2631
2632                               func (stream, "]%s",
2633                                     ((given & 0x00200000) != 0) ? "!" : "");
2634                             }
2635                           else
2636                             {
2637                               /* Post-indexed.  */
2638                               if ((given & 0x00400000) == 0x00400000)
2639                                 {
2640                                   /* Immediate.  */
2641                                   int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2642                                   if (offset)
2643                                     func (stream, "], #%s%d",
2644                                           (((given & 0x00800000) == 0)
2645                                            ? "-" : ""), offset);
2646                                   else
2647                                     func (stream, "]");
2648                                 }
2649                               else
2650                                 {
2651                                   /* Register.  */
2652                                   func (stream, "], %s%s",
2653                                         (((given & 0x00800000) == 0)
2654                                          ? "-" : ""),
2655                                         arm_regnames[given & 0xf]);
2656                                 }
2657                             }
2658                         }
2659                       break;
2660
2661                     case 'b':
2662                       {
2663                         int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2664                         info->print_address_func (disp*4 + pc + 8, info);
2665                       }
2666                       break;
2667
2668                     case 'c':
2669                       if (((given >> 28) & 0xf) != 0xe)
2670                         func (stream, "%s",
2671                               arm_conditional [(given >> 28) & 0xf]);
2672                       break;
2673
2674                     case 'm':
2675                       {
2676                         int started = 0;
2677                         int reg;
2678
2679                         func (stream, "{");
2680                         for (reg = 0; reg < 16; reg++)
2681                           if ((given & (1 << reg)) != 0)
2682                             {
2683                               if (started)
2684                                 func (stream, ", ");
2685                               started = 1;
2686                               func (stream, "%s", arm_regnames[reg]);
2687                             }
2688                         func (stream, "}");
2689                       }
2690                       break;
2691
2692                     case 'o':
2693                       if ((given & 0x02000000) != 0)
2694                         {
2695                           int rotate = (given & 0xf00) >> 7;
2696                           int immed = (given & 0xff);
2697                           immed = (((immed << (32 - rotate))
2698                                     | (immed >> rotate)) & 0xffffffff);
2699                           func (stream, "#%d\t; 0x%x", immed, immed);
2700                         }
2701                       else
2702                         arm_decode_shift (given, func, stream);
2703                       break;
2704
2705                     case 'p':
2706                       if ((given & 0x0000f000) == 0x0000f000)
2707                         func (stream, "p");
2708                       break;
2709
2710                     case 't':
2711                       if ((given & 0x01200000) == 0x00200000)
2712                         func (stream, "t");
2713                       break;
2714
2715                     case 'A':
2716                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2717
2718                       if ((given & (1 << 24)) != 0)
2719                         {
2720                           int offset = given & 0xff;
2721
2722                           if (offset)
2723                             func (stream, ", #%s%d]%s",
2724                                   ((given & 0x00800000) == 0 ? "-" : ""),
2725                                   offset * 4,
2726                                   ((given & 0x00200000) != 0 ? "!" : ""));
2727                           else
2728                             func (stream, "]");
2729                         }
2730                       else
2731                         {
2732                           int offset = given & 0xff;
2733
2734                           func (stream, "]");
2735
2736                           if (given & (1 << 21))
2737                             {
2738                               if (offset)
2739                                 func (stream, ", #%s%d",
2740                                       ((given & 0x00800000) == 0 ? "-" : ""),
2741                                       offset * 4);
2742                             }
2743                           else
2744                             func (stream, ", {%d}", offset);
2745                         }
2746                       break;
2747
2748                     case 'B':
2749                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
2750                       {
2751                         bfd_vma address;
2752                         bfd_vma offset = 0;
2753
2754                         if (given & 0x00800000)
2755                           /* Is signed, hi bits should be ones.  */
2756                           offset = (-1) ^ 0x00ffffff;
2757
2758                         /* Offset is (SignExtend(offset field)<<2).  */
2759                         offset += given & 0x00ffffff;
2760                         offset <<= 2;
2761                         address = offset + pc + 8;
2762
2763                         if (given & 0x01000000)
2764                           /* H bit allows addressing to 2-byte boundaries.  */
2765                           address += 2;
2766
2767                         info->print_address_func (address, info);
2768                       }
2769                       break;
2770
2771                     case 'C':
2772                       func (stream, "_");
2773                       if (given & 0x80000)
2774                         func (stream, "f");
2775                       if (given & 0x40000)
2776                         func (stream, "s");
2777                       if (given & 0x20000)
2778                         func (stream, "x");
2779                       if (given & 0x10000)
2780                         func (stream, "c");
2781                       break;
2782
2783                     case 'U':
2784                       switch (given & 0xf)
2785                         {
2786                         case 0xf: func(stream, "sy"); break;
2787                         case 0x7: func(stream, "un"); break;
2788                         case 0xe: func(stream, "st"); break;
2789                         case 0x6: func(stream, "unst"); break;
2790                         default:
2791                           func(stream, "#%d", (int)given & 0xf);
2792                           break;
2793                         }
2794                       break;
2795
2796                     case '0': case '1': case '2': case '3': case '4':
2797                     case '5': case '6': case '7': case '8': case '9':
2798                       {
2799                         int width;
2800                         unsigned long value;
2801
2802                         c = arm_decode_bitfield (c, given, &value, &width);
2803                         
2804                         switch (*c)
2805                           {
2806                           case 'r':
2807                             func (stream, "%s", arm_regnames[value]);
2808                             break;
2809                           case 'd':
2810                             func (stream, "%ld", value);
2811                             break;
2812                           case 'b':
2813                             func (stream, "%ld", value * 8);
2814                             break;
2815                           case 'W':
2816                             func (stream, "%ld", value + 1);
2817                             break;
2818                           case 'x':
2819                             func (stream, "0x%08lx", value);
2820
2821                             /* Some SWI instructions have special
2822                                meanings.  */
2823                             if ((given & 0x0fffffff) == 0x0FF00000)
2824                               func (stream, "\t; IMB");
2825                             else if ((given & 0x0fffffff) == 0x0FF00001)
2826                               func (stream, "\t; IMBRange");
2827                             break;
2828                           case 'X':
2829                             func (stream, "%01lx", value & 0xf);
2830                             break;
2831                           case '`':
2832                             c++;
2833                             if (value == 0)
2834                               func (stream, "%c", *c);
2835                             break;
2836                           case '\'':
2837                             c++;
2838                             if (value == ((1ul << width) - 1))
2839                               func (stream, "%c", *c);
2840                             break;
2841                           case '?':
2842                             func (stream, "%c", c[(1 << width) - (int)value]);
2843                             c += 1 << width;
2844                             break;
2845                           default:
2846                             abort ();
2847                           }
2848                         break;
2849
2850                       case 'e':
2851                         {
2852                           int imm;
2853
2854                           imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2855                           func (stream, "%d", imm);
2856                         }
2857                         break;
2858
2859                       case 'E':
2860                         /* LSB and WIDTH fields of BFI or BFC.  The machine-
2861                            language instruction encodes LSB and MSB.  */
2862                         {
2863                           long msb = (given & 0x001f0000) >> 16;
2864                           long lsb = (given & 0x00000f80) >> 7;
2865
2866                           long width = msb - lsb + 1;
2867                           if (width > 0)
2868                             func (stream, "#%lu, #%lu", lsb, width);
2869                           else
2870                             func (stream, "(invalid: %lu:%lu)", lsb, msb);
2871                         }
2872                         break;
2873
2874                       case 'V':
2875                         /* 16-bit unsigned immediate from a MOVT or MOVW
2876                            instruction, encoded in bits 0:11 and 15:19.  */
2877                         {
2878                           long hi = (given & 0x000f0000) >> 4;
2879                           long lo = (given & 0x00000fff);
2880                           long imm16 = hi | lo;
2881                           func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2882                         }
2883                         break;
2884
2885                       default:
2886                         abort ();
2887                       }
2888                     }
2889                 }
2890               else
2891                 func (stream, "%c", *c);
2892             }
2893           return;
2894         }
2895     }
2896   abort ();
2897 }
2898
2899 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
2900
2901 static void
2902 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2903 {
2904   const struct opcode16 *insn;
2905   void *stream = info->stream;
2906   fprintf_ftype func = info->fprintf_func;
2907
2908   for (insn = thumb_opcodes; insn->assembler; insn++)
2909     if ((given & insn->mask) == insn->value)
2910       {
2911         const char *c = insn->assembler;
2912         for (; *c; c++)
2913           {
2914             int domaskpc = 0;
2915             int domasklr = 0;
2916
2917             if (*c != '%')
2918               {
2919                 func (stream, "%c", *c);
2920                 continue;
2921               }
2922
2923             switch (*++c)
2924               {
2925               case '%':
2926                 func (stream, "%%");
2927                 break;
2928
2929               case 'c':
2930                 if (ifthen_state)
2931                   func (stream, "%s", arm_conditional[IFTHEN_COND]);
2932                 break;
2933
2934               case 'C':
2935                 if (ifthen_state)
2936                   func (stream, "%s", arm_conditional[IFTHEN_COND]);
2937                 else
2938                   func (stream, "s");
2939                 break;
2940
2941               case 'I':
2942                 {
2943                   unsigned int tmp;
2944
2945                   ifthen_next_state = given & 0xff;
2946                   for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
2947                     func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
2948                   func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
2949                 }
2950                 break;
2951
2952               case 'x':
2953                 if (ifthen_next_state)
2954                   func (stream, "\t; unpredictable branch in IT block\n");
2955                 break;
2956
2957               case 'X':
2958                 if (ifthen_state)
2959                   func (stream, "\t; unpredictable <IT:%s>",
2960                         arm_conditional[IFTHEN_COND]);
2961                 break;
2962
2963               case 'S':
2964                 {
2965                   long reg;
2966
2967                   reg = (given >> 3) & 0x7;
2968                   if (given & (1 << 6))
2969                     reg += 8;
2970
2971                   func (stream, "%s", arm_regnames[reg]);
2972                 }
2973                 break;
2974
2975               case 'D':
2976                 {
2977                   long reg;
2978
2979                   reg = given & 0x7;
2980                   if (given & (1 << 7))
2981                     reg += 8;
2982
2983                   func (stream, "%s", arm_regnames[reg]);
2984                 }
2985                 break;
2986
2987               case 'N':
2988                 if (given & (1 << 8))
2989                   domasklr = 1;
2990                 /* Fall through.  */
2991               case 'O':
2992                 if (*c == 'O' && (given & (1 << 8)))
2993                   domaskpc = 1;
2994                 /* Fall through.  */
2995               case 'M':
2996                 {
2997                   int started = 0;
2998                   int reg;
2999
3000                   func (stream, "{");
3001
3002                   /* It would be nice if we could spot
3003                      ranges, and generate the rS-rE format: */
3004                   for (reg = 0; (reg < 8); reg++)
3005                     if ((given & (1 << reg)) != 0)
3006                       {
3007                         if (started)
3008                           func (stream, ", ");
3009                         started = 1;
3010                         func (stream, "%s", arm_regnames[reg]);
3011                       }
3012
3013                   if (domasklr)
3014                     {
3015                       if (started)
3016                         func (stream, ", ");
3017                       started = 1;
3018                       func (stream, arm_regnames[14] /* "lr" */);
3019                     }
3020
3021                   if (domaskpc)
3022                     {
3023                       if (started)
3024                         func (stream, ", ");
3025                       func (stream, arm_regnames[15] /* "pc" */);
3026                     }
3027
3028                   func (stream, "}");
3029                 }
3030                 break;
3031
3032               case 'b':
3033                 /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
3034                 {
3035                   bfd_vma address = (pc + 4
3036                                      + ((given & 0x00f8) >> 2)
3037                                      + ((given & 0x0200) >> 3));
3038                   info->print_address_func (address, info);
3039                 }
3040                 break;
3041
3042               case 's':
3043                 /* Right shift immediate -- bits 6..10; 1-31 print
3044                    as themselves, 0 prints as 32.  */
3045                 {
3046                   long imm = (given & 0x07c0) >> 6;
3047                   if (imm == 0)
3048                     imm = 32;
3049                   func (stream, "#%ld", imm);
3050                 }
3051                 break;
3052
3053               case '0': case '1': case '2': case '3': case '4':
3054               case '5': case '6': case '7': case '8': case '9':
3055                 {
3056                   int bitstart = *c++ - '0';
3057                   int bitend = 0;
3058
3059                   while (*c >= '0' && *c <= '9')
3060                     bitstart = (bitstart * 10) + *c++ - '0';
3061
3062                   switch (*c)
3063                     {
3064                     case '-':
3065                       {
3066                         long reg;
3067
3068                         c++;
3069                         while (*c >= '0' && *c <= '9')
3070                           bitend = (bitend * 10) + *c++ - '0';
3071                         if (!bitend)
3072                           abort ();
3073                         reg = given >> bitstart;
3074                         reg &= (2 << (bitend - bitstart)) - 1;
3075                         switch (*c)
3076                           {
3077                           case 'r':
3078                             func (stream, "%s", arm_regnames[reg]);
3079                             break;
3080
3081                           case 'd':
3082                             func (stream, "%ld", reg);
3083                             break;
3084
3085                           case 'H':
3086                             func (stream, "%ld", reg << 1);
3087                             break;
3088
3089                           case 'W':
3090                             func (stream, "%ld", reg << 2);
3091                             break;
3092
3093                           case 'a':
3094                             /* PC-relative address -- the bottom two
3095                                bits of the address are dropped
3096                                before the calculation.  */
3097                             info->print_address_func
3098                               (((pc + 4) & ~3) + (reg << 2), info);
3099                             break;
3100
3101                           case 'x':
3102                             func (stream, "0x%04lx", reg);
3103                             break;
3104
3105                           case 'B':
3106                             reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3107                             info->print_address_func (reg * 2 + pc + 4, info);
3108                             break;
3109
3110                           case 'c':
3111                             func (stream, "%s", arm_conditional [reg]);
3112                             break;
3113
3114                           default:
3115                             abort ();
3116                           }
3117                       }
3118                       break;
3119
3120                     case '\'':
3121                       c++;
3122                       if ((given & (1 << bitstart)) != 0)
3123                         func (stream, "%c", *c);
3124                       break;
3125
3126                     case '?':
3127                       ++c;
3128                       if ((given & (1 << bitstart)) != 0)
3129                         func (stream, "%c", *c++);
3130                       else
3131                         func (stream, "%c", *++c);
3132                       break;
3133
3134                     default:
3135                       abort ();
3136                     }
3137                 }
3138                 break;
3139
3140               default:
3141                 abort ();
3142               }
3143           }
3144         return;
3145       }
3146
3147   /* No match.  */
3148   abort ();
3149 }
3150
3151 /* Return the name of an V7M special register.  */
3152 static const char *
3153 psr_name (int regno)
3154 {
3155   switch (regno)
3156     {
3157     case 0: return "APSR";
3158     case 1: return "IAPSR";
3159     case 2: return "EAPSR";
3160     case 3: return "PSR";
3161     case 5: return "IPSR";
3162     case 6: return "EPSR";
3163     case 7: return "IEPSR";
3164     case 8: return "MSP";
3165     case 9: return "PSP";
3166     case 16: return "PRIMASK";
3167     case 17: return "BASEPRI";
3168     case 18: return "BASEPRI_MASK";
3169     case 19: return "FAULTMASK";
3170     case 20: return "CONTROL";
3171     default: return "<unknown>";
3172     }
3173 }
3174
3175 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
3176
3177 static void
3178 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3179 {
3180   const struct opcode32 *insn;
3181   void *stream = info->stream;
3182   fprintf_ftype func = info->fprintf_func;
3183
3184   if (print_insn_coprocessor (pc, info, given, TRUE))
3185     return;
3186
3187   if (print_insn_neon (info, given, TRUE))
3188     return;
3189
3190   for (insn = thumb32_opcodes; insn->assembler; insn++)
3191     if ((given & insn->mask) == insn->value)
3192       {
3193         const char *c = insn->assembler;
3194         for (; *c; c++)
3195           {
3196             if (*c != '%')
3197               {
3198                 func (stream, "%c", *c);
3199                 continue;
3200               }
3201
3202             switch (*++c)
3203               {
3204               case '%':
3205                 func (stream, "%%");
3206                 break;
3207
3208               case 'c':
3209                 if (ifthen_state)
3210                   func (stream, "%s", arm_conditional[IFTHEN_COND]);
3211                 break;
3212
3213               case 'x':
3214                 if (ifthen_next_state)
3215                   func (stream, "\t; unpredictable branch in IT block\n");
3216                 break;
3217
3218               case 'X':
3219                 if (ifthen_state)
3220                   func (stream, "\t; unpredictable <IT:%s>",
3221                         arm_conditional[IFTHEN_COND]);
3222                 break;
3223
3224               case 'I':
3225                 {
3226                   unsigned int imm12 = 0;
3227                   imm12 |= (given & 0x000000ffu);
3228                   imm12 |= (given & 0x00007000u) >> 4;
3229                   imm12 |= (given & 0x04000000u) >> 15;
3230                   func (stream, "#%u\t; 0x%x", imm12, imm12);
3231                 }
3232                 break;
3233
3234               case 'M':
3235                 {
3236                   unsigned int bits = 0, imm, imm8, mod;
3237                   bits |= (given & 0x000000ffu);
3238                   bits |= (given & 0x00007000u) >> 4;
3239                   bits |= (given & 0x04000000u) >> 15;
3240                   imm8 = (bits & 0x0ff);
3241                   mod = (bits & 0xf00) >> 8;
3242                   switch (mod)
3243                     {
3244                     case 0: imm = imm8; break;
3245                     case 1: imm = ((imm8<<16) | imm8); break;
3246                     case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3247                     case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3248                     default:
3249                       mod  = (bits & 0xf80) >> 7;
3250                       imm8 = (bits & 0x07f) | 0x80;
3251                       imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3252                     }
3253                   func (stream, "#%u\t; 0x%x", imm, imm);
3254                 }
3255                 break;
3256                   
3257               case 'J':
3258                 {
3259                   unsigned int imm = 0;
3260                   imm |= (given & 0x000000ffu);
3261                   imm |= (given & 0x00007000u) >> 4;
3262                   imm |= (given & 0x04000000u) >> 15;
3263                   imm |= (given & 0x000f0000u) >> 4;
3264                   func (stream, "#%u\t; 0x%x", imm, imm);
3265                 }
3266                 break;
3267
3268               case 'K':
3269                 {
3270                   unsigned int imm = 0;
3271                   imm |= (given & 0x000f0000u) >> 16;
3272                   imm |= (given & 0x00000ff0u) >> 0;
3273                   imm |= (given & 0x0000000fu) << 12;
3274                   func (stream, "#%u\t; 0x%x", imm, imm);
3275                 }
3276                 break;
3277
3278               case 'S':
3279                 {
3280                   unsigned int reg = (given & 0x0000000fu);
3281                   unsigned int stp = (given & 0x00000030u) >> 4;
3282                   unsigned int imm = 0;
3283                   imm |= (given & 0x000000c0u) >> 6;
3284                   imm |= (given & 0x00007000u) >> 10;
3285
3286                   func (stream, "%s", arm_regnames[reg]);
3287                   switch (stp)
3288                     {
3289                     case 0:
3290                       if (imm > 0)
3291                         func (stream, ", lsl #%u", imm);
3292                       break;
3293
3294                     case 1:
3295                       if (imm == 0)
3296                         imm = 32;
3297                       func (stream, ", lsr #%u", imm);
3298                       break;
3299
3300                     case 2:
3301                       if (imm == 0)
3302                         imm = 32;
3303                       func (stream, ", asr #%u", imm);
3304                       break;
3305
3306                     case 3:
3307                       if (imm == 0)
3308                         func (stream, ", rrx");
3309                       else
3310                         func (stream, ", ror #%u", imm);
3311                     }
3312                 }
3313                 break;
3314
3315               case 'a':
3316                 {
3317                   unsigned int Rn  = (given & 0x000f0000) >> 16;
3318                   unsigned int U   = (given & 0x00800000) >> 23;
3319                   unsigned int op  = (given & 0x00000f00) >> 8;
3320                   unsigned int i12 = (given & 0x00000fff);
3321                   unsigned int i8  = (given & 0x000000ff);
3322                   bfd_boolean writeback = FALSE, postind = FALSE;
3323                   int offset = 0;
3324
3325                   func (stream, "[%s", arm_regnames[Rn]);
3326                   if (U) /* 12-bit positive immediate offset */
3327                     offset = i12;
3328                   else if (Rn == 15) /* 12-bit negative immediate offset */
3329                     offset = -(int)i12;
3330                   else if (op == 0x0) /* shifted register offset */
3331                     {
3332                       unsigned int Rm = (i8 & 0x0f);
3333                       unsigned int sh = (i8 & 0x30) >> 4;
3334                       func (stream, ", %s", arm_regnames[Rm]);
3335                       if (sh)
3336                         func (stream, ", lsl #%u", sh);
3337                       func (stream, "]");
3338                       break;
3339                     }
3340                   else switch (op)
3341                     {
3342                     case 0xE:  /* 8-bit positive immediate offset */
3343                       offset = i8;
3344                       break;
3345
3346                     case 0xC:  /* 8-bit negative immediate offset */
3347                       offset = -i8;
3348                       break;
3349
3350                     case 0xF:  /* 8-bit + preindex with wb */
3351                       offset = i8;
3352                       writeback = TRUE;
3353                       break;
3354
3355                     case 0xD:  /* 8-bit - preindex with wb */
3356                       offset = -i8;
3357                       writeback = TRUE;
3358                       break;
3359
3360                     case 0xB:  /* 8-bit + postindex */
3361                       offset = i8;
3362                       postind = TRUE;
3363                       break;
3364
3365                     case 0x9:  /* 8-bit - postindex */
3366                       offset = -i8;
3367                       postind = TRUE;
3368                       break;
3369
3370                     default:
3371                       func (stream, ", <undefined>]");
3372                       goto skip;
3373                     }
3374
3375                   if (postind)
3376                     func (stream, "], #%d", offset);
3377                   else
3378                     {
3379                       if (offset)
3380                         func (stream, ", #%d", offset);
3381                       func (stream, writeback ? "]!" : "]");
3382                     }
3383
3384                   if (Rn == 15)
3385                     {
3386                       func (stream, "\t; ");
3387                       info->print_address_func (((pc + 4) & ~3) + offset, info);
3388                     }
3389                 }
3390               skip:
3391                 break;
3392
3393               case 'A':
3394                 {
3395                   unsigned int P   = (given & 0x01000000) >> 24;
3396                   unsigned int U   = (given & 0x00800000) >> 23;
3397                   unsigned int W   = (given & 0x00400000) >> 21;
3398                   unsigned int Rn  = (given & 0x000f0000) >> 16;
3399                   unsigned int off = (given & 0x000000ff);
3400
3401                   func (stream, "[%s", arm_regnames[Rn]);
3402                   if (P)
3403                     {
3404                       if (off || !U)
3405                         func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3406                       func (stream, "]");
3407                       if (W)
3408                         func (stream, "!");
3409                     }
3410                   else
3411                     {
3412                       func (stream, "], ");
3413                       if (W)
3414                         func (stream, "#%c%u", U ? '+' : '-', off * 4);
3415                       else
3416                         func (stream, "{%u}", off);
3417                     }
3418                 }
3419                 break;
3420
3421               case 'w':
3422                 {
3423                   unsigned int Sbit = (given & 0x01000000) >> 24;
3424                   unsigned int type = (given & 0x00600000) >> 21;
3425                   switch (type)
3426                     {
3427                     case 0: func (stream, Sbit ? "sb" : "b"); break;
3428                     case 1: func (stream, Sbit ? "sh" : "h"); break;
3429                     case 2:
3430                       if (Sbit)
3431                         func (stream, "??");
3432                       break;
3433                     case 3:
3434                       func (stream, "??");
3435                       break;
3436                     }
3437                 }
3438                 break;
3439
3440               case 'm':
3441                 {
3442                   int started = 0;
3443                   int reg;
3444
3445                   func (stream, "{");
3446                   for (reg = 0; reg < 16; reg++)
3447                     if ((given & (1 << reg)) != 0)
3448                       {
3449                         if (started)
3450                           func (stream, ", ");
3451                         started = 1;
3452                         func (stream, "%s", arm_regnames[reg]);
3453                       }
3454                   func (stream, "}");
3455                 }
3456                 break;
3457
3458               case 'E':
3459                 {
3460                   unsigned int msb = (given & 0x0000001f);
3461                   unsigned int lsb = 0;
3462                   lsb |= (given & 0x000000c0u) >> 6;
3463                   lsb |= (given & 0x00007000u) >> 10;
3464                   func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3465                 }
3466                 break;
3467
3468               case 'F':
3469                 {
3470                   unsigned int width = (given & 0x0000001f) + 1;
3471                   unsigned int lsb = 0;
3472                   lsb |= (given & 0x000000c0u) >> 6;
3473                   lsb |= (given & 0x00007000u) >> 10;
3474                   func (stream, "#%u, #%u", lsb, width);
3475                 }
3476                 break;
3477
3478               case 'b':
3479                 {
3480                   unsigned int S = (given & 0x04000000u) >> 26;
3481                   unsigned int J1 = (given & 0x00002000u) >> 13;
3482                   unsigned int J2 = (given & 0x00000800u) >> 11;
3483                   int offset = 0;
3484
3485                   offset |= !S << 20;
3486                   offset |= J2 << 19;
3487                   offset |= J1 << 18;
3488                   offset |= (given & 0x003f0000) >> 4;
3489                   offset |= (given & 0x000007ff) << 1;
3490                   offset -= (1 << 20);
3491
3492                   info->print_address_func (pc + 4 + offset, info);
3493                 }
3494                 break;
3495
3496               case 'B':
3497                 {
3498                   unsigned int S = (given & 0x04000000u) >> 26;
3499                   unsigned int I1 = (given & 0x00002000u) >> 13;
3500                   unsigned int I2 = (given & 0x00000800u) >> 11;
3501                   int offset = 0;
3502
3503                   offset |= !S << 24;
3504                   offset |= !(I1 ^ S) << 23;
3505                   offset |= !(I2 ^ S) << 22;
3506                   offset |= (given & 0x03ff0000u) >> 4;
3507                   offset |= (given & 0x000007ffu) << 1;
3508                   offset -= (1 << 24);
3509                   offset += pc + 4;
3510
3511                   /* BLX target addresses are always word aligned.  */
3512                   if ((given & 0x00001000u) == 0)
3513                       offset &= ~2u;
3514
3515                   info->print_address_func (offset, info);
3516                 }
3517                 break;
3518
3519               case 's':
3520                 {
3521                   unsigned int shift = 0;
3522                   shift |= (given & 0x000000c0u) >> 6;
3523                   shift |= (given & 0x00007000u) >> 10;
3524                   if (given & 0x00200000u)
3525                     func (stream, ", asr #%u", shift);
3526                   else if (shift)
3527                     func (stream, ", lsl #%u", shift);
3528                   /* else print nothing - lsl #0 */
3529                 }
3530                 break;
3531
3532               case 'R':
3533                 {
3534                   unsigned int rot = (given & 0x00000030) >> 4;
3535                   if (rot)
3536                     func (stream, ", ror #%u", rot * 8);
3537                 }
3538                 break;
3539
3540               case 'U':
3541                 switch (given & 0xf)
3542                   {
3543                   case 0xf: func(stream, "sy"); break;
3544                   case 0x7: func(stream, "un"); break;
3545                   case 0xe: func(stream, "st"); break;
3546                   case 0x6: func(stream, "unst"); break;
3547                   default:
3548                     func(stream, "#%d", (int)given & 0xf);
3549                     break;
3550                   }
3551                 break;
3552
3553               case 'C':
3554                 if ((given & 0xff) == 0)
3555                   {
3556                     func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3557                     if (given & 0x800)
3558                       func (stream, "f");
3559                     if (given & 0x400)
3560                       func (stream, "s");
3561                     if (given & 0x200)
3562                       func (stream, "x");
3563                     if (given & 0x100)
3564                       func (stream, "c");
3565                   }
3566                 else
3567                   {
3568                     func (stream, psr_name (given & 0xff));
3569                   }
3570                 break;
3571
3572               case 'D':
3573                 if ((given & 0xff) == 0)
3574                   func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3575                 else
3576                   func (stream, psr_name (given & 0xff));
3577                 break;
3578
3579               case '0': case '1': case '2': case '3': case '4':
3580               case '5': case '6': case '7': case '8': case '9':
3581                 {
3582                   int width;
3583                   unsigned long val;
3584
3585                   c = arm_decode_bitfield (c, given, &val, &width);
3586                         
3587                   switch (*c)
3588                     {
3589                     case 'd': func (stream, "%lu", val); break;
3590                     case 'W': func (stream, "%lu", val * 4); break;
3591                     case 'r': func (stream, "%s", arm_regnames[val]); break;
3592
3593                     case 'c':
3594                       func (stream, "%s", arm_conditional[val]);
3595                       break;
3596
3597                     case '\'':
3598                       c++;
3599                       if (val == ((1ul << width) - 1))
3600                         func (stream, "%c", *c);
3601                       break;
3602                       
3603                     case '`':
3604                       c++;
3605                       if (val == 0)
3606                         func (stream, "%c", *c);
3607                       break;
3608
3609                     case '?':
3610                       func (stream, "%c", c[(1 << width) - (int)val]);
3611                       c += 1 << width;
3612                       break;
3613
3614                     default:
3615                       abort ();
3616                     }
3617                 }
3618                 break;
3619
3620               default:
3621                 abort ();
3622               }
3623           }
3624         return;
3625       }
3626
3627   /* No match.  */
3628   abort ();
3629 }
3630
3631 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3632    being displayed in symbol relative addresses.  */
3633
3634 bfd_boolean
3635 arm_symbol_is_valid (asymbol * sym,
3636                      struct disassemble_info * info ATTRIBUTE_UNUSED)
3637 {
3638   const char * name;
3639   
3640   if (sym == NULL)
3641     return FALSE;
3642
3643   name = bfd_asymbol_name (sym);
3644
3645   return (name && *name != '$');
3646 }
3647
3648 /* Parse an individual disassembler option.  */
3649
3650 void
3651 parse_arm_disassembler_option (char *option)
3652 {
3653   if (option == NULL)
3654     return;
3655
3656   if (strneq (option, "reg-names-", 10))
3657     {
3658       int i;
3659
3660       option += 10;
3661
3662       for (i = NUM_ARM_REGNAMES; i--;)
3663         if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3664           {
3665             regname_selected = i;
3666             break;
3667           }
3668
3669       if (i < 0)
3670         /* XXX - should break 'option' at following delimiter.  */
3671         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3672     }
3673   else if (strneq (option, "force-thumb", 11))
3674     force_thumb = 1;
3675   else if (strneq (option, "no-force-thumb", 14))
3676     force_thumb = 0;
3677   else
3678     /* XXX - should break 'option' at following delimiter.  */
3679     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3680
3681   return;
3682 }
3683
3684 /* Parse the string of disassembler options, spliting it at whitespaces
3685    or commas.  (Whitespace separators supported for backwards compatibility).  */
3686
3687 static void
3688 parse_disassembler_options (char *options)
3689 {
3690   if (options == NULL)
3691     return;
3692
3693   while (*options)
3694     {
3695       parse_arm_disassembler_option (options);
3696
3697       /* Skip forward to next seperator.  */
3698       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3699         ++ options;
3700       /* Skip forward past seperators.  */
3701       while (ISSPACE (*options) || (*options == ','))
3702         ++ options;      
3703     }
3704 }
3705
3706 /* Search back through the insn stream to determine if this instruction is
3707    conditionally executed.  */
3708 static void
3709 find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3710                    bfd_boolean little)
3711 {
3712   unsigned char b[2];
3713   unsigned int insn;
3714   int status;
3715   /* COUNT is twice the number of instructions seen.  It will be odd if we
3716      just crossed an instruction boundary.  */
3717   int count;
3718   int it_count;
3719   unsigned int seen_it;
3720   bfd_vma addr;
3721
3722   ifthen_address = pc;
3723   ifthen_state = 0;
3724
3725   addr = pc;
3726   count = 1;
3727   it_count = 0;
3728   seen_it = 0;
3729   /* Scan backwards looking for IT instructions, keeping track of where
3730      instruction boundaries are.  We don't know if something is actually an
3731      IT instruction until we find a definite instruction boundary.  */
3732   for (;;)
3733     {
3734       if (addr == 0 || info->symbol_at_address_func(addr, info))
3735         {
3736           /* A symbol must be on an instruction boundary, and will not
3737              be within an IT block.  */
3738           if (seen_it && (count & 1))
3739             break;
3740
3741           return;
3742         }
3743       addr -= 2;
3744       status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3745       if (status)
3746         return;
3747
3748       if (little)
3749         insn = (b[0]) | (b[1] << 8);
3750       else
3751         insn = (b[1]) | (b[0] << 8);
3752       if (seen_it)
3753         {
3754           if ((insn & 0xf800) < 0xe800)
3755             {
3756               /* Addr + 2 is an instruction boundary.  See if this matches
3757                  the expected boundary based on the position of the last
3758                  IT candidate.  */
3759               if (count & 1)
3760                 break;
3761               seen_it = 0;
3762             }
3763         }
3764       if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3765         {
3766           /* This could be an IT instruction.  */
3767           seen_it = insn;
3768           it_count = count >> 1;
3769         }
3770       if ((insn & 0xf800) >= 0xe800)
3771         count++;
3772       else
3773         count = (count + 2) | 1;
3774       /* IT blocks contain at most 4 instructions.  */
3775       if (count >= 8 && !seen_it)
3776         return;
3777     }
3778   /* We found an IT instruction.  */
3779   ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3780   if ((ifthen_state & 0xf) == 0)
3781     ifthen_state = 0;
3782 }
3783
3784 /* NOTE: There are no checks in these routines that
3785    the relevant number of data bytes exist.  */
3786
3787 static int
3788 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3789 {
3790   unsigned char b[4];
3791   long          given;
3792   int           status;
3793   int           is_thumb;
3794   int           size;
3795   void          (*printer) (bfd_vma, struct disassemble_info *, long);
3796
3797   if (info->disassembler_options)
3798     {
3799       parse_disassembler_options (info->disassembler_options);
3800
3801       /* To avoid repeated parsing of these options, we remove them here.  */
3802       info->disassembler_options = NULL;
3803     }
3804
3805   is_thumb = force_thumb;
3806
3807   if (!is_thumb && info->symbols != NULL)
3808     {
3809       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3810         {
3811           coff_symbol_type * cs;
3812
3813           cs = coffsymbol (*info->symbols);
3814           is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
3815                       || cs->native->u.syment.n_sclass == C_THUMBSTAT
3816                       || cs->native->u.syment.n_sclass == C_THUMBLABEL
3817                       || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
3818                       || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
3819         }
3820       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
3821         {
3822           elf_symbol_type *  es;
3823           unsigned int       type;
3824
3825           es = *(elf_symbol_type **)(info->symbols);
3826           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3827
3828           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
3829         }
3830     }
3831
3832   info->display_endian  = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
3833   info->bytes_per_line = 4;
3834
3835   if (!is_thumb)
3836     {
3837       /* In ARM mode endianness is a straightforward issue: the instruction
3838          is four bytes long and is either ordered 0123 or 3210.  */
3839       printer = print_insn_arm;
3840       info->bytes_per_chunk = 4;
3841       size = 4;
3842
3843       status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
3844       if (little)
3845         given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
3846       else
3847         given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
3848     }
3849   else
3850     {
3851       /* In Thumb mode we have the additional wrinkle of two
3852          instruction lengths.  Fortunately, the bits that determine
3853          the length of the current instruction are always to be found
3854          in the first two bytes.  */
3855       printer = print_insn_thumb16;
3856       info->bytes_per_chunk = 2;
3857       size = 2;
3858
3859       status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
3860       if (little)
3861         given = (b[0]) | (b[1] << 8);
3862       else
3863         given = (b[1]) | (b[0] << 8);
3864
3865       if (!status)
3866         {
3867           /* These bit patterns signal a four-byte Thumb
3868              instruction.  */
3869           if ((given & 0xF800) == 0xF800
3870               || (given & 0xF800) == 0xF000
3871               || (given & 0xF800) == 0xE800)
3872             {
3873               status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
3874               if (little)
3875                 given = (b[0]) | (b[1] << 8) | (given << 16);
3876               else
3877                 given = (b[1]) | (b[0] << 8) | (given << 16);
3878
3879               printer = print_insn_thumb32;
3880               size = 4;
3881             }
3882         }
3883
3884       if (ifthen_address != pc)
3885         find_ifthen_state(pc, info, little);
3886
3887       if (ifthen_state)
3888         {
3889           if ((ifthen_state & 0xf) == 0x8)
3890             ifthen_next_state = 0;
3891           else
3892             ifthen_next_state = (ifthen_state & 0xe0)
3893                                 | ((ifthen_state & 0xf) << 1);
3894         }
3895     }
3896
3897   if (status)
3898     {
3899       info->memory_error_func (status, pc, info);
3900       return -1;
3901     }
3902   if (info->flags & INSN_HAS_RELOC)
3903     /* If the instruction has a reloc associated with it, then
3904        the offset field in the instruction will actually be the
3905        addend for the reloc.  (We are using REL type relocs).
3906        In such cases, we can ignore the pc when computing
3907        addresses, since the addend is not currently pc-relative.  */
3908     pc = 0;
3909
3910   printer (pc, info, given);
3911
3912   if (is_thumb)
3913     {
3914       ifthen_state = ifthen_next_state;
3915       ifthen_address += size;
3916     }
3917   return size;
3918 }
3919
3920 int
3921 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3922 {
3923   return print_insn (pc, info, FALSE);
3924 }
3925
3926 int
3927 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3928 {
3929   return print_insn (pc, info, TRUE);
3930 }
3931
3932 void
3933 print_arm_disassembler_options (FILE *stream)
3934 {
3935   int i;
3936
3937   fprintf (stream, _("\n\
3938 The following ARM specific disassembler options are supported for use with\n\
3939 the -M switch:\n"));
3940
3941   for (i = NUM_ARM_REGNAMES; i--;)
3942     fprintf (stream, "  reg-names-%s %*c%s\n",
3943              regnames[i].name,
3944              (int)(14 - strlen (regnames[i].name)), ' ',
3945              regnames[i].description);
3946
3947   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
3948   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
3949 }