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