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