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