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