OSDN Git Service

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