PR 10288
[external/binutils.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2    Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3    2004, 2007, 2009  Free Software Foundation, Inc.
4    Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5    Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7    This file is part of libopcodes.
8
9    This library is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13
14    It is distributed in the hope that it will be useful, but WITHOUT
15    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
17    License for more details.
18
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22    MA 02110-1301, USA.  */
23
24 #include "sysdep.h"
25
26 #include "dis-asm.h"
27 #include "opcode/arm.h"
28 #include "opintl.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
31
32 /* FIXME: This shouldn't be done here.  */
33 #include "coff/internal.h"
34 #include "libcoff.h"
35 #include "elf-bfd.h"
36 #include "elf/internal.h"
37 #include "elf/arm.h"
38
39 /* FIXME: Belongs in global header.  */
40 #ifndef strneq
41 #define strneq(a,b,n)   (strncmp ((a), (b), (n)) == 0)
42 #endif
43
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a)     (sizeof (a) / sizeof (a)[0])
46 #endif
47
48 struct opcode32
49 {
50   unsigned long arch;           /* Architecture defining this insn.  */
51   unsigned long value;          /* If arch == 0 then value is a sentinel.  */
52   unsigned long mask;           /* Recognise insn if (op & mask) == value.  */
53   const char *  assembler;      /* How to disassemble this insn.  */
54 };
55
56 struct opcode16
57 {
58   unsigned long arch;           /* Architecture defining this insn.  */
59   unsigned short value, mask;   /* Recognise insn if (op&mask)==value.  */
60   const char *assembler;        /* How to disassemble this insn.  */
61 };
62
63 /* print_insn_coprocessor recognizes the following format control codes:
64
65    %%                   %
66
67    %c                   print condition code (always bits 28-31 in ARM mode)
68    %q                   print shifter argument
69    %u                   print condition code (unconditional in ARM mode)
70    %A                   print address for ldc/stc/ldf/stf instruction
71    %B                   print vstm/vldm register list
72    %C                   print vstr/vldr address operand
73    %I                   print cirrus signed shift immediate: bits 0..3|4..6
74    %F                   print the COUNT field of a LFM/SFM instruction.
75    %P                   print floating point precision in arithmetic insn
76    %Q                   print floating point precision in ldf/stf insn
77    %R                   print floating point rounding mode
78
79    %<bitfield>r         print as an ARM register
80    %<bitfield>d         print the bitfield in decimal
81    %<bitfield>k         print immediate for VFPv3 conversion instruction
82    %<bitfield>x         print the bitfield in hex
83    %<bitfield>X         print the bitfield as 1 hex digit without leading "0x"
84    %<bitfield>f         print a floating point constant if >7 else a
85                         floating point register
86    %<bitfield>w         print as an iWMMXt width field - [bhwd]ss/us
87    %<bitfield>g         print as an iWMMXt 64-bit register
88    %<bitfield>G         print as an iWMMXt general purpose or control register
89    %<bitfield>D         print as a NEON D register
90    %<bitfield>Q         print as a NEON Q register
91
92    %y<code>             print a single precision VFP reg.
93                           Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
94    %z<code>             print a double precision VFP reg
95                           Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
96
97    %<bitfield>'c        print specified char iff bitfield is all ones
98    %<bitfield>`c        print specified char iff bitfield is all zeroes
99    %<bitfield>?ab...    select from array of values in big endian order
100    
101    %L                   print as an iWMMXt N/M width field.
102    %Z                   print the Immediate of a WSHUFH instruction.
103    %l                   like 'A' except use byte offsets for 'B' & 'H'
104                         versions.
105    %i                   print 5-bit immediate in bits 8,3..0
106                         (print "32" when 0)
107    %r                   print register offset address for wldt/wstr instruction.  */
108
109 enum
110 {
111   SENTINEL_IWMMXT_START = 1,
112   SENTINEL_IWMMXT_END,
113   SENTINEL_GENERIC_START
114 } opcode_sentinels;
115
116 #define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
117
118 /* Common coprocessor opcodes shared between Arm and Thumb-2.  */
119
120 static const struct opcode32 coprocessor_opcodes[] =
121 {
122   /* XScale instructions.  */
123   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
124   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
125   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
126   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
127   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
128
129   /* Intel Wireless MMX technology instructions.  */
130   { 0, SENTINEL_IWMMXT_START, 0, "" },
131   {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
132   {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
133   {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
134   {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
135   {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
136   {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
137   {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
138   {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
139   {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
140   {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
141   {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
142   {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
143   {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
144   {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
145   {ARM_CEXT_XSCALE, 0x0e130190, 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, 0x0f300ff0, "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, 0x0c500000, "strb%c\t%12-15r, %a"},
1007   {ARM_EXT_V1, 0x000000b0, 0x0e1000f0, "strh%c\t%12-15r, %s"},
1008   {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1009   {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1010   {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1011   {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1012   {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1013   {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1014   {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1015   {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1016   {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1017   {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1018   {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1019   {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
1020   {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
1021   {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
1022   {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
1023   {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1024   {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1025   {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1026   {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1027   {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1028   {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1029   {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1030   {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1031   {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1032   {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
1033   {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1034   {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1035   {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1036   {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1037   {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1038   {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1039   {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1040   {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1041   {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1042   {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1043   {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1044
1045   /* The rest.  */
1046   {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1047   {0, 0x00000000, 0x00000000, 0}
1048 };
1049
1050 /* print_insn_thumb16 recognizes the following format control codes:
1051
1052    %S                   print Thumb register (bits 3..5 as high number if bit 6 set)
1053    %D                   print Thumb register (bits 0..2 as high number if bit 7 set)
1054    %<bitfield>I         print bitfield as a signed decimal
1055                                 (top bit of range being the sign bit)
1056    %N                   print Thumb register mask (with LR)
1057    %O                   print Thumb register mask (with PC)
1058    %M                   print Thumb register mask
1059    %b                   print CZB's 6-bit unsigned branch destination
1060    %s                   print Thumb right-shift immediate (6..10; 0 == 32).
1061    %c                   print the condition code
1062    %C                   print the condition code, or "s" if not conditional
1063    %x                   print warning if conditional an not at end of IT block"
1064    %X                   print "\t; unpredictable <IT:code>" if conditional
1065    %I                   print IT instruction suffix and operands
1066    %<bitfield>r         print bitfield as an ARM register
1067    %<bitfield>d         print bitfield as a decimal
1068    %<bitfield>H         print (bitfield * 2) as a decimal
1069    %<bitfield>W         print (bitfield * 4) as a decimal
1070    %<bitfield>a         print (bitfield * 4) as a pc-rel offset + decoded symbol
1071    %<bitfield>B         print Thumb branch destination (signed displacement)
1072    %<bitfield>c         print bitfield as a condition code
1073    %<bitnum>'c          print specified char iff bit is one
1074    %<bitnum>?ab         print a if bit is one else print b.  */
1075
1076 static const struct opcode16 thumb_opcodes[] =
1077 {
1078   /* Thumb instructions.  */
1079
1080   /* ARM V6K no-argument instructions.  */
1081   {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1082   {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1083   {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1084   {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1085   {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1086   {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1087
1088   /* ARM V6T2 instructions.  */
1089   {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1090   {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1091   {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1092
1093   /* ARM V6.  */
1094   {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1095   {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1096   {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1097   {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1098   {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1099   {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1100   {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1101   {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1102   {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1103   {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1104   {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1105
1106   /* ARM V5 ISA extends Thumb.  */
1107   {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional.  */
1108   /* This is BLX(2).  BLX(1) is a 32-bit instruction.  */
1109   {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"},      /* note: 4 bit register number.  */
1110   /* ARM V4T ISA (Thumb v1).  */
1111   {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1112   /* Format 4.  */
1113   {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1114   {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1115   {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1116   {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1117   {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1118   {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1119   {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1120   {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1121   {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1122   {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1123   {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1124   {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1125   {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1126   {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1127   {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1128   {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1129   /* format 13 */
1130   {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1131   {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1132   /* format 5 */
1133   {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1134   {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1135   {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1136   {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1137   /* format 14 */
1138   {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1139   {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1140   /* format 2 */
1141   {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1142   {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1143   {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1144   {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1145   /* format 8 */
1146   {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1147   {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1148   {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1149   /* format 7 */
1150   {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1151   {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1152   /* format 1 */
1153   {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1154   {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1155   {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1156   /* format 3 */
1157   {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1158   {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1159   {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1160   {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1161   /* format 6 */
1162   {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"},  /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1163   /* format 9 */
1164   {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1165   {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1166   {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1167   {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1168   /* format 10 */
1169   {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1170   {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1171   /* format 11 */
1172   {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1173   {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1174   /* format 12 */
1175   {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1176   {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1177   /* format 15 */
1178   {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1179   {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1180   /* format 17 */
1181   {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1182   /* format 16 */
1183   {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1184   {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1185   /* format 18 */
1186   {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1187
1188   /* The E800 .. FFFF range is unconditionally redirected to the
1189      32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1190      are processed via that table.  Thus, we can never encounter a
1191      bare "second half of BL/BLX(1)" instruction here.  */
1192   {ARM_EXT_V1,  0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1193   {0, 0, 0, 0}
1194 };
1195
1196 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1197    We adopt the convention that hw1 is the high 16 bits of .value and
1198    .mask, hw2 the low 16 bits.
1199
1200    print_insn_thumb32 recognizes the following format control codes:
1201
1202        %%               %
1203
1204        %I               print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1205        %M               print a modified 12-bit immediate (same location)
1206        %J               print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1207        %K               print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1208        %S               print a possibly-shifted Rm
1209
1210        %a               print the address of a plain load/store
1211        %w               print the width and signedness of a core load/store
1212        %m               print register mask for ldm/stm
1213
1214        %E               print the lsb and width fields of a bfc/bfi instruction
1215        %F               print the lsb and width fields of a sbfx/ubfx instruction
1216        %b               print a conditional branch offset
1217        %B               print an unconditional branch offset
1218        %s               print the shift field of an SSAT instruction
1219        %R               print the rotation field of an SXT instruction
1220        %U               print barrier type.
1221        %P               print address for pli instruction.
1222        %c               print the condition code
1223        %x               print warning if conditional an not at end of IT block"
1224        %X               print "\t; unpredictable <IT:code>" if conditional
1225
1226        %<bitfield>d     print bitfield in decimal
1227        %<bitfield>W     print bitfield*4 in decimal
1228        %<bitfield>r     print bitfield as an ARM register
1229        %<bitfield>c     print bitfield as a condition code
1230
1231        %<bitfield>'c    print specified char iff bitfield is all ones
1232        %<bitfield>`c    print specified char iff bitfield is all zeroes
1233        %<bitfield>?ab... select from array of values in big endian order
1234
1235    With one exception at the bottom (done because BL and BLX(1) need
1236    to come dead last), this table was machine-sorted first in
1237    decreasing order of number of bits set in the mask, then in
1238    increasing numeric order of mask, then in increasing numeric order
1239    of opcode.  This order is not the clearest for a human reader, but
1240    is guaranteed never to catch a special-case bit pattern with a more
1241    general mask, which is important, because this instruction encoding
1242    makes heavy use of special-case bit patterns.  */
1243 static const struct opcode32 thumb32_opcodes[] =
1244 {
1245   /* V7 instructions.  */
1246   {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1247   {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1248   {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1249   {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1250   {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1251   {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1252   {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1253
1254   /* Instructions defined in the basic V6T2 set.  */
1255   {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1256   {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1257   {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1258   {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1259   {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1260   {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1261
1262   {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1263   {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1264   {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1265   {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1266   {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1267   {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1268   {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1269   {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1270   {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1271   {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1272   {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1273   {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1274   {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1275   {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1276   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1277   {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1278   {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1279   {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1280   {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1281   {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1282   {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1283   {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1284   {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1285   {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1286   {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1287   {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1288   {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1289   {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1290   {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1291   {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1292   {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1293   {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1294   {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1295   {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1296   {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1297   {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
1298   {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1299   {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1300   {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1301   {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1302   {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1303   {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1304   {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1305   {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1306   {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1307   {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1308   {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1309   {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1310   {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1311   {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1312   {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1313   {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1314   {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1315   {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1316   {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1317   {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1318   {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1319   {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1320   {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1321   {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1322   {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1323   {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1324   {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1325   {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1326   {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1327   {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1328   {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1329   {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1330   {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1331   {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1332   {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1333   {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1334   {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1335   {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1336   {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1337   {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1338   {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1339   {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1340   {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1341   {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1342   {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1343   {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1344   {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1345   {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1346   {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1347   {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1348   {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1349   {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1350   {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1351   {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1352   {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1353   {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1354   {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1355   {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1356   {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1357   {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1358   {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1359   {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1360   {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1361   {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1362   {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1363   {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1364   {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1365   {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1366   {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1367   {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1368   {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1369   {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1370   {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1371   {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1372   {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1373   {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1374   {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1375   {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1376   {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1377   {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1378   {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1379   {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1380   {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1381   {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1382   {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1383   {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1384   {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1385   {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1386   {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1387   {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1388   {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1389   {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1390   {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1391   {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1392   {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1393   {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1394   {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1395   {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1396   {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1397   {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1398   {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1399   {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1400   {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1401   {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1402   {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1403   {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1404   {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1405   {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1406   {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1407   {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1408   {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1409   {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1410   {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1411   {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1412   {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1413   {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1414   {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1415   {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1416   {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1417   {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1418   {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1419   {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1420   {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1421   {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1422   {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1423   {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1424   {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1425   {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1426   {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1427   {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1428   {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1429   {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1430   {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1431   {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1432   {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1433   {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1434
1435   /* Filter out Bcc with cond=E or F, which are used for other instructions.  */
1436   {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1437   {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1438   {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1439   {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1440
1441   /* These have been 32-bit since the invention of Thumb.  */
1442   {ARM_EXT_V4T,  0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1443   {ARM_EXT_V4T,  0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1444
1445   /* Fallback.  */
1446   {ARM_EXT_V1,   0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1447   {0, 0, 0, 0}
1448 };
1449    
1450 static const char *const arm_conditional[] =
1451 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1452  "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1453
1454 static const char *const arm_fp_const[] =
1455 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1456
1457 static const char *const arm_shift[] =
1458 {"lsl", "lsr", "asr", "ror"};
1459
1460 typedef struct
1461 {
1462   const char *name;
1463   const char *description;
1464   const char *reg_names[16];
1465 }
1466 arm_regname;
1467
1468 static const arm_regname regnames[] =
1469 {
1470   { "raw" , "Select raw register names",
1471     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1472   { "gcc",  "Select register names used by GCC",
1473     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1474   { "std",  "Select register names used in ARM's ISA documentation",
1475     { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp",  "lr",  "pc" }},
1476   { "apcs", "Select register names used in the APCS",
1477     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl",  "fp",  "ip",  "sp",  "lr",  "pc" }},
1478   { "atpcs", "Select register names used in the ATPCS",
1479     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7",  "v8",  "IP",  "SP",  "LR",  "PC" }},
1480   { "special-atpcs", "Select special register names used in the ATPCS",
1481     { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL",  "FP",  "IP",  "SP",  "LR",  "PC" }},
1482 };
1483
1484 static const char *const iwmmxt_wwnames[] =
1485 {"b", "h", "w", "d"};
1486
1487 static const char *const iwmmxt_wwssnames[] =
1488 {"b", "bus", "bc", "bss",
1489  "h", "hus", "hc", "hss",
1490  "w", "wus", "wc", "wss",
1491  "d", "dus", "dc", "dss"
1492 };
1493
1494 static const char *const iwmmxt_regnames[] =
1495 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1496   "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1497 };
1498
1499 static const char *const iwmmxt_cregnames[] =
1500 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1501   "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1502 };
1503
1504 /* Default to GCC register name set.  */
1505 static unsigned int regname_selected = 1;
1506
1507 #define NUM_ARM_REGNAMES  NUM_ELEM (regnames)
1508 #define arm_regnames      regnames[regname_selected].reg_names
1509
1510 static bfd_boolean force_thumb = FALSE;
1511
1512 /* Current IT instruction state.  This contains the same state as the IT
1513    bits in the CPSR.  */
1514 static unsigned int ifthen_state;
1515 /* IT state for the next instruction.  */
1516 static unsigned int ifthen_next_state;
1517 /* The address of the insn for which the IT state is valid.  */
1518 static bfd_vma ifthen_address;
1519 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1520
1521 /* Cached mapping symbol state.  */
1522 enum map_type
1523 {
1524   MAP_ARM,
1525   MAP_THUMB,
1526   MAP_DATA
1527 };
1528
1529 enum map_type last_type;
1530 int last_mapping_sym = -1;
1531 bfd_vma last_mapping_addr = 0;
1532
1533 \f
1534 /* Functions.  */
1535 int
1536 get_arm_regname_num_options (void)
1537 {
1538   return NUM_ARM_REGNAMES;
1539 }
1540
1541 int
1542 set_arm_regname_option (int option)
1543 {
1544   int old = regname_selected;
1545   regname_selected = option;
1546   return old;
1547 }
1548
1549 int
1550 get_arm_regnames (int option,
1551                   const char **setname,
1552                   const char **setdescription,
1553                   const char *const **register_names)
1554 {
1555   *setname = regnames[option].name;
1556   *setdescription = regnames[option].description;
1557   *register_names = regnames[option].reg_names;
1558   return 16;
1559 }
1560
1561 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1562    Returns pointer to following character of the format string and
1563    fills in *VALUEP and *WIDTHP with the extracted value and number of
1564    bits extracted.  WIDTHP can be NULL.  */
1565
1566 static const char *
1567 arm_decode_bitfield (const char *ptr,
1568                      unsigned long insn,
1569                      unsigned long *valuep,
1570                      int *widthp)
1571 {
1572   unsigned long value = 0;
1573   int width = 0;
1574   
1575   do 
1576     {
1577       int start, end;
1578       int bits;
1579
1580       for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1581         start = start * 10 + *ptr - '0';
1582       if (*ptr == '-')
1583         for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1584           end = end * 10 + *ptr - '0';
1585       else
1586         end = start;
1587       bits = end - start;
1588       if (bits < 0)
1589         abort ();
1590       value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1591       width += bits + 1;
1592     }
1593   while (*ptr++ == ',');
1594   *valuep = value;
1595   if (widthp)
1596     *widthp = width;
1597   return ptr - 1;
1598 }
1599
1600 static void
1601 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1602                   int print_shift)
1603 {
1604   func (stream, "%s", arm_regnames[given & 0xf]);
1605
1606   if ((given & 0xff0) != 0)
1607     {
1608       if ((given & 0x10) == 0)
1609         {
1610           int amount = (given & 0xf80) >> 7;
1611           int shift = (given & 0x60) >> 5;
1612
1613           if (amount == 0)
1614             {
1615               if (shift == 3)
1616                 {
1617                   func (stream, ", rrx");
1618                   return;
1619                 }
1620
1621               amount = 32;
1622             }
1623
1624           if (print_shift)
1625             func (stream, ", %s #%d", arm_shift[shift], amount);
1626           else
1627             func (stream, ", #%d", amount);
1628         }
1629       else if (print_shift)
1630         func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1631               arm_regnames[(given & 0xf00) >> 8]);
1632       else
1633         func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1634     }
1635 }
1636
1637 /* Print one coprocessor instruction on INFO->STREAM.
1638    Return TRUE if the instuction matched, FALSE if this is not a
1639    recognised coprocessor instruction.  */
1640
1641 static bfd_boolean
1642 print_insn_coprocessor (bfd_vma pc,
1643                         struct disassemble_info *info,
1644                         long given,
1645                         bfd_boolean thumb)
1646 {
1647   const struct opcode32 *insn;
1648   void *stream = info->stream;
1649   fprintf_ftype func = info->fprintf_func;
1650   unsigned long mask;
1651   unsigned long value;
1652   unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
1653   int cond;
1654
1655   for (insn = coprocessor_opcodes; insn->assembler; insn++)
1656     {
1657       signed long value_in_comment = 0;
1658       const char *c;
1659
1660       if (insn->arch == 0)
1661         switch (insn->value)
1662           {
1663           case SENTINEL_IWMMXT_START:
1664             if (info->mach != bfd_mach_arm_XScale
1665                 && info->mach != bfd_mach_arm_iWMMXt
1666                 && info->mach != bfd_mach_arm_iWMMXt2)
1667               do
1668                 insn++;
1669               while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1670             continue;
1671
1672           case SENTINEL_IWMMXT_END:
1673             continue;
1674
1675           case SENTINEL_GENERIC_START:
1676             allowed_arches = ((arm_feature_set *) info->private_data)->core;
1677             continue;
1678
1679           default:
1680             abort ();
1681           }
1682
1683       mask = insn->mask;
1684       value = insn->value;
1685       if (thumb)
1686         {
1687           /* The high 4 bits are 0xe for Arm conditional instructions, and
1688              0xe for arm unconditional instructions.  The rest of the
1689              encoding is the same.  */
1690           mask |= 0xf0000000;
1691           value |= 0xe0000000;
1692           if (ifthen_state)
1693             cond = IFTHEN_COND;
1694           else
1695             cond = 16;
1696         }
1697       else
1698         {
1699           /* Only match unconditional instuctions against unconditional
1700              patterns.  */
1701           if ((given & 0xf0000000) == 0xf0000000)
1702             {
1703               mask |= 0xf0000000;
1704               cond = 16;
1705             }
1706           else
1707             {
1708               cond = (given >> 28) & 0xf;
1709               if (cond == 0xe)
1710                 cond = 16;
1711             }
1712         }
1713       
1714       if ((given & mask) != value)
1715         continue;
1716
1717       if ((insn->arch & allowed_arches) == 0)
1718         continue;
1719
1720       for (c = insn->assembler; *c; c++)
1721         {
1722           if (*c == '%')
1723             {
1724               switch (*++c)
1725                 {
1726                 case '%':
1727                   func (stream, "%%");
1728                   break;
1729
1730                 case 'A':
1731                   {
1732                     int offset = given & 0xff;
1733
1734                     func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1735
1736                     value_in_comment = offset * 4;
1737                     if ((given & 0x00800000) == 0)
1738                       value_in_comment = - value_in_comment;
1739                     
1740                     if ((given & (1 << 24)) != 0)
1741                       {
1742                         if (offset)
1743                           func (stream, ", #%d]%s",
1744                                 value_in_comment,
1745                                 ((given & 0x00200000) != 0 ? "!" : ""));
1746                         else
1747                           func (stream, "]");
1748                       }
1749                     else
1750                       {
1751                         func (stream, "]");
1752
1753                         if (given & (1 << 21))
1754                           {
1755                             if (offset)
1756                               func (stream, ", #%d", value_in_comment);
1757                           }
1758                         else
1759                           {
1760                             func (stream, ", {%d}", offset);
1761                             value_in_comment = offset;
1762                           }
1763                       }
1764                   }
1765                   break;
1766
1767                 case 'B':
1768                   {
1769                     int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1770                     int offset = (given >> 1) & 0x3f;
1771
1772                     if (offset == 1)
1773                       func (stream, "{d%d}", regno);
1774                     else if (regno + offset > 32)
1775                       func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1776                     else
1777                       func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1778                   }
1779                   break;
1780
1781                 case 'C':
1782                   {
1783                     int rn = (given >> 16) & 0xf;
1784                     int offset = (given & 0xff) * 4;
1785                     int add = (given >> 23) & 1;
1786
1787                     func (stream, "[%s", arm_regnames[rn]);
1788
1789                     if (offset)
1790                       {
1791                         if (!add)
1792                           offset = -offset;
1793                         func (stream, ", #%d", offset);
1794                         if (rn != 15)
1795                           value_in_comment = offset;
1796                       }
1797                     func (stream, "]");
1798                     if (rn == 15)
1799                       {
1800                         func (stream, "\t; ");
1801                         /* FIXME: Unsure if info->bytes_per_chunk is the
1802                            right thing to use here.  */
1803                         info->print_address_func (offset + pc
1804                                                   + info->bytes_per_chunk * 2, info);
1805                       }
1806                   }
1807                   break;
1808
1809                 case 'c':
1810                   func (stream, "%s", arm_conditional[cond]);
1811                   break;
1812
1813                 case 'I':
1814                   /* Print a Cirrus/DSP shift immediate.  */
1815                   /* Immediates are 7bit signed ints with bits 0..3 in
1816                      bits 0..3 of opcode and bits 4..6 in bits 5..7
1817                      of opcode.  */
1818                   {
1819                     int imm;
1820
1821                     imm = (given & 0xf) | ((given & 0xe0) >> 1);
1822
1823                     /* Is ``imm'' a negative number?  */
1824                     if (imm & 0x40)
1825                       imm |= (-1 << 7);
1826
1827                     func (stream, "%d", imm);
1828                   }
1829
1830                   break;
1831
1832                 case 'F':
1833                   switch (given & 0x00408000)
1834                     {
1835                     case 0:
1836                       func (stream, "4");
1837                       break;
1838                     case 0x8000:
1839                       func (stream, "1");
1840                       break;
1841                     case 0x00400000:
1842                       func (stream, "2");
1843                       break;
1844                     default:
1845                       func (stream, "3");
1846                     }
1847                   break;
1848
1849                 case 'P':
1850                   switch (given & 0x00080080)
1851                     {
1852                     case 0:
1853                       func (stream, "s");
1854                       break;
1855                     case 0x80:
1856                       func (stream, "d");
1857                       break;
1858                     case 0x00080000:
1859                       func (stream, "e");
1860                       break;
1861                     default:
1862                       func (stream, _("<illegal precision>"));
1863                       break;
1864                     }
1865                   break;
1866
1867                 case 'Q':
1868                   switch (given & 0x00408000)
1869                     {
1870                     case 0:
1871                       func (stream, "s");
1872                       break;
1873                     case 0x8000:
1874                       func (stream, "d");
1875                       break;
1876                     case 0x00400000:
1877                       func (stream, "e");
1878                       break;
1879                     default:
1880                       func (stream, "p");
1881                       break;
1882                     }
1883                   break;
1884
1885                 case 'R':
1886                   switch (given & 0x60)
1887                     {
1888                     case 0:
1889                       break;
1890                     case 0x20:
1891                       func (stream, "p");
1892                       break;
1893                     case 0x40:
1894                       func (stream, "m");
1895                       break;
1896                     default:
1897                       func (stream, "z");
1898                       break;
1899                     }
1900                   break;
1901
1902                 case '0': case '1': case '2': case '3': case '4':
1903                 case '5': case '6': case '7': case '8': case '9':
1904                   {
1905                     int width;
1906                     unsigned long value;
1907
1908                     c = arm_decode_bitfield (c, given, &value, &width);
1909
1910                     switch (*c)
1911                       {
1912                       case 'r':
1913                         func (stream, "%s", arm_regnames[value]);
1914                         break;
1915                       case 'D':
1916                         func (stream, "d%ld", value);
1917                         break;
1918                       case 'Q':
1919                         if (value & 1)
1920                           func (stream, "<illegal reg q%ld.5>", value >> 1);
1921                         else
1922                           func (stream, "q%ld", value >> 1);
1923                         break;
1924                       case 'd':
1925                         func (stream, "%ld", value);
1926                         value_in_comment = value;
1927                         break;
1928                       case 'k':
1929                         {
1930                           int from = (given & (1 << 7)) ? 32 : 16;
1931                           func (stream, "%ld", from - value);
1932                         }
1933                         break;
1934
1935                       case 'f':
1936                         if (value > 7)
1937                           func (stream, "#%s", arm_fp_const[value & 7]);
1938                         else
1939                           func (stream, "f%ld", value);
1940                         break;
1941
1942                       case 'w':
1943                         if (width == 2)
1944                           func (stream, "%s", iwmmxt_wwnames[value]);
1945                         else
1946                           func (stream, "%s", iwmmxt_wwssnames[value]);
1947                         break;
1948
1949                       case 'g':
1950                         func (stream, "%s", iwmmxt_regnames[value]);
1951                         break;
1952                       case 'G':
1953                         func (stream, "%s", iwmmxt_cregnames[value]);
1954                         break;
1955
1956                       case 'x':
1957                         func (stream, "0x%lx", value);
1958                         break;
1959
1960                       case '`':
1961                         c++;
1962                         if (value == 0)
1963                           func (stream, "%c", *c);
1964                         break;
1965                       case '\'':
1966                         c++;
1967                         if (value == ((1ul << width) - 1))
1968                           func (stream, "%c", *c);
1969                         break;
1970                       case '?':
1971                         func (stream, "%c", c[(1 << width) - (int) value]);
1972                         c += 1 << width;
1973                         break;
1974                       default:
1975                         abort ();
1976                       }
1977                     break;
1978
1979                   case 'y':
1980                   case 'z':
1981                     {
1982                       int single = *c++ == 'y';
1983                       int regno;
1984
1985                       switch (*c)
1986                         {
1987                         case '4': /* Sm pair */
1988                         case '0': /* Sm, Dm */
1989                           regno = given & 0x0000000f;
1990                           if (single)
1991                             {
1992                               regno <<= 1;
1993                               regno += (given >> 5) & 1;
1994                             }
1995                           else
1996                             regno += ((given >> 5) & 1) << 4;
1997                           break;
1998
1999                         case '1': /* Sd, Dd */
2000                           regno = (given >> 12) & 0x0000000f;
2001                           if (single)
2002                             {
2003                               regno <<= 1;
2004                               regno += (given >> 22) & 1;
2005                             }
2006                           else
2007                             regno += ((given >> 22) & 1) << 4;
2008                           break;
2009
2010                         case '2': /* Sn, Dn */
2011                           regno = (given >> 16) & 0x0000000f;
2012                           if (single)
2013                             {
2014                               regno <<= 1;
2015                               regno += (given >> 7) & 1;
2016                             }
2017                           else
2018                             regno += ((given >> 7) & 1) << 4;
2019                           break;
2020
2021                         case '3': /* List */
2022                           func (stream, "{");
2023                           regno = (given >> 12) & 0x0000000f;
2024                           if (single)
2025                             {
2026                               regno <<= 1;
2027                               regno += (given >> 22) & 1;
2028                             }
2029                           else
2030                             regno += ((given >> 22) & 1) << 4;
2031                           break;
2032
2033                         default:
2034                           abort ();
2035                         }
2036
2037                       func (stream, "%c%d", single ? 's' : 'd', regno);
2038
2039                       if (*c == '3')
2040                         {
2041                           int count = given & 0xff;
2042
2043                           if (single == 0)
2044                             count >>= 1;
2045
2046                           if (--count)
2047                             {
2048                               func (stream, "-%c%d",
2049                                     single ? 's' : 'd',
2050                                     regno + count);
2051                             }
2052
2053                           func (stream, "}");
2054                         }
2055                       else if (*c == '4')
2056                         func (stream, ", %c%d", single ? 's' : 'd',
2057                               regno + 1);
2058                     }
2059                     break;
2060
2061                   case 'L':
2062                     switch (given & 0x00400100)
2063                       {
2064                       case 0x00000000: func (stream, "b"); break;
2065                       case 0x00400000: func (stream, "h"); break;
2066                       case 0x00000100: func (stream, "w"); break;
2067                       case 0x00400100: func (stream, "d"); break;
2068                       default:
2069                         break;
2070                       }
2071                     break;
2072
2073                   case 'Z':
2074                     {
2075                       int value;
2076                       /* given (20, 23) | given (0, 3) */
2077                       value = ((given >> 16) & 0xf0) | (given & 0xf);
2078                       func (stream, "%d", value);
2079                     }
2080                     break;
2081
2082                   case 'l':
2083                     /* This is like the 'A' operator, except that if
2084                        the width field "M" is zero, then the offset is
2085                        *not* multiplied by four.  */
2086                     {
2087                       int offset = given & 0xff;
2088                       int multiplier = (given & 0x00000100) ? 4 : 1;
2089
2090                       func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2091
2092                       if (multiplier > 1)
2093                         {
2094                           value_in_comment = offset * multiplier;
2095                           if ((given & 0x00800000) == 0)
2096                             value_in_comment = - value_in_comment;
2097                         }
2098
2099                       if (offset)
2100                         {
2101                           if ((given & 0x01000000) != 0)
2102                             func (stream, ", #%s%d]%s",
2103                                   ((given & 0x00800000) == 0 ? "-" : ""),
2104                                   offset * multiplier,
2105                                   ((given & 0x00200000) != 0 ? "!" : ""));
2106                           else
2107                             func (stream, "], #%s%d",
2108                                   ((given & 0x00800000) == 0 ? "-" : ""),
2109                                   offset * multiplier);
2110                         }
2111                       else
2112                         func (stream, "]");
2113                     }
2114                     break;
2115
2116                   case 'r':
2117                     {
2118                       int imm4 = (given >> 4) & 0xf;
2119                       int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2120                       int ubit = (given >> 23) & 1;
2121                       const char *rm = arm_regnames [given & 0xf];
2122                       const char *rn = arm_regnames [(given >> 16) & 0xf];
2123
2124                       switch (puw_bits)
2125                         {
2126                         case 1:
2127                         case 3:
2128                           func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2129                           if (imm4)
2130                             func (stream, ", lsl #%d", imm4);
2131                           break;
2132
2133                         case 4:
2134                         case 5:
2135                         case 6:
2136                         case 7:
2137                           func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2138                           if (imm4 > 0)
2139                             func (stream, ", lsl #%d", imm4);
2140                           func (stream, "]");
2141                           if (puw_bits == 5 || puw_bits == 7)
2142                             func (stream, "!");
2143                           break;
2144
2145                         default:
2146                           func (stream, "INVALID");
2147                         }
2148                     }
2149                     break;
2150
2151                   case 'i':
2152                     {
2153                       long imm5;
2154                       imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2155                       func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2156                     }
2157                     break;
2158
2159                   default:
2160                     abort ();
2161                   }
2162                 }
2163             }
2164           else
2165             func (stream, "%c", *c);
2166         }
2167
2168       if (value_in_comment > 32 || value_in_comment < -16)
2169         func (stream, "\t; 0x%lx", value_in_comment);
2170
2171       return TRUE;
2172     }
2173   return FALSE;
2174 }
2175
2176 /* Decodes and prints ARM addressing modes.  Returns the offset
2177    used in the address, if any, if it is worthwhile printing the
2178    offset as a hexadecimal value in a comment at the end of the
2179    line of disassembly.  */
2180
2181 static signed long
2182 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2183 {
2184   void *stream = info->stream;
2185   fprintf_ftype func = info->fprintf_func;
2186   int offset = 0;
2187
2188   if (((given & 0x000f0000) == 0x000f0000)
2189       && ((given & 0x02000000) == 0))
2190     {
2191       offset = given & 0xfff;
2192
2193       func (stream, "[pc");
2194
2195       if (given & 0x01000000)
2196         {
2197           if ((given & 0x00800000) == 0)
2198             offset = - offset;
2199
2200           /* Pre-indexed.  */
2201           func (stream, ", #%d]", offset);
2202
2203           offset += pc + 8;
2204
2205           /* Cope with the possibility of write-back
2206              being used.  Probably a very dangerous thing
2207              for the programmer to do, but who are we to
2208              argue ?  */
2209           if (given & 0x00200000)
2210             func (stream, "!");
2211         }
2212       else
2213         {
2214           /* Post indexed.  */
2215           func (stream, "], #%d", offset);
2216
2217           /* ie ignore the offset.  */
2218           offset = pc + 8;
2219         }
2220
2221       func (stream, "\t; ");
2222       info->print_address_func (offset, info);
2223       offset = 0;
2224     }
2225   else
2226     {
2227       func (stream, "[%s",
2228             arm_regnames[(given >> 16) & 0xf]);
2229       if ((given & 0x01000000) != 0)
2230         {
2231           if ((given & 0x02000000) == 0)
2232             {
2233               offset = given & 0xfff;
2234               if (offset)
2235                 func (stream, ", #%s%d",
2236                       (((given & 0x00800000) == 0)
2237                        ? "-" : ""), offset);
2238             }
2239           else
2240             {
2241               func (stream, ", %s",
2242                     (((given & 0x00800000) == 0)
2243                      ? "-" : ""));
2244               arm_decode_shift (given, func, stream, 1);
2245             }
2246
2247           func (stream, "]%s",
2248                 ((given & 0x00200000) != 0) ? "!" : "");
2249         }
2250       else
2251         {
2252           if ((given & 0x02000000) == 0)
2253             {
2254               offset = given & 0xfff;
2255               if (offset)
2256                 func (stream, "], #%s%d",
2257                       (((given & 0x00800000) == 0)
2258                        ? "-" : ""), offset);
2259               else
2260                 func (stream, "]");
2261             }
2262           else
2263             {
2264               func (stream, "], %s",
2265                     (((given & 0x00800000) == 0)
2266                      ? "-" : ""));
2267               arm_decode_shift (given, func, stream, 1);
2268             }
2269         }
2270     }
2271
2272   return (signed long) offset;
2273 }
2274
2275 /* Print one neon instruction on INFO->STREAM.
2276    Return TRUE if the instuction matched, FALSE if this is not a
2277    recognised neon instruction.  */
2278
2279 static bfd_boolean
2280 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2281 {
2282   const struct opcode32 *insn;
2283   void *stream = info->stream;
2284   fprintf_ftype func = info->fprintf_func;
2285
2286   if (thumb)
2287     {
2288       if ((given & 0xef000000) == 0xef000000)
2289         {
2290           /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding.  */
2291           unsigned long bit28 = given & (1 << 28);
2292
2293           given &= 0x00ffffff;
2294           if (bit28)
2295             given |= 0xf3000000;
2296           else
2297             given |= 0xf2000000;
2298         }
2299       else if ((given & 0xff000000) == 0xf9000000)
2300         given ^= 0xf9000000 ^ 0xf4000000;
2301       else
2302         return FALSE;
2303     }
2304   
2305   for (insn = neon_opcodes; insn->assembler; insn++)
2306     {
2307       if ((given & insn->mask) == insn->value)
2308         {
2309           signed long value_in_comment = 0;
2310           const char *c;
2311
2312           for (c = insn->assembler; *c; c++)
2313             {
2314               if (*c == '%')
2315                 {
2316                   switch (*++c)
2317                     {
2318                     case '%':
2319                       func (stream, "%%");
2320                       break;
2321
2322                     case 'c':
2323                       if (thumb && ifthen_state)
2324                         func (stream, "%s", arm_conditional[IFTHEN_COND]);
2325                       break;
2326
2327                     case 'A':
2328                       {
2329                         static const unsigned char enc[16] = 
2330                         {
2331                           0x4, 0x14, /* st4 0,1 */
2332                           0x4, /* st1 2 */
2333                           0x4, /* st2 3 */
2334                           0x3, /* st3 4 */
2335                           0x13, /* st3 5 */
2336                           0x3, /* st1 6 */
2337                           0x1, /* st1 7 */
2338                           0x2, /* st2 8 */
2339                           0x12, /* st2 9 */
2340                           0x2, /* st1 10 */
2341                           0, 0, 0, 0, 0
2342                         };
2343                         int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2344                         int rn = ((given >> 16) & 0xf);
2345                         int rm = ((given >> 0) & 0xf);
2346                         int align = ((given >> 4) & 0x3);
2347                         int type = ((given >> 8) & 0xf);
2348                         int n = enc[type] & 0xf;
2349                         int stride = (enc[type] >> 4) + 1;
2350                         int ix;
2351                         
2352                         func (stream, "{");
2353                         if (stride > 1)
2354                           for (ix = 0; ix != n; ix++)
2355                             func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2356                         else if (n == 1)
2357                           func (stream, "d%d", rd);
2358                         else
2359                           func (stream, "d%d-d%d", rd, rd + n - 1);
2360                         func (stream, "}, [%s", arm_regnames[rn]);
2361                         if (align)
2362                           func (stream, ", :%d", 32 << align);
2363                         func (stream, "]");
2364                         if (rm == 0xd)
2365                           func (stream, "!");
2366                         else if (rm != 0xf)
2367                           func (stream, ", %s", arm_regnames[rm]);
2368                       }
2369                       break;
2370                       
2371                     case 'B':
2372                       {
2373                         int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2374                         int rn = ((given >> 16) & 0xf);
2375                         int rm = ((given >> 0) & 0xf);
2376                         int idx_align = ((given >> 4) & 0xf);
2377                         int align = 0;
2378                         int size = ((given >> 10) & 0x3);
2379                         int idx = idx_align >> (size + 1);
2380                         int length = ((given >> 8) & 3) + 1;
2381                         int stride = 1;
2382                         int i;
2383
2384                         if (length > 1 && size > 0)
2385                           stride = (idx_align & (1 << size)) ? 2 : 1;
2386                         
2387                         switch (length)
2388                           {
2389                           case 1:
2390                             {
2391                               int amask = (1 << size) - 1;
2392                               if ((idx_align & (1 << size)) != 0)
2393                                 return FALSE;
2394                               if (size > 0)
2395                                 {
2396                                   if ((idx_align & amask) == amask)
2397                                     align = 8 << size;
2398                                   else if ((idx_align & amask) != 0)
2399                                     return FALSE;
2400                                 }
2401                               }
2402                             break;
2403                           
2404                           case 2:
2405                             if (size == 2 && (idx_align & 2) != 0)
2406                               return FALSE;
2407                             align = (idx_align & 1) ? 16 << size : 0;
2408                             break;
2409                           
2410                           case 3:
2411                             if ((size == 2 && (idx_align & 3) != 0)
2412                                 || (idx_align & 1) != 0)
2413                               return FALSE;
2414                             break;
2415                           
2416                           case 4:
2417                             if (size == 2)
2418                               {
2419                                 if ((idx_align & 3) == 3)
2420                                   return FALSE;
2421                                 align = (idx_align & 3) * 64;
2422                               }
2423                             else
2424                               align = (idx_align & 1) ? 32 << size : 0;
2425                             break;
2426                           
2427                           default:
2428                             abort ();
2429                           }
2430                                 
2431                         func (stream, "{");
2432                         for (i = 0; i < length; i++)
2433                           func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2434                             rd + i * stride, idx);
2435                         func (stream, "}, [%s", arm_regnames[rn]);
2436                         if (align)
2437                           func (stream, ", :%d", align);
2438                         func (stream, "]");
2439                         if (rm == 0xd)
2440                           func (stream, "!");
2441                         else if (rm != 0xf)
2442                           func (stream, ", %s", arm_regnames[rm]);
2443                       }
2444                       break;
2445                       
2446                     case 'C':
2447                       {
2448                         int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2449                         int rn = ((given >> 16) & 0xf);
2450                         int rm = ((given >> 0) & 0xf);
2451                         int align = ((given >> 4) & 0x1);
2452                         int size = ((given >> 6) & 0x3);
2453                         int type = ((given >> 8) & 0x3);
2454                         int n = type + 1;
2455                         int stride = ((given >> 5) & 0x1);
2456                         int ix;
2457                         
2458                         if (stride && (n == 1))
2459                           n++;
2460                         else
2461                           stride++;
2462                         
2463                         func (stream, "{");
2464                         if (stride > 1)
2465                           for (ix = 0; ix != n; ix++)
2466                             func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2467                         else if (n == 1)
2468                           func (stream, "d%d[]", rd);
2469                         else
2470                           func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2471                         func (stream, "}, [%s", arm_regnames[rn]);
2472                         if (align)
2473                           {
2474                             int align = (8 * (type + 1)) << size;
2475                             if (type == 3)
2476                               align = (size > 1) ? align >> 1 : align;
2477                             if (type == 2 || (type == 0 && !size))
2478                               func (stream, ", :<bad align %d>", align);
2479                             else
2480                               func (stream, ", :%d", align);
2481                           }
2482                         func (stream, "]");
2483                         if (rm == 0xd)
2484                           func (stream, "!");
2485                         else if (rm != 0xf)
2486                           func (stream, ", %s", arm_regnames[rm]);
2487                       }
2488                       break;
2489                       
2490                     case 'D':
2491                       {
2492                         int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2493                         int size = (given >> 20) & 3;
2494                         int reg = raw_reg & ((4 << size) - 1);
2495                         int ix = raw_reg >> size >> 2;
2496                         
2497                         func (stream, "d%d[%d]", reg, ix);
2498                       }
2499                       break;
2500                       
2501                     case 'E':
2502                       /* Neon encoded constant for mov, mvn, vorr, vbic.  */
2503                       {
2504                         int bits = 0;
2505                         int cmode = (given >> 8) & 0xf;
2506                         int op = (given >> 5) & 0x1;
2507                         unsigned long value = 0, hival = 0;
2508                         unsigned shift;
2509                         int size = 0;
2510                         int isfloat = 0;
2511                         
2512                         bits |= ((given >> 24) & 1) << 7;
2513                         bits |= ((given >> 16) & 7) << 4;
2514                         bits |= ((given >> 0) & 15) << 0;
2515                         
2516                         if (cmode < 8)
2517                           {
2518                             shift = (cmode >> 1) & 3;
2519                             value = (unsigned long) bits << (8 * shift);
2520                             size = 32;
2521                           }
2522                         else if (cmode < 12)
2523                           {
2524                             shift = (cmode >> 1) & 1;
2525                             value = (unsigned long) bits << (8 * shift);
2526                             size = 16;
2527                           }
2528                         else if (cmode < 14)
2529                           {
2530                             shift = (cmode & 1) + 1;
2531                             value = (unsigned long) bits << (8 * shift);
2532                             value |= (1ul << (8 * shift)) - 1;
2533                             size = 32;
2534                           }
2535                         else if (cmode == 14)
2536                           {
2537                             if (op)
2538                               {
2539                                 /* Bit replication into bytes.  */
2540                                 int ix;
2541                                 unsigned long mask;
2542                                 
2543                                 value = 0;
2544                                 hival = 0;
2545                                 for (ix = 7; ix >= 0; ix--)
2546                                   {
2547                                     mask = ((bits >> ix) & 1) ? 0xff : 0;
2548                                     if (ix <= 3)
2549                                       value = (value << 8) | mask;
2550                                     else
2551                                       hival = (hival << 8) | mask;
2552                                   }
2553                                 size = 64;
2554                               }
2555                             else
2556                               {
2557                                 /* Byte replication.  */
2558                                 value = (unsigned long) bits;
2559                                 size = 8;
2560                               }
2561                           }
2562                         else if (!op)
2563                           {
2564                             /* Floating point encoding.  */
2565                             int tmp;
2566                             
2567                             value = (unsigned long)  (bits & 0x7f) << 19;
2568                             value |= (unsigned long) (bits & 0x80) << 24;
2569                             tmp = bits & 0x40 ? 0x3c : 0x40;
2570                             value |= (unsigned long) tmp << 24;
2571                             size = 32;
2572                             isfloat = 1;
2573                           }
2574                         else
2575                           {
2576                             func (stream, "<illegal constant %.8x:%x:%x>",
2577                                   bits, cmode, op);
2578                             size = 32;
2579                             break;
2580                           }
2581                         switch (size)
2582                           {
2583                           case 8:
2584                             func (stream, "#%ld\t; 0x%.2lx", value, value);
2585                             break;
2586                           
2587                           case 16:
2588                             func (stream, "#%ld\t; 0x%.4lx", value, value);
2589                             break;
2590
2591                           case 32:
2592                             if (isfloat)
2593                               {
2594                                 unsigned char valbytes[4];
2595                                 double fvalue;
2596                                 
2597                                 /* Do this a byte at a time so we don't have to
2598                                    worry about the host's endianness.  */
2599                                 valbytes[0] = value & 0xff;
2600                                 valbytes[1] = (value >> 8) & 0xff;
2601                                 valbytes[2] = (value >> 16) & 0xff;
2602                                 valbytes[3] = (value >> 24) & 0xff;
2603                                 
2604                                 floatformat_to_double 
2605                                   (&floatformat_ieee_single_little, valbytes,
2606                                   &fvalue);
2607                                                                 
2608                                 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2609                                       value);
2610                               }
2611                             else
2612                               func (stream, "#%ld\t; 0x%.8lx",
2613                                 (long) ((value & 0x80000000)
2614                                         ? value | ~0xffffffffl : value), value);
2615                             break;
2616
2617                           case 64:
2618                             func (stream, "#0x%.8lx%.8lx", hival, value);
2619                             break;
2620                           
2621                           default:
2622                             abort ();
2623                           }
2624                       }
2625                       break;
2626                       
2627                     case 'F':
2628                       {
2629                         int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2630                         int num = (given >> 8) & 0x3;
2631                         
2632                         if (!num)
2633                           func (stream, "{d%d}", regno);
2634                         else if (num + regno >= 32)
2635                           func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2636                         else
2637                           func (stream, "{d%d-d%d}", regno, regno + num);
2638                       }
2639                       break;
2640       
2641
2642                     case '0': case '1': case '2': case '3': case '4':
2643                     case '5': case '6': case '7': case '8': case '9':
2644                       {
2645                         int width;
2646                         unsigned long value;
2647
2648                         c = arm_decode_bitfield (c, given, &value, &width);
2649                         
2650                         switch (*c)
2651                           {
2652                           case 'r':
2653                             func (stream, "%s", arm_regnames[value]);
2654                             break;
2655                           case 'd':
2656                             func (stream, "%ld", value);
2657                             value_in_comment = value;
2658                             break;
2659                           case 'e':
2660                             func (stream, "%ld", (1ul << width) - value);
2661                             break;
2662                             
2663                           case 'S':
2664                           case 'T':
2665                           case 'U':
2666                             /* Various width encodings.  */
2667                             {
2668                               int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2669                               int limit;
2670                               unsigned low, high;
2671
2672                               c++;
2673                               if (*c >= '0' && *c <= '9')
2674                                 limit = *c - '0';
2675                               else if (*c >= 'a' && *c <= 'f')
2676                                 limit = *c - 'a' + 10;
2677                               else
2678                                 abort ();
2679                               low = limit >> 2;
2680                               high = limit & 3;
2681
2682                               if (value < low || value > high)
2683                                 func (stream, "<illegal width %d>", base << value);
2684                               else
2685                                 func (stream, "%d", base << value);
2686                             }
2687                             break;
2688                           case 'R':
2689                             if (given & (1 << 6))
2690                               goto Q;
2691                             /* FALLTHROUGH */
2692                           case 'D':
2693                             func (stream, "d%ld", value);
2694                             break;
2695                           case 'Q':
2696                           Q:
2697                             if (value & 1)
2698                               func (stream, "<illegal reg q%ld.5>", value >> 1);
2699                             else
2700                               func (stream, "q%ld", value >> 1);
2701                             break;
2702                             
2703                           case '`':
2704                             c++;
2705                             if (value == 0)
2706                               func (stream, "%c", *c);
2707                             break;
2708                           case '\'':
2709                             c++;
2710                             if (value == ((1ul << width) - 1))
2711                               func (stream, "%c", *c);
2712                             break;
2713                           case '?':
2714                             func (stream, "%c", c[(1 << width) - (int) value]);
2715                             c += 1 << width;
2716                             break;
2717                           default:
2718                             abort ();
2719                           }
2720                         break;
2721
2722                       default:
2723                         abort ();
2724                       }
2725                     }
2726                 }
2727               else
2728                 func (stream, "%c", *c);
2729             }
2730
2731           if (value_in_comment > 32 || value_in_comment < -16)
2732             func (stream, "\t; 0x%lx", value_in_comment);
2733
2734           return TRUE;
2735         }
2736     }
2737   return FALSE;
2738 }
2739
2740 /* Print one ARM instruction from PC on INFO->STREAM.  */
2741
2742 static void
2743 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2744 {
2745   const struct opcode32 *insn;
2746   void *stream = info->stream;
2747   fprintf_ftype func = info->fprintf_func;
2748
2749   if (print_insn_coprocessor (pc, info, given, FALSE))
2750     return;
2751
2752   if (print_insn_neon (info, given, FALSE))
2753     return;
2754
2755   for (insn = arm_opcodes; insn->assembler; insn++)
2756     {
2757       if ((given & insn->mask) != insn->value)
2758         continue;
2759     
2760       if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
2761         continue;
2762
2763       /* Special case: an instruction with all bits set in the condition field
2764          (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2765          or by the catchall at the end of the table.  */
2766       if ((given & 0xF0000000) != 0xF0000000
2767           || (insn->mask & 0xF0000000) == 0xF0000000
2768           || (insn->mask == 0 && insn->value == 0))
2769         {
2770           signed long value_in_comment = 0;
2771           const char *c;
2772
2773           for (c = insn->assembler; *c; c++)
2774             {
2775               if (*c == '%')
2776                 {
2777                   switch (*++c)
2778                     {
2779                     case '%':
2780                       func (stream, "%%");
2781                       break;
2782
2783                     case 'a':
2784                       value_in_comment = print_arm_address (pc, info, given);
2785                       break;
2786
2787                     case 'P':
2788                       /* Set P address bit and use normal address
2789                          printing routine.  */
2790                       value_in_comment = print_arm_address (pc, info, given | (1 << 24));
2791                       break;
2792
2793                     case 's':
2794                       if ((given & 0x004f0000) == 0x004f0000)
2795                         {
2796                           /* PC relative with immediate offset.  */
2797                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2798
2799                           if ((given & 0x00800000) == 0)
2800                             offset = -offset;
2801
2802                           func (stream, "[pc, #%d]\t; ", offset);
2803                           info->print_address_func (offset + pc + 8, info);
2804                         }
2805                       else
2806                         {
2807                           int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2808
2809                           if ((given & 0x00800000) == 0)
2810                             offset = -offset;
2811
2812                           func (stream, "[%s",
2813                                 arm_regnames[(given >> 16) & 0xf]);
2814
2815                           if ((given & 0x01000000) != 0)
2816                             {
2817                               /* Pre-indexed.  */
2818                               if ((given & 0x00400000) == 0x00400000)
2819                                 {
2820                                   /* Immediate.  */
2821                                   if (offset)
2822                                     func (stream, ", #%d", offset);
2823                                   value_in_comment = offset;
2824                                 }
2825                               else
2826                                 {
2827                                   /* Register.  */
2828                                   func (stream, ", %s%s", offset < 0 ? "-" : "",
2829                                         arm_regnames[given & 0xf]);
2830                                 }
2831
2832                               func (stream, "]%s",
2833                                     ((given & 0x00200000) != 0) ? "!" : "");
2834                             }
2835                           else
2836                             {
2837                               /* Post-indexed.  */
2838                               if ((given & 0x00400000) == 0x00400000)
2839                                 {
2840                                   /* Immediate.  */
2841                                   if (offset)
2842                                     func (stream, "], #%d", offset);
2843                                   else
2844                                     func (stream, "]");
2845
2846                                   value_in_comment = offset;
2847                                 }
2848                               else
2849                                 {
2850                                   /* Register.  */
2851                                   func (stream, "], %s%s", offset < 0 ? "-" : "",
2852                                         arm_regnames[given & 0xf]);
2853                                 }
2854                             }
2855                         }
2856                       break;
2857
2858                     case 'b':
2859                       {
2860                         int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2861                         info->print_address_func (disp * 4 + pc + 8, info);
2862                       }
2863                       break;
2864
2865                     case 'c':
2866                       if (((given >> 28) & 0xf) != 0xe)
2867                         func (stream, "%s",
2868                               arm_conditional [(given >> 28) & 0xf]);
2869                       break;
2870
2871                     case 'm':
2872                       {
2873                         int started = 0;
2874                         int reg;
2875
2876                         func (stream, "{");
2877                         for (reg = 0; reg < 16; reg++)
2878                           if ((given & (1 << reg)) != 0)
2879                             {
2880                               if (started)
2881                                 func (stream, ", ");
2882                               started = 1;
2883                               func (stream, "%s", arm_regnames[reg]);
2884                             }
2885                         func (stream, "}");
2886                       }
2887                       break;
2888
2889                     case 'q':
2890                       arm_decode_shift (given, func, stream, 0);
2891                       break;
2892
2893                     case 'o':
2894                       if ((given & 0x02000000) != 0)
2895                         {
2896                           int rotate = (given & 0xf00) >> 7;
2897                           int immed = (given & 0xff);
2898
2899                           immed = (((immed << (32 - rotate))
2900                                     | (immed >> rotate)) & 0xffffffff);
2901                           func (stream, "#%d", immed);
2902                           value_in_comment = immed;
2903                         }
2904                       else
2905                         arm_decode_shift (given, func, stream, 1);
2906                       break;
2907
2908                     case 'p':
2909                       if ((given & 0x0000f000) == 0x0000f000)
2910                         func (stream, "p");
2911                       break;
2912
2913                     case 't':
2914                       if ((given & 0x01200000) == 0x00200000)
2915                         func (stream, "t");
2916                       break;
2917
2918                     case 'A':
2919                       {
2920                         int offset = given & 0xff;
2921
2922                         value_in_comment = offset * 4;
2923                         if ((given & 0x00800000) == 0)
2924                           value_in_comment = - value_in_comment;
2925
2926                         func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2927
2928                         if ((given & (1 << 24)) != 0)
2929                           {
2930                             if (offset)
2931                               func (stream, ", #%d]%s",
2932                                     value_in_comment,
2933                                     ((given & 0x00200000) != 0 ? "!" : ""));
2934                             else
2935                               func (stream, "]");
2936                           }
2937                         else
2938                           {
2939                             func (stream, "]");
2940
2941                             if (given & (1 << 21))
2942                               {
2943                                 if (offset)
2944                                   func (stream, ", #%d", value_in_comment);
2945                               }
2946                             else
2947                               {
2948                                 func (stream, ", {%d}", offset);
2949                                 value_in_comment = offset;
2950                               }
2951                           }
2952                       }
2953                       break;
2954
2955                     case 'B':
2956                       /* Print ARM V5 BLX(1) address: pc+25 bits.  */
2957                       {
2958                         bfd_vma address;
2959                         bfd_vma offset = 0;
2960
2961                         if (given & 0x00800000)
2962                           /* Is signed, hi bits should be ones.  */
2963                           offset = (-1) ^ 0x00ffffff;
2964
2965                         /* Offset is (SignExtend(offset field)<<2).  */
2966                         offset += given & 0x00ffffff;
2967                         offset <<= 2;
2968                         address = offset + pc + 8;
2969
2970                         if (given & 0x01000000)
2971                           /* H bit allows addressing to 2-byte boundaries.  */
2972                           address += 2;
2973
2974                         info->print_address_func (address, info);
2975                       }
2976                       break;
2977
2978                     case 'C':
2979                       func (stream, "_");
2980                       if (given & 0x80000)
2981                         func (stream, "f");
2982                       if (given & 0x40000)
2983                         func (stream, "s");
2984                       if (given & 0x20000)
2985                         func (stream, "x");
2986                       if (given & 0x10000)
2987                         func (stream, "c");
2988                       break;
2989
2990                     case 'U':
2991                       switch (given & 0xf)
2992                         {
2993                         case 0xf: func (stream, "sy"); break;
2994                         case 0x7: func (stream, "un"); break;
2995                         case 0xe: func (stream, "st"); break;
2996                         case 0x6: func (stream, "unst"); break;
2997                         default:
2998                           func (stream, "#%d", (int) given & 0xf);
2999                           break;
3000                         }
3001                       break;
3002
3003                     case '0': case '1': case '2': case '3': case '4':
3004                     case '5': case '6': case '7': case '8': case '9':
3005                       {
3006                         int width;
3007                         unsigned long value;
3008
3009                         c = arm_decode_bitfield (c, given, &value, &width);
3010                         
3011                         switch (*c)
3012                           {
3013                           case 'r':
3014                             func (stream, "%s", arm_regnames[value]);
3015                             break;
3016                           case 'd':
3017                             func (stream, "%ld", value);
3018                             value_in_comment = value;
3019                             break;
3020                           case 'b':
3021                             func (stream, "%ld", value * 8);
3022                             value_in_comment = value * 8;
3023                             break;
3024                           case 'W':
3025                             func (stream, "%ld", value + 1);
3026                             value_in_comment = value + 1;
3027                             break;
3028                           case 'x':
3029                             func (stream, "0x%08lx", value);
3030
3031                             /* Some SWI instructions have special
3032                                meanings.  */
3033                             if ((given & 0x0fffffff) == 0x0FF00000)
3034                               func (stream, "\t; IMB");
3035                             else if ((given & 0x0fffffff) == 0x0FF00001)
3036                               func (stream, "\t; IMBRange");
3037                             break;
3038                           case 'X':
3039                             func (stream, "%01lx", value & 0xf);
3040                             value_in_comment = value;
3041                             break;
3042                           case '`':
3043                             c++;
3044                             if (value == 0)
3045                               func (stream, "%c", *c);
3046                             break;
3047                           case '\'':
3048                             c++;
3049                             if (value == ((1ul << width) - 1))
3050                               func (stream, "%c", *c);
3051                             break;
3052                           case '?':
3053                             func (stream, "%c", c[(1 << width) - (int) value]);
3054                             c += 1 << width;
3055                             break;
3056                           default:
3057                             abort ();
3058                           }
3059                         break;
3060
3061                       case 'e':
3062                         {
3063                           int imm;
3064
3065                           imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3066                           func (stream, "%d", imm);
3067                           value_in_comment = imm;
3068                         }
3069                         break;
3070
3071                       case 'E':
3072                         /* LSB and WIDTH fields of BFI or BFC.  The machine-
3073                            language instruction encodes LSB and MSB.  */
3074                         {
3075                           long msb = (given & 0x001f0000) >> 16;
3076                           long lsb = (given & 0x00000f80) >> 7;
3077                           long width = msb - lsb + 1;
3078
3079                           if (width > 0)
3080                             func (stream, "#%lu, #%lu", lsb, width);
3081                           else
3082                             func (stream, "(invalid: %lu:%lu)", lsb, msb);
3083                         }
3084                         break;
3085
3086                       case 'V':
3087                         /* 16-bit unsigned immediate from a MOVT or MOVW
3088                            instruction, encoded in bits 0:11 and 15:19.  */
3089                         {
3090                           long hi = (given & 0x000f0000) >> 4;
3091                           long lo = (given & 0x00000fff);
3092                           long imm16 = hi | lo;
3093
3094                           func (stream, "#%lu", imm16);
3095                           value_in_comment = imm16;
3096                         }
3097                         break;
3098
3099                       default:
3100                         abort ();
3101                       }
3102                     }
3103                 }
3104               else
3105                 func (stream, "%c", *c);
3106             }
3107
3108           if (value_in_comment > 32 || value_in_comment < -16)
3109             func (stream, "\t; 0x%lx", value_in_comment);
3110           return;
3111         }
3112     }
3113   abort ();
3114 }
3115
3116 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM.  */
3117
3118 static void
3119 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3120 {
3121   const struct opcode16 *insn;
3122   void *stream = info->stream;
3123   fprintf_ftype func = info->fprintf_func;
3124
3125   for (insn = thumb_opcodes; insn->assembler; insn++)
3126     if ((given & insn->mask) == insn->value)
3127       {
3128         signed long value_in_comment = 0;
3129         const char *c = insn->assembler;
3130
3131         for (; *c; c++)
3132           {
3133             int domaskpc = 0;
3134             int domasklr = 0;
3135
3136             if (*c != '%')
3137               {
3138                 func (stream, "%c", *c);
3139                 continue;
3140               }
3141
3142             switch (*++c)
3143               {
3144               case '%':
3145                 func (stream, "%%");
3146                 break;
3147
3148               case 'c':
3149                 if (ifthen_state)
3150                   func (stream, "%s", arm_conditional[IFTHEN_COND]);
3151                 break;
3152
3153               case 'C':
3154                 if (ifthen_state)
3155                   func (stream, "%s", arm_conditional[IFTHEN_COND]);
3156                 else
3157                   func (stream, "s");
3158                 break;
3159
3160               case 'I':
3161                 {
3162                   unsigned int tmp;
3163
3164                   ifthen_next_state = given & 0xff;
3165                   for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3166                     func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3167                   func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3168                 }
3169                 break;
3170
3171               case 'x':
3172                 if (ifthen_next_state)
3173                   func (stream, "\t; unpredictable branch in IT block\n");
3174                 break;
3175
3176               case 'X':
3177                 if (ifthen_state)
3178                   func (stream, "\t; unpredictable <IT:%s>",
3179                         arm_conditional[IFTHEN_COND]);
3180                 break;
3181
3182               case 'S':
3183                 {
3184                   long reg;
3185
3186                   reg = (given >> 3) & 0x7;
3187                   if (given & (1 << 6))
3188                     reg += 8;
3189
3190                   func (stream, "%s", arm_regnames[reg]);
3191                 }
3192                 break;
3193
3194               case 'D':
3195                 {
3196                   long reg;
3197
3198                   reg = given & 0x7;
3199                   if (given & (1 << 7))
3200                     reg += 8;
3201
3202                   func (stream, "%s", arm_regnames[reg]);
3203                 }
3204                 break;
3205
3206               case 'N':
3207                 if (given & (1 << 8))
3208                   domasklr = 1;
3209                 /* Fall through.  */
3210               case 'O':
3211                 if (*c == 'O' && (given & (1 << 8)))
3212                   domaskpc = 1;
3213                 /* Fall through.  */
3214               case 'M':
3215                 {
3216                   int started = 0;
3217                   int reg;
3218
3219                   func (stream, "{");
3220
3221                   /* It would be nice if we could spot
3222                      ranges, and generate the rS-rE format: */
3223                   for (reg = 0; (reg < 8); reg++)
3224                     if ((given & (1 << reg)) != 0)
3225                       {
3226                         if (started)
3227                           func (stream, ", ");
3228                         started = 1;
3229                         func (stream, "%s", arm_regnames[reg]);
3230                       }
3231
3232                   if (domasklr)
3233                     {
3234                       if (started)
3235                         func (stream, ", ");
3236                       started = 1;
3237                       func (stream, arm_regnames[14] /* "lr" */);
3238                     }
3239
3240                   if (domaskpc)
3241                     {
3242                       if (started)
3243                         func (stream, ", ");
3244                       func (stream, arm_regnames[15] /* "pc" */);
3245                     }
3246
3247                   func (stream, "}");
3248                 }
3249                 break;
3250
3251               case 'b':
3252                 /* Print ARM V6T2 CZB address: pc+4+6 bits.  */
3253                 {
3254                   bfd_vma address = (pc + 4
3255                                      + ((given & 0x00f8) >> 2)
3256                                      + ((given & 0x0200) >> 3));
3257                   info->print_address_func (address, info);
3258                 }
3259                 break;
3260
3261               case 's':
3262                 /* Right shift immediate -- bits 6..10; 1-31 print
3263                    as themselves, 0 prints as 32.  */
3264                 {
3265                   long imm = (given & 0x07c0) >> 6;
3266                   if (imm == 0)
3267                     imm = 32;
3268                   func (stream, "#%ld", imm);
3269                 }
3270                 break;
3271
3272               case '0': case '1': case '2': case '3': case '4':
3273               case '5': case '6': case '7': case '8': case '9':
3274                 {
3275                   int bitstart = *c++ - '0';
3276                   int bitend = 0;
3277
3278                   while (*c >= '0' && *c <= '9')
3279                     bitstart = (bitstart * 10) + *c++ - '0';
3280
3281                   switch (*c)
3282                     {
3283                     case '-':
3284                       {
3285                         long reg;
3286
3287                         c++;
3288                         while (*c >= '0' && *c <= '9')
3289                           bitend = (bitend * 10) + *c++ - '0';
3290                         if (!bitend)
3291                           abort ();
3292                         reg = given >> bitstart;
3293                         reg &= (2 << (bitend - bitstart)) - 1;
3294                         switch (*c)
3295                           {
3296                           case 'r':
3297                             func (stream, "%s", arm_regnames[reg]);
3298                             break;
3299
3300                           case 'd':
3301                             func (stream, "%ld", reg);
3302                             value_in_comment = reg;
3303                             break;
3304
3305                           case 'H':
3306                             func (stream, "%ld", reg << 1);
3307                             value_in_comment = reg << 1;
3308                             break;
3309
3310                           case 'W':
3311                             func (stream, "%ld", reg << 2);
3312                             value_in_comment = reg << 2;
3313                             break;
3314
3315                           case 'a':
3316                             /* PC-relative address -- the bottom two
3317                                bits of the address are dropped
3318                                before the calculation.  */
3319                             info->print_address_func
3320                               (((pc + 4) & ~3) + (reg << 2), info);
3321                             value_in_comment = 0;
3322                             break;
3323
3324                           case 'x':
3325                             func (stream, "0x%04lx", reg);
3326                             break;
3327
3328                           case 'B':
3329                             reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3330                             info->print_address_func (reg * 2 + pc + 4, info);
3331                             value_in_comment = 0;
3332                             break;
3333
3334                           case 'c':
3335                             func (stream, "%s", arm_conditional [reg]);
3336                             break;
3337
3338                           default:
3339                             abort ();
3340                           }
3341                       }
3342                       break;
3343
3344                     case '\'':
3345                       c++;
3346                       if ((given & (1 << bitstart)) != 0)
3347                         func (stream, "%c", *c);
3348                       break;
3349
3350                     case '?':
3351                       ++c;
3352                       if ((given & (1 << bitstart)) != 0)
3353                         func (stream, "%c", *c++);
3354                       else
3355                         func (stream, "%c", *++c);
3356                       break;
3357
3358                     default:
3359                       abort ();
3360                     }
3361                 }
3362                 break;
3363
3364               default:
3365                 abort ();
3366               }
3367           }
3368
3369         if (value_in_comment > 32 || value_in_comment < -16)
3370           func (stream, "\t; 0x%lx", value_in_comment);
3371         return;
3372       }
3373
3374   /* No match.  */
3375   abort ();
3376 }
3377
3378 /* Return the name of an V7M special register.  */
3379
3380 static const char *
3381 psr_name (int regno)
3382 {
3383   switch (regno)
3384     {
3385     case 0: return "APSR";
3386     case 1: return "IAPSR";
3387     case 2: return "EAPSR";
3388     case 3: return "PSR";
3389     case 5: return "IPSR";
3390     case 6: return "EPSR";
3391     case 7: return "IEPSR";
3392     case 8: return "MSP";
3393     case 9: return "PSP";
3394     case 16: return "PRIMASK";
3395     case 17: return "BASEPRI";
3396     case 18: return "BASEPRI_MASK";
3397     case 19: return "FAULTMASK";
3398     case 20: return "CONTROL";
3399     default: return "<unknown>";
3400     }
3401 }
3402
3403 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM.  */
3404
3405 static void
3406 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3407 {
3408   const struct opcode32 *insn;
3409   void *stream = info->stream;
3410   fprintf_ftype func = info->fprintf_func;
3411
3412   if (print_insn_coprocessor (pc, info, given, TRUE))
3413     return;
3414
3415   if (print_insn_neon (info, given, TRUE))
3416     return;
3417
3418   for (insn = thumb32_opcodes; insn->assembler; insn++)
3419     if ((given & insn->mask) == insn->value)
3420       {
3421         signed long value_in_comment = 0;
3422         const char *c = insn->assembler;
3423
3424         for (; *c; c++)
3425           {
3426             if (*c != '%')
3427               {
3428                 func (stream, "%c", *c);
3429                 continue;
3430               }
3431
3432             switch (*++c)
3433               {
3434               case '%':
3435                 func (stream, "%%");
3436                 break;
3437
3438               case 'c':
3439                 if (ifthen_state)
3440                   func (stream, "%s", arm_conditional[IFTHEN_COND]);
3441                 break;
3442
3443               case 'x':
3444                 if (ifthen_next_state)
3445                   func (stream, "\t; unpredictable branch in IT block\n");
3446                 break;
3447
3448               case 'X':
3449                 if (ifthen_state)
3450                   func (stream, "\t; unpredictable <IT:%s>",
3451                         arm_conditional[IFTHEN_COND]);
3452                 break;
3453
3454               case 'I':
3455                 {
3456                   unsigned int imm12 = 0;
3457
3458                   imm12 |= (given & 0x000000ffu);
3459                   imm12 |= (given & 0x00007000u) >> 4;
3460                   imm12 |= (given & 0x04000000u) >> 15;
3461                   func (stream, "#%u", imm12);
3462                   value_in_comment = imm12;
3463                 }
3464                 break;
3465
3466               case 'M':
3467                 {
3468                   unsigned int bits = 0, imm, imm8, mod;
3469
3470                   bits |= (given & 0x000000ffu);
3471                   bits |= (given & 0x00007000u) >> 4;
3472                   bits |= (given & 0x04000000u) >> 15;
3473                   imm8 = (bits & 0x0ff);
3474                   mod = (bits & 0xf00) >> 8;
3475                   switch (mod)
3476                     {
3477                     case 0: imm = imm8; break;
3478                     case 1: imm = ((imm8<<16) | imm8); break;
3479                     case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3480                     case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3481                     default:
3482                       mod  = (bits & 0xf80) >> 7;
3483                       imm8 = (bits & 0x07f) | 0x80;
3484                       imm  = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3485                     }
3486                   func (stream, "#%u", imm);
3487                   value_in_comment = imm;
3488                 }
3489                 break;
3490                   
3491               case 'J':
3492                 {
3493                   unsigned int imm = 0;
3494
3495                   imm |= (given & 0x000000ffu);
3496                   imm |= (given & 0x00007000u) >> 4;
3497                   imm |= (given & 0x04000000u) >> 15;
3498                   imm |= (given & 0x000f0000u) >> 4;
3499                   func (stream, "#%u", imm);
3500                   value_in_comment = imm;
3501                 }
3502                 break;
3503
3504               case 'K':
3505                 {
3506                   unsigned int imm = 0;
3507
3508                   imm |= (given & 0x000f0000u) >> 16;
3509                   imm |= (given & 0x00000ff0u) >> 0;
3510                   imm |= (given & 0x0000000fu) << 12;
3511                   func (stream, "#%u", imm);
3512                   value_in_comment = imm;
3513                 }
3514                 break;
3515
3516               case 'S':
3517                 {
3518                   unsigned int reg = (given & 0x0000000fu);
3519                   unsigned int stp = (given & 0x00000030u) >> 4;
3520                   unsigned int imm = 0;
3521                   imm |= (given & 0x000000c0u) >> 6;
3522                   imm |= (given & 0x00007000u) >> 10;
3523
3524                   func (stream, "%s", arm_regnames[reg]);
3525                   switch (stp)
3526                     {
3527                     case 0:
3528                       if (imm > 0)
3529                         func (stream, ", lsl #%u", imm);
3530                       break;
3531
3532                     case 1:
3533                       if (imm == 0)
3534                         imm = 32;
3535                       func (stream, ", lsr #%u", imm);
3536                       break;
3537
3538                     case 2:
3539                       if (imm == 0)
3540                         imm = 32;
3541                       func (stream, ", asr #%u", imm);
3542                       break;
3543
3544                     case 3:
3545                       if (imm == 0)
3546                         func (stream, ", rrx");
3547                       else
3548                         func (stream, ", ror #%u", imm);
3549                     }
3550                 }
3551                 break;
3552
3553               case 'a':
3554                 {
3555                   unsigned int Rn  = (given & 0x000f0000) >> 16;
3556                   unsigned int U   = (given & 0x00800000) >> 23;
3557                   unsigned int op  = (given & 0x00000f00) >> 8;
3558                   unsigned int i12 = (given & 0x00000fff);
3559                   unsigned int i8  = (given & 0x000000ff);
3560                   bfd_boolean writeback = FALSE, postind = FALSE;
3561                   int offset = 0;
3562
3563                   func (stream, "[%s", arm_regnames[Rn]);
3564                   if (U) /* 12-bit positive immediate offset.  */
3565                     {
3566                       offset = i12;
3567                       if (Rn != 15)
3568                         value_in_comment = offset;
3569                     }
3570                   else if (Rn == 15) /* 12-bit negative immediate offset.  */
3571                     offset = - (int) i12;
3572                   else if (op == 0x0) /* Shifted register offset.  */
3573                     {
3574                       unsigned int Rm = (i8 & 0x0f);
3575                       unsigned int sh = (i8 & 0x30) >> 4;
3576
3577                       func (stream, ", %s", arm_regnames[Rm]);
3578                       if (sh)
3579                         func (stream, ", lsl #%u", sh);
3580                       func (stream, "]");
3581                       break;
3582                     }
3583                   else switch (op)
3584                     {
3585                     case 0xE:  /* 8-bit positive immediate offset.  */
3586                       offset = i8;
3587                       break;
3588
3589                     case 0xC:  /* 8-bit negative immediate offset.  */
3590                       offset = -i8;
3591                       break;
3592
3593                     case 0xF:  /* 8-bit + preindex with wb.  */
3594                       offset = i8;
3595                       writeback = TRUE;
3596                       break;
3597
3598                     case 0xD:  /* 8-bit - preindex with wb.  */
3599                       offset = -i8;
3600                       writeback = TRUE;
3601                       break;
3602
3603                     case 0xB:  /* 8-bit + postindex.  */
3604                       offset = i8;
3605                       postind = TRUE;
3606                       break;
3607
3608                     case 0x9:  /* 8-bit - postindex.  */
3609                       offset = -i8;
3610                       postind = TRUE;
3611                       break;
3612
3613                     default:
3614                       func (stream, ", <undefined>]");
3615                       goto skip;
3616                     }
3617
3618                   if (postind)
3619                     func (stream, "], #%d", offset);
3620                   else
3621                     {
3622                       if (offset)
3623                         func (stream, ", #%d", offset);
3624                       func (stream, writeback ? "]!" : "]");
3625                     }
3626
3627                   if (Rn == 15)
3628                     {
3629                       func (stream, "\t; ");
3630                       info->print_address_func (((pc + 4) & ~3) + offset, info);
3631                     }
3632                 }
3633               skip:
3634                 break;
3635
3636               case 'A':
3637                 {
3638                   unsigned int P   = (given & 0x01000000) >> 24;
3639                   unsigned int U   = (given & 0x00800000) >> 23;
3640                   unsigned int W   = (given & 0x00400000) >> 21;
3641                   unsigned int Rn  = (given & 0x000f0000) >> 16;
3642                   unsigned int off = (given & 0x000000ff);
3643
3644                   func (stream, "[%s", arm_regnames[Rn]);
3645                   if (P)
3646                     {
3647                       if (off || !U)
3648                         {
3649                           func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3650                           value_in_comment = off * 4 * U ? 1 : -1;
3651                         }
3652                       func (stream, "]");
3653                       if (W)
3654                         func (stream, "!");
3655                     }
3656                   else
3657                     {
3658                       func (stream, "], ");
3659                       if (W)
3660                         {
3661                           func (stream, "#%c%u", U ? '+' : '-', off * 4);
3662                           value_in_comment = off * 4 * U ? 1 : -1;
3663                         }
3664                       else
3665                         {
3666                           func (stream, "{%u}", off);
3667                           value_in_comment = off;
3668                         }
3669                     }
3670                 }
3671                 break;
3672
3673               case 'w':
3674                 {
3675                   unsigned int Sbit = (given & 0x01000000) >> 24;
3676                   unsigned int type = (given & 0x00600000) >> 21;
3677
3678                   switch (type)
3679                     {
3680                     case 0: func (stream, Sbit ? "sb" : "b"); break;
3681                     case 1: func (stream, Sbit ? "sh" : "h"); break;
3682                     case 2:
3683                       if (Sbit)
3684                         func (stream, "??");
3685                       break;
3686                     case 3:
3687                       func (stream, "??");
3688                       break;
3689                     }
3690                 }
3691                 break;
3692
3693               case 'm':
3694                 {
3695                   int started = 0;
3696                   int reg;
3697
3698                   func (stream, "{");
3699                   for (reg = 0; reg < 16; reg++)
3700                     if ((given & (1 << reg)) != 0)
3701                       {
3702                         if (started)
3703                           func (stream, ", ");
3704                         started = 1;
3705                         func (stream, "%s", arm_regnames[reg]);
3706                       }
3707                   func (stream, "}");
3708                 }
3709                 break;
3710
3711               case 'E':
3712                 {
3713                   unsigned int msb = (given & 0x0000001f);
3714                   unsigned int lsb = 0;
3715
3716                   lsb |= (given & 0x000000c0u) >> 6;
3717                   lsb |= (given & 0x00007000u) >> 10;
3718                   func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3719                 }
3720                 break;
3721
3722               case 'F':
3723                 {
3724                   unsigned int width = (given & 0x0000001f) + 1;
3725                   unsigned int lsb = 0;
3726
3727                   lsb |= (given & 0x000000c0u) >> 6;
3728                   lsb |= (given & 0x00007000u) >> 10;
3729                   func (stream, "#%u, #%u", lsb, width);
3730                 }
3731                 break;
3732
3733               case 'b':
3734                 {
3735                   unsigned int S = (given & 0x04000000u) >> 26;
3736                   unsigned int J1 = (given & 0x00002000u) >> 13;
3737                   unsigned int J2 = (given & 0x00000800u) >> 11;
3738                   int offset = 0;
3739
3740                   offset |= !S << 20;
3741                   offset |= J2 << 19;
3742                   offset |= J1 << 18;
3743                   offset |= (given & 0x003f0000) >> 4;
3744                   offset |= (given & 0x000007ff) << 1;
3745                   offset -= (1 << 20);
3746
3747                   info->print_address_func (pc + 4 + offset, info);
3748                 }
3749                 break;
3750
3751               case 'B':
3752                 {
3753                   unsigned int S = (given & 0x04000000u) >> 26;
3754                   unsigned int I1 = (given & 0x00002000u) >> 13;
3755                   unsigned int I2 = (given & 0x00000800u) >> 11;
3756                   int offset = 0;
3757
3758                   offset |= !S << 24;
3759                   offset |= !(I1 ^ S) << 23;
3760                   offset |= !(I2 ^ S) << 22;
3761                   offset |= (given & 0x03ff0000u) >> 4;
3762                   offset |= (given & 0x000007ffu) << 1;
3763                   offset -= (1 << 24);
3764                   offset += pc + 4;
3765
3766                   /* BLX target addresses are always word aligned.  */
3767                   if ((given & 0x00001000u) == 0)
3768                       offset &= ~2u;
3769
3770                   info->print_address_func (offset, info);
3771                 }
3772                 break;
3773
3774               case 's':
3775                 {
3776                   unsigned int shift = 0;
3777
3778                   shift |= (given & 0x000000c0u) >> 6;
3779                   shift |= (given & 0x00007000u) >> 10;
3780                   if (given & 0x00200000u)
3781                     func (stream, ", asr #%u", shift);
3782                   else if (shift)
3783                     func (stream, ", lsl #%u", shift);
3784                   /* else print nothing - lsl #0 */
3785                 }
3786                 break;
3787
3788               case 'R':
3789                 {
3790                   unsigned int rot = (given & 0x00000030) >> 4;
3791
3792                   if (rot)
3793                     func (stream, ", ror #%u", rot * 8);
3794                 }
3795                 break;
3796
3797               case 'U':
3798                 switch (given & 0xf)
3799                   {
3800                   case 0xf: func (stream, "sy"); break;
3801                   case 0x7: func (stream, "un"); break;
3802                   case 0xe: func (stream, "st"); break;
3803                   case 0x6: func (stream, "unst"); break;
3804                   default:
3805                     func (stream, "#%d", (int) given & 0xf);
3806                     break;
3807                   }
3808                 break;
3809
3810               case 'C':
3811                 if ((given & 0xff) == 0)
3812                   {
3813                     func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3814                     if (given & 0x800)
3815                       func (stream, "f");
3816                     if (given & 0x400)
3817                       func (stream, "s");
3818                     if (given & 0x200)
3819                       func (stream, "x");
3820                     if (given & 0x100)
3821                       func (stream, "c");
3822                   }
3823                 else
3824                   {
3825                     func (stream, psr_name (given & 0xff));
3826                   }
3827                 break;
3828
3829               case 'D':
3830                 if ((given & 0xff) == 0)
3831                   func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3832                 else
3833                   func (stream, psr_name (given & 0xff));
3834                 break;
3835
3836               case '0': case '1': case '2': case '3': case '4':
3837               case '5': case '6': case '7': case '8': case '9':
3838                 {
3839                   int width;
3840                   unsigned long val;
3841
3842                   c = arm_decode_bitfield (c, given, &val, &width);
3843                         
3844                   switch (*c)
3845                     {
3846                     case 'd':
3847                       func (stream, "%lu", val);
3848                       value_in_comment = val;
3849                       break;
3850                     case 'W':
3851                       func (stream, "%lu", val * 4);
3852                       value_in_comment = val * 4;
3853                       break;
3854                     case 'r': func (stream, "%s", arm_regnames[val]); break;
3855
3856                     case 'c':
3857                       func (stream, "%s", arm_conditional[val]);
3858                       break;
3859
3860                     case '\'':
3861                       c++;
3862                       if (val == ((1ul << width) - 1))
3863                         func (stream, "%c", *c);
3864                       break;
3865                       
3866                     case '`':
3867                       c++;
3868                       if (val == 0)
3869                         func (stream, "%c", *c);
3870                       break;
3871
3872                     case '?':
3873                       func (stream, "%c", c[(1 << width) - (int) val]);
3874                       c += 1 << width;
3875                       break;
3876
3877                     default:
3878                       abort ();
3879                     }
3880                 }
3881                 break;
3882
3883               default:
3884                 abort ();
3885               }
3886           }
3887
3888         if (value_in_comment > 32 || value_in_comment < -16)
3889           func (stream, "\t; 0x%lx", value_in_comment);
3890         return;
3891       }
3892
3893   /* No match.  */
3894   abort ();
3895 }
3896
3897 /* Print data bytes on INFO->STREAM.  */
3898
3899 static void
3900 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3901                  struct disassemble_info *info,
3902                  long given)
3903 {
3904   switch (info->bytes_per_chunk)
3905     {
3906     case 1:
3907       info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3908       break;
3909     case 2:
3910       info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3911       break;
3912     case 4:
3913       info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3914       break;
3915     default:
3916       abort ();
3917     }
3918 }
3919
3920 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3921    being displayed in symbol relative addresses.  */
3922
3923 bfd_boolean
3924 arm_symbol_is_valid (asymbol * sym,
3925                      struct disassemble_info * info ATTRIBUTE_UNUSED)
3926 {
3927   const char * name;
3928   
3929   if (sym == NULL)
3930     return FALSE;
3931
3932   name = bfd_asymbol_name (sym);
3933
3934   return (name && *name != '$');
3935 }
3936
3937 /* Parse an individual disassembler option.  */
3938
3939 void
3940 parse_arm_disassembler_option (char *option)
3941 {
3942   if (option == NULL)
3943     return;
3944
3945   if (CONST_STRNEQ (option, "reg-names-"))
3946     {
3947       int i;
3948
3949       option += 10;
3950
3951       for (i = NUM_ARM_REGNAMES; i--;)
3952         if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3953           {
3954             regname_selected = i;
3955             break;
3956           }
3957
3958       if (i < 0)
3959         /* XXX - should break 'option' at following delimiter.  */
3960         fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3961     }
3962   else if (CONST_STRNEQ (option, "force-thumb"))
3963     force_thumb = 1;
3964   else if (CONST_STRNEQ (option, "no-force-thumb"))
3965     force_thumb = 0;
3966   else
3967     /* XXX - should break 'option' at following delimiter.  */
3968     fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3969
3970   return;
3971 }
3972
3973 /* Parse the string of disassembler options, spliting it at whitespaces
3974    or commas.  (Whitespace separators supported for backwards compatibility).  */
3975
3976 static void
3977 parse_disassembler_options (char *options)
3978 {
3979   if (options == NULL)
3980     return;
3981
3982   while (*options)
3983     {
3984       parse_arm_disassembler_option (options);
3985
3986       /* Skip forward to next seperator.  */
3987       while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3988         ++ options;
3989       /* Skip forward past seperators.  */
3990       while (ISSPACE (*options) || (*options == ','))
3991         ++ options;      
3992     }
3993 }
3994
3995 /* Search back through the insn stream to determine if this instruction is
3996    conditionally executed.  */
3997
3998 static void
3999 find_ifthen_state (bfd_vma pc,
4000                    struct disassemble_info *info,
4001                    bfd_boolean little)
4002 {
4003   unsigned char b[2];
4004   unsigned int insn;
4005   int status;
4006   /* COUNT is twice the number of instructions seen.  It will be odd if we
4007      just crossed an instruction boundary.  */
4008   int count;
4009   int it_count;
4010   unsigned int seen_it;
4011   bfd_vma addr;
4012
4013   ifthen_address = pc;
4014   ifthen_state = 0;
4015
4016   addr = pc;
4017   count = 1;
4018   it_count = 0;
4019   seen_it = 0;
4020   /* Scan backwards looking for IT instructions, keeping track of where
4021      instruction boundaries are.  We don't know if something is actually an
4022      IT instruction until we find a definite instruction boundary.  */
4023   for (;;)
4024     {
4025       if (addr == 0 || info->symbol_at_address_func (addr, info))
4026         {
4027           /* A symbol must be on an instruction boundary, and will not
4028              be within an IT block.  */
4029           if (seen_it && (count & 1))
4030             break;
4031
4032           return;
4033         }
4034       addr -= 2;
4035       status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4036       if (status)
4037         return;
4038
4039       if (little)
4040         insn = (b[0]) | (b[1] << 8);
4041       else
4042         insn = (b[1]) | (b[0] << 8);
4043       if (seen_it)
4044         {
4045           if ((insn & 0xf800) < 0xe800)
4046             {
4047               /* Addr + 2 is an instruction boundary.  See if this matches
4048                  the expected boundary based on the position of the last
4049                  IT candidate.  */
4050               if (count & 1)
4051                 break;
4052               seen_it = 0;
4053             }
4054         }
4055       if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4056         {
4057           /* This could be an IT instruction.  */
4058           seen_it = insn;
4059           it_count = count >> 1;
4060         }
4061       if ((insn & 0xf800) >= 0xe800)
4062         count++;
4063       else
4064         count = (count + 2) | 1;
4065       /* IT blocks contain at most 4 instructions.  */
4066       if (count >= 8 && !seen_it)
4067         return;
4068     }
4069   /* We found an IT instruction.  */
4070   ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4071   if ((ifthen_state & 0xf) == 0)
4072     ifthen_state = 0;
4073 }
4074
4075 /* Try to infer the code type (Arm or Thumb) from a symbol.
4076    Returns nonzero if *MAP_TYPE was set.  */
4077
4078 static int
4079 get_sym_code_type (struct disassemble_info *info,
4080                    int n,
4081                    enum map_type *map_type)
4082 {
4083   elf_symbol_type *es;
4084   unsigned int type;
4085   const char *name;
4086
4087   es = *(elf_symbol_type **)(info->symtab + n);
4088   type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4089
4090   /* If the symbol has function type then use that.  */
4091   if (type == STT_FUNC || type == STT_ARM_TFUNC)
4092     {
4093       *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4094       return TRUE;
4095     }
4096
4097   /* Check for mapping symbols.  */
4098   name = bfd_asymbol_name (info->symtab[n]);
4099   if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4100       && (name[2] == 0 || name[2] == '.'))
4101     {
4102       *map_type = ((name[1] == 'a') ? MAP_ARM
4103                    : (name[1] == 't') ? MAP_THUMB
4104                    : MAP_DATA);
4105       return TRUE;
4106     }
4107
4108   return FALSE;
4109 }
4110
4111 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4112    of the supplied arm_feature_set structure with bitmasks indicating
4113    the support base architectures and coprocessor extensions.
4114
4115    FIXME: This could more efficiently implemented as a constant array,
4116    although it would also be less robust.  */
4117
4118 static void
4119 select_arm_features (unsigned long mach,
4120                      arm_feature_set * features)
4121 {
4122 #undef  ARM_FEATURE
4123 #define ARM_FEATURE(ARCH,CEXT) \
4124   features->core = (ARCH); \
4125   features->coproc = (CEXT) | FPU_FPA; \
4126   return
4127
4128   switch (mach)
4129     {
4130     case bfd_mach_arm_2:       ARM_ARCH_V2;
4131     case bfd_mach_arm_2a:      ARM_ARCH_V2S;
4132     case bfd_mach_arm_3:       ARM_ARCH_V3;
4133     case bfd_mach_arm_3M:      ARM_ARCH_V3M;
4134     case bfd_mach_arm_4:       ARM_ARCH_V4;
4135     case bfd_mach_arm_4T:      ARM_ARCH_V4T;
4136     case bfd_mach_arm_5:       ARM_ARCH_V5;
4137     case bfd_mach_arm_5T:      ARM_ARCH_V5T;
4138     case bfd_mach_arm_5TE:     ARM_ARCH_V5TE;
4139     case bfd_mach_arm_XScale:  ARM_ARCH_XSCALE;
4140     case bfd_mach_arm_ep9312:  ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4141     case bfd_mach_arm_iWMMXt:  ARM_ARCH_IWMMXT;
4142     case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4143       /* If the machine type is unknown allow all
4144          architecture types and all extensions.  */
4145     case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4146     default:
4147       abort ();
4148     }
4149 }
4150
4151
4152 /* NOTE: There are no checks in these routines that
4153    the relevant number of data bytes exist.  */
4154
4155 static int
4156 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4157 {
4158   unsigned char b[4];
4159   long          given;
4160   int           status;
4161   int           is_thumb = FALSE;
4162   int           is_data = FALSE;
4163   int           little_code;
4164   unsigned int  size = 4;
4165   void          (*printer) (bfd_vma, struct disassemble_info *, long);
4166   bfd_boolean   found = FALSE;
4167
4168   if (info->disassembler_options)
4169     {
4170       parse_disassembler_options (info->disassembler_options);
4171
4172       /* To avoid repeated parsing of these options, we remove them here.  */
4173       info->disassembler_options = NULL;
4174     }
4175
4176   /* PR 10288: Control which instructions will be disassembled.  */
4177   if (info->private_data == NULL)
4178     {
4179       static arm_feature_set features;
4180
4181       if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4182         /* If the user did not use the -m command line switch then default to
4183            disassembling all types of ARM instruction.
4184            
4185            The info->mach value has to be ignored as this will be based on
4186            the default archictecture for the target and/or hints in the notes
4187            section, but it will never be greater than the current largest arm
4188            machine value (iWMMXt2), which is only equivalent to the V5TE
4189            architecture.  ARM architectures have advanced beyond the machine
4190            value encoding, and these newer architectures would be ignored if
4191            the machine value was used.
4192
4193            Ie the -m switch is used to restrict which instructions will be
4194            disassembled.  If it is necessary to use the -m switch to tell
4195            objdump that an ARM binary is being disassembled, eg because the
4196            input is a raw binary file, but it is also desired to disassemble
4197            all ARM instructions then use "-marm".  This will select the
4198            "unknown" arm architecture which is compatible with any ARM
4199            instruction.  */
4200           info->mach = bfd_mach_arm_unknown;
4201
4202       /* Compute the architecture bitmask from the machine number.
4203          Note: This assumes that the machine number will not change
4204          during disassembly....  */
4205       select_arm_features (info->mach, & features);
4206
4207       info->private_data = & features;
4208     }
4209   
4210   /* Decide if our code is going to be little-endian, despite what the
4211      function argument might say.  */
4212   little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4213
4214   /* First check the full symtab for a mapping symbol, even if there
4215      are no usable non-mapping symbols for this address.  */
4216   if (info->symtab != NULL
4217       && * info->symtab
4218       && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4219     {
4220       bfd_vma addr;
4221       int n;
4222       int last_sym = -1;
4223       enum map_type type = MAP_ARM;
4224
4225       if (pc <= last_mapping_addr)
4226         last_mapping_sym = -1;
4227       is_thumb = (last_type == MAP_THUMB);
4228       found = FALSE;
4229       /* Start scanning at the start of the function, or wherever
4230          we finished last time.  */
4231       n = info->symtab_pos + 1;
4232       if (n < last_mapping_sym)
4233         n = last_mapping_sym;
4234
4235       /* Scan up to the location being disassembled.  */
4236       for (; n < info->symtab_size; n++)
4237         {
4238           addr = bfd_asymbol_value (info->symtab[n]);
4239           if (addr > pc)
4240             break;
4241           if ((info->section == NULL
4242                || info->section == info->symtab[n]->section)
4243               && get_sym_code_type (info, n, &type))
4244             {
4245               last_sym = n;
4246               found = TRUE;
4247             }
4248         }
4249
4250       if (!found)
4251         {
4252           n = info->symtab_pos;
4253           if (n < last_mapping_sym - 1)
4254             n = last_mapping_sym - 1;
4255
4256           /* No mapping symbol found at this address.  Look backwards
4257              for a preceeding one.  */
4258           for (; n >= 0; n--)
4259             {
4260               if ((info->section == NULL
4261                    || info->section == info->symtab[n]->section)
4262                   && get_sym_code_type (info, n, &type))
4263                 {
4264                   last_sym = n;
4265                   found = TRUE;
4266                   break;
4267                 }
4268             }
4269         }
4270
4271       last_mapping_sym = last_sym;
4272       last_type = type;
4273       is_thumb = (last_type == MAP_THUMB);
4274       is_data = (last_type == MAP_DATA);
4275
4276       /* Look a little bit ahead to see if we should print out
4277          two or four bytes of data.  If there's a symbol,
4278          mapping or otherwise, after two bytes then don't
4279          print more.  */
4280       if (is_data)
4281         {
4282           size = 4 - (pc & 3);
4283           for (n = last_sym + 1; n < info->symtab_size; n++)
4284             {
4285               addr = bfd_asymbol_value (info->symtab[n]);
4286               if (addr > pc)
4287                 {
4288                   if (addr - pc < size)
4289                     size = addr - pc;
4290                   break;
4291                 }
4292             }
4293           /* If the next symbol is after three bytes, we need to
4294              print only part of the data, so that we can use either
4295              .byte or .short.  */
4296           if (size == 3)
4297             size = (pc & 1) ? 1 : 2;
4298         }
4299     }
4300
4301   if (info->symbols != NULL)
4302     {
4303       if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4304         {
4305           coff_symbol_type * cs;
4306
4307           cs = coffsymbol (*info->symbols);
4308           is_thumb = (   cs->native->u.syment.n_sclass == C_THUMBEXT
4309                       || cs->native->u.syment.n_sclass == C_THUMBSTAT
4310                       || cs->native->u.syment.n_sclass == C_THUMBLABEL
4311                       || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4312                       || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4313         }
4314       else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4315                && !found)
4316         {
4317           /* If no mapping symbol has been found then fall back to the type
4318              of the function symbol.  */
4319           elf_symbol_type *  es;
4320           unsigned int       type;
4321
4322           es = *(elf_symbol_type **)(info->symbols);
4323           type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4324
4325           is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4326         }
4327     }
4328
4329   if (force_thumb)
4330     is_thumb = TRUE;
4331
4332   if (is_data)
4333     info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4334   else
4335     info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4336
4337   info->bytes_per_line = 4;
4338
4339   /* PR 10263: Disassemble data if requested to do so by the user.  */
4340   if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4341     {
4342       int i;
4343
4344       /* Size was already set above.  */
4345       info->bytes_per_chunk = size;
4346       printer = print_insn_data;
4347
4348       status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4349       given = 0;
4350       if (little)
4351         for (i = size - 1; i >= 0; i--)
4352           given = b[i] | (given << 8);
4353       else
4354         for (i = 0; i < (int) size; i++)
4355           given = b[i] | (given << 8);
4356     }
4357   else if (!is_thumb)
4358     {
4359       /* In ARM mode endianness is a straightforward issue: the instruction
4360          is four bytes long and is either ordered 0123 or 3210.  */
4361       printer = print_insn_arm;
4362       info->bytes_per_chunk = 4;
4363       size = 4;
4364
4365       status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4366       if (little_code)
4367         given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4368       else
4369         given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4370     }
4371   else
4372     {
4373       /* In Thumb mode we have the additional wrinkle of two
4374          instruction lengths.  Fortunately, the bits that determine
4375          the length of the current instruction are always to be found
4376          in the first two bytes.  */
4377       printer = print_insn_thumb16;
4378       info->bytes_per_chunk = 2;
4379       size = 2;
4380
4381       status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4382       if (little_code)
4383         given = (b[0]) | (b[1] << 8);
4384       else
4385         given = (b[1]) | (b[0] << 8);
4386
4387       if (!status)
4388         {
4389           /* These bit patterns signal a four-byte Thumb
4390              instruction.  */
4391           if ((given & 0xF800) == 0xF800
4392               || (given & 0xF800) == 0xF000
4393               || (given & 0xF800) == 0xE800)
4394             {
4395               status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4396               if (little_code)
4397                 given = (b[0]) | (b[1] << 8) | (given << 16);
4398               else
4399                 given = (b[1]) | (b[0] << 8) | (given << 16);
4400
4401               printer = print_insn_thumb32;
4402               size = 4;
4403             }
4404         }
4405
4406       if (ifthen_address != pc)
4407         find_ifthen_state (pc, info, little_code);
4408
4409       if (ifthen_state)
4410         {
4411           if ((ifthen_state & 0xf) == 0x8)
4412             ifthen_next_state = 0;
4413           else
4414             ifthen_next_state = (ifthen_state & 0xe0)
4415                                 | ((ifthen_state & 0xf) << 1);
4416         }
4417     }
4418
4419   if (status)
4420     {
4421       info->memory_error_func (status, pc, info);
4422       return -1;
4423     }
4424   if (info->flags & INSN_HAS_RELOC)
4425     /* If the instruction has a reloc associated with it, then
4426        the offset field in the instruction will actually be the
4427        addend for the reloc.  (We are using REL type relocs).
4428        In such cases, we can ignore the pc when computing
4429        addresses, since the addend is not currently pc-relative.  */
4430     pc = 0;
4431
4432   printer (pc, info, given);
4433
4434   if (is_thumb)
4435     {
4436       ifthen_state = ifthen_next_state;
4437       ifthen_address += size;
4438     }
4439   return size;
4440 }
4441
4442 int
4443 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4444 {
4445   /* Detect BE8-ness and record it in the disassembler info.  */
4446   if (info->flavour == bfd_target_elf_flavour
4447       && info->section != NULL
4448       && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4449     info->endian_code = BFD_ENDIAN_LITTLE;
4450
4451   return print_insn (pc, info, FALSE);
4452 }
4453
4454 int
4455 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4456 {
4457   return print_insn (pc, info, TRUE);
4458 }
4459
4460 void
4461 print_arm_disassembler_options (FILE *stream)
4462 {
4463   int i;
4464
4465   fprintf (stream, _("\n\
4466 The following ARM specific disassembler options are supported for use with\n\
4467 the -M switch:\n"));
4468
4469   for (i = NUM_ARM_REGNAMES; i--;)
4470     fprintf (stream, "  reg-names-%s %*c%s\n",
4471              regnames[i].name,
4472              (int)(14 - strlen (regnames[i].name)), ' ',
4473              regnames[i].description);
4474
4475   fprintf (stream, "  force-thumb              Assume all insns are Thumb insns\n");
4476   fprintf (stream, "  no-force-thumb           Examine preceeding label to determine an insn's type\n\n");
4477 }