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