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