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