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