gas/
[binutils.git] / opcodes / arm-dis.c
blob2e6d4e8ef38a50a591f4e3dfe7027d250bb367f2
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009, 2010 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 library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
24 #include "sysdep.h"
26 #include "dis-asm.h"
27 #include "opcode/arm.h"
28 #include "opintl.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
32 /* FIXME: This shouldn't be done here. */
33 #include "coff/internal.h"
34 #include "libcoff.h"
35 #include "elf-bfd.h"
36 #include "elf/internal.h"
37 #include "elf/arm.h"
39 /* FIXME: Belongs in global header. */
40 #ifndef strneq
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
42 #endif
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
46 #endif
48 /* Cached mapping symbol state. */
49 enum map_type
51 MAP_ARM,
52 MAP_THUMB,
53 MAP_DATA
56 struct arm_private_data
58 /* The features to use when disassembling optional instructions. */
59 arm_feature_set features;
61 /* Whether any mapping symbols are present in the provided symbol
62 table. -1 if we do not know yet, otherwise 0 or 1. */
63 int has_mapping_symbols;
65 /* Track the last type (although this doesn't seem to be useful) */
66 enum map_type last_type;
68 /* Tracking symbol table information */
69 int last_mapping_sym;
70 bfd_vma last_mapping_addr;
73 struct opcode32
75 unsigned long arch; /* Architecture defining this insn. */
76 unsigned long value; /* If arch == 0 then value is a sentinel. */
77 unsigned long mask; /* Recognise insn if (op & mask) == value. */
78 const char * assembler; /* How to disassemble this insn. */
81 struct opcode16
83 unsigned long arch; /* Architecture defining this insn. */
84 unsigned short value, mask; /* Recognise insn if (op & mask) == value. */
85 const char *assembler; /* How to disassemble this insn. */
88 /* print_insn_coprocessor recognizes the following format control codes:
90 %% %
92 %c print condition code (always bits 28-31 in ARM mode)
93 %q print shifter argument
94 %u print condition code (unconditional in ARM mode)
95 %A print address for ldc/stc/ldf/stf instruction
96 %B print vstm/vldm register list
97 %I print cirrus signed shift immediate: bits 0..3|4..6
98 %F print the COUNT field of a LFM/SFM instruction.
99 %P print floating point precision in arithmetic insn
100 %Q print floating point precision in ldf/stf insn
101 %R print floating point rounding mode
103 %<bitfield>r print as an ARM register
104 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
105 %<bitfield>ru as %<>r but each u register must be unique.
106 %<bitfield>d print the bitfield in decimal
107 %<bitfield>k print immediate for VFPv3 conversion instruction
108 %<bitfield>x print the bitfield in hex
109 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
110 %<bitfield>f print a floating point constant if >7 else a
111 floating point register
112 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
113 %<bitfield>g print as an iWMMXt 64-bit register
114 %<bitfield>G print as an iWMMXt general purpose or control register
115 %<bitfield>D print as a NEON D register
116 %<bitfield>Q print as a NEON Q register
118 %y<code> print a single precision VFP reg.
119 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
120 %z<code> print a double precision VFP reg
121 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
123 %<bitfield>'c print specified char iff bitfield is all ones
124 %<bitfield>`c print specified char iff bitfield is all zeroes
125 %<bitfield>?ab... select from array of values in big endian order
127 %L print as an iWMMXt N/M width field.
128 %Z print the Immediate of a WSHUFH instruction.
129 %l like 'A' except use byte offsets for 'B' & 'H'
130 versions.
131 %i print 5-bit immediate in bits 8,3..0
132 (print "32" when 0)
133 %r print register offset address for wldt/wstr instruction. */
135 enum opcode_sentinel_enum
137 SENTINEL_IWMMXT_START = 1,
138 SENTINEL_IWMMXT_END,
139 SENTINEL_GENERIC_START
140 } opcode_sentinels;
142 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
143 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
145 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
147 static const struct opcode32 coprocessor_opcodes[] =
149 /* XScale instructions. */
150 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
151 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
152 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
153 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
154 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
156 /* Intel Wireless MMX technology instructions. */
157 { 0, SENTINEL_IWMMXT_START, 0, "" },
158 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
159 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
160 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
161 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
162 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
163 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
164 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
165 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
166 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
167 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
168 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
169 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
170 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
171 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
172 {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
173 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
174 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
175 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
176 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
177 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
178 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
179 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
180 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
186 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
187 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
188 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
190 {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
191 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
192 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
193 {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
194 {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
196 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
197 {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
199 {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
200 {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
202 {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
203 {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
205 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
206 {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
207 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
208 {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
209 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
210 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
211 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
212 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
213 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
214 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
215 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
216 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
217 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
218 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
219 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
220 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
221 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
222 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
223 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
224 {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
225 {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
226 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
227 {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
228 {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
229 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
230 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
231 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
232 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
233 { 0, SENTINEL_IWMMXT_END, 0, "" },
235 /* Floating point coprocessor (FPA) instructions. */
236 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
237 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
238 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
239 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
243 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
244 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
245 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
246 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
247 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
248 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
249 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
250 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
251 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
252 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
253 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
254 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
255 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
256 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
257 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
258 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
259 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
260 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
261 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
262 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
263 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
264 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
265 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
266 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
267 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
268 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
269 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
270 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
271 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
272 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
273 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
274 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
275 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
276 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
277 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
278 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
280 /* Register load/store. */
281 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
282 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
283 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
284 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
285 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
286 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
287 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
288 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
289 {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
290 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
291 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
292 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
293 {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
294 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
295 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
296 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
298 {FPU_VFP_EXT_V1xD, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
299 {FPU_VFP_EXT_V1xD, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
300 {FPU_VFP_EXT_V1xD, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
301 {FPU_VFP_EXT_V1xD, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
303 /* Data transfer between ARM and NEON registers. */
304 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
305 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
306 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
307 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
308 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
309 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
310 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
311 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
312 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
313 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
314 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
315 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
316 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
317 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
318 /* Half-precision conversion instructions. */
319 {FPU_VFP_EXT_FP16, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
320 {FPU_VFP_EXT_FP16, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
322 /* Floating point coprocessor (VFP) instructions. */
323 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
324 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
325 {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
326 {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
327 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
328 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
329 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
330 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
331 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
332 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
333 {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
334 {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
335 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
336 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
337 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
338 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
339 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
340 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
341 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
342 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
343 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
344 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
345 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
346 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
347 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
348 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
349 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
350 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
351 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
352 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
353 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
354 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
355 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
356 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
357 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
358 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
359 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
360 {FPU_VFP_EXT_V3xD, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
361 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
362 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
363 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
364 {FPU_VFP_EXT_V3xD, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
365 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
366 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
367 {FPU_VFP_EXT_V3xD, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
368 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
369 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
370 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
371 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
372 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
373 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
374 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
375 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
376 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
377 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
378 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
379 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
380 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
381 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
382 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
383 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
384 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
385 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
386 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
387 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
388 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
389 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
391 /* Cirrus coprocessor instructions. */
392 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
393 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
394 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
395 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
396 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
397 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
398 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
399 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
400 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
401 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
402 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
403 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
404 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
405 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
406 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
407 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
408 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
409 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
410 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
411 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
412 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
413 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
414 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
415 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
416 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
417 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
418 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
419 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
420 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
421 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
422 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
423 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
424 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
425 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
426 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
427 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
428 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
429 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
430 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
431 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
432 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
433 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
434 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
435 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
436 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
437 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
438 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
439 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
440 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
441 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
442 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
443 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
444 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
445 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
446 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
447 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
448 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
449 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
450 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
451 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
452 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
453 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
454 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
455 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
456 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
457 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
458 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
459 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
460 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
461 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
462 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
463 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
464 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
465 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
466 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
467 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
468 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
469 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
470 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
471 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
473 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
475 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
477 /* VFP Fused multiply add instructions. */
478 {FPU_VFP_EXT_FMA, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
479 {FPU_VFP_EXT_FMA, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
480 {FPU_VFP_EXT_FMA, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
481 {FPU_VFP_EXT_FMA, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
482 {FPU_VFP_EXT_FMA, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
483 {FPU_VFP_EXT_FMA, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
484 {FPU_VFP_EXT_FMA, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
485 {FPU_VFP_EXT_FMA, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
487 /* Generic coprocessor instructions. */
488 { 0, SENTINEL_GENERIC_START, 0, "" },
489 {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
490 {ARM_EXT_V5E, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
491 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
492 {ARM_EXT_V2, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
493 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
494 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
495 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
496 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
498 /* V6 coprocessor instructions. */
499 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
500 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
502 /* V5 coprocessor instructions. */
503 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
504 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
505 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
506 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
507 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
509 {0, 0, 0, 0}
512 /* Neon opcode table: This does not encode the top byte -- that is
513 checked by the print_insn_neon routine, as it depends on whether we are
514 doing thumb32 or arm32 disassembly. */
516 /* print_insn_neon recognizes the following format control codes:
518 %% %
520 %c print condition code
521 %A print v{st,ld}[1234] operands
522 %B print v{st,ld}[1234] any one operands
523 %C print v{st,ld}[1234] single->all operands
524 %D print scalar
525 %E print vmov, vmvn, vorr, vbic encoded constant
526 %F print vtbl,vtbx register list
528 %<bitfield>r print as an ARM register
529 %<bitfield>d print the bitfield in decimal
530 %<bitfield>e print the 2^N - bitfield in decimal
531 %<bitfield>D print as a NEON D register
532 %<bitfield>Q print as a NEON Q register
533 %<bitfield>R print as a NEON D or Q register
534 %<bitfield>Sn print byte scaled width limited by n
535 %<bitfield>Tn print short scaled width limited by n
536 %<bitfield>Un print long scaled width limited by n
538 %<bitfield>'c print specified char iff bitfield is all ones
539 %<bitfield>`c print specified char iff bitfield is all zeroes
540 %<bitfield>?ab... select from array of values in big endian order. */
542 static const struct opcode32 neon_opcodes[] =
544 /* Extract. */
545 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
546 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
548 /* Move data element to all lanes. */
549 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
550 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
551 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
553 /* Table lookup. */
554 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
555 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
557 /* Half-precision conversions. */
558 {FPU_VFP_EXT_FP16, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
559 {FPU_VFP_EXT_FP16, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
561 /* NEON fused multiply add instructions. */
562 {FPU_NEON_EXT_FMA, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
563 {FPU_NEON_EXT_FMA, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
565 /* Two registers, miscellaneous. */
566 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
567 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
568 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
569 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
570 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
571 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
572 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
573 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
574 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
575 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
576 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
577 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
578 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
579 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
580 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
581 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
582 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
583 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
584 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
585 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
586 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
587 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
588 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
589 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
590 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
591 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
592 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
593 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
594 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
595 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
596 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
597 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
598 {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"},
600 /* Three registers of the same length. */
601 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
602 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
616 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
617 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
618 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
619 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
625 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
626 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
627 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
628 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
629 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
630 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
631 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
632 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
633 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
634 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
636 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
637 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
638 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
639 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
641 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
642 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
643 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
644 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
645 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
646 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
647 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
648 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
649 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
650 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
651 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
652 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
653 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
655 /* One register and an immediate value. */
656 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
657 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
658 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
659 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
660 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
661 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
662 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
663 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
664 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
665 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
666 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
667 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
668 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
670 /* Two registers and a shift amount. */
671 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
672 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
673 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
674 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
675 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
676 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
677 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
678 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
679 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
680 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
681 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
682 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
683 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
684 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
685 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
686 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
687 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
688 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
689 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
690 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
691 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
692 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
693 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
694 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
695 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
696 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
697 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
698 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
699 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
700 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
701 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
702 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
703 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
704 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
705 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
706 {FPU_NEON_EXT_V1, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
707 {FPU_NEON_EXT_V1, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
708 {FPU_NEON_EXT_V1, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
709 {FPU_NEON_EXT_V1, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
710 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
711 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
712 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
713 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
714 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
715 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
716 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
717 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
718 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
719 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
720 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
721 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
722 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
723 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
724 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
725 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
726 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
727 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
728 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
730 /* Three registers of different lengths. */
731 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
732 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
733 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
734 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
735 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
736 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
737 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
738 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
739 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
740 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
741 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
742 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
743 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
744 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
745 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
746 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
747 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
749 /* Two registers and a scalar. */
750 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
751 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
752 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
753 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
754 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
755 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
756 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
757 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
758 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
759 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
760 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
761 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
762 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
763 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
764 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
765 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
766 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
767 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
768 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
769 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
770 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
771 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
773 /* Element and structure load/store. */
774 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
775 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
776 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
777 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
778 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
779 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
780 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
781 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
782 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
783 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
784 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
785 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
786 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
787 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
788 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
789 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
790 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
791 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
792 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
794 {0,0 ,0, 0}
797 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
798 ordered: they must be searched linearly from the top to obtain a correct
799 match. */
801 /* print_insn_arm recognizes the following format control codes:
803 %% %
805 %a print address for ldr/str instruction
806 %s print address for ldr/str halfword/signextend instruction
807 %S like %s but allow UNPREDICTABLE addressing
808 %b print branch destination
809 %c print condition code (always bits 28-31)
810 %m print register mask for ldm/stm instruction
811 %o print operand2 (immediate or register + shift)
812 %p print 'p' iff bits 12-15 are 15
813 %t print 't' iff bit 21 set and bit 24 clear
814 %B print arm BLX(1) destination
815 %C print the PSR sub type.
816 %U print barrier type.
817 %P print address for pli instruction.
819 %<bitfield>r print as an ARM register
820 %<bitfield>R as %r but r15 is UNPREDICTABLE
821 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
822 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
823 %<bitfield>d print the bitfield in decimal
824 %<bitfield>W print the bitfield plus one in decimal
825 %<bitfield>x print the bitfield in hex
826 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
828 %<bitfield>'c print specified char iff bitfield is all ones
829 %<bitfield>`c print specified char iff bitfield is all zeroes
830 %<bitfield>?ab... select from array of values in big endian order
832 %e print arm SMI operand (bits 0..7,8..19).
833 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
834 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
835 %R print the SPSR/CPSR or banked register of an MRS. */
837 static const struct opcode32 arm_opcodes[] =
839 /* ARM instructions. */
840 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
841 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
842 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
843 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
844 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
845 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
846 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
848 /* Virtualization Extension instructions. */
849 {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
850 {ARM_EXT_VIRT, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
852 /* Integer Divide Extension instructions. */
853 {ARM_EXT_ADIV, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
854 {ARM_EXT_ADIV, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
856 /* MP Extension instructions. */
857 {ARM_EXT_MP, 0xf410f000, 0xfc70f000, "pldw\t%a"},
859 /* V7 instructions. */
860 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
861 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
862 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
863 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
864 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
866 /* ARM V6T2 instructions. */
867 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
868 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
869 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
870 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
872 {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
873 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
875 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
876 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
877 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
878 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
880 /* ARM Security extension instructions. */
881 {ARM_EXT_SEC, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
883 /* ARM V6K instructions. */
884 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
885 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
886 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
887 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
888 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
889 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
890 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
892 /* ARM V6K NOP hints. */
893 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
894 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
895 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
896 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
897 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
899 /* ARM V6 instructions. */
900 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
901 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
902 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
903 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
904 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
905 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
906 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
907 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
908 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
909 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
910 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
911 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
920 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
921 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
922 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
923 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
924 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
925 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
926 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
927 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
928 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
929 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
930 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
931 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
932 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
933 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
934 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
935 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
936 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
937 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
938 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
939 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
940 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
941 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
942 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
943 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
944 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
945 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
946 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
947 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
948 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
949 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
950 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
951 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
952 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
953 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
954 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
955 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
956 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
957 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
958 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
959 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
960 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
961 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
962 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
963 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
964 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
965 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
966 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
967 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
968 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
969 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
970 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
971 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
972 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
973 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
974 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
975 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
976 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
977 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
978 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
979 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
980 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
981 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
982 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
983 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
984 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
985 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
986 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
987 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
988 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
989 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
990 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
991 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
992 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
993 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
994 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
995 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
996 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
997 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
998 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
999 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
1000 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
1001 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
1002 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1003 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1004 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1005 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1006 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
1007 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1008 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1009 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
1010 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
1011 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
1012 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
1013 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
1014 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1015 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1016 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1017 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1018 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1019 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1020 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1021 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1023 /* V5J instruction. */
1024 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1026 /* V5 Instructions. */
1027 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1028 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
1029 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1030 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1032 /* V5E "El Segundo" Instructions. */
1033 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1034 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1035 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
1036 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1037 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1038 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1039 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1041 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1042 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1044 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1045 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1046 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1047 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1049 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1050 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1051 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1052 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1054 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1055 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1057 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1058 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1059 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1060 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1062 /* ARM Instructions. */
1063 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1065 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1066 {ARM_EXT_V1, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1067 {ARM_EXT_V1, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1068 {ARM_EXT_V1, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1069 {ARM_EXT_V1, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1070 {ARM_EXT_V1, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1072 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1073 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1074 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1075 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1077 {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
1078 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1079 {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
1080 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1082 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1083 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1086 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1087 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1090 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1091 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1094 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1095 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1096 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1098 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1099 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1100 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1102 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1103 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1104 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1106 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1107 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1108 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1110 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1111 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1112 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1114 {ARM_EXT_VIRT, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1115 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1116 {ARM_EXT_V3, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1118 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1119 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1120 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1122 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1123 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1124 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1126 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1127 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1128 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1130 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1131 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1132 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1134 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1135 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1136 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1138 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1139 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1140 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1141 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1142 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1143 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1144 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1146 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1147 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1148 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1150 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1151 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1152 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1154 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1155 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1157 {ARM_EXT_V1, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1159 {ARM_EXT_V1, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1160 {ARM_EXT_V1, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1162 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1163 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1164 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1165 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1166 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1167 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1168 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1169 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1171 /* The rest. */
1172 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1173 {0, 0x00000000, 0x00000000, 0}
1176 /* print_insn_thumb16 recognizes the following format control codes:
1178 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1179 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1180 %<bitfield>I print bitfield as a signed decimal
1181 (top bit of range being the sign bit)
1182 %N print Thumb register mask (with LR)
1183 %O print Thumb register mask (with PC)
1184 %M print Thumb register mask
1185 %b print CZB's 6-bit unsigned branch destination
1186 %s print Thumb right-shift immediate (6..10; 0 == 32).
1187 %c print the condition code
1188 %C print the condition code, or "s" if not conditional
1189 %x print warning if conditional an not at end of IT block"
1190 %X print "\t; unpredictable <IT:code>" if conditional
1191 %I print IT instruction suffix and operands
1192 %W print Thumb Writeback indicator for LDMIA
1193 %<bitfield>r print bitfield as an ARM register
1194 %<bitfield>d print bitfield as a decimal
1195 %<bitfield>H print (bitfield * 2) as a decimal
1196 %<bitfield>W print (bitfield * 4) as a decimal
1197 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1198 %<bitfield>B print Thumb branch destination (signed displacement)
1199 %<bitfield>c print bitfield as a condition code
1200 %<bitnum>'c print specified char iff bit is one
1201 %<bitnum>?ab print a if bit is one else print b. */
1203 static const struct opcode16 thumb_opcodes[] =
1205 /* Thumb instructions. */
1207 /* ARM V6K no-argument instructions. */
1208 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1209 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1210 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1211 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1212 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1213 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1215 /* ARM V6T2 instructions. */
1216 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1217 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1218 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1220 /* ARM V6. */
1221 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1222 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1223 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1224 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1225 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1226 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1227 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1228 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1229 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1230 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1231 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1233 /* ARM V5 ISA extends Thumb. */
1234 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1235 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1236 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1237 /* ARM V4T ISA (Thumb v1). */
1238 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1239 /* Format 4. */
1240 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1241 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1242 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1243 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1244 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1245 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1246 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1247 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1248 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1249 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1250 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1251 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1252 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1253 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1254 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1255 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1256 /* format 13 */
1257 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1258 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1259 /* format 5 */
1260 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1261 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1262 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1263 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1264 /* format 14 */
1265 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1266 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1267 /* format 2 */
1268 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1269 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1270 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1271 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1272 /* format 8 */
1273 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1274 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1275 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1276 /* format 7 */
1277 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1278 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1279 /* format 1 */
1280 {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1281 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1282 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1283 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1284 /* format 3 */
1285 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1286 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1287 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1288 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1289 /* format 6 */
1290 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1291 /* format 9 */
1292 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1293 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1294 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1295 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1296 /* format 10 */
1297 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1298 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1299 /* format 11 */
1300 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1301 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1302 /* format 12 */
1303 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1304 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1305 /* format 15 */
1306 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1307 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1308 /* format 17 */
1309 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1310 /* format 16 */
1311 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1312 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1313 /* format 18 */
1314 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1316 /* The E800 .. FFFF range is unconditionally redirected to the
1317 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1318 are processed via that table. Thus, we can never encounter a
1319 bare "second half of BL/BLX(1)" instruction here. */
1320 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1321 {0, 0, 0, 0}
1324 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1325 We adopt the convention that hw1 is the high 16 bits of .value and
1326 .mask, hw2 the low 16 bits.
1328 print_insn_thumb32 recognizes the following format control codes:
1330 %% %
1332 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1333 %M print a modified 12-bit immediate (same location)
1334 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1335 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1336 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1337 %S print a possibly-shifted Rm
1339 %L print address for a ldrd/strd instruction
1340 %a print the address of a plain load/store
1341 %w print the width and signedness of a core load/store
1342 %m print register mask for ldm/stm
1344 %E print the lsb and width fields of a bfc/bfi instruction
1345 %F print the lsb and width fields of a sbfx/ubfx instruction
1346 %b print a conditional branch offset
1347 %B print an unconditional branch offset
1348 %s print the shift field of an SSAT instruction
1349 %R print the rotation field of an SXT instruction
1350 %U print barrier type.
1351 %P print address for pli instruction.
1352 %c print the condition code
1353 %x print warning if conditional an not at end of IT block"
1354 %X print "\t; unpredictable <IT:code>" if conditional
1356 %<bitfield>d print bitfield in decimal
1357 %<bitfield>W print bitfield*4 in decimal
1358 %<bitfield>r print bitfield as an ARM register
1359 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1360 %<bitfield>c print bitfield as a condition code
1362 %<bitfield>'c print specified char iff bitfield is all ones
1363 %<bitfield>`c print specified char iff bitfield is all zeroes
1364 %<bitfield>?ab... select from array of values in big endian order
1366 With one exception at the bottom (done because BL and BLX(1) need
1367 to come dead last), this table was machine-sorted first in
1368 decreasing order of number of bits set in the mask, then in
1369 increasing numeric order of mask, then in increasing numeric order
1370 of opcode. This order is not the clearest for a human reader, but
1371 is guaranteed never to catch a special-case bit pattern with a more
1372 general mask, which is important, because this instruction encoding
1373 makes heavy use of special-case bit patterns. */
1374 static const struct opcode32 thumb32_opcodes[] =
1376 /* V7 instructions. */
1377 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1378 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1379 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1380 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1381 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1382 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1385 /* Virtualization Extension instructions. */
1386 {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1387 /* We skip ERET as that is SUBS pc, lr, #0. */
1389 /* MP Extension instructions. */
1390 {ARM_EXT_MP, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1392 /* Security extension instructions. */
1393 {ARM_EXT_SEC, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1395 /* Instructions defined in the basic V6T2 set. */
1396 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1397 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1398 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1399 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1400 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1401 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1403 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1404 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1405 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1406 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1407 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1408 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1409 {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1410 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1411 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1412 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1413 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1414 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1415 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1416 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1417 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1418 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1419 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1420 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1421 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1422 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1423 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1424 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1425 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1426 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1427 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1428 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1429 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1430 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1431 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1432 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1433 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1434 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1436 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1437 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1438 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1439 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1440 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1441 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1442 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1443 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1444 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1445 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1446 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1447 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1448 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1449 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1452 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1453 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1454 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1455 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1456 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1457 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1459 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1460 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1461 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1462 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1463 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1464 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1466 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1467 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1468 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1469 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1470 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1471 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1472 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1473 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1474 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1475 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1476 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1477 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1478 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1479 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1480 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1481 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1482 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1483 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1484 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1485 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1486 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1487 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1488 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1489 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1490 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1491 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1492 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1493 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1494 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1495 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1496 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1497 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1498 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1499 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1500 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1501 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1502 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1503 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1504 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1505 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1506 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1507 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1508 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1509 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1510 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1511 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1512 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1513 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1514 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1515 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1516 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1517 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1518 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1519 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1520 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1521 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1522 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1523 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1524 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1525 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1526 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1527 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1528 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1529 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1530 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1531 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1532 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1533 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1534 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1535 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1536 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1537 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1538 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1539 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1540 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1541 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1542 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1543 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1544 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1545 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1546 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1547 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1548 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1549 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1550 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1551 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1552 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1553 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1554 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1555 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1556 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1557 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1558 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1559 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1560 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1561 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1562 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1563 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1564 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1565 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1566 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1567 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1568 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1569 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1570 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1571 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1572 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1573 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1575 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1576 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1577 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1578 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1579 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1581 /* These have been 32-bit since the invention of Thumb. */
1582 {ARM_EXT_V4T, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1583 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1585 /* Fallback. */
1586 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1587 {0, 0, 0, 0}
1590 static const char *const arm_conditional[] =
1591 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1592 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1594 static const char *const arm_fp_const[] =
1595 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1597 static const char *const arm_shift[] =
1598 {"lsl", "lsr", "asr", "ror"};
1600 typedef struct
1602 const char *name;
1603 const char *description;
1604 const char *reg_names[16];
1606 arm_regname;
1608 static const arm_regname regnames[] =
1610 { "raw" , "Select raw register names",
1611 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1612 { "gcc", "Select register names used by GCC",
1613 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1614 { "std", "Select register names used in ARM's ISA documentation",
1615 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1616 { "apcs", "Select register names used in the APCS",
1617 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1618 { "atpcs", "Select register names used in the ATPCS",
1619 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1620 { "special-atpcs", "Select special register names used in the ATPCS",
1621 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1624 static const char *const iwmmxt_wwnames[] =
1625 {"b", "h", "w", "d"};
1627 static const char *const iwmmxt_wwssnames[] =
1628 {"b", "bus", "bc", "bss",
1629 "h", "hus", "hc", "hss",
1630 "w", "wus", "wc", "wss",
1631 "d", "dus", "dc", "dss"
1634 static const char *const iwmmxt_regnames[] =
1635 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1636 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1639 static const char *const iwmmxt_cregnames[] =
1640 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1641 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1644 /* Default to GCC register name set. */
1645 static unsigned int regname_selected = 1;
1647 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1648 #define arm_regnames regnames[regname_selected].reg_names
1650 static bfd_boolean force_thumb = FALSE;
1652 /* Current IT instruction state. This contains the same state as the IT
1653 bits in the CPSR. */
1654 static unsigned int ifthen_state;
1655 /* IT state for the next instruction. */
1656 static unsigned int ifthen_next_state;
1657 /* The address of the insn for which the IT state is valid. */
1658 static bfd_vma ifthen_address;
1659 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1662 /* Functions. */
1664 get_arm_regname_num_options (void)
1666 return NUM_ARM_REGNAMES;
1670 set_arm_regname_option (int option)
1672 int old = regname_selected;
1673 regname_selected = option;
1674 return old;
1678 get_arm_regnames (int option,
1679 const char **setname,
1680 const char **setdescription,
1681 const char *const **register_names)
1683 *setname = regnames[option].name;
1684 *setdescription = regnames[option].description;
1685 *register_names = regnames[option].reg_names;
1686 return 16;
1689 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1690 Returns pointer to following character of the format string and
1691 fills in *VALUEP and *WIDTHP with the extracted value and number of
1692 bits extracted. WIDTHP can be NULL. */
1694 static const char *
1695 arm_decode_bitfield (const char *ptr,
1696 unsigned long insn,
1697 unsigned long *valuep,
1698 int *widthp)
1700 unsigned long value = 0;
1701 int width = 0;
1705 int start, end;
1706 int bits;
1708 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1709 start = start * 10 + *ptr - '0';
1710 if (*ptr == '-')
1711 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1712 end = end * 10 + *ptr - '0';
1713 else
1714 end = start;
1715 bits = end - start;
1716 if (bits < 0)
1717 abort ();
1718 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1719 width += bits + 1;
1721 while (*ptr++ == ',');
1722 *valuep = value;
1723 if (widthp)
1724 *widthp = width;
1725 return ptr - 1;
1728 static void
1729 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1730 bfd_boolean print_shift)
1732 func (stream, "%s", arm_regnames[given & 0xf]);
1734 if ((given & 0xff0) != 0)
1736 if ((given & 0x10) == 0)
1738 int amount = (given & 0xf80) >> 7;
1739 int shift = (given & 0x60) >> 5;
1741 if (amount == 0)
1743 if (shift == 3)
1745 func (stream, ", rrx");
1746 return;
1749 amount = 32;
1752 if (print_shift)
1753 func (stream, ", %s #%d", arm_shift[shift], amount);
1754 else
1755 func (stream, ", #%d", amount);
1757 else if ((given & 0x80) == 0x80)
1758 func (stream, "\t; <illegal shifter operand>");
1759 else if (print_shift)
1760 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1761 arm_regnames[(given & 0xf00) >> 8]);
1762 else
1763 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1767 #define W_BIT 21
1768 #define I_BIT 22
1769 #define U_BIT 23
1770 #define P_BIT 24
1772 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1773 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1774 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1775 #define PRE_BIT_SET (given & (1 << P_BIT))
1777 /* Print one coprocessor instruction on INFO->STREAM.
1778 Return TRUE if the instuction matched, FALSE if this is not a
1779 recognised coprocessor instruction. */
1781 static bfd_boolean
1782 print_insn_coprocessor (bfd_vma pc,
1783 struct disassemble_info *info,
1784 long given,
1785 bfd_boolean thumb)
1787 const struct opcode32 *insn;
1788 void *stream = info->stream;
1789 fprintf_ftype func = info->fprintf_func;
1790 unsigned long mask;
1791 unsigned long value = 0;
1792 struct arm_private_data *private_data = info->private_data;
1793 unsigned long allowed_arches = private_data->features.coproc;
1794 int cond;
1796 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1798 unsigned long u_reg = 16;
1799 bfd_boolean is_unpredictable = FALSE;
1800 signed long value_in_comment = 0;
1801 const char *c;
1803 if (insn->arch == 0)
1804 switch (insn->value)
1806 case SENTINEL_IWMMXT_START:
1807 if (info->mach != bfd_mach_arm_XScale
1808 && info->mach != bfd_mach_arm_iWMMXt
1809 && info->mach != bfd_mach_arm_iWMMXt2)
1811 insn++;
1812 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1813 continue;
1815 case SENTINEL_IWMMXT_END:
1816 continue;
1818 case SENTINEL_GENERIC_START:
1819 allowed_arches = private_data->features.core;
1820 continue;
1822 default:
1823 abort ();
1826 mask = insn->mask;
1827 value = insn->value;
1828 if (thumb)
1830 /* The high 4 bits are 0xe for Arm conditional instructions, and
1831 0xe for arm unconditional instructions. The rest of the
1832 encoding is the same. */
1833 mask |= 0xf0000000;
1834 value |= 0xe0000000;
1835 if (ifthen_state)
1836 cond = IFTHEN_COND;
1837 else
1838 cond = 16;
1840 else
1842 /* Only match unconditional instuctions against unconditional
1843 patterns. */
1844 if ((given & 0xf0000000) == 0xf0000000)
1846 mask |= 0xf0000000;
1847 cond = 16;
1849 else
1851 cond = (given >> 28) & 0xf;
1852 if (cond == 0xe)
1853 cond = 16;
1857 if ((given & mask) != value)
1858 continue;
1860 if ((insn->arch & allowed_arches) == 0)
1861 continue;
1863 for (c = insn->assembler; *c; c++)
1865 if (*c == '%')
1867 switch (*++c)
1869 case '%':
1870 func (stream, "%%");
1871 break;
1873 case 'A':
1875 int rn = (given >> 16) & 0xf;
1876 bfd_vma offset = given & 0xff;
1878 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1880 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1882 /* Not unindexed. The offset is scaled. */
1883 offset = offset * 4;
1884 if (NEGATIVE_BIT_SET)
1885 offset = - offset;
1886 if (rn != 15)
1887 value_in_comment = offset;
1890 if (PRE_BIT_SET)
1892 if (offset)
1893 func (stream, ", #%d]%s",
1894 offset,
1895 WRITEBACK_BIT_SET ? "!" : "");
1896 else if (NEGATIVE_BIT_SET)
1897 func (stream, ", #-0]");
1898 else
1899 func (stream, "]");
1901 else
1903 func (stream, "]");
1905 if (WRITEBACK_BIT_SET)
1907 if (offset)
1908 func (stream, ", #%d", offset);
1909 else if (NEGATIVE_BIT_SET)
1910 func (stream, ", #-0");
1912 else
1914 func (stream, ", {%s%d}",
1915 (NEGATIVE_BIT_SET && !offset) ? "-" : "",
1916 offset);
1917 value_in_comment = offset;
1920 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1922 func (stream, "\t; ");
1923 /* For unaligned PCs, apply off-by-alignment
1924 correction. */
1925 info->print_address_func (offset + pc
1926 + info->bytes_per_chunk * 2
1927 - (pc & 3),
1928 info);
1931 break;
1933 case 'B':
1935 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1936 int offset = (given >> 1) & 0x3f;
1938 if (offset == 1)
1939 func (stream, "{d%d}", regno);
1940 else if (regno + offset > 32)
1941 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1942 else
1943 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1945 break;
1947 case 'c':
1948 func (stream, "%s", arm_conditional[cond]);
1949 break;
1951 case 'I':
1952 /* Print a Cirrus/DSP shift immediate. */
1953 /* Immediates are 7bit signed ints with bits 0..3 in
1954 bits 0..3 of opcode and bits 4..6 in bits 5..7
1955 of opcode. */
1957 int imm;
1959 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1961 /* Is ``imm'' a negative number? */
1962 if (imm & 0x40)
1963 imm |= (-1 << 7);
1965 func (stream, "%d", imm);
1968 break;
1970 case 'F':
1971 switch (given & 0x00408000)
1973 case 0:
1974 func (stream, "4");
1975 break;
1976 case 0x8000:
1977 func (stream, "1");
1978 break;
1979 case 0x00400000:
1980 func (stream, "2");
1981 break;
1982 default:
1983 func (stream, "3");
1985 break;
1987 case 'P':
1988 switch (given & 0x00080080)
1990 case 0:
1991 func (stream, "s");
1992 break;
1993 case 0x80:
1994 func (stream, "d");
1995 break;
1996 case 0x00080000:
1997 func (stream, "e");
1998 break;
1999 default:
2000 func (stream, _("<illegal precision>"));
2001 break;
2003 break;
2005 case 'Q':
2006 switch (given & 0x00408000)
2008 case 0:
2009 func (stream, "s");
2010 break;
2011 case 0x8000:
2012 func (stream, "d");
2013 break;
2014 case 0x00400000:
2015 func (stream, "e");
2016 break;
2017 default:
2018 func (stream, "p");
2019 break;
2021 break;
2023 case 'R':
2024 switch (given & 0x60)
2026 case 0:
2027 break;
2028 case 0x20:
2029 func (stream, "p");
2030 break;
2031 case 0x40:
2032 func (stream, "m");
2033 break;
2034 default:
2035 func (stream, "z");
2036 break;
2038 break;
2040 case '0': case '1': case '2': case '3': case '4':
2041 case '5': case '6': case '7': case '8': case '9':
2043 int width;
2045 c = arm_decode_bitfield (c, given, &value, &width);
2047 switch (*c)
2049 case 'R':
2050 if (value == 15)
2051 is_unpredictable = TRUE;
2052 /* Fall through. */
2053 case 'r':
2054 if (c[1] == 'u')
2056 /* Eat the 'u' character. */
2057 ++ c;
2059 if (u_reg == value)
2060 is_unpredictable = TRUE;
2061 u_reg = value;
2063 func (stream, "%s", arm_regnames[value]);
2064 break;
2065 case 'D':
2066 func (stream, "d%ld", value);
2067 break;
2068 case 'Q':
2069 if (value & 1)
2070 func (stream, "<illegal reg q%ld.5>", value >> 1);
2071 else
2072 func (stream, "q%ld", value >> 1);
2073 break;
2074 case 'd':
2075 func (stream, "%ld", value);
2076 value_in_comment = value;
2077 break;
2078 case 'k':
2080 int from = (given & (1 << 7)) ? 32 : 16;
2081 func (stream, "%ld", from - value);
2083 break;
2085 case 'f':
2086 if (value > 7)
2087 func (stream, "#%s", arm_fp_const[value & 7]);
2088 else
2089 func (stream, "f%ld", value);
2090 break;
2092 case 'w':
2093 if (width == 2)
2094 func (stream, "%s", iwmmxt_wwnames[value]);
2095 else
2096 func (stream, "%s", iwmmxt_wwssnames[value]);
2097 break;
2099 case 'g':
2100 func (stream, "%s", iwmmxt_regnames[value]);
2101 break;
2102 case 'G':
2103 func (stream, "%s", iwmmxt_cregnames[value]);
2104 break;
2106 case 'x':
2107 func (stream, "0x%lx", (value & 0xffffffffUL));
2108 break;
2110 case '`':
2111 c++;
2112 if (value == 0)
2113 func (stream, "%c", *c);
2114 break;
2115 case '\'':
2116 c++;
2117 if (value == ((1ul << width) - 1))
2118 func (stream, "%c", *c);
2119 break;
2120 case '?':
2121 func (stream, "%c", c[(1 << width) - (int) value]);
2122 c += 1 << width;
2123 break;
2124 default:
2125 abort ();
2127 break;
2129 case 'y':
2130 case 'z':
2132 int single = *c++ == 'y';
2133 int regno;
2135 switch (*c)
2137 case '4': /* Sm pair */
2138 case '0': /* Sm, Dm */
2139 regno = given & 0x0000000f;
2140 if (single)
2142 regno <<= 1;
2143 regno += (given >> 5) & 1;
2145 else
2146 regno += ((given >> 5) & 1) << 4;
2147 break;
2149 case '1': /* Sd, Dd */
2150 regno = (given >> 12) & 0x0000000f;
2151 if (single)
2153 regno <<= 1;
2154 regno += (given >> 22) & 1;
2156 else
2157 regno += ((given >> 22) & 1) << 4;
2158 break;
2160 case '2': /* Sn, Dn */
2161 regno = (given >> 16) & 0x0000000f;
2162 if (single)
2164 regno <<= 1;
2165 regno += (given >> 7) & 1;
2167 else
2168 regno += ((given >> 7) & 1) << 4;
2169 break;
2171 case '3': /* List */
2172 func (stream, "{");
2173 regno = (given >> 12) & 0x0000000f;
2174 if (single)
2176 regno <<= 1;
2177 regno += (given >> 22) & 1;
2179 else
2180 regno += ((given >> 22) & 1) << 4;
2181 break;
2183 default:
2184 abort ();
2187 func (stream, "%c%d", single ? 's' : 'd', regno);
2189 if (*c == '3')
2191 int count = given & 0xff;
2193 if (single == 0)
2194 count >>= 1;
2196 if (--count)
2198 func (stream, "-%c%d",
2199 single ? 's' : 'd',
2200 regno + count);
2203 func (stream, "}");
2205 else if (*c == '4')
2206 func (stream, ", %c%d", single ? 's' : 'd',
2207 regno + 1);
2209 break;
2211 case 'L':
2212 switch (given & 0x00400100)
2214 case 0x00000000: func (stream, "b"); break;
2215 case 0x00400000: func (stream, "h"); break;
2216 case 0x00000100: func (stream, "w"); break;
2217 case 0x00400100: func (stream, "d"); break;
2218 default:
2219 break;
2221 break;
2223 case 'Z':
2225 /* given (20, 23) | given (0, 3) */
2226 value = ((given >> 16) & 0xf0) | (given & 0xf);
2227 func (stream, "%d", value);
2229 break;
2231 case 'l':
2232 /* This is like the 'A' operator, except that if
2233 the width field "M" is zero, then the offset is
2234 *not* multiplied by four. */
2236 int offset = given & 0xff;
2237 int multiplier = (given & 0x00000100) ? 4 : 1;
2239 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2241 if (multiplier > 1)
2243 value_in_comment = offset * multiplier;
2244 if (NEGATIVE_BIT_SET)
2245 value_in_comment = - value_in_comment;
2248 if (offset)
2250 if (PRE_BIT_SET)
2251 func (stream, ", #%s%d]%s",
2252 NEGATIVE_BIT_SET ? "-" : "",
2253 offset * multiplier,
2254 WRITEBACK_BIT_SET ? "!" : "");
2255 else
2256 func (stream, "], #%s%d",
2257 NEGATIVE_BIT_SET ? "-" : "",
2258 offset * multiplier);
2260 else
2261 func (stream, "]");
2263 break;
2265 case 'r':
2267 int imm4 = (given >> 4) & 0xf;
2268 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2269 int ubit = ! NEGATIVE_BIT_SET;
2270 const char *rm = arm_regnames [given & 0xf];
2271 const char *rn = arm_regnames [(given >> 16) & 0xf];
2273 switch (puw_bits)
2275 case 1:
2276 case 3:
2277 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2278 if (imm4)
2279 func (stream, ", lsl #%d", imm4);
2280 break;
2282 case 4:
2283 case 5:
2284 case 6:
2285 case 7:
2286 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2287 if (imm4 > 0)
2288 func (stream, ", lsl #%d", imm4);
2289 func (stream, "]");
2290 if (puw_bits == 5 || puw_bits == 7)
2291 func (stream, "!");
2292 break;
2294 default:
2295 func (stream, "INVALID");
2298 break;
2300 case 'i':
2302 long imm5;
2303 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2304 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2306 break;
2308 default:
2309 abort ();
2313 else
2314 func (stream, "%c", *c);
2317 if (value_in_comment > 32 || value_in_comment < -16)
2318 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2320 if (is_unpredictable)
2321 func (stream, UNPREDICTABLE_INSTRUCTION);
2323 return TRUE;
2325 return FALSE;
2328 /* Decodes and prints ARM addressing modes. Returns the offset
2329 used in the address, if any, if it is worthwhile printing the
2330 offset as a hexadecimal value in a comment at the end of the
2331 line of disassembly. */
2333 static signed long
2334 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2336 void *stream = info->stream;
2337 fprintf_ftype func = info->fprintf_func;
2338 bfd_vma offset = 0;
2340 if (((given & 0x000f0000) == 0x000f0000)
2341 && ((given & 0x02000000) == 0))
2343 offset = given & 0xfff;
2345 func (stream, "[pc");
2347 if (PRE_BIT_SET)
2349 /* Pre-indexed. Elide offset of positive zero when
2350 non-writeback. */
2351 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2352 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", offset);
2354 if (NEGATIVE_BIT_SET)
2355 offset = -offset;
2357 offset += pc + 8;
2359 /* Cope with the possibility of write-back
2360 being used. Probably a very dangerous thing
2361 for the programmer to do, but who are we to
2362 argue ? */
2363 func (stream, "]%s", WRITEBACK_BIT_SET ? "!" : "");
2365 else /* Post indexed. */
2367 func (stream, "], #%s%d", NEGATIVE_BIT_SET ? "-" : "", offset);
2369 /* Ie ignore the offset. */
2370 offset = pc + 8;
2373 func (stream, "\t; ");
2374 info->print_address_func (offset, info);
2375 offset = 0;
2377 else
2379 func (stream, "[%s",
2380 arm_regnames[(given >> 16) & 0xf]);
2382 if (PRE_BIT_SET)
2384 if ((given & 0x02000000) == 0)
2386 /* Elide offset of positive zero when non-writeback. */
2387 offset = given & 0xfff;
2388 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2389 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", offset);
2391 else
2393 func (stream, ", %s", NEGATIVE_BIT_SET ? "-" : "");
2394 arm_decode_shift (given, func, stream, TRUE);
2397 func (stream, "]%s",
2398 WRITEBACK_BIT_SET ? "!" : "");
2400 else
2402 if ((given & 0x02000000) == 0)
2404 /* Always show offset. */
2405 offset = given & 0xfff;
2406 func (stream, "], #%s%d",
2407 NEGATIVE_BIT_SET ? "-" : "", offset);
2409 else
2411 func (stream, "], %s",
2412 NEGATIVE_BIT_SET ? "-" : "");
2413 arm_decode_shift (given, func, stream, TRUE);
2418 return (signed long) offset;
2421 /* Print one neon instruction on INFO->STREAM.
2422 Return TRUE if the instuction matched, FALSE if this is not a
2423 recognised neon instruction. */
2425 static bfd_boolean
2426 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2428 const struct opcode32 *insn;
2429 void *stream = info->stream;
2430 fprintf_ftype func = info->fprintf_func;
2432 if (thumb)
2434 if ((given & 0xef000000) == 0xef000000)
2436 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2437 unsigned long bit28 = given & (1 << 28);
2439 given &= 0x00ffffff;
2440 if (bit28)
2441 given |= 0xf3000000;
2442 else
2443 given |= 0xf2000000;
2445 else if ((given & 0xff000000) == 0xf9000000)
2446 given ^= 0xf9000000 ^ 0xf4000000;
2447 else
2448 return FALSE;
2451 for (insn = neon_opcodes; insn->assembler; insn++)
2453 if ((given & insn->mask) == insn->value)
2455 signed long value_in_comment = 0;
2456 const char *c;
2458 for (c = insn->assembler; *c; c++)
2460 if (*c == '%')
2462 switch (*++c)
2464 case '%':
2465 func (stream, "%%");
2466 break;
2468 case 'c':
2469 if (thumb && ifthen_state)
2470 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2471 break;
2473 case 'A':
2475 static const unsigned char enc[16] =
2477 0x4, 0x14, /* st4 0,1 */
2478 0x4, /* st1 2 */
2479 0x4, /* st2 3 */
2480 0x3, /* st3 4 */
2481 0x13, /* st3 5 */
2482 0x3, /* st1 6 */
2483 0x1, /* st1 7 */
2484 0x2, /* st2 8 */
2485 0x12, /* st2 9 */
2486 0x2, /* st1 10 */
2487 0, 0, 0, 0, 0
2489 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2490 int rn = ((given >> 16) & 0xf);
2491 int rm = ((given >> 0) & 0xf);
2492 int align = ((given >> 4) & 0x3);
2493 int type = ((given >> 8) & 0xf);
2494 int n = enc[type] & 0xf;
2495 int stride = (enc[type] >> 4) + 1;
2496 int ix;
2498 func (stream, "{");
2499 if (stride > 1)
2500 for (ix = 0; ix != n; ix++)
2501 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2502 else if (n == 1)
2503 func (stream, "d%d", rd);
2504 else
2505 func (stream, "d%d-d%d", rd, rd + n - 1);
2506 func (stream, "}, [%s", arm_regnames[rn]);
2507 if (align)
2508 func (stream, " :%d", 32 << align);
2509 func (stream, "]");
2510 if (rm == 0xd)
2511 func (stream, "!");
2512 else if (rm != 0xf)
2513 func (stream, ", %s", arm_regnames[rm]);
2515 break;
2517 case 'B':
2519 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2520 int rn = ((given >> 16) & 0xf);
2521 int rm = ((given >> 0) & 0xf);
2522 int idx_align = ((given >> 4) & 0xf);
2523 int align = 0;
2524 int size = ((given >> 10) & 0x3);
2525 int idx = idx_align >> (size + 1);
2526 int length = ((given >> 8) & 3) + 1;
2527 int stride = 1;
2528 int i;
2530 if (length > 1 && size > 0)
2531 stride = (idx_align & (1 << size)) ? 2 : 1;
2533 switch (length)
2535 case 1:
2537 int amask = (1 << size) - 1;
2538 if ((idx_align & (1 << size)) != 0)
2539 return FALSE;
2540 if (size > 0)
2542 if ((idx_align & amask) == amask)
2543 align = 8 << size;
2544 else if ((idx_align & amask) != 0)
2545 return FALSE;
2548 break;
2550 case 2:
2551 if (size == 2 && (idx_align & 2) != 0)
2552 return FALSE;
2553 align = (idx_align & 1) ? 16 << size : 0;
2554 break;
2556 case 3:
2557 if ((size == 2 && (idx_align & 3) != 0)
2558 || (idx_align & 1) != 0)
2559 return FALSE;
2560 break;
2562 case 4:
2563 if (size == 2)
2565 if ((idx_align & 3) == 3)
2566 return FALSE;
2567 align = (idx_align & 3) * 64;
2569 else
2570 align = (idx_align & 1) ? 32 << size : 0;
2571 break;
2573 default:
2574 abort ();
2577 func (stream, "{");
2578 for (i = 0; i < length; i++)
2579 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2580 rd + i * stride, idx);
2581 func (stream, "}, [%s", arm_regnames[rn]);
2582 if (align)
2583 func (stream, " :%d", align);
2584 func (stream, "]");
2585 if (rm == 0xd)
2586 func (stream, "!");
2587 else if (rm != 0xf)
2588 func (stream, ", %s", arm_regnames[rm]);
2590 break;
2592 case 'C':
2594 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2595 int rn = ((given >> 16) & 0xf);
2596 int rm = ((given >> 0) & 0xf);
2597 int align = ((given >> 4) & 0x1);
2598 int size = ((given >> 6) & 0x3);
2599 int type = ((given >> 8) & 0x3);
2600 int n = type + 1;
2601 int stride = ((given >> 5) & 0x1);
2602 int ix;
2604 if (stride && (n == 1))
2605 n++;
2606 else
2607 stride++;
2609 func (stream, "{");
2610 if (stride > 1)
2611 for (ix = 0; ix != n; ix++)
2612 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2613 else if (n == 1)
2614 func (stream, "d%d[]", rd);
2615 else
2616 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2617 func (stream, "}, [%s", arm_regnames[rn]);
2618 if (align)
2620 align = (8 * (type + 1)) << size;
2621 if (type == 3)
2622 align = (size > 1) ? align >> 1 : align;
2623 if (type == 2 || (type == 0 && !size))
2624 func (stream, " :<bad align %d>", align);
2625 else
2626 func (stream, " :%d", align);
2628 func (stream, "]");
2629 if (rm == 0xd)
2630 func (stream, "!");
2631 else if (rm != 0xf)
2632 func (stream, ", %s", arm_regnames[rm]);
2634 break;
2636 case 'D':
2638 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2639 int size = (given >> 20) & 3;
2640 int reg = raw_reg & ((4 << size) - 1);
2641 int ix = raw_reg >> size >> 2;
2643 func (stream, "d%d[%d]", reg, ix);
2645 break;
2647 case 'E':
2648 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2650 int bits = 0;
2651 int cmode = (given >> 8) & 0xf;
2652 int op = (given >> 5) & 0x1;
2653 unsigned long value = 0, hival = 0;
2654 unsigned shift;
2655 int size = 0;
2656 int isfloat = 0;
2658 bits |= ((given >> 24) & 1) << 7;
2659 bits |= ((given >> 16) & 7) << 4;
2660 bits |= ((given >> 0) & 15) << 0;
2662 if (cmode < 8)
2664 shift = (cmode >> 1) & 3;
2665 value = (unsigned long) bits << (8 * shift);
2666 size = 32;
2668 else if (cmode < 12)
2670 shift = (cmode >> 1) & 1;
2671 value = (unsigned long) bits << (8 * shift);
2672 size = 16;
2674 else if (cmode < 14)
2676 shift = (cmode & 1) + 1;
2677 value = (unsigned long) bits << (8 * shift);
2678 value |= (1ul << (8 * shift)) - 1;
2679 size = 32;
2681 else if (cmode == 14)
2683 if (op)
2685 /* Bit replication into bytes. */
2686 int ix;
2687 unsigned long mask;
2689 value = 0;
2690 hival = 0;
2691 for (ix = 7; ix >= 0; ix--)
2693 mask = ((bits >> ix) & 1) ? 0xff : 0;
2694 if (ix <= 3)
2695 value = (value << 8) | mask;
2696 else
2697 hival = (hival << 8) | mask;
2699 size = 64;
2701 else
2703 /* Byte replication. */
2704 value = (unsigned long) bits;
2705 size = 8;
2708 else if (!op)
2710 /* Floating point encoding. */
2711 int tmp;
2713 value = (unsigned long) (bits & 0x7f) << 19;
2714 value |= (unsigned long) (bits & 0x80) << 24;
2715 tmp = bits & 0x40 ? 0x3c : 0x40;
2716 value |= (unsigned long) tmp << 24;
2717 size = 32;
2718 isfloat = 1;
2720 else
2722 func (stream, "<illegal constant %.8x:%x:%x>",
2723 bits, cmode, op);
2724 size = 32;
2725 break;
2727 switch (size)
2729 case 8:
2730 func (stream, "#%ld\t; 0x%.2lx", value, value);
2731 break;
2733 case 16:
2734 func (stream, "#%ld\t; 0x%.4lx", value, value);
2735 break;
2737 case 32:
2738 if (isfloat)
2740 unsigned char valbytes[4];
2741 double fvalue;
2743 /* Do this a byte at a time so we don't have to
2744 worry about the host's endianness. */
2745 valbytes[0] = value & 0xff;
2746 valbytes[1] = (value >> 8) & 0xff;
2747 valbytes[2] = (value >> 16) & 0xff;
2748 valbytes[3] = (value >> 24) & 0xff;
2750 floatformat_to_double
2751 (& floatformat_ieee_single_little, valbytes,
2752 & fvalue);
2754 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2755 value);
2757 else
2758 func (stream, "#%ld\t; 0x%.8lx",
2759 (long) (((value & 0x80000000L) != 0)
2760 ? value | ~0xffffffffL : value),
2761 value);
2762 break;
2764 case 64:
2765 func (stream, "#0x%.8lx%.8lx", hival, value);
2766 break;
2768 default:
2769 abort ();
2772 break;
2774 case 'F':
2776 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2777 int num = (given >> 8) & 0x3;
2779 if (!num)
2780 func (stream, "{d%d}", regno);
2781 else if (num + regno >= 32)
2782 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2783 else
2784 func (stream, "{d%d-d%d}", regno, regno + num);
2786 break;
2789 case '0': case '1': case '2': case '3': case '4':
2790 case '5': case '6': case '7': case '8': case '9':
2792 int width;
2793 unsigned long value;
2795 c = arm_decode_bitfield (c, given, &value, &width);
2797 switch (*c)
2799 case 'r':
2800 func (stream, "%s", arm_regnames[value]);
2801 break;
2802 case 'd':
2803 func (stream, "%ld", value);
2804 value_in_comment = value;
2805 break;
2806 case 'e':
2807 func (stream, "%ld", (1ul << width) - value);
2808 break;
2810 case 'S':
2811 case 'T':
2812 case 'U':
2813 /* Various width encodings. */
2815 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2816 int limit;
2817 unsigned low, high;
2819 c++;
2820 if (*c >= '0' && *c <= '9')
2821 limit = *c - '0';
2822 else if (*c >= 'a' && *c <= 'f')
2823 limit = *c - 'a' + 10;
2824 else
2825 abort ();
2826 low = limit >> 2;
2827 high = limit & 3;
2829 if (value < low || value > high)
2830 func (stream, "<illegal width %d>", base << value);
2831 else
2832 func (stream, "%d", base << value);
2834 break;
2835 case 'R':
2836 if (given & (1 << 6))
2837 goto Q;
2838 /* FALLTHROUGH */
2839 case 'D':
2840 func (stream, "d%ld", value);
2841 break;
2842 case 'Q':
2844 if (value & 1)
2845 func (stream, "<illegal reg q%ld.5>", value >> 1);
2846 else
2847 func (stream, "q%ld", value >> 1);
2848 break;
2850 case '`':
2851 c++;
2852 if (value == 0)
2853 func (stream, "%c", *c);
2854 break;
2855 case '\'':
2856 c++;
2857 if (value == ((1ul << width) - 1))
2858 func (stream, "%c", *c);
2859 break;
2860 case '?':
2861 func (stream, "%c", c[(1 << width) - (int) value]);
2862 c += 1 << width;
2863 break;
2864 default:
2865 abort ();
2867 break;
2869 default:
2870 abort ();
2874 else
2875 func (stream, "%c", *c);
2878 if (value_in_comment > 32 || value_in_comment < -16)
2879 func (stream, "\t; 0x%lx", value_in_comment);
2881 return TRUE;
2884 return FALSE;
2887 /* Return the name of a v7A special register. */
2889 static const char *
2890 banked_regname (unsigned reg)
2892 switch (reg)
2894 case 15: return "CPSR";
2895 case 32: return "R8_usr";
2896 case 33: return "R9_usr";
2897 case 34: return "R10_usr";
2898 case 35: return "R11_usr";
2899 case 36: return "R12_usr";
2900 case 37: return "SP_usr";
2901 case 38: return "LR_usr";
2902 case 40: return "R8_fiq";
2903 case 41: return "R9_fiq";
2904 case 42: return "R10_fiq";
2905 case 43: return "R11_fiq";
2906 case 44: return "R12_fiq";
2907 case 45: return "SP_fiq";
2908 case 46: return "LR_fiq";
2909 case 48: return "LR_irq";
2910 case 49: return "SP_irq";
2911 case 50: return "LR_svc";
2912 case 51: return "SP_svc";
2913 case 52: return "LR_abt";
2914 case 53: return "SP_abt";
2915 case 54: return "LR_und";
2916 case 55: return "SP_und";
2917 case 60: return "LR_mon";
2918 case 61: return "SP_mon";
2919 case 62: return "ELR_hyp";
2920 case 63: return "SP_hyp";
2921 case 79: return "SPSR";
2922 case 110: return "SPSR_fiq";
2923 case 112: return "SPSR_irq";
2924 case 114: return "SPSR_svc";
2925 case 116: return "SPSR_abt";
2926 case 118: return "SPSR_und";
2927 case 124: return "SPSR_mon";
2928 case 126: return "SPSR_hyp";
2929 default: return NULL;
2933 /* Print one ARM instruction from PC on INFO->STREAM. */
2935 static void
2936 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2938 const struct opcode32 *insn;
2939 void *stream = info->stream;
2940 fprintf_ftype func = info->fprintf_func;
2941 struct arm_private_data *private_data = info->private_data;
2943 if (print_insn_coprocessor (pc, info, given, FALSE))
2944 return;
2946 if (print_insn_neon (info, given, FALSE))
2947 return;
2949 for (insn = arm_opcodes; insn->assembler; insn++)
2951 if ((given & insn->mask) != insn->value)
2952 continue;
2954 if ((insn->arch & private_data->features.core) == 0)
2955 continue;
2957 /* Special case: an instruction with all bits set in the condition field
2958 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2959 or by the catchall at the end of the table. */
2960 if ((given & 0xF0000000) != 0xF0000000
2961 || (insn->mask & 0xF0000000) == 0xF0000000
2962 || (insn->mask == 0 && insn->value == 0))
2964 unsigned long u_reg = 16;
2965 unsigned long U_reg = 16;
2966 bfd_boolean is_unpredictable = FALSE;
2967 signed long value_in_comment = 0;
2968 const char *c;
2970 for (c = insn->assembler; *c; c++)
2972 if (*c == '%')
2974 bfd_boolean allow_unpredictable = FALSE;
2976 switch (*++c)
2978 case '%':
2979 func (stream, "%%");
2980 break;
2982 case 'a':
2983 value_in_comment = print_arm_address (pc, info, given);
2984 break;
2986 case 'P':
2987 /* Set P address bit and use normal address
2988 printing routine. */
2989 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
2990 break;
2992 case 'S':
2993 allow_unpredictable = TRUE;
2994 case 's':
2995 if ((given & 0x004f0000) == 0x004f0000)
2997 /* PC relative with immediate offset. */
2998 bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3000 if (NEGATIVE_BIT_SET)
3001 offset = - offset;
3003 if (PRE_BIT_SET)
3005 /* Elide positive zero offset. */
3006 if (offset || NEGATIVE_BIT_SET)
3007 func (stream, "[pc, #%s%d]\t; ",
3008 NEGATIVE_BIT_SET ? "-" : "", offset);
3009 else
3010 func (stream, "[pc]\t; ");
3011 if (NEGATIVE_BIT_SET)
3012 offset = -offset;
3013 info->print_address_func (offset + pc + 8, info);
3015 else
3017 /* Always show the offset. */
3018 func (stream, "[pc], #%s%d",
3019 NEGATIVE_BIT_SET ? "-" : "", offset);
3020 if (! allow_unpredictable)
3021 is_unpredictable = TRUE;
3024 else
3026 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3028 func (stream, "[%s",
3029 arm_regnames[(given >> 16) & 0xf]);
3031 if (PRE_BIT_SET)
3033 if (IMMEDIATE_BIT_SET)
3035 /* Elide offset for non-writeback
3036 positive zero. */
3037 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3038 || offset)
3039 func (stream, ", #%s%d",
3040 NEGATIVE_BIT_SET ? "-" : "", offset);
3042 if (NEGATIVE_BIT_SET)
3043 offset = -offset;
3045 value_in_comment = offset;
3047 else
3049 /* Register Offset or Register Pre-Indexed. */
3050 func (stream, ", %s%s",
3051 NEGATIVE_BIT_SET ? "-" : "",
3052 arm_regnames[given & 0xf]);
3054 /* Writing back to the register that is the source/
3055 destination of the load/store is unpredictable. */
3056 if (! allow_unpredictable
3057 && WRITEBACK_BIT_SET
3058 && ((given & 0xf) == ((given >> 12) & 0xf)))
3059 is_unpredictable = TRUE;
3062 func (stream, "]%s",
3063 WRITEBACK_BIT_SET ? "!" : "");
3065 else
3067 if (IMMEDIATE_BIT_SET)
3069 /* Immediate Post-indexed. */
3070 /* PR 10924: Offset must be printed, even if it is zero. */
3071 func (stream, "], #%s%d",
3072 NEGATIVE_BIT_SET ? "-" : "", offset);
3073 if (NEGATIVE_BIT_SET)
3074 offset = -offset;
3075 value_in_comment = offset;
3077 else
3079 /* Register Post-indexed. */
3080 func (stream, "], %s%s",
3081 NEGATIVE_BIT_SET ? "-" : "",
3082 arm_regnames[given & 0xf]);
3084 /* Writing back to the register that is the source/
3085 destination of the load/store is unpredictable. */
3086 if (! allow_unpredictable
3087 && (given & 0xf) == ((given >> 12) & 0xf))
3088 is_unpredictable = TRUE;
3091 if (! allow_unpredictable)
3093 /* Writeback is automatically implied by post- addressing.
3094 Setting the W bit is unnecessary and ARM specify it as
3095 being unpredictable. */
3096 if (WRITEBACK_BIT_SET
3097 /* Specifying the PC register as the post-indexed
3098 registers is also unpredictable. */
3099 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3100 is_unpredictable = TRUE;
3104 break;
3106 case 'b':
3108 bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3109 info->print_address_func (disp * 4 + pc + 8, info);
3111 break;
3113 case 'c':
3114 if (((given >> 28) & 0xf) != 0xe)
3115 func (stream, "%s",
3116 arm_conditional [(given >> 28) & 0xf]);
3117 break;
3119 case 'm':
3121 int started = 0;
3122 int reg;
3124 func (stream, "{");
3125 for (reg = 0; reg < 16; reg++)
3126 if ((given & (1 << reg)) != 0)
3128 if (started)
3129 func (stream, ", ");
3130 started = 1;
3131 func (stream, "%s", arm_regnames[reg]);
3133 func (stream, "}");
3134 if (! started)
3135 is_unpredictable = TRUE;
3137 break;
3139 case 'q':
3140 arm_decode_shift (given, func, stream, FALSE);
3141 break;
3143 case 'o':
3144 if ((given & 0x02000000) != 0)
3146 int rotate = (given & 0xf00) >> 7;
3147 int immed = (given & 0xff);
3149 immed = (((immed << (32 - rotate))
3150 | (immed >> rotate)) & 0xffffffff);
3151 func (stream, "#%d", immed);
3152 value_in_comment = immed;
3154 else
3155 arm_decode_shift (given, func, stream, TRUE);
3156 break;
3158 case 'p':
3159 if ((given & 0x0000f000) == 0x0000f000)
3161 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3162 mechanism for setting PSR flag bits. They are
3163 obsolete in V6 onwards. */
3164 if ((private_data->features.core & ARM_EXT_V6) == 0)
3165 func (stream, "p");
3167 break;
3169 case 't':
3170 if ((given & 0x01200000) == 0x00200000)
3171 func (stream, "t");
3172 break;
3174 case 'A':
3176 int offset = given & 0xff;
3178 value_in_comment = offset * 4;
3179 if (NEGATIVE_BIT_SET)
3180 value_in_comment = - value_in_comment;
3182 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3184 if (PRE_BIT_SET)
3186 if (offset)
3187 func (stream, ", #%d]%s",
3188 value_in_comment,
3189 WRITEBACK_BIT_SET ? "!" : "");
3190 else
3191 func (stream, "]");
3193 else
3195 func (stream, "]");
3197 if (WRITEBACK_BIT_SET)
3199 if (offset)
3200 func (stream, ", #%d", value_in_comment);
3202 else
3204 func (stream, ", {%d}", offset);
3205 value_in_comment = offset;
3209 break;
3211 case 'B':
3212 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3214 bfd_vma address;
3215 bfd_vma offset = 0;
3217 if (! NEGATIVE_BIT_SET)
3218 /* Is signed, hi bits should be ones. */
3219 offset = (-1) ^ 0x00ffffff;
3221 /* Offset is (SignExtend(offset field)<<2). */
3222 offset += given & 0x00ffffff;
3223 offset <<= 2;
3224 address = offset + pc + 8;
3226 if (given & 0x01000000)
3227 /* H bit allows addressing to 2-byte boundaries. */
3228 address += 2;
3230 info->print_address_func (address, info);
3232 break;
3234 case 'C':
3235 if ((given & 0x02000200) == 0x200)
3237 const char * name;
3238 unsigned sysm = (given & 0x004f0000) >> 16;
3240 sysm |= (given & 0x300) >> 4;
3241 name = banked_regname (sysm);
3243 if (name != NULL)
3244 func (stream, "%s", name);
3245 else
3246 func (stream, "(UNDEF: %lu)", sysm);
3248 else
3250 func (stream, "%cPSR_",
3251 (given & 0x00400000) ? 'S' : 'C');
3252 if (given & 0x80000)
3253 func (stream, "f");
3254 if (given & 0x40000)
3255 func (stream, "s");
3256 if (given & 0x20000)
3257 func (stream, "x");
3258 if (given & 0x10000)
3259 func (stream, "c");
3261 break;
3263 case 'U':
3264 if ((given & 0xf0) == 0x60)
3266 switch (given & 0xf)
3268 case 0xf: func (stream, "sy"); break;
3269 default:
3270 func (stream, "#%d", (int) given & 0xf);
3271 break;
3274 else
3276 switch (given & 0xf)
3278 case 0xf: func (stream, "sy"); break;
3279 case 0x7: func (stream, "un"); break;
3280 case 0xe: func (stream, "st"); break;
3281 case 0x6: func (stream, "unst"); break;
3282 case 0xb: func (stream, "ish"); break;
3283 case 0xa: func (stream, "ishst"); break;
3284 case 0x3: func (stream, "osh"); break;
3285 case 0x2: func (stream, "oshst"); break;
3286 default:
3287 func (stream, "#%d", (int) given & 0xf);
3288 break;
3291 break;
3293 case '0': case '1': case '2': case '3': case '4':
3294 case '5': case '6': case '7': case '8': case '9':
3296 int width;
3297 unsigned long value;
3299 c = arm_decode_bitfield (c, given, &value, &width);
3301 switch (*c)
3303 case 'R':
3304 if (value == 15)
3305 is_unpredictable = TRUE;
3306 /* Fall through. */
3307 case 'r':
3308 if (c[1] == 'u')
3310 /* Eat the 'u' character. */
3311 ++ c;
3313 if (u_reg == value)
3314 is_unpredictable = TRUE;
3315 u_reg = value;
3317 if (c[1] == 'U')
3319 /* Eat the 'U' character. */
3320 ++ c;
3322 if (U_reg == value)
3323 is_unpredictable = TRUE;
3324 U_reg = value;
3326 func (stream, "%s", arm_regnames[value]);
3327 break;
3328 case 'd':
3329 func (stream, "%ld", value);
3330 value_in_comment = value;
3331 break;
3332 case 'b':
3333 func (stream, "%ld", value * 8);
3334 value_in_comment = value * 8;
3335 break;
3336 case 'W':
3337 func (stream, "%ld", value + 1);
3338 value_in_comment = value + 1;
3339 break;
3340 case 'x':
3341 func (stream, "0x%08lx", value);
3343 /* Some SWI instructions have special
3344 meanings. */
3345 if ((given & 0x0fffffff) == 0x0FF00000)
3346 func (stream, "\t; IMB");
3347 else if ((given & 0x0fffffff) == 0x0FF00001)
3348 func (stream, "\t; IMBRange");
3349 break;
3350 case 'X':
3351 func (stream, "%01lx", value & 0xf);
3352 value_in_comment = value;
3353 break;
3354 case '`':
3355 c++;
3356 if (value == 0)
3357 func (stream, "%c", *c);
3358 break;
3359 case '\'':
3360 c++;
3361 if (value == ((1ul << width) - 1))
3362 func (stream, "%c", *c);
3363 break;
3364 case '?':
3365 func (stream, "%c", c[(1 << width) - (int) value]);
3366 c += 1 << width;
3367 break;
3368 default:
3369 abort ();
3371 break;
3373 case 'e':
3375 int imm;
3377 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3378 func (stream, "%d", imm);
3379 value_in_comment = imm;
3381 break;
3383 case 'E':
3384 /* LSB and WIDTH fields of BFI or BFC. The machine-
3385 language instruction encodes LSB and MSB. */
3387 long msb = (given & 0x001f0000) >> 16;
3388 long lsb = (given & 0x00000f80) >> 7;
3389 long w = msb - lsb + 1;
3391 if (w > 0)
3392 func (stream, "#%lu, #%lu", lsb, w);
3393 else
3394 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3396 break;
3398 case 'R':
3399 /* Get the PSR/banked register name. */
3401 const char * name;
3402 unsigned sysm = (given & 0x004f0000) >> 16;
3404 sysm |= (given & 0x300) >> 4;
3405 name = banked_regname (sysm);
3407 if (name != NULL)
3408 func (stream, "%s", name);
3409 else
3410 func (stream, "(UNDEF: %lu)", sysm);
3412 break;
3414 case 'V':
3415 /* 16-bit unsigned immediate from a MOVT or MOVW
3416 instruction, encoded in bits 0:11 and 15:19. */
3418 long hi = (given & 0x000f0000) >> 4;
3419 long lo = (given & 0x00000fff);
3420 long imm16 = hi | lo;
3422 func (stream, "#%lu", imm16);
3423 value_in_comment = imm16;
3425 break;
3427 default:
3428 abort ();
3432 else
3433 func (stream, "%c", *c);
3436 if (value_in_comment > 32 || value_in_comment < -16)
3437 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3439 if (is_unpredictable)
3440 func (stream, UNPREDICTABLE_INSTRUCTION);
3442 return;
3445 abort ();
3448 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3450 static void
3451 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3453 const struct opcode16 *insn;
3454 void *stream = info->stream;
3455 fprintf_ftype func = info->fprintf_func;
3457 for (insn = thumb_opcodes; insn->assembler; insn++)
3458 if ((given & insn->mask) == insn->value)
3460 signed long value_in_comment = 0;
3461 const char *c = insn->assembler;
3463 for (; *c; c++)
3465 int domaskpc = 0;
3466 int domasklr = 0;
3468 if (*c != '%')
3470 func (stream, "%c", *c);
3471 continue;
3474 switch (*++c)
3476 case '%':
3477 func (stream, "%%");
3478 break;
3480 case 'c':
3481 if (ifthen_state)
3482 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3483 break;
3485 case 'C':
3486 if (ifthen_state)
3487 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3488 else
3489 func (stream, "s");
3490 break;
3492 case 'I':
3494 unsigned int tmp;
3496 ifthen_next_state = given & 0xff;
3497 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3498 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3499 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3501 break;
3503 case 'x':
3504 if (ifthen_next_state)
3505 func (stream, "\t; unpredictable branch in IT block\n");
3506 break;
3508 case 'X':
3509 if (ifthen_state)
3510 func (stream, "\t; unpredictable <IT:%s>",
3511 arm_conditional[IFTHEN_COND]);
3512 break;
3514 case 'S':
3516 long reg;
3518 reg = (given >> 3) & 0x7;
3519 if (given & (1 << 6))
3520 reg += 8;
3522 func (stream, "%s", arm_regnames[reg]);
3524 break;
3526 case 'D':
3528 long reg;
3530 reg = given & 0x7;
3531 if (given & (1 << 7))
3532 reg += 8;
3534 func (stream, "%s", arm_regnames[reg]);
3536 break;
3538 case 'N':
3539 if (given & (1 << 8))
3540 domasklr = 1;
3541 /* Fall through. */
3542 case 'O':
3543 if (*c == 'O' && (given & (1 << 8)))
3544 domaskpc = 1;
3545 /* Fall through. */
3546 case 'M':
3548 int started = 0;
3549 int reg;
3551 func (stream, "{");
3553 /* It would be nice if we could spot
3554 ranges, and generate the rS-rE format: */
3555 for (reg = 0; (reg < 8); reg++)
3556 if ((given & (1 << reg)) != 0)
3558 if (started)
3559 func (stream, ", ");
3560 started = 1;
3561 func (stream, "%s", arm_regnames[reg]);
3564 if (domasklr)
3566 if (started)
3567 func (stream, ", ");
3568 started = 1;
3569 func (stream, arm_regnames[14] /* "lr" */);
3572 if (domaskpc)
3574 if (started)
3575 func (stream, ", ");
3576 func (stream, arm_regnames[15] /* "pc" */);
3579 func (stream, "}");
3581 break;
3583 case 'W':
3584 /* Print writeback indicator for a LDMIA. We are doing a
3585 writeback if the base register is not in the register
3586 mask. */
3587 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3588 func (stream, "!");
3589 break;
3591 case 'b':
3592 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3594 bfd_vma address = (pc + 4
3595 + ((given & 0x00f8) >> 2)
3596 + ((given & 0x0200) >> 3));
3597 info->print_address_func (address, info);
3599 break;
3601 case 's':
3602 /* Right shift immediate -- bits 6..10; 1-31 print
3603 as themselves, 0 prints as 32. */
3605 long imm = (given & 0x07c0) >> 6;
3606 if (imm == 0)
3607 imm = 32;
3608 func (stream, "#%ld", imm);
3610 break;
3612 case '0': case '1': case '2': case '3': case '4':
3613 case '5': case '6': case '7': case '8': case '9':
3615 int bitstart = *c++ - '0';
3616 int bitend = 0;
3618 while (*c >= '0' && *c <= '9')
3619 bitstart = (bitstart * 10) + *c++ - '0';
3621 switch (*c)
3623 case '-':
3625 bfd_vma reg;
3627 c++;
3628 while (*c >= '0' && *c <= '9')
3629 bitend = (bitend * 10) + *c++ - '0';
3630 if (!bitend)
3631 abort ();
3632 reg = given >> bitstart;
3633 reg &= (2 << (bitend - bitstart)) - 1;
3635 switch (*c)
3637 case 'r':
3638 func (stream, "%s", arm_regnames[reg]);
3639 break;
3641 case 'd':
3642 func (stream, "%ld", reg);
3643 value_in_comment = reg;
3644 break;
3646 case 'H':
3647 func (stream, "%ld", reg << 1);
3648 value_in_comment = reg << 1;
3649 break;
3651 case 'W':
3652 func (stream, "%ld", reg << 2);
3653 value_in_comment = reg << 2;
3654 break;
3656 case 'a':
3657 /* PC-relative address -- the bottom two
3658 bits of the address are dropped
3659 before the calculation. */
3660 info->print_address_func
3661 (((pc + 4) & ~3) + (reg << 2), info);
3662 value_in_comment = 0;
3663 break;
3665 case 'x':
3666 func (stream, "0x%04lx", reg);
3667 break;
3669 case 'B':
3670 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3671 info->print_address_func (reg * 2 + pc + 4, info);
3672 value_in_comment = 0;
3673 break;
3675 case 'c':
3676 func (stream, "%s", arm_conditional [reg]);
3677 break;
3679 default:
3680 abort ();
3683 break;
3685 case '\'':
3686 c++;
3687 if ((given & (1 << bitstart)) != 0)
3688 func (stream, "%c", *c);
3689 break;
3691 case '?':
3692 ++c;
3693 if ((given & (1 << bitstart)) != 0)
3694 func (stream, "%c", *c++);
3695 else
3696 func (stream, "%c", *++c);
3697 break;
3699 default:
3700 abort ();
3703 break;
3705 default:
3706 abort ();
3710 if (value_in_comment > 32 || value_in_comment < -16)
3711 func (stream, "\t; 0x%lx", value_in_comment);
3712 return;
3715 /* No match. */
3716 abort ();
3719 /* Return the name of an V7M special register. */
3721 static const char *
3722 psr_name (int regno)
3724 switch (regno)
3726 case 0: return "APSR";
3727 case 1: return "IAPSR";
3728 case 2: return "EAPSR";
3729 case 3: return "PSR";
3730 case 5: return "IPSR";
3731 case 6: return "EPSR";
3732 case 7: return "IEPSR";
3733 case 8: return "MSP";
3734 case 9: return "PSP";
3735 case 16: return "PRIMASK";
3736 case 17: return "BASEPRI";
3737 case 18: return "BASEPRI_MAX";
3738 case 19: return "FAULTMASK";
3739 case 20: return "CONTROL";
3740 default: return "<unknown>";
3744 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3746 static void
3747 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3749 const struct opcode32 *insn;
3750 void *stream = info->stream;
3751 fprintf_ftype func = info->fprintf_func;
3753 if (print_insn_coprocessor (pc, info, given, TRUE))
3754 return;
3756 if (print_insn_neon (info, given, TRUE))
3757 return;
3759 for (insn = thumb32_opcodes; insn->assembler; insn++)
3760 if ((given & insn->mask) == insn->value)
3762 bfd_boolean is_unpredictable = FALSE;
3763 signed long value_in_comment = 0;
3764 const char *c = insn->assembler;
3766 for (; *c; c++)
3768 if (*c != '%')
3770 func (stream, "%c", *c);
3771 continue;
3774 switch (*++c)
3776 case '%':
3777 func (stream, "%%");
3778 break;
3780 case 'c':
3781 if (ifthen_state)
3782 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3783 break;
3785 case 'x':
3786 if (ifthen_next_state)
3787 func (stream, "\t; unpredictable branch in IT block\n");
3788 break;
3790 case 'X':
3791 if (ifthen_state)
3792 func (stream, "\t; unpredictable <IT:%s>",
3793 arm_conditional[IFTHEN_COND]);
3794 break;
3796 case 'I':
3798 unsigned int imm12 = 0;
3800 imm12 |= (given & 0x000000ffu);
3801 imm12 |= (given & 0x00007000u) >> 4;
3802 imm12 |= (given & 0x04000000u) >> 15;
3803 func (stream, "#%u", imm12);
3804 value_in_comment = imm12;
3806 break;
3808 case 'M':
3810 unsigned int bits = 0, imm, imm8, mod;
3812 bits |= (given & 0x000000ffu);
3813 bits |= (given & 0x00007000u) >> 4;
3814 bits |= (given & 0x04000000u) >> 15;
3815 imm8 = (bits & 0x0ff);
3816 mod = (bits & 0xf00) >> 8;
3817 switch (mod)
3819 case 0: imm = imm8; break;
3820 case 1: imm = ((imm8 << 16) | imm8); break;
3821 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3822 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3823 default:
3824 mod = (bits & 0xf80) >> 7;
3825 imm8 = (bits & 0x07f) | 0x80;
3826 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3828 func (stream, "#%u", imm);
3829 value_in_comment = imm;
3831 break;
3833 case 'J':
3835 unsigned int imm = 0;
3837 imm |= (given & 0x000000ffu);
3838 imm |= (given & 0x00007000u) >> 4;
3839 imm |= (given & 0x04000000u) >> 15;
3840 imm |= (given & 0x000f0000u) >> 4;
3841 func (stream, "#%u", imm);
3842 value_in_comment = imm;
3844 break;
3846 case 'K':
3848 unsigned int imm = 0;
3850 imm |= (given & 0x000f0000u) >> 16;
3851 imm |= (given & 0x00000ff0u) >> 0;
3852 imm |= (given & 0x0000000fu) << 12;
3853 func (stream, "#%u", imm);
3854 value_in_comment = imm;
3856 break;
3858 case 'V':
3860 unsigned int imm = 0;
3862 imm |= (given & 0x00000fffu);
3863 imm |= (given & 0x000f0000u) >> 4;
3864 func (stream, "#%u", imm);
3865 value_in_comment = imm;
3867 break;
3869 case 'S':
3871 unsigned int reg = (given & 0x0000000fu);
3872 unsigned int stp = (given & 0x00000030u) >> 4;
3873 unsigned int imm = 0;
3874 imm |= (given & 0x000000c0u) >> 6;
3875 imm |= (given & 0x00007000u) >> 10;
3877 func (stream, "%s", arm_regnames[reg]);
3878 switch (stp)
3880 case 0:
3881 if (imm > 0)
3882 func (stream, ", lsl #%u", imm);
3883 break;
3885 case 1:
3886 if (imm == 0)
3887 imm = 32;
3888 func (stream, ", lsr #%u", imm);
3889 break;
3891 case 2:
3892 if (imm == 0)
3893 imm = 32;
3894 func (stream, ", asr #%u", imm);
3895 break;
3897 case 3:
3898 if (imm == 0)
3899 func (stream, ", rrx");
3900 else
3901 func (stream, ", ror #%u", imm);
3904 break;
3906 case 'a':
3908 unsigned int Rn = (given & 0x000f0000) >> 16;
3909 unsigned int U = ! NEGATIVE_BIT_SET;
3910 unsigned int op = (given & 0x00000f00) >> 8;
3911 unsigned int i12 = (given & 0x00000fff);
3912 unsigned int i8 = (given & 0x000000ff);
3913 bfd_boolean writeback = FALSE, postind = FALSE;
3914 bfd_vma offset = 0;
3916 func (stream, "[%s", arm_regnames[Rn]);
3917 if (U) /* 12-bit positive immediate offset. */
3919 offset = i12;
3920 if (Rn != 15)
3921 value_in_comment = offset;
3923 else if (Rn == 15) /* 12-bit negative immediate offset. */
3924 offset = - (int) i12;
3925 else if (op == 0x0) /* Shifted register offset. */
3927 unsigned int Rm = (i8 & 0x0f);
3928 unsigned int sh = (i8 & 0x30) >> 4;
3930 func (stream, ", %s", arm_regnames[Rm]);
3931 if (sh)
3932 func (stream, ", lsl #%u", sh);
3933 func (stream, "]");
3934 break;
3936 else switch (op)
3938 case 0xE: /* 8-bit positive immediate offset. */
3939 offset = i8;
3940 break;
3942 case 0xC: /* 8-bit negative immediate offset. */
3943 offset = -i8;
3944 break;
3946 case 0xF: /* 8-bit + preindex with wb. */
3947 offset = i8;
3948 writeback = TRUE;
3949 break;
3951 case 0xD: /* 8-bit - preindex with wb. */
3952 offset = -i8;
3953 writeback = TRUE;
3954 break;
3956 case 0xB: /* 8-bit + postindex. */
3957 offset = i8;
3958 postind = TRUE;
3959 break;
3961 case 0x9: /* 8-bit - postindex. */
3962 offset = -i8;
3963 postind = TRUE;
3964 break;
3966 default:
3967 func (stream, ", <undefined>]");
3968 goto skip;
3971 if (postind)
3972 func (stream, "], #%d", offset);
3973 else
3975 if (offset)
3976 func (stream, ", #%d", offset);
3977 func (stream, writeback ? "]!" : "]");
3980 if (Rn == 15)
3982 func (stream, "\t; ");
3983 info->print_address_func (((pc + 4) & ~3) + offset, info);
3986 skip:
3987 break;
3989 case 'A':
3991 unsigned int U = ! NEGATIVE_BIT_SET;
3992 unsigned int W = WRITEBACK_BIT_SET;
3993 unsigned int Rn = (given & 0x000f0000) >> 16;
3994 unsigned int off = (given & 0x000000ff);
3996 func (stream, "[%s", arm_regnames[Rn]);
3998 if (PRE_BIT_SET)
4000 if (off || !U)
4002 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4003 value_in_comment = off * 4 * U ? 1 : -1;
4005 func (stream, "]");
4006 if (W)
4007 func (stream, "!");
4009 else
4011 func (stream, "], ");
4012 if (W)
4014 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4015 value_in_comment = off * 4 * U ? 1 : -1;
4017 else
4019 func (stream, "{%u}", off);
4020 value_in_comment = off;
4024 break;
4026 case 'w':
4028 unsigned int Sbit = (given & 0x01000000) >> 24;
4029 unsigned int type = (given & 0x00600000) >> 21;
4031 switch (type)
4033 case 0: func (stream, Sbit ? "sb" : "b"); break;
4034 case 1: func (stream, Sbit ? "sh" : "h"); break;
4035 case 2:
4036 if (Sbit)
4037 func (stream, "??");
4038 break;
4039 case 3:
4040 func (stream, "??");
4041 break;
4044 break;
4046 case 'm':
4048 int started = 0;
4049 int reg;
4051 func (stream, "{");
4052 for (reg = 0; reg < 16; reg++)
4053 if ((given & (1 << reg)) != 0)
4055 if (started)
4056 func (stream, ", ");
4057 started = 1;
4058 func (stream, "%s", arm_regnames[reg]);
4060 func (stream, "}");
4062 break;
4064 case 'E':
4066 unsigned int msb = (given & 0x0000001f);
4067 unsigned int lsb = 0;
4069 lsb |= (given & 0x000000c0u) >> 6;
4070 lsb |= (given & 0x00007000u) >> 10;
4071 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4073 break;
4075 case 'F':
4077 unsigned int width = (given & 0x0000001f) + 1;
4078 unsigned int lsb = 0;
4080 lsb |= (given & 0x000000c0u) >> 6;
4081 lsb |= (given & 0x00007000u) >> 10;
4082 func (stream, "#%u, #%u", lsb, width);
4084 break;
4086 case 'b':
4088 unsigned int S = (given & 0x04000000u) >> 26;
4089 unsigned int J1 = (given & 0x00002000u) >> 13;
4090 unsigned int J2 = (given & 0x00000800u) >> 11;
4091 bfd_vma offset = 0;
4093 offset |= !S << 20;
4094 offset |= J2 << 19;
4095 offset |= J1 << 18;
4096 offset |= (given & 0x003f0000) >> 4;
4097 offset |= (given & 0x000007ff) << 1;
4098 offset -= (1 << 20);
4100 info->print_address_func (pc + 4 + offset, info);
4102 break;
4104 case 'B':
4106 unsigned int S = (given & 0x04000000u) >> 26;
4107 unsigned int I1 = (given & 0x00002000u) >> 13;
4108 unsigned int I2 = (given & 0x00000800u) >> 11;
4109 bfd_vma offset = 0;
4111 offset |= !S << 24;
4112 offset |= !(I1 ^ S) << 23;
4113 offset |= !(I2 ^ S) << 22;
4114 offset |= (given & 0x03ff0000u) >> 4;
4115 offset |= (given & 0x000007ffu) << 1;
4116 offset -= (1 << 24);
4117 offset += pc + 4;
4119 /* BLX target addresses are always word aligned. */
4120 if ((given & 0x00001000u) == 0)
4121 offset &= ~2u;
4123 info->print_address_func (offset, info);
4125 break;
4127 case 's':
4129 unsigned int shift = 0;
4131 shift |= (given & 0x000000c0u) >> 6;
4132 shift |= (given & 0x00007000u) >> 10;
4133 if (WRITEBACK_BIT_SET)
4134 func (stream, ", asr #%u", shift);
4135 else if (shift)
4136 func (stream, ", lsl #%u", shift);
4137 /* else print nothing - lsl #0 */
4139 break;
4141 case 'R':
4143 unsigned int rot = (given & 0x00000030) >> 4;
4145 if (rot)
4146 func (stream, ", ror #%u", rot * 8);
4148 break;
4150 case 'U':
4151 if ((given & 0xf0) == 0x60)
4153 switch (given & 0xf)
4155 case 0xf: func (stream, "sy"); break;
4156 default:
4157 func (stream, "#%d", (int) given & 0xf);
4158 break;
4161 else
4163 switch (given & 0xf)
4165 case 0xf: func (stream, "sy"); break;
4166 case 0x7: func (stream, "un"); break;
4167 case 0xe: func (stream, "st"); break;
4168 case 0x6: func (stream, "unst"); break;
4169 case 0xb: func (stream, "ish"); break;
4170 case 0xa: func (stream, "ishst"); break;
4171 case 0x3: func (stream, "osh"); break;
4172 case 0x2: func (stream, "oshst"); break;
4173 default:
4174 func (stream, "#%d", (int) given & 0xf);
4175 break;
4178 break;
4180 case 'C':
4181 if ((given & 0xff) == 0)
4183 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4184 if (given & 0x800)
4185 func (stream, "f");
4186 if (given & 0x400)
4187 func (stream, "s");
4188 if (given & 0x200)
4189 func (stream, "x");
4190 if (given & 0x100)
4191 func (stream, "c");
4193 else if ((given & 0x20) == 0x20)
4195 char const* name;
4196 unsigned sysm = (given & 0xf00) >> 8;
4198 sysm |= (given & 0x30);
4199 sysm |= (given & 0x00100000) >> 14;
4200 name = banked_regname (sysm);
4202 if (name != NULL)
4203 func (stream, "%s", name);
4204 else
4205 func (stream, "(UNDEF: %lu)", sysm);
4207 else
4209 func (stream, psr_name (given & 0xff));
4211 break;
4213 case 'D':
4214 if (((given & 0xff) == 0)
4215 || ((given & 0x20) == 0x20))
4217 char const* name;
4218 unsigned sm = (given & 0xf0000) >> 16;
4220 sm |= (given & 0x30);
4221 sm |= (given & 0x00100000) >> 14;
4222 name = banked_regname (sm);
4224 if (name != NULL)
4225 func (stream, "%s", name);
4226 else
4227 func (stream, "(UNDEF: %lu)", sm);
4229 else
4230 func (stream, psr_name (given & 0xff));
4231 break;
4233 case '0': case '1': case '2': case '3': case '4':
4234 case '5': case '6': case '7': case '8': case '9':
4236 int width;
4237 unsigned long val;
4239 c = arm_decode_bitfield (c, given, &val, &width);
4241 switch (*c)
4243 case 'd':
4244 func (stream, "%lu", val);
4245 value_in_comment = val;
4246 break;
4248 case 'W':
4249 func (stream, "%lu", val * 4);
4250 value_in_comment = val * 4;
4251 break;
4253 case 'R':
4254 if (val == 15)
4255 is_unpredictable = TRUE;
4256 /* Fall through. */
4257 case 'r':
4258 func (stream, "%s", arm_regnames[val]);
4259 break;
4261 case 'c':
4262 func (stream, "%s", arm_conditional[val]);
4263 break;
4265 case '\'':
4266 c++;
4267 if (val == ((1ul << width) - 1))
4268 func (stream, "%c", *c);
4269 break;
4271 case '`':
4272 c++;
4273 if (val == 0)
4274 func (stream, "%c", *c);
4275 break;
4277 case '?':
4278 func (stream, "%c", c[(1 << width) - (int) val]);
4279 c += 1 << width;
4280 break;
4282 case 'x':
4283 func (stream, "0x%lx", val & 0xffffffffUL);
4284 break;
4286 default:
4287 abort ();
4290 break;
4292 case 'L':
4293 /* PR binutils/12534
4294 If we have a PC relative offset in an LDRD or STRD
4295 instructions then display the decoded address. */
4296 if (((given >> 16) & 0xf) == 0xf)
4298 bfd_vma offset = (given & 0xff) * 4;
4300 if ((given & (1 << 23)) == 0)
4301 offset = - offset;
4302 func (stream, "\t; ");
4303 info->print_address_func ((pc & ~3) + 4 + offset, info);
4305 break;
4307 default:
4308 abort ();
4312 if (value_in_comment > 32 || value_in_comment < -16)
4313 func (stream, "\t; 0x%lx", value_in_comment);
4315 if (is_unpredictable)
4316 func (stream, UNPREDICTABLE_INSTRUCTION);
4318 return;
4321 /* No match. */
4322 abort ();
4325 /* Print data bytes on INFO->STREAM. */
4327 static void
4328 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4329 struct disassemble_info *info,
4330 long given)
4332 switch (info->bytes_per_chunk)
4334 case 1:
4335 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4336 break;
4337 case 2:
4338 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4339 break;
4340 case 4:
4341 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4342 break;
4343 default:
4344 abort ();
4348 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4349 being displayed in symbol relative addresses. */
4351 bfd_boolean
4352 arm_symbol_is_valid (asymbol * sym,
4353 struct disassemble_info * info ATTRIBUTE_UNUSED)
4355 const char * name;
4357 if (sym == NULL)
4358 return FALSE;
4360 name = bfd_asymbol_name (sym);
4362 return (name && *name != '$');
4365 /* Parse an individual disassembler option. */
4367 void
4368 parse_arm_disassembler_option (char *option)
4370 if (option == NULL)
4371 return;
4373 if (CONST_STRNEQ (option, "reg-names-"))
4375 int i;
4377 option += 10;
4379 for (i = NUM_ARM_REGNAMES; i--;)
4380 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4382 regname_selected = i;
4383 break;
4386 if (i < 0)
4387 /* XXX - should break 'option' at following delimiter. */
4388 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4390 else if (CONST_STRNEQ (option, "force-thumb"))
4391 force_thumb = 1;
4392 else if (CONST_STRNEQ (option, "no-force-thumb"))
4393 force_thumb = 0;
4394 else
4395 /* XXX - should break 'option' at following delimiter. */
4396 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4398 return;
4401 /* Parse the string of disassembler options, spliting it at whitespaces
4402 or commas. (Whitespace separators supported for backwards compatibility). */
4404 static void
4405 parse_disassembler_options (char *options)
4407 if (options == NULL)
4408 return;
4410 while (*options)
4412 parse_arm_disassembler_option (options);
4414 /* Skip forward to next seperator. */
4415 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4416 ++ options;
4417 /* Skip forward past seperators. */
4418 while (ISSPACE (*options) || (*options == ','))
4419 ++ options;
4423 /* Search back through the insn stream to determine if this instruction is
4424 conditionally executed. */
4426 static void
4427 find_ifthen_state (bfd_vma pc,
4428 struct disassemble_info *info,
4429 bfd_boolean little)
4431 unsigned char b[2];
4432 unsigned int insn;
4433 int status;
4434 /* COUNT is twice the number of instructions seen. It will be odd if we
4435 just crossed an instruction boundary. */
4436 int count;
4437 int it_count;
4438 unsigned int seen_it;
4439 bfd_vma addr;
4441 ifthen_address = pc;
4442 ifthen_state = 0;
4444 addr = pc;
4445 count = 1;
4446 it_count = 0;
4447 seen_it = 0;
4448 /* Scan backwards looking for IT instructions, keeping track of where
4449 instruction boundaries are. We don't know if something is actually an
4450 IT instruction until we find a definite instruction boundary. */
4451 for (;;)
4453 if (addr == 0 || info->symbol_at_address_func (addr, info))
4455 /* A symbol must be on an instruction boundary, and will not
4456 be within an IT block. */
4457 if (seen_it && (count & 1))
4458 break;
4460 return;
4462 addr -= 2;
4463 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4464 if (status)
4465 return;
4467 if (little)
4468 insn = (b[0]) | (b[1] << 8);
4469 else
4470 insn = (b[1]) | (b[0] << 8);
4471 if (seen_it)
4473 if ((insn & 0xf800) < 0xe800)
4475 /* Addr + 2 is an instruction boundary. See if this matches
4476 the expected boundary based on the position of the last
4477 IT candidate. */
4478 if (count & 1)
4479 break;
4480 seen_it = 0;
4483 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4485 /* This could be an IT instruction. */
4486 seen_it = insn;
4487 it_count = count >> 1;
4489 if ((insn & 0xf800) >= 0xe800)
4490 count++;
4491 else
4492 count = (count + 2) | 1;
4493 /* IT blocks contain at most 4 instructions. */
4494 if (count >= 8 && !seen_it)
4495 return;
4497 /* We found an IT instruction. */
4498 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4499 if ((ifthen_state & 0xf) == 0)
4500 ifthen_state = 0;
4503 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4504 mapping symbol. */
4506 static int
4507 is_mapping_symbol (struct disassemble_info *info, int n,
4508 enum map_type *map_type)
4510 const char *name;
4512 name = bfd_asymbol_name (info->symtab[n]);
4513 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4514 && (name[2] == 0 || name[2] == '.'))
4516 *map_type = ((name[1] == 'a') ? MAP_ARM
4517 : (name[1] == 't') ? MAP_THUMB
4518 : MAP_DATA);
4519 return TRUE;
4522 return FALSE;
4525 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4526 Returns nonzero if *MAP_TYPE was set. */
4528 static int
4529 get_map_sym_type (struct disassemble_info *info,
4530 int n,
4531 enum map_type *map_type)
4533 /* If the symbol is in a different section, ignore it. */
4534 if (info->section != NULL && info->section != info->symtab[n]->section)
4535 return FALSE;
4537 return is_mapping_symbol (info, n, map_type);
4540 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4541 Returns nonzero if *MAP_TYPE was set. */
4543 static int
4544 get_sym_code_type (struct disassemble_info *info,
4545 int n,
4546 enum map_type *map_type)
4548 elf_symbol_type *es;
4549 unsigned int type;
4551 /* If the symbol is in a different section, ignore it. */
4552 if (info->section != NULL && info->section != info->symtab[n]->section)
4553 return FALSE;
4555 es = *(elf_symbol_type **)(info->symtab + n);
4556 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4558 /* If the symbol has function type then use that. */
4559 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4561 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4562 *map_type = MAP_THUMB;
4563 else
4564 *map_type = MAP_ARM;
4565 return TRUE;
4568 return FALSE;
4571 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4572 of the supplied arm_feature_set structure with bitmasks indicating
4573 the support base architectures and coprocessor extensions.
4575 FIXME: This could more efficiently implemented as a constant array,
4576 although it would also be less robust. */
4578 static void
4579 select_arm_features (unsigned long mach,
4580 arm_feature_set * features)
4582 #undef ARM_FEATURE
4583 #define ARM_FEATURE(ARCH,CEXT) \
4584 features->core = (ARCH); \
4585 features->coproc = (CEXT) | FPU_FPA; \
4586 return
4588 switch (mach)
4590 case bfd_mach_arm_2: ARM_ARCH_V2;
4591 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4592 case bfd_mach_arm_3: ARM_ARCH_V3;
4593 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4594 case bfd_mach_arm_4: ARM_ARCH_V4;
4595 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4596 case bfd_mach_arm_5: ARM_ARCH_V5;
4597 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4598 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4599 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4600 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4601 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4602 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4603 /* If the machine type is unknown allow all
4604 architecture types and all extensions. */
4605 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4606 default:
4607 abort ();
4612 /* NOTE: There are no checks in these routines that
4613 the relevant number of data bytes exist. */
4615 static int
4616 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4618 unsigned char b[4];
4619 long given;
4620 int status;
4621 int is_thumb = FALSE;
4622 int is_data = FALSE;
4623 int little_code;
4624 unsigned int size = 4;
4625 void (*printer) (bfd_vma, struct disassemble_info *, long);
4626 bfd_boolean found = FALSE;
4627 struct arm_private_data *private_data;
4629 if (info->disassembler_options)
4631 parse_disassembler_options (info->disassembler_options);
4633 /* To avoid repeated parsing of these options, we remove them here. */
4634 info->disassembler_options = NULL;
4637 /* PR 10288: Control which instructions will be disassembled. */
4638 if (info->private_data == NULL)
4640 static struct arm_private_data private;
4642 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4643 /* If the user did not use the -m command line switch then default to
4644 disassembling all types of ARM instruction.
4646 The info->mach value has to be ignored as this will be based on
4647 the default archictecture for the target and/or hints in the notes
4648 section, but it will never be greater than the current largest arm
4649 machine value (iWMMXt2), which is only equivalent to the V5TE
4650 architecture. ARM architectures have advanced beyond the machine
4651 value encoding, and these newer architectures would be ignored if
4652 the machine value was used.
4654 Ie the -m switch is used to restrict which instructions will be
4655 disassembled. If it is necessary to use the -m switch to tell
4656 objdump that an ARM binary is being disassembled, eg because the
4657 input is a raw binary file, but it is also desired to disassemble
4658 all ARM instructions then use "-marm". This will select the
4659 "unknown" arm architecture which is compatible with any ARM
4660 instruction. */
4661 info->mach = bfd_mach_arm_unknown;
4663 /* Compute the architecture bitmask from the machine number.
4664 Note: This assumes that the machine number will not change
4665 during disassembly.... */
4666 select_arm_features (info->mach, & private.features);
4668 private.has_mapping_symbols = -1;
4669 private.last_mapping_sym = -1;
4670 private.last_mapping_addr = 0;
4672 info->private_data = & private;
4675 private_data = info->private_data;
4677 /* Decide if our code is going to be little-endian, despite what the
4678 function argument might say. */
4679 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4681 /* For ELF, consult the symbol table to determine what kind of code
4682 or data we have. */
4683 if (info->symtab_size != 0
4684 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4686 bfd_vma addr;
4687 int n, start;
4688 int last_sym = -1;
4689 enum map_type type = MAP_ARM;
4691 /* Start scanning at the start of the function, or wherever
4692 we finished last time. */
4693 start = info->symtab_pos + 1;
4694 if (start < private_data->last_mapping_sym)
4695 start = private_data->last_mapping_sym;
4696 found = FALSE;
4698 /* First, look for mapping symbols. */
4699 if (private_data->has_mapping_symbols != 0)
4701 /* Scan up to the location being disassembled. */
4702 for (n = start; n < info->symtab_size; n++)
4704 addr = bfd_asymbol_value (info->symtab[n]);
4705 if (addr > pc)
4706 break;
4707 if (get_map_sym_type (info, n, &type))
4709 last_sym = n;
4710 found = TRUE;
4714 if (!found)
4716 /* No mapping symbol found at this address. Look backwards
4717 for a preceding one. */
4718 for (n = start - 1; n >= 0; n--)
4720 if (get_map_sym_type (info, n, &type))
4722 last_sym = n;
4723 found = TRUE;
4724 break;
4729 if (found)
4730 private_data->has_mapping_symbols = 1;
4732 /* No mapping symbols were found. A leading $d may be
4733 omitted for sections which start with data; but for
4734 compatibility with legacy and stripped binaries, only
4735 assume the leading $d if there is at least one mapping
4736 symbol in the file. */
4737 if (!found && private_data->has_mapping_symbols == -1)
4739 /* Look for mapping symbols, in any section. */
4740 for (n = 0; n < info->symtab_size; n++)
4741 if (is_mapping_symbol (info, n, &type))
4743 private_data->has_mapping_symbols = 1;
4744 break;
4746 if (private_data->has_mapping_symbols == -1)
4747 private_data->has_mapping_symbols = 0;
4750 if (!found && private_data->has_mapping_symbols == 1)
4752 type = MAP_DATA;
4753 found = TRUE;
4757 /* Next search for function symbols to separate ARM from Thumb
4758 in binaries without mapping symbols. */
4759 if (!found)
4761 /* Scan up to the location being disassembled. */
4762 for (n = start; n < info->symtab_size; n++)
4764 addr = bfd_asymbol_value (info->symtab[n]);
4765 if (addr > pc)
4766 break;
4767 if (get_sym_code_type (info, n, &type))
4769 last_sym = n;
4770 found = TRUE;
4774 if (!found)
4776 /* No mapping symbol found at this address. Look backwards
4777 for a preceding one. */
4778 for (n = start - 1; n >= 0; n--)
4780 if (get_sym_code_type (info, n, &type))
4782 last_sym = n;
4783 found = TRUE;
4784 break;
4790 private_data->last_mapping_sym = last_sym;
4791 private_data->last_type = type;
4792 is_thumb = (private_data->last_type == MAP_THUMB);
4793 is_data = (private_data->last_type == MAP_DATA);
4795 /* Look a little bit ahead to see if we should print out
4796 two or four bytes of data. If there's a symbol,
4797 mapping or otherwise, after two bytes then don't
4798 print more. */
4799 if (is_data)
4801 size = 4 - (pc & 3);
4802 for (n = last_sym + 1; n < info->symtab_size; n++)
4804 addr = bfd_asymbol_value (info->symtab[n]);
4805 if (addr > pc
4806 && (info->section == NULL
4807 || info->section == info->symtab[n]->section))
4809 if (addr - pc < size)
4810 size = addr - pc;
4811 break;
4814 /* If the next symbol is after three bytes, we need to
4815 print only part of the data, so that we can use either
4816 .byte or .short. */
4817 if (size == 3)
4818 size = (pc & 1) ? 1 : 2;
4822 if (info->symbols != NULL)
4824 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4826 coff_symbol_type * cs;
4828 cs = coffsymbol (*info->symbols);
4829 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4830 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4831 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4832 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4833 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4835 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4836 && !found)
4838 /* If no mapping symbol has been found then fall back to the type
4839 of the function symbol. */
4840 elf_symbol_type * es;
4841 unsigned int type;
4843 es = *(elf_symbol_type **)(info->symbols);
4844 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4846 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
4847 == ST_BRANCH_TO_THUMB)
4848 || type == STT_ARM_16BIT);
4852 if (force_thumb)
4853 is_thumb = TRUE;
4855 if (is_data)
4856 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4857 else
4858 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4860 info->bytes_per_line = 4;
4862 /* PR 10263: Disassemble data if requested to do so by the user. */
4863 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4865 int i;
4867 /* Size was already set above. */
4868 info->bytes_per_chunk = size;
4869 printer = print_insn_data;
4871 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4872 given = 0;
4873 if (little)
4874 for (i = size - 1; i >= 0; i--)
4875 given = b[i] | (given << 8);
4876 else
4877 for (i = 0; i < (int) size; i++)
4878 given = b[i] | (given << 8);
4880 else if (!is_thumb)
4882 /* In ARM mode endianness is a straightforward issue: the instruction
4883 is four bytes long and is either ordered 0123 or 3210. */
4884 printer = print_insn_arm;
4885 info->bytes_per_chunk = 4;
4886 size = 4;
4888 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4889 if (little_code)
4890 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4891 else
4892 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4894 else
4896 /* In Thumb mode we have the additional wrinkle of two
4897 instruction lengths. Fortunately, the bits that determine
4898 the length of the current instruction are always to be found
4899 in the first two bytes. */
4900 printer = print_insn_thumb16;
4901 info->bytes_per_chunk = 2;
4902 size = 2;
4904 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4905 if (little_code)
4906 given = (b[0]) | (b[1] << 8);
4907 else
4908 given = (b[1]) | (b[0] << 8);
4910 if (!status)
4912 /* These bit patterns signal a four-byte Thumb
4913 instruction. */
4914 if ((given & 0xF800) == 0xF800
4915 || (given & 0xF800) == 0xF000
4916 || (given & 0xF800) == 0xE800)
4918 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4919 if (little_code)
4920 given = (b[0]) | (b[1] << 8) | (given << 16);
4921 else
4922 given = (b[1]) | (b[0] << 8) | (given << 16);
4924 printer = print_insn_thumb32;
4925 size = 4;
4929 if (ifthen_address != pc)
4930 find_ifthen_state (pc, info, little_code);
4932 if (ifthen_state)
4934 if ((ifthen_state & 0xf) == 0x8)
4935 ifthen_next_state = 0;
4936 else
4937 ifthen_next_state = (ifthen_state & 0xe0)
4938 | ((ifthen_state & 0xf) << 1);
4942 if (status)
4944 info->memory_error_func (status, pc, info);
4945 return -1;
4947 if (info->flags & INSN_HAS_RELOC)
4948 /* If the instruction has a reloc associated with it, then
4949 the offset field in the instruction will actually be the
4950 addend for the reloc. (We are using REL type relocs).
4951 In such cases, we can ignore the pc when computing
4952 addresses, since the addend is not currently pc-relative. */
4953 pc = 0;
4955 printer (pc, info, given);
4957 if (is_thumb)
4959 ifthen_state = ifthen_next_state;
4960 ifthen_address += size;
4962 return size;
4966 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4968 /* Detect BE8-ness and record it in the disassembler info. */
4969 if (info->flavour == bfd_target_elf_flavour
4970 && info->section != NULL
4971 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4972 info->endian_code = BFD_ENDIAN_LITTLE;
4974 return print_insn (pc, info, FALSE);
4978 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4980 return print_insn (pc, info, TRUE);
4983 void
4984 print_arm_disassembler_options (FILE *stream)
4986 int i;
4988 fprintf (stream, _("\n\
4989 The following ARM specific disassembler options are supported for use with\n\
4990 the -M switch:\n"));
4992 for (i = NUM_ARM_REGNAMES; i--;)
4993 fprintf (stream, " reg-names-%s %*c%s\n",
4994 regnames[i].name,
4995 (int)(14 - strlen (regnames[i].name)), ' ',
4996 regnames[i].description);
4998 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4999 fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");