OSDN Git Service

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