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