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