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