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