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