opcodes/
[binutils-gdb.git] / opcodes / arm-dis.c
blob74d78cb462162d94ebfd6887cce2fd978b3041d9
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, 2012
4 Free Software Foundation, Inc.
5 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
6 Modification by James G. Smith (jsmith@cygnus.co.uk)
8 This file is part of libopcodes.
10 This library is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 It is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
25 #include "sysdep.h"
27 #include "dis-asm.h"
28 #include "opcode/arm.h"
29 #include "opintl.h"
30 #include "safe-ctype.h"
31 #include "floatformat.h"
33 /* FIXME: This shouldn't be done here. */
34 #include "coff/internal.h"
35 #include "libcoff.h"
36 #include "elf-bfd.h"
37 #include "elf/internal.h"
38 #include "elf/arm.h"
40 /* FIXME: Belongs in global header. */
41 #ifndef strneq
42 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
43 #endif
45 #ifndef NUM_ELEM
46 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
47 #endif
49 /* Cached mapping symbol state. */
50 enum map_type
52 MAP_ARM,
53 MAP_THUMB,
54 MAP_DATA
57 struct arm_private_data
59 /* The features to use when disassembling optional instructions. */
60 arm_feature_set features;
62 /* Whether any mapping symbols are present in the provided symbol
63 table. -1 if we do not know yet, otherwise 0 or 1. */
64 int has_mapping_symbols;
66 /* Track the last type (although this doesn't seem to be useful) */
67 enum map_type last_type;
69 /* Tracking symbol table information */
70 int last_mapping_sym;
71 bfd_vma last_mapping_addr;
74 struct opcode32
76 unsigned long arch; /* Architecture defining this insn. */
77 unsigned long value; /* If arch == 0 then value is a sentinel. */
78 unsigned long mask; /* Recognise insn if (op & mask) == value. */
79 const char * assembler; /* How to disassemble this insn. */
82 struct opcode16
84 unsigned long arch; /* Architecture defining this insn. */
85 unsigned short value, mask; /* Recognise insn if (op & mask) == value. */
86 const char *assembler; /* How to disassemble this insn. */
89 /* print_insn_coprocessor recognizes the following format control codes:
91 %% %
93 %c print condition code (always bits 28-31 in ARM mode)
94 %q print shifter argument
95 %u print condition code (unconditional in ARM mode)
96 %A print address for ldc/stc/ldf/stf instruction
97 %B print vstm/vldm register list
98 %I print cirrus signed shift immediate: bits 0..3|4..6
99 %F print the COUNT field of a LFM/SFM instruction.
100 %P print floating point precision in arithmetic insn
101 %Q print floating point precision in ldf/stf insn
102 %R print floating point rounding mode
104 %<bitfield>r print as an ARM register
105 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
106 %<bitfield>ru as %<>r but each u register must be unique.
107 %<bitfield>d print the bitfield in decimal
108 %<bitfield>k print immediate for VFPv3 conversion instruction
109 %<bitfield>x print the bitfield in hex
110 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
111 %<bitfield>f print a floating point constant if >7 else a
112 floating point register
113 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
114 %<bitfield>g print as an iWMMXt 64-bit register
115 %<bitfield>G print as an iWMMXt general purpose or control register
116 %<bitfield>D print as a NEON D register
117 %<bitfield>Q print as a NEON Q register
119 %y<code> print a single precision VFP reg.
120 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
121 %z<code> print a double precision VFP reg
122 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
124 %<bitfield>'c print specified char iff bitfield is all ones
125 %<bitfield>`c print specified char iff bitfield is all zeroes
126 %<bitfield>?ab... select from array of values in big endian order
128 %L print as an iWMMXt N/M width field.
129 %Z print the Immediate of a WSHUFH instruction.
130 %l like 'A' except use byte offsets for 'B' & 'H'
131 versions.
132 %i print 5-bit immediate in bits 8,3..0
133 (print "32" when 0)
134 %r print register offset address for wldt/wstr instruction. */
136 enum opcode_sentinel_enum
138 SENTINEL_IWMMXT_START = 1,
139 SENTINEL_IWMMXT_END,
140 SENTINEL_GENERIC_START
141 } opcode_sentinels;
143 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
144 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
146 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
148 static const struct opcode32 coprocessor_opcodes[] =
150 /* XScale instructions. */
151 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
152 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
153 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
154 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
155 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
157 /* Intel Wireless MMX technology instructions. */
158 { 0, SENTINEL_IWMMXT_START, 0, "" },
159 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
160 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
161 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
162 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
163 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
164 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
165 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
166 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
167 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
168 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
169 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
170 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
171 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
172 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
173 {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
174 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
175 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
176 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
177 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
178 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
179 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
180 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
186 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
187 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
188 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
189 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
190 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
191 {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
192 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
193 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
194 {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
196 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
197 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
199 {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
200 {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
202 {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
203 {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
205 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
206 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
207 {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
208 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
209 {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
210 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
211 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
212 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
213 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
214 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
215 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
216 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
217 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
218 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
219 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
220 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
221 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
222 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
223 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
224 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
225 {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
226 {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
227 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
228 {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
229 {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
230 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
231 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
232 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
233 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
234 { 0, SENTINEL_IWMMXT_END, 0, "" },
236 /* Floating point coprocessor (FPA) instructions. */
237 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
238 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
239 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
243 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
244 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
245 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
246 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
247 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
248 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
249 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
250 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
251 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
252 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
253 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
254 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
255 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
256 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
257 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
258 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
259 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
260 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
261 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
262 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
263 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
264 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
265 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
266 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
267 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
268 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
269 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
270 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
271 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
272 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
273 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
274 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
275 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
276 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
277 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
278 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
279 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
281 /* Register load/store. */
282 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
283 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
284 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
285 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
286 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
287 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
288 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
289 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
290 {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
291 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
292 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
293 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
294 {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
295 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
296 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
297 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
299 {FPU_VFP_EXT_V1xD, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
300 {FPU_VFP_EXT_V1xD, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
301 {FPU_VFP_EXT_V1xD, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
302 {FPU_VFP_EXT_V1xD, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
304 /* Data transfer between ARM and NEON registers. */
305 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
306 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
307 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
308 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
309 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
310 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
311 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
312 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
313 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
314 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
315 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
316 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
317 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
318 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
319 /* Half-precision conversion instructions. */
320 {FPU_VFP_EXT_FP16, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
321 {FPU_VFP_EXT_FP16, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
323 /* Floating point coprocessor (VFP) instructions. */
324 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
325 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
326 {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
327 {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
328 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
329 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
330 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
331 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
332 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
333 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
334 {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
335 {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
336 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
337 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
338 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
339 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
340 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
341 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
342 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
343 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
344 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
345 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
346 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
347 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
348 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
349 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
350 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
351 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
352 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
353 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
354 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
355 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
356 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
357 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
358 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
359 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
360 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
361 {FPU_VFP_EXT_V3xD, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
362 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
363 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
364 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
365 {FPU_VFP_EXT_V3xD, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
366 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
367 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
368 {FPU_VFP_EXT_V3xD, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
369 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
370 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
371 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
372 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
373 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
374 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
375 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
376 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
377 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
378 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
379 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
380 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
381 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
382 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
383 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
384 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
385 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
386 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
387 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
388 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
389 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
390 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
392 /* Cirrus coprocessor instructions. */
393 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
394 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
395 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
396 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
397 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
398 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
399 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
400 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
401 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
402 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
403 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
404 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
405 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
406 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
407 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
408 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
409 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
410 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
411 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
412 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
413 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
414 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
415 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
416 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
417 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
418 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
419 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
420 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
421 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
422 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
423 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
424 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
425 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
426 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
427 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
428 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
429 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
430 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
431 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
432 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
433 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
434 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
435 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
436 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
437 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
438 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
439 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
440 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
441 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
442 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
443 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
444 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
445 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
446 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
447 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
448 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
449 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
450 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
451 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
452 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
453 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
454 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
455 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
456 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
457 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
458 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
459 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
460 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
461 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
462 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
463 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
464 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
465 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
466 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
467 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
468 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
469 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
470 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
471 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
473 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
475 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
476 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
478 /* VFP Fused multiply add instructions. */
479 {FPU_VFP_EXT_FMA, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
480 {FPU_VFP_EXT_FMA, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
481 {FPU_VFP_EXT_FMA, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
482 {FPU_VFP_EXT_FMA, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
483 {FPU_VFP_EXT_FMA, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
484 {FPU_VFP_EXT_FMA, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
485 {FPU_VFP_EXT_FMA, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
486 {FPU_VFP_EXT_FMA, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
488 /* Generic coprocessor instructions. */
489 { 0, SENTINEL_GENERIC_START, 0, "" },
490 {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
491 {ARM_EXT_V5E, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
492 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
493 {ARM_EXT_V2, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
494 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
495 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
496 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
497 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
499 /* V6 coprocessor instructions. */
500 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
501 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
503 /* V5 coprocessor instructions. */
504 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
505 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
506 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
507 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
508 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
510 {0, 0, 0, 0}
513 /* Neon opcode table: This does not encode the top byte -- that is
514 checked by the print_insn_neon routine, as it depends on whether we are
515 doing thumb32 or arm32 disassembly. */
517 /* print_insn_neon recognizes the following format control codes:
519 %% %
521 %c print condition code
522 %A print v{st,ld}[1234] operands
523 %B print v{st,ld}[1234] any one operands
524 %C print v{st,ld}[1234] single->all operands
525 %D print scalar
526 %E print vmov, vmvn, vorr, vbic encoded constant
527 %F print vtbl,vtbx register list
529 %<bitfield>r print as an ARM register
530 %<bitfield>d print the bitfield in decimal
531 %<bitfield>e print the 2^N - bitfield in decimal
532 %<bitfield>D print as a NEON D register
533 %<bitfield>Q print as a NEON Q register
534 %<bitfield>R print as a NEON D or Q register
535 %<bitfield>Sn print byte scaled width limited by n
536 %<bitfield>Tn print short scaled width limited by n
537 %<bitfield>Un print long scaled width limited by n
539 %<bitfield>'c print specified char iff bitfield is all ones
540 %<bitfield>`c print specified char iff bitfield is all zeroes
541 %<bitfield>?ab... select from array of values in big endian order. */
543 static const struct opcode32 neon_opcodes[] =
545 /* Extract. */
546 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
547 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
549 /* Move data element to all lanes. */
550 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
551 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
552 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
554 /* Table lookup. */
555 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
556 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
558 /* Half-precision conversions. */
559 {FPU_VFP_EXT_FP16, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
560 {FPU_VFP_EXT_FP16, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
562 /* NEON fused multiply add instructions. */
563 {FPU_NEON_EXT_FMA, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
564 {FPU_NEON_EXT_FMA, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
566 /* Two registers, miscellaneous. */
567 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
568 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
569 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
570 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
571 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
572 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
573 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
574 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
575 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
576 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
577 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
578 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
579 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
580 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
581 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
582 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
583 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
584 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
585 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
586 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
587 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
588 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
589 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
590 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
591 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
592 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
593 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
594 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
595 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
596 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
597 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
598 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
599 {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"},
601 /* Three registers of the same length. */
602 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
616 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
617 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
618 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
619 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
625 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
626 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
627 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
628 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
629 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
630 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
631 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
632 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
633 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
634 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
636 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
637 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
638 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
639 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
641 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
642 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
643 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
644 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
645 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
646 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
647 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
648 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
649 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
650 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
651 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
652 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
653 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
654 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
656 /* One register and an immediate value. */
657 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
658 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
659 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
660 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
661 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
662 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
663 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
664 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
665 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
666 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
667 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
668 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
669 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
671 /* Two registers and a shift amount. */
672 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
673 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
674 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
675 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
676 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
677 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
678 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
679 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
680 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
681 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
682 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
683 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
684 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
685 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
686 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
687 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
688 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
689 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
690 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
691 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
692 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
693 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
694 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
695 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
696 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
697 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
698 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
699 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
700 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
701 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
702 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
703 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
704 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
705 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
706 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
707 {FPU_NEON_EXT_V1, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
708 {FPU_NEON_EXT_V1, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
709 {FPU_NEON_EXT_V1, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
710 {FPU_NEON_EXT_V1, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
711 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
712 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
713 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
714 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
715 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
716 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
717 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
718 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
719 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
720 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
721 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
722 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
723 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
724 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
725 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
726 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
727 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
728 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
729 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
731 /* Three registers of different lengths. */
732 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
733 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
734 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
735 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
736 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
737 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
738 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
739 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
740 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
741 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
742 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
743 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
744 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
745 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
746 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
747 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
748 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
750 /* Two registers and a scalar. */
751 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
752 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
753 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
754 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
755 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
756 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
757 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
758 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
759 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
760 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
761 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
762 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
763 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
764 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
765 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
766 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
767 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
768 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
769 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
770 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
771 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
772 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
774 /* Element and structure load/store. */
775 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
776 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
777 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
778 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
779 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
780 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
781 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
782 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
783 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
784 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
785 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
786 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
787 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
788 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
789 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
790 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
791 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
792 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
793 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
795 {0,0 ,0, 0}
798 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
799 ordered: they must be searched linearly from the top to obtain a correct
800 match. */
802 /* print_insn_arm recognizes the following format control codes:
804 %% %
806 %a print address for ldr/str instruction
807 %s print address for ldr/str halfword/signextend instruction
808 %S like %s but allow UNPREDICTABLE addressing
809 %b print branch destination
810 %c print condition code (always bits 28-31)
811 %m print register mask for ldm/stm instruction
812 %o print operand2 (immediate or register + shift)
813 %p print 'p' iff bits 12-15 are 15
814 %t print 't' iff bit 21 set and bit 24 clear
815 %B print arm BLX(1) destination
816 %C print the PSR sub type.
817 %U print barrier type.
818 %P print address for pli instruction.
820 %<bitfield>r print as an ARM register
821 %<bitfield>R as %r but r15 is UNPREDICTABLE
822 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
823 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
824 %<bitfield>d print the bitfield in decimal
825 %<bitfield>W print the bitfield plus one in decimal
826 %<bitfield>x print the bitfield in hex
827 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
829 %<bitfield>'c print specified char iff bitfield is all ones
830 %<bitfield>`c print specified char iff bitfield is all zeroes
831 %<bitfield>?ab... select from array of values in big endian order
833 %e print arm SMI operand (bits 0..7,8..19).
834 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
835 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
836 %R print the SPSR/CPSR or banked register of an MRS. */
838 static const struct opcode32 arm_opcodes[] =
840 /* ARM instructions. */
841 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
842 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
843 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
844 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
845 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
846 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
847 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
849 /* Virtualization Extension instructions. */
850 {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
851 {ARM_EXT_VIRT, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
853 /* Integer Divide Extension instructions. */
854 {ARM_EXT_ADIV, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
855 {ARM_EXT_ADIV, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
857 /* MP Extension instructions. */
858 {ARM_EXT_MP, 0xf410f000, 0xfc70f000, "pldw\t%a"},
860 /* V7 instructions. */
861 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
862 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
863 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
864 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
865 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
867 /* ARM V6T2 instructions. */
868 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
869 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
870 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
871 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
873 {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
874 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
876 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
877 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
878 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
879 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
881 /* ARM Security extension instructions. */
882 {ARM_EXT_SEC, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
884 /* ARM V6K instructions. */
885 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
886 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
887 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
888 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
889 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
890 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
891 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
893 /* ARM V6K NOP hints. */
894 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
895 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
896 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
897 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
898 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
900 /* ARM V6 instructions. */
901 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
902 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
903 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
904 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
905 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
906 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
907 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
908 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
909 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
910 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
911 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
920 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
921 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
922 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
923 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
924 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
925 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
926 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
927 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
928 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
929 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
930 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
931 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
932 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
933 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
934 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
935 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
936 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
937 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
938 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
939 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
940 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
941 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
942 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
943 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
944 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
945 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
946 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
947 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
948 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
949 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
950 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
951 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
952 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
953 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
954 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
955 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
956 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
957 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
958 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
959 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
960 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
961 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
962 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
963 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
964 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
965 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
966 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
967 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
968 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
969 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
970 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
971 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
972 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
973 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
974 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
975 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
976 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
977 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
978 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
979 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
980 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
981 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
982 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
983 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
984 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
985 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
986 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
987 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
988 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
989 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
990 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
991 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
992 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
993 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
994 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
995 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
996 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
997 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
998 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
999 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
1000 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
1001 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
1002 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
1003 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1004 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1005 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1006 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1007 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
1008 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1009 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1010 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
1011 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
1012 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
1013 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
1014 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
1015 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1016 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1017 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1018 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1019 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1020 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1021 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1022 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1024 /* V5J instruction. */
1025 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1027 /* V5 Instructions. */
1028 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1029 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
1030 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1031 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1033 /* V5E "El Segundo" Instructions. */
1034 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1035 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1036 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
1037 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1038 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1039 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1040 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1042 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1043 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1045 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1046 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1047 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1048 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1050 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1051 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1052 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1053 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1055 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1056 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1058 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1059 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1060 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1061 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1063 /* ARM Instructions. */
1064 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1066 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1067 {ARM_EXT_V1, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1068 {ARM_EXT_V1, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1069 {ARM_EXT_V1, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1070 {ARM_EXT_V1, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1071 {ARM_EXT_V1, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1073 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1074 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1075 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1076 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1078 {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
1079 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1080 {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
1081 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1083 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1085 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1087 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1089 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1091 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1093 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1095 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1096 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1097 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1099 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1100 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1101 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1103 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1104 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1105 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1107 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1108 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1109 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1111 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1112 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1113 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1115 {ARM_EXT_VIRT, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1116 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1117 {ARM_EXT_V3, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1119 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1120 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1121 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1123 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1124 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1125 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1127 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1128 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1129 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1131 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1132 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1133 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1135 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1136 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1137 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1139 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1140 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1141 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1142 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1143 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1144 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1145 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1147 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1148 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1149 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1151 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1152 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1153 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1155 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1156 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1158 {ARM_EXT_V1, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1160 {ARM_EXT_V1, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1161 {ARM_EXT_V1, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1163 {ARM_EXT_V1, 0x092d0001, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1164 {ARM_EXT_V1, 0x092d0002, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1165 {ARM_EXT_V1, 0x092d0004, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1166 {ARM_EXT_V1, 0x092d0008, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1167 {ARM_EXT_V1, 0x092d0010, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1168 {ARM_EXT_V1, 0x092d0020, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1169 {ARM_EXT_V1, 0x092d0040, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1170 {ARM_EXT_V1, 0x092d0080, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1171 {ARM_EXT_V1, 0x092d0100, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1172 {ARM_EXT_V1, 0x092d0200, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1173 {ARM_EXT_V1, 0x092d0400, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1174 {ARM_EXT_V1, 0x092d0800, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1175 {ARM_EXT_V1, 0x092d1000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1176 {ARM_EXT_V1, 0x092d2000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1177 {ARM_EXT_V1, 0x092d4000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1178 {ARM_EXT_V1, 0x092d8000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1179 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1180 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1181 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1183 {ARM_EXT_V1, 0x08bd0001, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1184 {ARM_EXT_V1, 0x08bd0002, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1185 {ARM_EXT_V1, 0x08bd0004, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1186 {ARM_EXT_V1, 0x08bd0008, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1187 {ARM_EXT_V1, 0x08bd0010, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1188 {ARM_EXT_V1, 0x08bd0020, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1189 {ARM_EXT_V1, 0x08bd0040, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1190 {ARM_EXT_V1, 0x08bd0080, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1191 {ARM_EXT_V1, 0x08bd0100, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1192 {ARM_EXT_V1, 0x08bd0200, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1193 {ARM_EXT_V1, 0x08bd0400, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1194 {ARM_EXT_V1, 0x08bd0800, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1195 {ARM_EXT_V1, 0x08bd1000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1196 {ARM_EXT_V1, 0x08bd2000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1197 {ARM_EXT_V1, 0x08bd4000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1198 {ARM_EXT_V1, 0x08bd8000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1199 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1200 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1201 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1203 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1204 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1206 /* The rest. */
1207 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1208 {0, 0x00000000, 0x00000000, 0}
1211 /* print_insn_thumb16 recognizes the following format control codes:
1213 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1214 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1215 %<bitfield>I print bitfield as a signed decimal
1216 (top bit of range being the sign bit)
1217 %N print Thumb register mask (with LR)
1218 %O print Thumb register mask (with PC)
1219 %M print Thumb register mask
1220 %b print CZB's 6-bit unsigned branch destination
1221 %s print Thumb right-shift immediate (6..10; 0 == 32).
1222 %c print the condition code
1223 %C print the condition code, or "s" if not conditional
1224 %x print warning if conditional an not at end of IT block"
1225 %X print "\t; unpredictable <IT:code>" if conditional
1226 %I print IT instruction suffix and operands
1227 %W print Thumb Writeback indicator for LDMIA
1228 %<bitfield>r print bitfield as an ARM register
1229 %<bitfield>d print bitfield as a decimal
1230 %<bitfield>H print (bitfield * 2) as a decimal
1231 %<bitfield>W print (bitfield * 4) as a decimal
1232 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1233 %<bitfield>B print Thumb branch destination (signed displacement)
1234 %<bitfield>c print bitfield as a condition code
1235 %<bitnum>'c print specified char iff bit is one
1236 %<bitnum>?ab print a if bit is one else print b. */
1238 static const struct opcode16 thumb_opcodes[] =
1240 /* Thumb instructions. */
1242 /* ARM V6K no-argument instructions. */
1243 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1244 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1245 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1246 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1247 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1248 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1250 /* ARM V6T2 instructions. */
1251 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1252 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1253 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1255 /* ARM V6. */
1256 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1257 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1258 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1259 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1260 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1261 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1262 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1263 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1264 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1265 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1266 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1268 /* ARM V5 ISA extends Thumb. */
1269 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1270 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1271 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1272 /* ARM V4T ISA (Thumb v1). */
1273 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1274 /* Format 4. */
1275 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1276 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1277 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1278 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1279 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1280 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1281 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1282 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1283 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1284 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1285 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1286 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1287 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1288 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1289 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1290 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1291 /* format 13 */
1292 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1293 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1294 /* format 5 */
1295 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1296 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1297 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1298 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1299 /* format 14 */
1300 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1301 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1302 /* format 2 */
1303 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1304 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1305 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1306 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1307 /* format 8 */
1308 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1309 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1310 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1311 /* format 7 */
1312 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1313 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1314 /* format 1 */
1315 {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1316 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1317 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1318 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1319 /* format 3 */
1320 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1321 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1322 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1323 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1324 /* format 6 */
1325 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1326 /* format 9 */
1327 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1328 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1329 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1330 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1331 /* format 10 */
1332 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1333 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1334 /* format 11 */
1335 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1336 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1337 /* format 12 */
1338 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1339 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1340 /* format 15 */
1341 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1342 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1343 /* format 17 */
1344 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1345 /* format 16 */
1346 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1347 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1348 /* format 18 */
1349 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1351 /* The E800 .. FFFF range is unconditionally redirected to the
1352 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1353 are processed via that table. Thus, we can never encounter a
1354 bare "second half of BL/BLX(1)" instruction here. */
1355 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1356 {0, 0, 0, 0}
1359 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1360 We adopt the convention that hw1 is the high 16 bits of .value and
1361 .mask, hw2 the low 16 bits.
1363 print_insn_thumb32 recognizes the following format control codes:
1365 %% %
1367 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1368 %M print a modified 12-bit immediate (same location)
1369 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1370 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1371 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1372 %S print a possibly-shifted Rm
1374 %L print address for a ldrd/strd instruction
1375 %a print the address of a plain load/store
1376 %w print the width and signedness of a core load/store
1377 %m print register mask for ldm/stm
1379 %E print the lsb and width fields of a bfc/bfi instruction
1380 %F print the lsb and width fields of a sbfx/ubfx instruction
1381 %b print a conditional branch offset
1382 %B print an unconditional branch offset
1383 %s print the shift field of an SSAT instruction
1384 %R print the rotation field of an SXT instruction
1385 %U print barrier type.
1386 %P print address for pli instruction.
1387 %c print the condition code
1388 %x print warning if conditional an not at end of IT block"
1389 %X print "\t; unpredictable <IT:code>" if conditional
1391 %<bitfield>d print bitfield in decimal
1392 %<bitfield>W print bitfield*4 in decimal
1393 %<bitfield>r print bitfield as an ARM register
1394 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1395 %<bitfield>c print bitfield as a condition code
1397 %<bitfield>'c print specified char iff bitfield is all ones
1398 %<bitfield>`c print specified char iff bitfield is all zeroes
1399 %<bitfield>?ab... select from array of values in big endian order
1401 With one exception at the bottom (done because BL and BLX(1) need
1402 to come dead last), this table was machine-sorted first in
1403 decreasing order of number of bits set in the mask, then in
1404 increasing numeric order of mask, then in increasing numeric order
1405 of opcode. This order is not the clearest for a human reader, but
1406 is guaranteed never to catch a special-case bit pattern with a more
1407 general mask, which is important, because this instruction encoding
1408 makes heavy use of special-case bit patterns. */
1409 static const struct opcode32 thumb32_opcodes[] =
1411 /* V7 instructions. */
1412 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1413 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1414 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1415 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1416 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1417 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1418 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1420 /* Virtualization Extension instructions. */
1421 {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1422 /* We skip ERET as that is SUBS pc, lr, #0. */
1424 /* MP Extension instructions. */
1425 {ARM_EXT_MP, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1427 /* Security extension instructions. */
1428 {ARM_EXT_SEC, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1430 /* Instructions defined in the basic V6T2 set. */
1431 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1432 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1433 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1434 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1435 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1436 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1438 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1439 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1440 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1441 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1442 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1443 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1444 {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1445 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1446 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1447 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1448 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1449 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1450 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1451 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1452 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1453 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1454 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1455 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1456 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1457 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1458 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1459 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1460 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1461 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1462 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1463 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1464 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1466 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1467 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1468 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1469 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1470 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1471 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1472 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1473 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1474 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1475 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1476 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1477 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1478 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1479 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1480 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1481 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1482 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1483 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1484 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1485 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1486 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1487 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1488 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1489 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1490 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1491 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1492 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1493 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1494 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1495 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1496 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1497 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1498 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1499 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1500 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1501 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1502 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1503 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1504 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1505 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1506 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1507 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1508 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1509 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1510 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1511 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1512 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1513 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1514 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1515 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1516 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1517 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1518 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1519 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1520 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1521 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1522 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1523 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1524 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1525 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1526 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1527 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1528 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1529 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1530 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1531 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1532 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1533 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1534 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1535 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1536 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1537 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1538 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1539 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1540 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1541 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1542 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1543 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1544 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1545 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1546 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1547 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1548 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1549 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1550 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1551 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1552 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1553 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1554 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1555 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1556 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1557 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1558 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1559 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1560 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1561 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1562 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1563 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1564 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1565 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1566 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1567 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1568 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1569 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1570 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1571 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1572 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1573 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1574 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1575 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1576 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1577 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1578 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1579 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1580 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1581 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1582 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1583 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1584 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1585 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1586 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1587 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1588 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1589 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1590 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1591 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1592 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1593 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1594 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1595 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1596 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1597 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1598 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1599 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1600 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1601 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1602 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1603 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1604 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1605 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1606 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1607 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1608 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1610 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1611 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1612 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1613 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1614 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1616 /* These have been 32-bit since the invention of Thumb. */
1617 {ARM_EXT_V4T, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1618 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1620 /* Fallback. */
1621 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1622 {0, 0, 0, 0}
1625 static const char *const arm_conditional[] =
1626 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1627 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1629 static const char *const arm_fp_const[] =
1630 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1632 static const char *const arm_shift[] =
1633 {"lsl", "lsr", "asr", "ror"};
1635 typedef struct
1637 const char *name;
1638 const char *description;
1639 const char *reg_names[16];
1641 arm_regname;
1643 static const arm_regname regnames[] =
1645 { "raw" , "Select raw register names",
1646 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1647 { "gcc", "Select register names used by GCC",
1648 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1649 { "std", "Select register names used in ARM's ISA documentation",
1650 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1651 { "apcs", "Select register names used in the APCS",
1652 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1653 { "atpcs", "Select register names used in the ATPCS",
1654 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1655 { "special-atpcs", "Select special register names used in the ATPCS",
1656 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1659 static const char *const iwmmxt_wwnames[] =
1660 {"b", "h", "w", "d"};
1662 static const char *const iwmmxt_wwssnames[] =
1663 {"b", "bus", "bc", "bss",
1664 "h", "hus", "hc", "hss",
1665 "w", "wus", "wc", "wss",
1666 "d", "dus", "dc", "dss"
1669 static const char *const iwmmxt_regnames[] =
1670 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1671 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1674 static const char *const iwmmxt_cregnames[] =
1675 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1676 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1679 /* Default to GCC register name set. */
1680 static unsigned int regname_selected = 1;
1682 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1683 #define arm_regnames regnames[regname_selected].reg_names
1685 static bfd_boolean force_thumb = FALSE;
1687 /* Current IT instruction state. This contains the same state as the IT
1688 bits in the CPSR. */
1689 static unsigned int ifthen_state;
1690 /* IT state for the next instruction. */
1691 static unsigned int ifthen_next_state;
1692 /* The address of the insn for which the IT state is valid. */
1693 static bfd_vma ifthen_address;
1694 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1697 /* Functions. */
1699 get_arm_regname_num_options (void)
1701 return NUM_ARM_REGNAMES;
1705 set_arm_regname_option (int option)
1707 int old = regname_selected;
1708 regname_selected = option;
1709 return old;
1713 get_arm_regnames (int option,
1714 const char **setname,
1715 const char **setdescription,
1716 const char *const **register_names)
1718 *setname = regnames[option].name;
1719 *setdescription = regnames[option].description;
1720 *register_names = regnames[option].reg_names;
1721 return 16;
1724 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1725 Returns pointer to following character of the format string and
1726 fills in *VALUEP and *WIDTHP with the extracted value and number of
1727 bits extracted. WIDTHP can be NULL. */
1729 static const char *
1730 arm_decode_bitfield (const char *ptr,
1731 unsigned long insn,
1732 unsigned long *valuep,
1733 int *widthp)
1735 unsigned long value = 0;
1736 int width = 0;
1740 int start, end;
1741 int bits;
1743 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1744 start = start * 10 + *ptr - '0';
1745 if (*ptr == '-')
1746 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1747 end = end * 10 + *ptr - '0';
1748 else
1749 end = start;
1750 bits = end - start;
1751 if (bits < 0)
1752 abort ();
1753 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1754 width += bits + 1;
1756 while (*ptr++ == ',');
1757 *valuep = value;
1758 if (widthp)
1759 *widthp = width;
1760 return ptr - 1;
1763 static void
1764 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1765 bfd_boolean print_shift)
1767 func (stream, "%s", arm_regnames[given & 0xf]);
1769 if ((given & 0xff0) != 0)
1771 if ((given & 0x10) == 0)
1773 int amount = (given & 0xf80) >> 7;
1774 int shift = (given & 0x60) >> 5;
1776 if (amount == 0)
1778 if (shift == 3)
1780 func (stream, ", rrx");
1781 return;
1784 amount = 32;
1787 if (print_shift)
1788 func (stream, ", %s #%d", arm_shift[shift], amount);
1789 else
1790 func (stream, ", #%d", amount);
1792 else if ((given & 0x80) == 0x80)
1793 func (stream, "\t; <illegal shifter operand>");
1794 else if (print_shift)
1795 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1796 arm_regnames[(given & 0xf00) >> 8]);
1797 else
1798 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1802 #define W_BIT 21
1803 #define I_BIT 22
1804 #define U_BIT 23
1805 #define P_BIT 24
1807 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1808 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1809 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1810 #define PRE_BIT_SET (given & (1 << P_BIT))
1812 /* Print one coprocessor instruction on INFO->STREAM.
1813 Return TRUE if the instuction matched, FALSE if this is not a
1814 recognised coprocessor instruction. */
1816 static bfd_boolean
1817 print_insn_coprocessor (bfd_vma pc,
1818 struct disassemble_info *info,
1819 long given,
1820 bfd_boolean thumb)
1822 const struct opcode32 *insn;
1823 void *stream = info->stream;
1824 fprintf_ftype func = info->fprintf_func;
1825 unsigned long mask;
1826 unsigned long value = 0;
1827 struct arm_private_data *private_data = info->private_data;
1828 unsigned long allowed_arches = private_data->features.coproc;
1829 int cond;
1831 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1833 unsigned long u_reg = 16;
1834 bfd_boolean is_unpredictable = FALSE;
1835 signed long value_in_comment = 0;
1836 const char *c;
1838 if (insn->arch == 0)
1839 switch (insn->value)
1841 case SENTINEL_IWMMXT_START:
1842 if (info->mach != bfd_mach_arm_XScale
1843 && info->mach != bfd_mach_arm_iWMMXt
1844 && info->mach != bfd_mach_arm_iWMMXt2)
1846 insn++;
1847 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1848 continue;
1850 case SENTINEL_IWMMXT_END:
1851 continue;
1853 case SENTINEL_GENERIC_START:
1854 allowed_arches = private_data->features.core;
1855 continue;
1857 default:
1858 abort ();
1861 mask = insn->mask;
1862 value = insn->value;
1863 if (thumb)
1865 /* The high 4 bits are 0xe for Arm conditional instructions, and
1866 0xe for arm unconditional instructions. The rest of the
1867 encoding is the same. */
1868 mask |= 0xf0000000;
1869 value |= 0xe0000000;
1870 if (ifthen_state)
1871 cond = IFTHEN_COND;
1872 else
1873 cond = 16;
1875 else
1877 /* Only match unconditional instuctions against unconditional
1878 patterns. */
1879 if ((given & 0xf0000000) == 0xf0000000)
1881 mask |= 0xf0000000;
1882 cond = 16;
1884 else
1886 cond = (given >> 28) & 0xf;
1887 if (cond == 0xe)
1888 cond = 16;
1892 if ((given & mask) != value)
1893 continue;
1895 if ((insn->arch & allowed_arches) == 0)
1896 continue;
1898 for (c = insn->assembler; *c; c++)
1900 if (*c == '%')
1902 switch (*++c)
1904 case '%':
1905 func (stream, "%%");
1906 break;
1908 case 'A':
1910 int rn = (given >> 16) & 0xf;
1911 bfd_vma offset = given & 0xff;
1913 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1915 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1917 /* Not unindexed. The offset is scaled. */
1918 offset = offset * 4;
1919 if (NEGATIVE_BIT_SET)
1920 offset = - offset;
1921 if (rn != 15)
1922 value_in_comment = offset;
1925 if (PRE_BIT_SET)
1927 if (offset)
1928 func (stream, ", #%d]%s",
1929 (int) offset,
1930 WRITEBACK_BIT_SET ? "!" : "");
1931 else if (NEGATIVE_BIT_SET)
1932 func (stream, ", #-0]");
1933 else
1934 func (stream, "]");
1936 else
1938 func (stream, "]");
1940 if (WRITEBACK_BIT_SET)
1942 if (offset)
1943 func (stream, ", #%d", (int) offset);
1944 else if (NEGATIVE_BIT_SET)
1945 func (stream, ", #-0");
1947 else
1949 func (stream, ", {%s%d}",
1950 (NEGATIVE_BIT_SET && !offset) ? "-" : "",
1951 (int) offset);
1952 value_in_comment = offset;
1955 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1957 func (stream, "\t; ");
1958 /* For unaligned PCs, apply off-by-alignment
1959 correction. */
1960 info->print_address_func (offset + pc
1961 + info->bytes_per_chunk * 2
1962 - (pc & 3),
1963 info);
1966 break;
1968 case 'B':
1970 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1971 int offset = (given >> 1) & 0x3f;
1973 if (offset == 1)
1974 func (stream, "{d%d}", regno);
1975 else if (regno + offset > 32)
1976 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1977 else
1978 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1980 break;
1982 case 'c':
1983 func (stream, "%s", arm_conditional[cond]);
1984 break;
1986 case 'I':
1987 /* Print a Cirrus/DSP shift immediate. */
1988 /* Immediates are 7bit signed ints with bits 0..3 in
1989 bits 0..3 of opcode and bits 4..6 in bits 5..7
1990 of opcode. */
1992 int imm;
1994 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1996 /* Is ``imm'' a negative number? */
1997 if (imm & 0x40)
1998 imm |= (-1 << 7);
2000 func (stream, "%d", imm);
2003 break;
2005 case 'F':
2006 switch (given & 0x00408000)
2008 case 0:
2009 func (stream, "4");
2010 break;
2011 case 0x8000:
2012 func (stream, "1");
2013 break;
2014 case 0x00400000:
2015 func (stream, "2");
2016 break;
2017 default:
2018 func (stream, "3");
2020 break;
2022 case 'P':
2023 switch (given & 0x00080080)
2025 case 0:
2026 func (stream, "s");
2027 break;
2028 case 0x80:
2029 func (stream, "d");
2030 break;
2031 case 0x00080000:
2032 func (stream, "e");
2033 break;
2034 default:
2035 func (stream, _("<illegal precision>"));
2036 break;
2038 break;
2040 case 'Q':
2041 switch (given & 0x00408000)
2043 case 0:
2044 func (stream, "s");
2045 break;
2046 case 0x8000:
2047 func (stream, "d");
2048 break;
2049 case 0x00400000:
2050 func (stream, "e");
2051 break;
2052 default:
2053 func (stream, "p");
2054 break;
2056 break;
2058 case 'R':
2059 switch (given & 0x60)
2061 case 0:
2062 break;
2063 case 0x20:
2064 func (stream, "p");
2065 break;
2066 case 0x40:
2067 func (stream, "m");
2068 break;
2069 default:
2070 func (stream, "z");
2071 break;
2073 break;
2075 case '0': case '1': case '2': case '3': case '4':
2076 case '5': case '6': case '7': case '8': case '9':
2078 int width;
2080 c = arm_decode_bitfield (c, given, &value, &width);
2082 switch (*c)
2084 case 'R':
2085 if (value == 15)
2086 is_unpredictable = TRUE;
2087 /* Fall through. */
2088 case 'r':
2089 if (c[1] == 'u')
2091 /* Eat the 'u' character. */
2092 ++ c;
2094 if (u_reg == value)
2095 is_unpredictable = TRUE;
2096 u_reg = value;
2098 func (stream, "%s", arm_regnames[value]);
2099 break;
2100 case 'D':
2101 func (stream, "d%ld", value);
2102 break;
2103 case 'Q':
2104 if (value & 1)
2105 func (stream, "<illegal reg q%ld.5>", value >> 1);
2106 else
2107 func (stream, "q%ld", value >> 1);
2108 break;
2109 case 'd':
2110 func (stream, "%ld", value);
2111 value_in_comment = value;
2112 break;
2113 case 'k':
2115 int from = (given & (1 << 7)) ? 32 : 16;
2116 func (stream, "%ld", from - value);
2118 break;
2120 case 'f':
2121 if (value > 7)
2122 func (stream, "#%s", arm_fp_const[value & 7]);
2123 else
2124 func (stream, "f%ld", value);
2125 break;
2127 case 'w':
2128 if (width == 2)
2129 func (stream, "%s", iwmmxt_wwnames[value]);
2130 else
2131 func (stream, "%s", iwmmxt_wwssnames[value]);
2132 break;
2134 case 'g':
2135 func (stream, "%s", iwmmxt_regnames[value]);
2136 break;
2137 case 'G':
2138 func (stream, "%s", iwmmxt_cregnames[value]);
2139 break;
2141 case 'x':
2142 func (stream, "0x%lx", (value & 0xffffffffUL));
2143 break;
2145 case '`':
2146 c++;
2147 if (value == 0)
2148 func (stream, "%c", *c);
2149 break;
2150 case '\'':
2151 c++;
2152 if (value == ((1ul << width) - 1))
2153 func (stream, "%c", *c);
2154 break;
2155 case '?':
2156 func (stream, "%c", c[(1 << width) - (int) value]);
2157 c += 1 << width;
2158 break;
2159 default:
2160 abort ();
2162 break;
2164 case 'y':
2165 case 'z':
2167 int single = *c++ == 'y';
2168 int regno;
2170 switch (*c)
2172 case '4': /* Sm pair */
2173 case '0': /* Sm, Dm */
2174 regno = given & 0x0000000f;
2175 if (single)
2177 regno <<= 1;
2178 regno += (given >> 5) & 1;
2180 else
2181 regno += ((given >> 5) & 1) << 4;
2182 break;
2184 case '1': /* Sd, Dd */
2185 regno = (given >> 12) & 0x0000000f;
2186 if (single)
2188 regno <<= 1;
2189 regno += (given >> 22) & 1;
2191 else
2192 regno += ((given >> 22) & 1) << 4;
2193 break;
2195 case '2': /* Sn, Dn */
2196 regno = (given >> 16) & 0x0000000f;
2197 if (single)
2199 regno <<= 1;
2200 regno += (given >> 7) & 1;
2202 else
2203 regno += ((given >> 7) & 1) << 4;
2204 break;
2206 case '3': /* List */
2207 func (stream, "{");
2208 regno = (given >> 12) & 0x0000000f;
2209 if (single)
2211 regno <<= 1;
2212 regno += (given >> 22) & 1;
2214 else
2215 regno += ((given >> 22) & 1) << 4;
2216 break;
2218 default:
2219 abort ();
2222 func (stream, "%c%d", single ? 's' : 'd', regno);
2224 if (*c == '3')
2226 int count = given & 0xff;
2228 if (single == 0)
2229 count >>= 1;
2231 if (--count)
2233 func (stream, "-%c%d",
2234 single ? 's' : 'd',
2235 regno + count);
2238 func (stream, "}");
2240 else if (*c == '4')
2241 func (stream, ", %c%d", single ? 's' : 'd',
2242 regno + 1);
2244 break;
2246 case 'L':
2247 switch (given & 0x00400100)
2249 case 0x00000000: func (stream, "b"); break;
2250 case 0x00400000: func (stream, "h"); break;
2251 case 0x00000100: func (stream, "w"); break;
2252 case 0x00400100: func (stream, "d"); break;
2253 default:
2254 break;
2256 break;
2258 case 'Z':
2260 /* given (20, 23) | given (0, 3) */
2261 value = ((given >> 16) & 0xf0) | (given & 0xf);
2262 func (stream, "%d", (int) value);
2264 break;
2266 case 'l':
2267 /* This is like the 'A' operator, except that if
2268 the width field "M" is zero, then the offset is
2269 *not* multiplied by four. */
2271 int offset = given & 0xff;
2272 int multiplier = (given & 0x00000100) ? 4 : 1;
2274 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2276 if (multiplier > 1)
2278 value_in_comment = offset * multiplier;
2279 if (NEGATIVE_BIT_SET)
2280 value_in_comment = - value_in_comment;
2283 if (offset)
2285 if (PRE_BIT_SET)
2286 func (stream, ", #%s%d]%s",
2287 NEGATIVE_BIT_SET ? "-" : "",
2288 offset * multiplier,
2289 WRITEBACK_BIT_SET ? "!" : "");
2290 else
2291 func (stream, "], #%s%d",
2292 NEGATIVE_BIT_SET ? "-" : "",
2293 offset * multiplier);
2295 else
2296 func (stream, "]");
2298 break;
2300 case 'r':
2302 int imm4 = (given >> 4) & 0xf;
2303 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2304 int ubit = ! NEGATIVE_BIT_SET;
2305 const char *rm = arm_regnames [given & 0xf];
2306 const char *rn = arm_regnames [(given >> 16) & 0xf];
2308 switch (puw_bits)
2310 case 1:
2311 case 3:
2312 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2313 if (imm4)
2314 func (stream, ", lsl #%d", imm4);
2315 break;
2317 case 4:
2318 case 5:
2319 case 6:
2320 case 7:
2321 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2322 if (imm4 > 0)
2323 func (stream, ", lsl #%d", imm4);
2324 func (stream, "]");
2325 if (puw_bits == 5 || puw_bits == 7)
2326 func (stream, "!");
2327 break;
2329 default:
2330 func (stream, "INVALID");
2333 break;
2335 case 'i':
2337 long imm5;
2338 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2339 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2341 break;
2343 default:
2344 abort ();
2348 else
2349 func (stream, "%c", *c);
2352 if (value_in_comment > 32 || value_in_comment < -16)
2353 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2355 if (is_unpredictable)
2356 func (stream, UNPREDICTABLE_INSTRUCTION);
2358 return TRUE;
2360 return FALSE;
2363 /* Decodes and prints ARM addressing modes. Returns the offset
2364 used in the address, if any, if it is worthwhile printing the
2365 offset as a hexadecimal value in a comment at the end of the
2366 line of disassembly. */
2368 static signed long
2369 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2371 void *stream = info->stream;
2372 fprintf_ftype func = info->fprintf_func;
2373 bfd_vma offset = 0;
2375 if (((given & 0x000f0000) == 0x000f0000)
2376 && ((given & 0x02000000) == 0))
2378 offset = given & 0xfff;
2380 func (stream, "[pc");
2382 if (PRE_BIT_SET)
2384 /* Pre-indexed. Elide offset of positive zero when
2385 non-writeback. */
2386 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2387 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2389 if (NEGATIVE_BIT_SET)
2390 offset = -offset;
2392 offset += pc + 8;
2394 /* Cope with the possibility of write-back
2395 being used. Probably a very dangerous thing
2396 for the programmer to do, but who are we to
2397 argue ? */
2398 func (stream, "]%s", WRITEBACK_BIT_SET ? "!" : "");
2400 else /* Post indexed. */
2402 func (stream, "], #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2404 /* Ie ignore the offset. */
2405 offset = pc + 8;
2408 func (stream, "\t; ");
2409 info->print_address_func (offset, info);
2410 offset = 0;
2412 else
2414 func (stream, "[%s",
2415 arm_regnames[(given >> 16) & 0xf]);
2417 if (PRE_BIT_SET)
2419 if ((given & 0x02000000) == 0)
2421 /* Elide offset of positive zero when non-writeback. */
2422 offset = given & 0xfff;
2423 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2424 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2426 else
2428 func (stream, ", %s", NEGATIVE_BIT_SET ? "-" : "");
2429 arm_decode_shift (given, func, stream, TRUE);
2432 func (stream, "]%s",
2433 WRITEBACK_BIT_SET ? "!" : "");
2435 else
2437 if ((given & 0x02000000) == 0)
2439 /* Always show offset. */
2440 offset = given & 0xfff;
2441 func (stream, "], #%s%d",
2442 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2444 else
2446 func (stream, "], %s",
2447 NEGATIVE_BIT_SET ? "-" : "");
2448 arm_decode_shift (given, func, stream, TRUE);
2453 return (signed long) offset;
2456 /* Print one neon instruction on INFO->STREAM.
2457 Return TRUE if the instuction matched, FALSE if this is not a
2458 recognised neon instruction. */
2460 static bfd_boolean
2461 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2463 const struct opcode32 *insn;
2464 void *stream = info->stream;
2465 fprintf_ftype func = info->fprintf_func;
2467 if (thumb)
2469 if ((given & 0xef000000) == 0xef000000)
2471 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2472 unsigned long bit28 = given & (1 << 28);
2474 given &= 0x00ffffff;
2475 if (bit28)
2476 given |= 0xf3000000;
2477 else
2478 given |= 0xf2000000;
2480 else if ((given & 0xff000000) == 0xf9000000)
2481 given ^= 0xf9000000 ^ 0xf4000000;
2482 else
2483 return FALSE;
2486 for (insn = neon_opcodes; insn->assembler; insn++)
2488 if ((given & insn->mask) == insn->value)
2490 signed long value_in_comment = 0;
2491 const char *c;
2493 for (c = insn->assembler; *c; c++)
2495 if (*c == '%')
2497 switch (*++c)
2499 case '%':
2500 func (stream, "%%");
2501 break;
2503 case 'c':
2504 if (thumb && ifthen_state)
2505 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2506 break;
2508 case 'A':
2510 static const unsigned char enc[16] =
2512 0x4, 0x14, /* st4 0,1 */
2513 0x4, /* st1 2 */
2514 0x4, /* st2 3 */
2515 0x3, /* st3 4 */
2516 0x13, /* st3 5 */
2517 0x3, /* st1 6 */
2518 0x1, /* st1 7 */
2519 0x2, /* st2 8 */
2520 0x12, /* st2 9 */
2521 0x2, /* st1 10 */
2522 0, 0, 0, 0, 0
2524 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2525 int rn = ((given >> 16) & 0xf);
2526 int rm = ((given >> 0) & 0xf);
2527 int align = ((given >> 4) & 0x3);
2528 int type = ((given >> 8) & 0xf);
2529 int n = enc[type] & 0xf;
2530 int stride = (enc[type] >> 4) + 1;
2531 int ix;
2533 func (stream, "{");
2534 if (stride > 1)
2535 for (ix = 0; ix != n; ix++)
2536 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2537 else if (n == 1)
2538 func (stream, "d%d", rd);
2539 else
2540 func (stream, "d%d-d%d", rd, rd + n - 1);
2541 func (stream, "}, [%s", arm_regnames[rn]);
2542 if (align)
2543 func (stream, " :%d", 32 << align);
2544 func (stream, "]");
2545 if (rm == 0xd)
2546 func (stream, "!");
2547 else if (rm != 0xf)
2548 func (stream, ", %s", arm_regnames[rm]);
2550 break;
2552 case 'B':
2554 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2555 int rn = ((given >> 16) & 0xf);
2556 int rm = ((given >> 0) & 0xf);
2557 int idx_align = ((given >> 4) & 0xf);
2558 int align = 0;
2559 int size = ((given >> 10) & 0x3);
2560 int idx = idx_align >> (size + 1);
2561 int length = ((given >> 8) & 3) + 1;
2562 int stride = 1;
2563 int i;
2565 if (length > 1 && size > 0)
2566 stride = (idx_align & (1 << size)) ? 2 : 1;
2568 switch (length)
2570 case 1:
2572 int amask = (1 << size) - 1;
2573 if ((idx_align & (1 << size)) != 0)
2574 return FALSE;
2575 if (size > 0)
2577 if ((idx_align & amask) == amask)
2578 align = 8 << size;
2579 else if ((idx_align & amask) != 0)
2580 return FALSE;
2583 break;
2585 case 2:
2586 if (size == 2 && (idx_align & 2) != 0)
2587 return FALSE;
2588 align = (idx_align & 1) ? 16 << size : 0;
2589 break;
2591 case 3:
2592 if ((size == 2 && (idx_align & 3) != 0)
2593 || (idx_align & 1) != 0)
2594 return FALSE;
2595 break;
2597 case 4:
2598 if (size == 2)
2600 if ((idx_align & 3) == 3)
2601 return FALSE;
2602 align = (idx_align & 3) * 64;
2604 else
2605 align = (idx_align & 1) ? 32 << size : 0;
2606 break;
2608 default:
2609 abort ();
2612 func (stream, "{");
2613 for (i = 0; i < length; i++)
2614 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2615 rd + i * stride, idx);
2616 func (stream, "}, [%s", arm_regnames[rn]);
2617 if (align)
2618 func (stream, " :%d", align);
2619 func (stream, "]");
2620 if (rm == 0xd)
2621 func (stream, "!");
2622 else if (rm != 0xf)
2623 func (stream, ", %s", arm_regnames[rm]);
2625 break;
2627 case 'C':
2629 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2630 int rn = ((given >> 16) & 0xf);
2631 int rm = ((given >> 0) & 0xf);
2632 int align = ((given >> 4) & 0x1);
2633 int size = ((given >> 6) & 0x3);
2634 int type = ((given >> 8) & 0x3);
2635 int n = type + 1;
2636 int stride = ((given >> 5) & 0x1);
2637 int ix;
2639 if (stride && (n == 1))
2640 n++;
2641 else
2642 stride++;
2644 func (stream, "{");
2645 if (stride > 1)
2646 for (ix = 0; ix != n; ix++)
2647 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2648 else if (n == 1)
2649 func (stream, "d%d[]", rd);
2650 else
2651 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2652 func (stream, "}, [%s", arm_regnames[rn]);
2653 if (align)
2655 align = (8 * (type + 1)) << size;
2656 if (type == 3)
2657 align = (size > 1) ? align >> 1 : align;
2658 if (type == 2 || (type == 0 && !size))
2659 func (stream, " :<bad align %d>", align);
2660 else
2661 func (stream, " :%d", align);
2663 func (stream, "]");
2664 if (rm == 0xd)
2665 func (stream, "!");
2666 else if (rm != 0xf)
2667 func (stream, ", %s", arm_regnames[rm]);
2669 break;
2671 case 'D':
2673 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2674 int size = (given >> 20) & 3;
2675 int reg = raw_reg & ((4 << size) - 1);
2676 int ix = raw_reg >> size >> 2;
2678 func (stream, "d%d[%d]", reg, ix);
2680 break;
2682 case 'E':
2683 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2685 int bits = 0;
2686 int cmode = (given >> 8) & 0xf;
2687 int op = (given >> 5) & 0x1;
2688 unsigned long value = 0, hival = 0;
2689 unsigned shift;
2690 int size = 0;
2691 int isfloat = 0;
2693 bits |= ((given >> 24) & 1) << 7;
2694 bits |= ((given >> 16) & 7) << 4;
2695 bits |= ((given >> 0) & 15) << 0;
2697 if (cmode < 8)
2699 shift = (cmode >> 1) & 3;
2700 value = (unsigned long) bits << (8 * shift);
2701 size = 32;
2703 else if (cmode < 12)
2705 shift = (cmode >> 1) & 1;
2706 value = (unsigned long) bits << (8 * shift);
2707 size = 16;
2709 else if (cmode < 14)
2711 shift = (cmode & 1) + 1;
2712 value = (unsigned long) bits << (8 * shift);
2713 value |= (1ul << (8 * shift)) - 1;
2714 size = 32;
2716 else if (cmode == 14)
2718 if (op)
2720 /* Bit replication into bytes. */
2721 int ix;
2722 unsigned long mask;
2724 value = 0;
2725 hival = 0;
2726 for (ix = 7; ix >= 0; ix--)
2728 mask = ((bits >> ix) & 1) ? 0xff : 0;
2729 if (ix <= 3)
2730 value = (value << 8) | mask;
2731 else
2732 hival = (hival << 8) | mask;
2734 size = 64;
2736 else
2738 /* Byte replication. */
2739 value = (unsigned long) bits;
2740 size = 8;
2743 else if (!op)
2745 /* Floating point encoding. */
2746 int tmp;
2748 value = (unsigned long) (bits & 0x7f) << 19;
2749 value |= (unsigned long) (bits & 0x80) << 24;
2750 tmp = bits & 0x40 ? 0x3c : 0x40;
2751 value |= (unsigned long) tmp << 24;
2752 size = 32;
2753 isfloat = 1;
2755 else
2757 func (stream, "<illegal constant %.8x:%x:%x>",
2758 bits, cmode, op);
2759 size = 32;
2760 break;
2762 switch (size)
2764 case 8:
2765 func (stream, "#%ld\t; 0x%.2lx", value, value);
2766 break;
2768 case 16:
2769 func (stream, "#%ld\t; 0x%.4lx", value, value);
2770 break;
2772 case 32:
2773 if (isfloat)
2775 unsigned char valbytes[4];
2776 double fvalue;
2778 /* Do this a byte at a time so we don't have to
2779 worry about the host's endianness. */
2780 valbytes[0] = value & 0xff;
2781 valbytes[1] = (value >> 8) & 0xff;
2782 valbytes[2] = (value >> 16) & 0xff;
2783 valbytes[3] = (value >> 24) & 0xff;
2785 floatformat_to_double
2786 (& floatformat_ieee_single_little, valbytes,
2787 & fvalue);
2789 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2790 value);
2792 else
2793 func (stream, "#%ld\t; 0x%.8lx",
2794 (long) (((value & 0x80000000L) != 0)
2795 ? value | ~0xffffffffL : value),
2796 value);
2797 break;
2799 case 64:
2800 func (stream, "#0x%.8lx%.8lx", hival, value);
2801 break;
2803 default:
2804 abort ();
2807 break;
2809 case 'F':
2811 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2812 int num = (given >> 8) & 0x3;
2814 if (!num)
2815 func (stream, "{d%d}", regno);
2816 else if (num + regno >= 32)
2817 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2818 else
2819 func (stream, "{d%d-d%d}", regno, regno + num);
2821 break;
2824 case '0': case '1': case '2': case '3': case '4':
2825 case '5': case '6': case '7': case '8': case '9':
2827 int width;
2828 unsigned long value;
2830 c = arm_decode_bitfield (c, given, &value, &width);
2832 switch (*c)
2834 case 'r':
2835 func (stream, "%s", arm_regnames[value]);
2836 break;
2837 case 'd':
2838 func (stream, "%ld", value);
2839 value_in_comment = value;
2840 break;
2841 case 'e':
2842 func (stream, "%ld", (1ul << width) - value);
2843 break;
2845 case 'S':
2846 case 'T':
2847 case 'U':
2848 /* Various width encodings. */
2850 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2851 int limit;
2852 unsigned low, high;
2854 c++;
2855 if (*c >= '0' && *c <= '9')
2856 limit = *c - '0';
2857 else if (*c >= 'a' && *c <= 'f')
2858 limit = *c - 'a' + 10;
2859 else
2860 abort ();
2861 low = limit >> 2;
2862 high = limit & 3;
2864 if (value < low || value > high)
2865 func (stream, "<illegal width %d>", base << value);
2866 else
2867 func (stream, "%d", base << value);
2869 break;
2870 case 'R':
2871 if (given & (1 << 6))
2872 goto Q;
2873 /* FALLTHROUGH */
2874 case 'D':
2875 func (stream, "d%ld", value);
2876 break;
2877 case 'Q':
2879 if (value & 1)
2880 func (stream, "<illegal reg q%ld.5>", value >> 1);
2881 else
2882 func (stream, "q%ld", value >> 1);
2883 break;
2885 case '`':
2886 c++;
2887 if (value == 0)
2888 func (stream, "%c", *c);
2889 break;
2890 case '\'':
2891 c++;
2892 if (value == ((1ul << width) - 1))
2893 func (stream, "%c", *c);
2894 break;
2895 case '?':
2896 func (stream, "%c", c[(1 << width) - (int) value]);
2897 c += 1 << width;
2898 break;
2899 default:
2900 abort ();
2902 break;
2904 default:
2905 abort ();
2909 else
2910 func (stream, "%c", *c);
2913 if (value_in_comment > 32 || value_in_comment < -16)
2914 func (stream, "\t; 0x%lx", value_in_comment);
2916 return TRUE;
2919 return FALSE;
2922 /* Return the name of a v7A special register. */
2924 static const char *
2925 banked_regname (unsigned reg)
2927 switch (reg)
2929 case 15: return "CPSR";
2930 case 32: return "R8_usr";
2931 case 33: return "R9_usr";
2932 case 34: return "R10_usr";
2933 case 35: return "R11_usr";
2934 case 36: return "R12_usr";
2935 case 37: return "SP_usr";
2936 case 38: return "LR_usr";
2937 case 40: return "R8_fiq";
2938 case 41: return "R9_fiq";
2939 case 42: return "R10_fiq";
2940 case 43: return "R11_fiq";
2941 case 44: return "R12_fiq";
2942 case 45: return "SP_fiq";
2943 case 46: return "LR_fiq";
2944 case 48: return "LR_irq";
2945 case 49: return "SP_irq";
2946 case 50: return "LR_svc";
2947 case 51: return "SP_svc";
2948 case 52: return "LR_abt";
2949 case 53: return "SP_abt";
2950 case 54: return "LR_und";
2951 case 55: return "SP_und";
2952 case 60: return "LR_mon";
2953 case 61: return "SP_mon";
2954 case 62: return "ELR_hyp";
2955 case 63: return "SP_hyp";
2956 case 79: return "SPSR";
2957 case 110: return "SPSR_fiq";
2958 case 112: return "SPSR_irq";
2959 case 114: return "SPSR_svc";
2960 case 116: return "SPSR_abt";
2961 case 118: return "SPSR_und";
2962 case 124: return "SPSR_mon";
2963 case 126: return "SPSR_hyp";
2964 default: return NULL;
2968 /* Print one ARM instruction from PC on INFO->STREAM. */
2970 static void
2971 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2973 const struct opcode32 *insn;
2974 void *stream = info->stream;
2975 fprintf_ftype func = info->fprintf_func;
2976 struct arm_private_data *private_data = info->private_data;
2978 if (print_insn_coprocessor (pc, info, given, FALSE))
2979 return;
2981 if (print_insn_neon (info, given, FALSE))
2982 return;
2984 for (insn = arm_opcodes; insn->assembler; insn++)
2986 if ((given & insn->mask) != insn->value)
2987 continue;
2989 if ((insn->arch & private_data->features.core) == 0)
2990 continue;
2992 /* Special case: an instruction with all bits set in the condition field
2993 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2994 or by the catchall at the end of the table. */
2995 if ((given & 0xF0000000) != 0xF0000000
2996 || (insn->mask & 0xF0000000) == 0xF0000000
2997 || (insn->mask == 0 && insn->value == 0))
2999 unsigned long u_reg = 16;
3000 unsigned long U_reg = 16;
3001 bfd_boolean is_unpredictable = FALSE;
3002 signed long value_in_comment = 0;
3003 const char *c;
3005 for (c = insn->assembler; *c; c++)
3007 if (*c == '%')
3009 bfd_boolean allow_unpredictable = FALSE;
3011 switch (*++c)
3013 case '%':
3014 func (stream, "%%");
3015 break;
3017 case 'a':
3018 value_in_comment = print_arm_address (pc, info, given);
3019 break;
3021 case 'P':
3022 /* Set P address bit and use normal address
3023 printing routine. */
3024 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
3025 break;
3027 case 'S':
3028 allow_unpredictable = TRUE;
3029 case 's':
3030 if ((given & 0x004f0000) == 0x004f0000)
3032 /* PC relative with immediate offset. */
3033 bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3035 if (PRE_BIT_SET)
3037 /* Elide positive zero offset. */
3038 if (offset || NEGATIVE_BIT_SET)
3039 func (stream, "[pc, #%s%d]\t; ",
3040 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3041 else
3042 func (stream, "[pc]\t; ");
3043 if (NEGATIVE_BIT_SET)
3044 offset = -offset;
3045 info->print_address_func (offset + pc + 8, info);
3047 else
3049 /* Always show the offset. */
3050 func (stream, "[pc], #%s%d",
3051 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3052 if (! allow_unpredictable)
3053 is_unpredictable = TRUE;
3056 else
3058 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3060 func (stream, "[%s",
3061 arm_regnames[(given >> 16) & 0xf]);
3063 if (PRE_BIT_SET)
3065 if (IMMEDIATE_BIT_SET)
3067 /* Elide offset for non-writeback
3068 positive zero. */
3069 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3070 || offset)
3071 func (stream, ", #%s%d",
3072 NEGATIVE_BIT_SET ? "-" : "", offset);
3074 if (NEGATIVE_BIT_SET)
3075 offset = -offset;
3077 value_in_comment = offset;
3079 else
3081 /* Register Offset or Register Pre-Indexed. */
3082 func (stream, ", %s%s",
3083 NEGATIVE_BIT_SET ? "-" : "",
3084 arm_regnames[given & 0xf]);
3086 /* Writing back to the register that is the source/
3087 destination of the load/store is unpredictable. */
3088 if (! allow_unpredictable
3089 && WRITEBACK_BIT_SET
3090 && ((given & 0xf) == ((given >> 12) & 0xf)))
3091 is_unpredictable = TRUE;
3094 func (stream, "]%s",
3095 WRITEBACK_BIT_SET ? "!" : "");
3097 else
3099 if (IMMEDIATE_BIT_SET)
3101 /* Immediate Post-indexed. */
3102 /* PR 10924: Offset must be printed, even if it is zero. */
3103 func (stream, "], #%s%d",
3104 NEGATIVE_BIT_SET ? "-" : "", offset);
3105 if (NEGATIVE_BIT_SET)
3106 offset = -offset;
3107 value_in_comment = offset;
3109 else
3111 /* Register Post-indexed. */
3112 func (stream, "], %s%s",
3113 NEGATIVE_BIT_SET ? "-" : "",
3114 arm_regnames[given & 0xf]);
3116 /* Writing back to the register that is the source/
3117 destination of the load/store is unpredictable. */
3118 if (! allow_unpredictable
3119 && (given & 0xf) == ((given >> 12) & 0xf))
3120 is_unpredictable = TRUE;
3123 if (! allow_unpredictable)
3125 /* Writeback is automatically implied by post- addressing.
3126 Setting the W bit is unnecessary and ARM specify it as
3127 being unpredictable. */
3128 if (WRITEBACK_BIT_SET
3129 /* Specifying the PC register as the post-indexed
3130 registers is also unpredictable. */
3131 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3132 is_unpredictable = TRUE;
3136 break;
3138 case 'b':
3140 bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3141 info->print_address_func (disp * 4 + pc + 8, info);
3143 break;
3145 case 'c':
3146 if (((given >> 28) & 0xf) != 0xe)
3147 func (stream, "%s",
3148 arm_conditional [(given >> 28) & 0xf]);
3149 break;
3151 case 'm':
3153 int started = 0;
3154 int reg;
3156 func (stream, "{");
3157 for (reg = 0; reg < 16; reg++)
3158 if ((given & (1 << reg)) != 0)
3160 if (started)
3161 func (stream, ", ");
3162 started = 1;
3163 func (stream, "%s", arm_regnames[reg]);
3165 func (stream, "}");
3166 if (! started)
3167 is_unpredictable = TRUE;
3169 break;
3171 case 'q':
3172 arm_decode_shift (given, func, stream, FALSE);
3173 break;
3175 case 'o':
3176 if ((given & 0x02000000) != 0)
3178 unsigned int rotate = (given & 0xf00) >> 7;
3179 unsigned int immed = (given & 0xff);
3180 unsigned int a, i;
3182 a = (((immed << (32 - rotate))
3183 | (immed >> rotate)) & 0xffffffff);
3184 /* If there is another encoding with smaller rotate,
3185 the rotate should be specified directly. */
3186 for (i = 0; i < 32; i += 2)
3187 if ((a << i | a >> (32 - i)) <= 0xff)
3188 break;
3190 if (i != rotate)
3191 func (stream, "#%d, %d", immed, rotate);
3192 else
3193 func (stream, "#%d", a);
3194 value_in_comment = a;
3196 else
3197 arm_decode_shift (given, func, stream, TRUE);
3198 break;
3200 case 'p':
3201 if ((given & 0x0000f000) == 0x0000f000)
3203 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3204 mechanism for setting PSR flag bits. They are
3205 obsolete in V6 onwards. */
3206 if ((private_data->features.core & ARM_EXT_V6) == 0)
3207 func (stream, "p");
3209 break;
3211 case 't':
3212 if ((given & 0x01200000) == 0x00200000)
3213 func (stream, "t");
3214 break;
3216 case 'A':
3218 int offset = given & 0xff;
3220 value_in_comment = offset * 4;
3221 if (NEGATIVE_BIT_SET)
3222 value_in_comment = - value_in_comment;
3224 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3226 if (PRE_BIT_SET)
3228 if (offset)
3229 func (stream, ", #%d]%s",
3230 (int) value_in_comment,
3231 WRITEBACK_BIT_SET ? "!" : "");
3232 else
3233 func (stream, "]");
3235 else
3237 func (stream, "]");
3239 if (WRITEBACK_BIT_SET)
3241 if (offset)
3242 func (stream, ", #%d", (int) value_in_comment);
3244 else
3246 func (stream, ", {%d}", (int) offset);
3247 value_in_comment = offset;
3251 break;
3253 case 'B':
3254 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3256 bfd_vma address;
3257 bfd_vma offset = 0;
3259 if (! NEGATIVE_BIT_SET)
3260 /* Is signed, hi bits should be ones. */
3261 offset = (-1) ^ 0x00ffffff;
3263 /* Offset is (SignExtend(offset field)<<2). */
3264 offset += given & 0x00ffffff;
3265 offset <<= 2;
3266 address = offset + pc + 8;
3268 if (given & 0x01000000)
3269 /* H bit allows addressing to 2-byte boundaries. */
3270 address += 2;
3272 info->print_address_func (address, info);
3274 break;
3276 case 'C':
3277 if ((given & 0x02000200) == 0x200)
3279 const char * name;
3280 unsigned sysm = (given & 0x004f0000) >> 16;
3282 sysm |= (given & 0x300) >> 4;
3283 name = banked_regname (sysm);
3285 if (name != NULL)
3286 func (stream, "%s", name);
3287 else
3288 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3290 else
3292 func (stream, "%cPSR_",
3293 (given & 0x00400000) ? 'S' : 'C');
3294 if (given & 0x80000)
3295 func (stream, "f");
3296 if (given & 0x40000)
3297 func (stream, "s");
3298 if (given & 0x20000)
3299 func (stream, "x");
3300 if (given & 0x10000)
3301 func (stream, "c");
3303 break;
3305 case 'U':
3306 if ((given & 0xf0) == 0x60)
3308 switch (given & 0xf)
3310 case 0xf: func (stream, "sy"); break;
3311 default:
3312 func (stream, "#%d", (int) given & 0xf);
3313 break;
3316 else
3318 switch (given & 0xf)
3320 case 0xf: func (stream, "sy"); break;
3321 case 0x7: func (stream, "un"); break;
3322 case 0xe: func (stream, "st"); break;
3323 case 0x6: func (stream, "unst"); break;
3324 case 0xb: func (stream, "ish"); break;
3325 case 0xa: func (stream, "ishst"); break;
3326 case 0x3: func (stream, "osh"); break;
3327 case 0x2: func (stream, "oshst"); break;
3328 default:
3329 func (stream, "#%d", (int) given & 0xf);
3330 break;
3333 break;
3335 case '0': case '1': case '2': case '3': case '4':
3336 case '5': case '6': case '7': case '8': case '9':
3338 int width;
3339 unsigned long value;
3341 c = arm_decode_bitfield (c, given, &value, &width);
3343 switch (*c)
3345 case 'R':
3346 if (value == 15)
3347 is_unpredictable = TRUE;
3348 /* Fall through. */
3349 case 'r':
3350 if (c[1] == 'u')
3352 /* Eat the 'u' character. */
3353 ++ c;
3355 if (u_reg == value)
3356 is_unpredictable = TRUE;
3357 u_reg = value;
3359 if (c[1] == 'U')
3361 /* Eat the 'U' character. */
3362 ++ c;
3364 if (U_reg == value)
3365 is_unpredictable = TRUE;
3366 U_reg = value;
3368 func (stream, "%s", arm_regnames[value]);
3369 break;
3370 case 'd':
3371 func (stream, "%ld", value);
3372 value_in_comment = value;
3373 break;
3374 case 'b':
3375 func (stream, "%ld", value * 8);
3376 value_in_comment = value * 8;
3377 break;
3378 case 'W':
3379 func (stream, "%ld", value + 1);
3380 value_in_comment = value + 1;
3381 break;
3382 case 'x':
3383 func (stream, "0x%08lx", value);
3385 /* Some SWI instructions have special
3386 meanings. */
3387 if ((given & 0x0fffffff) == 0x0FF00000)
3388 func (stream, "\t; IMB");
3389 else if ((given & 0x0fffffff) == 0x0FF00001)
3390 func (stream, "\t; IMBRange");
3391 break;
3392 case 'X':
3393 func (stream, "%01lx", value & 0xf);
3394 value_in_comment = value;
3395 break;
3396 case '`':
3397 c++;
3398 if (value == 0)
3399 func (stream, "%c", *c);
3400 break;
3401 case '\'':
3402 c++;
3403 if (value == ((1ul << width) - 1))
3404 func (stream, "%c", *c);
3405 break;
3406 case '?':
3407 func (stream, "%c", c[(1 << width) - (int) value]);
3408 c += 1 << width;
3409 break;
3410 default:
3411 abort ();
3413 break;
3415 case 'e':
3417 int imm;
3419 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3420 func (stream, "%d", imm);
3421 value_in_comment = imm;
3423 break;
3425 case 'E':
3426 /* LSB and WIDTH fields of BFI or BFC. The machine-
3427 language instruction encodes LSB and MSB. */
3429 long msb = (given & 0x001f0000) >> 16;
3430 long lsb = (given & 0x00000f80) >> 7;
3431 long w = msb - lsb + 1;
3433 if (w > 0)
3434 func (stream, "#%lu, #%lu", lsb, w);
3435 else
3436 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3438 break;
3440 case 'R':
3441 /* Get the PSR/banked register name. */
3443 const char * name;
3444 unsigned sysm = (given & 0x004f0000) >> 16;
3446 sysm |= (given & 0x300) >> 4;
3447 name = banked_regname (sysm);
3449 if (name != NULL)
3450 func (stream, "%s", name);
3451 else
3452 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3454 break;
3456 case 'V':
3457 /* 16-bit unsigned immediate from a MOVT or MOVW
3458 instruction, encoded in bits 0:11 and 15:19. */
3460 long hi = (given & 0x000f0000) >> 4;
3461 long lo = (given & 0x00000fff);
3462 long imm16 = hi | lo;
3464 func (stream, "#%lu", imm16);
3465 value_in_comment = imm16;
3467 break;
3469 default:
3470 abort ();
3474 else
3475 func (stream, "%c", *c);
3478 if (value_in_comment > 32 || value_in_comment < -16)
3479 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3481 if (is_unpredictable)
3482 func (stream, UNPREDICTABLE_INSTRUCTION);
3484 return;
3487 abort ();
3490 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3492 static void
3493 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3495 const struct opcode16 *insn;
3496 void *stream = info->stream;
3497 fprintf_ftype func = info->fprintf_func;
3499 for (insn = thumb_opcodes; insn->assembler; insn++)
3500 if ((given & insn->mask) == insn->value)
3502 signed long value_in_comment = 0;
3503 const char *c = insn->assembler;
3505 for (; *c; c++)
3507 int domaskpc = 0;
3508 int domasklr = 0;
3510 if (*c != '%')
3512 func (stream, "%c", *c);
3513 continue;
3516 switch (*++c)
3518 case '%':
3519 func (stream, "%%");
3520 break;
3522 case 'c':
3523 if (ifthen_state)
3524 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3525 break;
3527 case 'C':
3528 if (ifthen_state)
3529 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3530 else
3531 func (stream, "s");
3532 break;
3534 case 'I':
3536 unsigned int tmp;
3538 ifthen_next_state = given & 0xff;
3539 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3540 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3541 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3543 break;
3545 case 'x':
3546 if (ifthen_next_state)
3547 func (stream, "\t; unpredictable branch in IT block\n");
3548 break;
3550 case 'X':
3551 if (ifthen_state)
3552 func (stream, "\t; unpredictable <IT:%s>",
3553 arm_conditional[IFTHEN_COND]);
3554 break;
3556 case 'S':
3558 long reg;
3560 reg = (given >> 3) & 0x7;
3561 if (given & (1 << 6))
3562 reg += 8;
3564 func (stream, "%s", arm_regnames[reg]);
3566 break;
3568 case 'D':
3570 long reg;
3572 reg = given & 0x7;
3573 if (given & (1 << 7))
3574 reg += 8;
3576 func (stream, "%s", arm_regnames[reg]);
3578 break;
3580 case 'N':
3581 if (given & (1 << 8))
3582 domasklr = 1;
3583 /* Fall through. */
3584 case 'O':
3585 if (*c == 'O' && (given & (1 << 8)))
3586 domaskpc = 1;
3587 /* Fall through. */
3588 case 'M':
3590 int started = 0;
3591 int reg;
3593 func (stream, "{");
3595 /* It would be nice if we could spot
3596 ranges, and generate the rS-rE format: */
3597 for (reg = 0; (reg < 8); reg++)
3598 if ((given & (1 << reg)) != 0)
3600 if (started)
3601 func (stream, ", ");
3602 started = 1;
3603 func (stream, "%s", arm_regnames[reg]);
3606 if (domasklr)
3608 if (started)
3609 func (stream, ", ");
3610 started = 1;
3611 func (stream, "%s", arm_regnames[14] /* "lr" */);
3614 if (domaskpc)
3616 if (started)
3617 func (stream, ", ");
3618 func (stream, "%s", arm_regnames[15] /* "pc" */);
3621 func (stream, "}");
3623 break;
3625 case 'W':
3626 /* Print writeback indicator for a LDMIA. We are doing a
3627 writeback if the base register is not in the register
3628 mask. */
3629 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3630 func (stream, "!");
3631 break;
3633 case 'b':
3634 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3636 bfd_vma address = (pc + 4
3637 + ((given & 0x00f8) >> 2)
3638 + ((given & 0x0200) >> 3));
3639 info->print_address_func (address, info);
3641 break;
3643 case 's':
3644 /* Right shift immediate -- bits 6..10; 1-31 print
3645 as themselves, 0 prints as 32. */
3647 long imm = (given & 0x07c0) >> 6;
3648 if (imm == 0)
3649 imm = 32;
3650 func (stream, "#%ld", imm);
3652 break;
3654 case '0': case '1': case '2': case '3': case '4':
3655 case '5': case '6': case '7': case '8': case '9':
3657 int bitstart = *c++ - '0';
3658 int bitend = 0;
3660 while (*c >= '0' && *c <= '9')
3661 bitstart = (bitstart * 10) + *c++ - '0';
3663 switch (*c)
3665 case '-':
3667 bfd_vma reg;
3669 c++;
3670 while (*c >= '0' && *c <= '9')
3671 bitend = (bitend * 10) + *c++ - '0';
3672 if (!bitend)
3673 abort ();
3674 reg = given >> bitstart;
3675 reg &= (2 << (bitend - bitstart)) - 1;
3677 switch (*c)
3679 case 'r':
3680 func (stream, "%s", arm_regnames[reg]);
3681 break;
3683 case 'd':
3684 func (stream, "%ld", (long) reg);
3685 value_in_comment = reg;
3686 break;
3688 case 'H':
3689 func (stream, "%ld", (long) (reg << 1));
3690 value_in_comment = reg << 1;
3691 break;
3693 case 'W':
3694 func (stream, "%ld", (long) (reg << 2));
3695 value_in_comment = reg << 2;
3696 break;
3698 case 'a':
3699 /* PC-relative address -- the bottom two
3700 bits of the address are dropped
3701 before the calculation. */
3702 info->print_address_func
3703 (((pc + 4) & ~3) + (reg << 2), info);
3704 value_in_comment = 0;
3705 break;
3707 case 'x':
3708 func (stream, "0x%04lx", (long) reg);
3709 break;
3711 case 'B':
3712 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3713 info->print_address_func (reg * 2 + pc + 4, info);
3714 value_in_comment = 0;
3715 break;
3717 case 'c':
3718 func (stream, "%s", arm_conditional [reg]);
3719 break;
3721 default:
3722 abort ();
3725 break;
3727 case '\'':
3728 c++;
3729 if ((given & (1 << bitstart)) != 0)
3730 func (stream, "%c", *c);
3731 break;
3733 case '?':
3734 ++c;
3735 if ((given & (1 << bitstart)) != 0)
3736 func (stream, "%c", *c++);
3737 else
3738 func (stream, "%c", *++c);
3739 break;
3741 default:
3742 abort ();
3745 break;
3747 default:
3748 abort ();
3752 if (value_in_comment > 32 || value_in_comment < -16)
3753 func (stream, "\t; 0x%lx", value_in_comment);
3754 return;
3757 /* No match. */
3758 abort ();
3761 /* Return the name of an V7M special register. */
3763 static const char *
3764 psr_name (int regno)
3766 switch (regno)
3768 case 0: return "APSR";
3769 case 1: return "IAPSR";
3770 case 2: return "EAPSR";
3771 case 3: return "PSR";
3772 case 5: return "IPSR";
3773 case 6: return "EPSR";
3774 case 7: return "IEPSR";
3775 case 8: return "MSP";
3776 case 9: return "PSP";
3777 case 16: return "PRIMASK";
3778 case 17: return "BASEPRI";
3779 case 18: return "BASEPRI_MAX";
3780 case 19: return "FAULTMASK";
3781 case 20: return "CONTROL";
3782 default: return "<unknown>";
3786 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3788 static void
3789 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3791 const struct opcode32 *insn;
3792 void *stream = info->stream;
3793 fprintf_ftype func = info->fprintf_func;
3795 if (print_insn_coprocessor (pc, info, given, TRUE))
3796 return;
3798 if (print_insn_neon (info, given, TRUE))
3799 return;
3801 for (insn = thumb32_opcodes; insn->assembler; insn++)
3802 if ((given & insn->mask) == insn->value)
3804 bfd_boolean is_unpredictable = FALSE;
3805 signed long value_in_comment = 0;
3806 const char *c = insn->assembler;
3808 for (; *c; c++)
3810 if (*c != '%')
3812 func (stream, "%c", *c);
3813 continue;
3816 switch (*++c)
3818 case '%':
3819 func (stream, "%%");
3820 break;
3822 case 'c':
3823 if (ifthen_state)
3824 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3825 break;
3827 case 'x':
3828 if (ifthen_next_state)
3829 func (stream, "\t; unpredictable branch in IT block\n");
3830 break;
3832 case 'X':
3833 if (ifthen_state)
3834 func (stream, "\t; unpredictable <IT:%s>",
3835 arm_conditional[IFTHEN_COND]);
3836 break;
3838 case 'I':
3840 unsigned int imm12 = 0;
3842 imm12 |= (given & 0x000000ffu);
3843 imm12 |= (given & 0x00007000u) >> 4;
3844 imm12 |= (given & 0x04000000u) >> 15;
3845 func (stream, "#%u", imm12);
3846 value_in_comment = imm12;
3848 break;
3850 case 'M':
3852 unsigned int bits = 0, imm, imm8, mod;
3854 bits |= (given & 0x000000ffu);
3855 bits |= (given & 0x00007000u) >> 4;
3856 bits |= (given & 0x04000000u) >> 15;
3857 imm8 = (bits & 0x0ff);
3858 mod = (bits & 0xf00) >> 8;
3859 switch (mod)
3861 case 0: imm = imm8; break;
3862 case 1: imm = ((imm8 << 16) | imm8); break;
3863 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3864 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3865 default:
3866 mod = (bits & 0xf80) >> 7;
3867 imm8 = (bits & 0x07f) | 0x80;
3868 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3870 func (stream, "#%u", imm);
3871 value_in_comment = imm;
3873 break;
3875 case 'J':
3877 unsigned int imm = 0;
3879 imm |= (given & 0x000000ffu);
3880 imm |= (given & 0x00007000u) >> 4;
3881 imm |= (given & 0x04000000u) >> 15;
3882 imm |= (given & 0x000f0000u) >> 4;
3883 func (stream, "#%u", imm);
3884 value_in_comment = imm;
3886 break;
3888 case 'K':
3890 unsigned int imm = 0;
3892 imm |= (given & 0x000f0000u) >> 16;
3893 imm |= (given & 0x00000ff0u) >> 0;
3894 imm |= (given & 0x0000000fu) << 12;
3895 func (stream, "#%u", imm);
3896 value_in_comment = imm;
3898 break;
3900 case 'V':
3902 unsigned int imm = 0;
3904 imm |= (given & 0x00000fffu);
3905 imm |= (given & 0x000f0000u) >> 4;
3906 func (stream, "#%u", imm);
3907 value_in_comment = imm;
3909 break;
3911 case 'S':
3913 unsigned int reg = (given & 0x0000000fu);
3914 unsigned int stp = (given & 0x00000030u) >> 4;
3915 unsigned int imm = 0;
3916 imm |= (given & 0x000000c0u) >> 6;
3917 imm |= (given & 0x00007000u) >> 10;
3919 func (stream, "%s", arm_regnames[reg]);
3920 switch (stp)
3922 case 0:
3923 if (imm > 0)
3924 func (stream, ", lsl #%u", imm);
3925 break;
3927 case 1:
3928 if (imm == 0)
3929 imm = 32;
3930 func (stream, ", lsr #%u", imm);
3931 break;
3933 case 2:
3934 if (imm == 0)
3935 imm = 32;
3936 func (stream, ", asr #%u", imm);
3937 break;
3939 case 3:
3940 if (imm == 0)
3941 func (stream, ", rrx");
3942 else
3943 func (stream, ", ror #%u", imm);
3946 break;
3948 case 'a':
3950 unsigned int Rn = (given & 0x000f0000) >> 16;
3951 unsigned int U = ! NEGATIVE_BIT_SET;
3952 unsigned int op = (given & 0x00000f00) >> 8;
3953 unsigned int i12 = (given & 0x00000fff);
3954 unsigned int i8 = (given & 0x000000ff);
3955 bfd_boolean writeback = FALSE, postind = FALSE;
3956 bfd_vma offset = 0;
3958 func (stream, "[%s", arm_regnames[Rn]);
3959 if (U) /* 12-bit positive immediate offset. */
3961 offset = i12;
3962 if (Rn != 15)
3963 value_in_comment = offset;
3965 else if (Rn == 15) /* 12-bit negative immediate offset. */
3966 offset = - (int) i12;
3967 else if (op == 0x0) /* Shifted register offset. */
3969 unsigned int Rm = (i8 & 0x0f);
3970 unsigned int sh = (i8 & 0x30) >> 4;
3972 func (stream, ", %s", arm_regnames[Rm]);
3973 if (sh)
3974 func (stream, ", lsl #%u", sh);
3975 func (stream, "]");
3976 break;
3978 else switch (op)
3980 case 0xE: /* 8-bit positive immediate offset. */
3981 offset = i8;
3982 break;
3984 case 0xC: /* 8-bit negative immediate offset. */
3985 offset = -i8;
3986 break;
3988 case 0xF: /* 8-bit + preindex with wb. */
3989 offset = i8;
3990 writeback = TRUE;
3991 break;
3993 case 0xD: /* 8-bit - preindex with wb. */
3994 offset = -i8;
3995 writeback = TRUE;
3996 break;
3998 case 0xB: /* 8-bit + postindex. */
3999 offset = i8;
4000 postind = TRUE;
4001 break;
4003 case 0x9: /* 8-bit - postindex. */
4004 offset = -i8;
4005 postind = TRUE;
4006 break;
4008 default:
4009 func (stream, ", <undefined>]");
4010 goto skip;
4013 if (postind)
4014 func (stream, "], #%d", (int) offset);
4015 else
4017 if (offset)
4018 func (stream, ", #%d", (int) offset);
4019 func (stream, writeback ? "]!" : "]");
4022 if (Rn == 15)
4024 func (stream, "\t; ");
4025 info->print_address_func (((pc + 4) & ~3) + offset, info);
4028 skip:
4029 break;
4031 case 'A':
4033 unsigned int U = ! NEGATIVE_BIT_SET;
4034 unsigned int W = WRITEBACK_BIT_SET;
4035 unsigned int Rn = (given & 0x000f0000) >> 16;
4036 unsigned int off = (given & 0x000000ff);
4038 func (stream, "[%s", arm_regnames[Rn]);
4040 if (PRE_BIT_SET)
4042 if (off || !U)
4044 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4045 value_in_comment = off * 4 * U ? 1 : -1;
4047 func (stream, "]");
4048 if (W)
4049 func (stream, "!");
4051 else
4053 func (stream, "], ");
4054 if (W)
4056 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4057 value_in_comment = off * 4 * U ? 1 : -1;
4059 else
4061 func (stream, "{%u}", off);
4062 value_in_comment = off;
4066 break;
4068 case 'w':
4070 unsigned int Sbit = (given & 0x01000000) >> 24;
4071 unsigned int type = (given & 0x00600000) >> 21;
4073 switch (type)
4075 case 0: func (stream, Sbit ? "sb" : "b"); break;
4076 case 1: func (stream, Sbit ? "sh" : "h"); break;
4077 case 2:
4078 if (Sbit)
4079 func (stream, "??");
4080 break;
4081 case 3:
4082 func (stream, "??");
4083 break;
4086 break;
4088 case 'm':
4090 int started = 0;
4091 int reg;
4093 func (stream, "{");
4094 for (reg = 0; reg < 16; reg++)
4095 if ((given & (1 << reg)) != 0)
4097 if (started)
4098 func (stream, ", ");
4099 started = 1;
4100 func (stream, "%s", arm_regnames[reg]);
4102 func (stream, "}");
4104 break;
4106 case 'E':
4108 unsigned int msb = (given & 0x0000001f);
4109 unsigned int lsb = 0;
4111 lsb |= (given & 0x000000c0u) >> 6;
4112 lsb |= (given & 0x00007000u) >> 10;
4113 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4115 break;
4117 case 'F':
4119 unsigned int width = (given & 0x0000001f) + 1;
4120 unsigned int lsb = 0;
4122 lsb |= (given & 0x000000c0u) >> 6;
4123 lsb |= (given & 0x00007000u) >> 10;
4124 func (stream, "#%u, #%u", lsb, width);
4126 break;
4128 case 'b':
4130 unsigned int S = (given & 0x04000000u) >> 26;
4131 unsigned int J1 = (given & 0x00002000u) >> 13;
4132 unsigned int J2 = (given & 0x00000800u) >> 11;
4133 bfd_vma offset = 0;
4135 offset |= !S << 20;
4136 offset |= J2 << 19;
4137 offset |= J1 << 18;
4138 offset |= (given & 0x003f0000) >> 4;
4139 offset |= (given & 0x000007ff) << 1;
4140 offset -= (1 << 20);
4142 info->print_address_func (pc + 4 + offset, info);
4144 break;
4146 case 'B':
4148 unsigned int S = (given & 0x04000000u) >> 26;
4149 unsigned int I1 = (given & 0x00002000u) >> 13;
4150 unsigned int I2 = (given & 0x00000800u) >> 11;
4151 bfd_vma offset = 0;
4153 offset |= !S << 24;
4154 offset |= !(I1 ^ S) << 23;
4155 offset |= !(I2 ^ S) << 22;
4156 offset |= (given & 0x03ff0000u) >> 4;
4157 offset |= (given & 0x000007ffu) << 1;
4158 offset -= (1 << 24);
4159 offset += pc + 4;
4161 /* BLX target addresses are always word aligned. */
4162 if ((given & 0x00001000u) == 0)
4163 offset &= ~2u;
4165 info->print_address_func (offset, info);
4167 break;
4169 case 's':
4171 unsigned int shift = 0;
4173 shift |= (given & 0x000000c0u) >> 6;
4174 shift |= (given & 0x00007000u) >> 10;
4175 if (WRITEBACK_BIT_SET)
4176 func (stream, ", asr #%u", shift);
4177 else if (shift)
4178 func (stream, ", lsl #%u", shift);
4179 /* else print nothing - lsl #0 */
4181 break;
4183 case 'R':
4185 unsigned int rot = (given & 0x00000030) >> 4;
4187 if (rot)
4188 func (stream, ", ror #%u", rot * 8);
4190 break;
4192 case 'U':
4193 if ((given & 0xf0) == 0x60)
4195 switch (given & 0xf)
4197 case 0xf: func (stream, "sy"); break;
4198 default:
4199 func (stream, "#%d", (int) given & 0xf);
4200 break;
4203 else
4205 switch (given & 0xf)
4207 case 0xf: func (stream, "sy"); break;
4208 case 0x7: func (stream, "un"); break;
4209 case 0xe: func (stream, "st"); break;
4210 case 0x6: func (stream, "unst"); break;
4211 case 0xb: func (stream, "ish"); break;
4212 case 0xa: func (stream, "ishst"); break;
4213 case 0x3: func (stream, "osh"); break;
4214 case 0x2: func (stream, "oshst"); break;
4215 default:
4216 func (stream, "#%d", (int) given & 0xf);
4217 break;
4220 break;
4222 case 'C':
4223 if ((given & 0xff) == 0)
4225 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4226 if (given & 0x800)
4227 func (stream, "f");
4228 if (given & 0x400)
4229 func (stream, "s");
4230 if (given & 0x200)
4231 func (stream, "x");
4232 if (given & 0x100)
4233 func (stream, "c");
4235 else if ((given & 0x20) == 0x20)
4237 char const* name;
4238 unsigned sysm = (given & 0xf00) >> 8;
4240 sysm |= (given & 0x30);
4241 sysm |= (given & 0x00100000) >> 14;
4242 name = banked_regname (sysm);
4244 if (name != NULL)
4245 func (stream, "%s", name);
4246 else
4247 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
4249 else
4251 func (stream, "%s", psr_name (given & 0xff));
4253 break;
4255 case 'D':
4256 if (((given & 0xff) == 0)
4257 || ((given & 0x20) == 0x20))
4259 char const* name;
4260 unsigned sm = (given & 0xf0000) >> 16;
4262 sm |= (given & 0x30);
4263 sm |= (given & 0x00100000) >> 14;
4264 name = banked_regname (sm);
4266 if (name != NULL)
4267 func (stream, "%s", name);
4268 else
4269 func (stream, "(UNDEF: %lu)", (unsigned long) sm);
4271 else
4272 func (stream, "%s", psr_name (given & 0xff));
4273 break;
4275 case '0': case '1': case '2': case '3': case '4':
4276 case '5': case '6': case '7': case '8': case '9':
4278 int width;
4279 unsigned long val;
4281 c = arm_decode_bitfield (c, given, &val, &width);
4283 switch (*c)
4285 case 'd':
4286 func (stream, "%lu", val);
4287 value_in_comment = val;
4288 break;
4290 case 'W':
4291 func (stream, "%lu", val * 4);
4292 value_in_comment = val * 4;
4293 break;
4295 case 'R':
4296 if (val == 15)
4297 is_unpredictable = TRUE;
4298 /* Fall through. */
4299 case 'r':
4300 func (stream, "%s", arm_regnames[val]);
4301 break;
4303 case 'c':
4304 func (stream, "%s", arm_conditional[val]);
4305 break;
4307 case '\'':
4308 c++;
4309 if (val == ((1ul << width) - 1))
4310 func (stream, "%c", *c);
4311 break;
4313 case '`':
4314 c++;
4315 if (val == 0)
4316 func (stream, "%c", *c);
4317 break;
4319 case '?':
4320 func (stream, "%c", c[(1 << width) - (int) val]);
4321 c += 1 << width;
4322 break;
4324 case 'x':
4325 func (stream, "0x%lx", val & 0xffffffffUL);
4326 break;
4328 default:
4329 abort ();
4332 break;
4334 case 'L':
4335 /* PR binutils/12534
4336 If we have a PC relative offset in an LDRD or STRD
4337 instructions then display the decoded address. */
4338 if (((given >> 16) & 0xf) == 0xf)
4340 bfd_vma offset = (given & 0xff) * 4;
4342 if ((given & (1 << 23)) == 0)
4343 offset = - offset;
4344 func (stream, "\t; ");
4345 info->print_address_func ((pc & ~3) + 4 + offset, info);
4347 break;
4349 default:
4350 abort ();
4354 if (value_in_comment > 32 || value_in_comment < -16)
4355 func (stream, "\t; 0x%lx", value_in_comment);
4357 if (is_unpredictable)
4358 func (stream, UNPREDICTABLE_INSTRUCTION);
4360 return;
4363 /* No match. */
4364 abort ();
4367 /* Print data bytes on INFO->STREAM. */
4369 static void
4370 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4371 struct disassemble_info *info,
4372 long given)
4374 switch (info->bytes_per_chunk)
4376 case 1:
4377 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4378 break;
4379 case 2:
4380 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4381 break;
4382 case 4:
4383 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4384 break;
4385 default:
4386 abort ();
4390 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4391 being displayed in symbol relative addresses. */
4393 bfd_boolean
4394 arm_symbol_is_valid (asymbol * sym,
4395 struct disassemble_info * info ATTRIBUTE_UNUSED)
4397 const char * name;
4399 if (sym == NULL)
4400 return FALSE;
4402 name = bfd_asymbol_name (sym);
4404 return (name && *name != '$');
4407 /* Parse an individual disassembler option. */
4409 void
4410 parse_arm_disassembler_option (char *option)
4412 if (option == NULL)
4413 return;
4415 if (CONST_STRNEQ (option, "reg-names-"))
4417 int i;
4419 option += 10;
4421 for (i = NUM_ARM_REGNAMES; i--;)
4422 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4424 regname_selected = i;
4425 break;
4428 if (i < 0)
4429 /* XXX - should break 'option' at following delimiter. */
4430 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4432 else if (CONST_STRNEQ (option, "force-thumb"))
4433 force_thumb = 1;
4434 else if (CONST_STRNEQ (option, "no-force-thumb"))
4435 force_thumb = 0;
4436 else
4437 /* XXX - should break 'option' at following delimiter. */
4438 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4440 return;
4443 /* Parse the string of disassembler options, spliting it at whitespaces
4444 or commas. (Whitespace separators supported for backwards compatibility). */
4446 static void
4447 parse_disassembler_options (char *options)
4449 if (options == NULL)
4450 return;
4452 while (*options)
4454 parse_arm_disassembler_option (options);
4456 /* Skip forward to next seperator. */
4457 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4458 ++ options;
4459 /* Skip forward past seperators. */
4460 while (ISSPACE (*options) || (*options == ','))
4461 ++ options;
4465 /* Search back through the insn stream to determine if this instruction is
4466 conditionally executed. */
4468 static void
4469 find_ifthen_state (bfd_vma pc,
4470 struct disassemble_info *info,
4471 bfd_boolean little)
4473 unsigned char b[2];
4474 unsigned int insn;
4475 int status;
4476 /* COUNT is twice the number of instructions seen. It will be odd if we
4477 just crossed an instruction boundary. */
4478 int count;
4479 int it_count;
4480 unsigned int seen_it;
4481 bfd_vma addr;
4483 ifthen_address = pc;
4484 ifthen_state = 0;
4486 addr = pc;
4487 count = 1;
4488 it_count = 0;
4489 seen_it = 0;
4490 /* Scan backwards looking for IT instructions, keeping track of where
4491 instruction boundaries are. We don't know if something is actually an
4492 IT instruction until we find a definite instruction boundary. */
4493 for (;;)
4495 if (addr == 0 || info->symbol_at_address_func (addr, info))
4497 /* A symbol must be on an instruction boundary, and will not
4498 be within an IT block. */
4499 if (seen_it && (count & 1))
4500 break;
4502 return;
4504 addr -= 2;
4505 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4506 if (status)
4507 return;
4509 if (little)
4510 insn = (b[0]) | (b[1] << 8);
4511 else
4512 insn = (b[1]) | (b[0] << 8);
4513 if (seen_it)
4515 if ((insn & 0xf800) < 0xe800)
4517 /* Addr + 2 is an instruction boundary. See if this matches
4518 the expected boundary based on the position of the last
4519 IT candidate. */
4520 if (count & 1)
4521 break;
4522 seen_it = 0;
4525 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4527 /* This could be an IT instruction. */
4528 seen_it = insn;
4529 it_count = count >> 1;
4531 if ((insn & 0xf800) >= 0xe800)
4532 count++;
4533 else
4534 count = (count + 2) | 1;
4535 /* IT blocks contain at most 4 instructions. */
4536 if (count >= 8 && !seen_it)
4537 return;
4539 /* We found an IT instruction. */
4540 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4541 if ((ifthen_state & 0xf) == 0)
4542 ifthen_state = 0;
4545 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4546 mapping symbol. */
4548 static int
4549 is_mapping_symbol (struct disassemble_info *info, int n,
4550 enum map_type *map_type)
4552 const char *name;
4554 name = bfd_asymbol_name (info->symtab[n]);
4555 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4556 && (name[2] == 0 || name[2] == '.'))
4558 *map_type = ((name[1] == 'a') ? MAP_ARM
4559 : (name[1] == 't') ? MAP_THUMB
4560 : MAP_DATA);
4561 return TRUE;
4564 return FALSE;
4567 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4568 Returns nonzero if *MAP_TYPE was set. */
4570 static int
4571 get_map_sym_type (struct disassemble_info *info,
4572 int n,
4573 enum map_type *map_type)
4575 /* If the symbol is in a different section, ignore it. */
4576 if (info->section != NULL && info->section != info->symtab[n]->section)
4577 return FALSE;
4579 return is_mapping_symbol (info, n, map_type);
4582 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4583 Returns nonzero if *MAP_TYPE was set. */
4585 static int
4586 get_sym_code_type (struct disassemble_info *info,
4587 int n,
4588 enum map_type *map_type)
4590 elf_symbol_type *es;
4591 unsigned int type;
4593 /* If the symbol is in a different section, ignore it. */
4594 if (info->section != NULL && info->section != info->symtab[n]->section)
4595 return FALSE;
4597 es = *(elf_symbol_type **)(info->symtab + n);
4598 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4600 /* If the symbol has function type then use that. */
4601 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4603 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4604 *map_type = MAP_THUMB;
4605 else
4606 *map_type = MAP_ARM;
4607 return TRUE;
4610 return FALSE;
4613 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4614 of the supplied arm_feature_set structure with bitmasks indicating
4615 the support base architectures and coprocessor extensions.
4617 FIXME: This could more efficiently implemented as a constant array,
4618 although it would also be less robust. */
4620 static void
4621 select_arm_features (unsigned long mach,
4622 arm_feature_set * features)
4624 #undef ARM_FEATURE
4625 #define ARM_FEATURE(ARCH,CEXT) \
4626 features->core = (ARCH); \
4627 features->coproc = (CEXT) | FPU_FPA; \
4628 return
4630 switch (mach)
4632 case bfd_mach_arm_2: ARM_ARCH_V2;
4633 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4634 case bfd_mach_arm_3: ARM_ARCH_V3;
4635 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4636 case bfd_mach_arm_4: ARM_ARCH_V4;
4637 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4638 case bfd_mach_arm_5: ARM_ARCH_V5;
4639 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4640 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4641 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4642 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4643 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4644 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4645 /* If the machine type is unknown allow all
4646 architecture types and all extensions. */
4647 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4648 default:
4649 abort ();
4654 /* NOTE: There are no checks in these routines that
4655 the relevant number of data bytes exist. */
4657 static int
4658 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4660 unsigned char b[4];
4661 long given;
4662 int status;
4663 int is_thumb = FALSE;
4664 int is_data = FALSE;
4665 int little_code;
4666 unsigned int size = 4;
4667 void (*printer) (bfd_vma, struct disassemble_info *, long);
4668 bfd_boolean found = FALSE;
4669 struct arm_private_data *private_data;
4671 if (info->disassembler_options)
4673 parse_disassembler_options (info->disassembler_options);
4675 /* To avoid repeated parsing of these options, we remove them here. */
4676 info->disassembler_options = NULL;
4679 /* PR 10288: Control which instructions will be disassembled. */
4680 if (info->private_data == NULL)
4682 static struct arm_private_data private;
4684 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4685 /* If the user did not use the -m command line switch then default to
4686 disassembling all types of ARM instruction.
4688 The info->mach value has to be ignored as this will be based on
4689 the default archictecture for the target and/or hints in the notes
4690 section, but it will never be greater than the current largest arm
4691 machine value (iWMMXt2), which is only equivalent to the V5TE
4692 architecture. ARM architectures have advanced beyond the machine
4693 value encoding, and these newer architectures would be ignored if
4694 the machine value was used.
4696 Ie the -m switch is used to restrict which instructions will be
4697 disassembled. If it is necessary to use the -m switch to tell
4698 objdump that an ARM binary is being disassembled, eg because the
4699 input is a raw binary file, but it is also desired to disassemble
4700 all ARM instructions then use "-marm". This will select the
4701 "unknown" arm architecture which is compatible with any ARM
4702 instruction. */
4703 info->mach = bfd_mach_arm_unknown;
4705 /* Compute the architecture bitmask from the machine number.
4706 Note: This assumes that the machine number will not change
4707 during disassembly.... */
4708 select_arm_features (info->mach, & private.features);
4710 private.has_mapping_symbols = -1;
4711 private.last_mapping_sym = -1;
4712 private.last_mapping_addr = 0;
4714 info->private_data = & private;
4717 private_data = info->private_data;
4719 /* Decide if our code is going to be little-endian, despite what the
4720 function argument might say. */
4721 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4723 /* For ELF, consult the symbol table to determine what kind of code
4724 or data we have. */
4725 if (info->symtab_size != 0
4726 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4728 bfd_vma addr;
4729 int n, start;
4730 int last_sym = -1;
4731 enum map_type type = MAP_ARM;
4733 /* Start scanning at the start of the function, or wherever
4734 we finished last time. */
4735 /* PR 14006. When the address is 0 we are either at the start of the
4736 very first function, or else the first function in a new, unlinked
4737 executable section (eg because uf -ffunction-sections). Either way
4738 start scanning from the beginning of the symbol table, not where we
4739 left off last time. */
4740 if (pc == 0)
4741 start = 0;
4742 else
4744 start = info->symtab_pos + 1;
4745 if (start < private_data->last_mapping_sym)
4746 start = private_data->last_mapping_sym;
4748 found = FALSE;
4750 /* First, look for mapping symbols. */
4751 if (private_data->has_mapping_symbols != 0)
4753 /* Scan up to the location being disassembled. */
4754 for (n = start; n < info->symtab_size; n++)
4756 addr = bfd_asymbol_value (info->symtab[n]);
4757 if (addr > pc)
4758 break;
4759 if (get_map_sym_type (info, n, &type))
4761 last_sym = n;
4762 found = TRUE;
4766 if (!found)
4768 /* No mapping symbol found at this address. Look backwards
4769 for a preceding one. */
4770 for (n = start - 1; n >= 0; n--)
4772 if (get_map_sym_type (info, n, &type))
4774 last_sym = n;
4775 found = TRUE;
4776 break;
4781 if (found)
4782 private_data->has_mapping_symbols = 1;
4784 /* No mapping symbols were found. A leading $d may be
4785 omitted for sections which start with data; but for
4786 compatibility with legacy and stripped binaries, only
4787 assume the leading $d if there is at least one mapping
4788 symbol in the file. */
4789 if (!found && private_data->has_mapping_symbols == -1)
4791 /* Look for mapping symbols, in any section. */
4792 for (n = 0; n < info->symtab_size; n++)
4793 if (is_mapping_symbol (info, n, &type))
4795 private_data->has_mapping_symbols = 1;
4796 break;
4798 if (private_data->has_mapping_symbols == -1)
4799 private_data->has_mapping_symbols = 0;
4802 if (!found && private_data->has_mapping_symbols == 1)
4804 type = MAP_DATA;
4805 found = TRUE;
4809 /* Next search for function symbols to separate ARM from Thumb
4810 in binaries without mapping symbols. */
4811 if (!found)
4813 /* Scan up to the location being disassembled. */
4814 for (n = start; n < info->symtab_size; n++)
4816 addr = bfd_asymbol_value (info->symtab[n]);
4817 if (addr > pc)
4818 break;
4819 if (get_sym_code_type (info, n, &type))
4821 last_sym = n;
4822 found = TRUE;
4826 if (!found)
4828 /* No mapping symbol found at this address. Look backwards
4829 for a preceding one. */
4830 for (n = start - 1; n >= 0; n--)
4832 if (get_sym_code_type (info, n, &type))
4834 last_sym = n;
4835 found = TRUE;
4836 break;
4842 private_data->last_mapping_sym = last_sym;
4843 private_data->last_type = type;
4844 is_thumb = (private_data->last_type == MAP_THUMB);
4845 is_data = (private_data->last_type == MAP_DATA);
4847 /* Look a little bit ahead to see if we should print out
4848 two or four bytes of data. If there's a symbol,
4849 mapping or otherwise, after two bytes then don't
4850 print more. */
4851 if (is_data)
4853 size = 4 - (pc & 3);
4854 for (n = last_sym + 1; n < info->symtab_size; n++)
4856 addr = bfd_asymbol_value (info->symtab[n]);
4857 if (addr > pc
4858 && (info->section == NULL
4859 || info->section == info->symtab[n]->section))
4861 if (addr - pc < size)
4862 size = addr - pc;
4863 break;
4866 /* If the next symbol is after three bytes, we need to
4867 print only part of the data, so that we can use either
4868 .byte or .short. */
4869 if (size == 3)
4870 size = (pc & 1) ? 1 : 2;
4874 if (info->symbols != NULL)
4876 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4878 coff_symbol_type * cs;
4880 cs = coffsymbol (*info->symbols);
4881 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4882 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4883 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4884 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4885 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4887 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4888 && !found)
4890 /* If no mapping symbol has been found then fall back to the type
4891 of the function symbol. */
4892 elf_symbol_type * es;
4893 unsigned int type;
4895 es = *(elf_symbol_type **)(info->symbols);
4896 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4898 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
4899 == ST_BRANCH_TO_THUMB)
4900 || type == STT_ARM_16BIT);
4904 if (force_thumb)
4905 is_thumb = TRUE;
4907 if (is_data)
4908 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4909 else
4910 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4912 info->bytes_per_line = 4;
4914 /* PR 10263: Disassemble data if requested to do so by the user. */
4915 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4917 int i;
4919 /* Size was already set above. */
4920 info->bytes_per_chunk = size;
4921 printer = print_insn_data;
4923 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4924 given = 0;
4925 if (little)
4926 for (i = size - 1; i >= 0; i--)
4927 given = b[i] | (given << 8);
4928 else
4929 for (i = 0; i < (int) size; i++)
4930 given = b[i] | (given << 8);
4932 else if (!is_thumb)
4934 /* In ARM mode endianness is a straightforward issue: the instruction
4935 is four bytes long and is either ordered 0123 or 3210. */
4936 printer = print_insn_arm;
4937 info->bytes_per_chunk = 4;
4938 size = 4;
4940 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4941 if (little_code)
4942 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4943 else
4944 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4946 else
4948 /* In Thumb mode we have the additional wrinkle of two
4949 instruction lengths. Fortunately, the bits that determine
4950 the length of the current instruction are always to be found
4951 in the first two bytes. */
4952 printer = print_insn_thumb16;
4953 info->bytes_per_chunk = 2;
4954 size = 2;
4956 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4957 if (little_code)
4958 given = (b[0]) | (b[1] << 8);
4959 else
4960 given = (b[1]) | (b[0] << 8);
4962 if (!status)
4964 /* These bit patterns signal a four-byte Thumb
4965 instruction. */
4966 if ((given & 0xF800) == 0xF800
4967 || (given & 0xF800) == 0xF000
4968 || (given & 0xF800) == 0xE800)
4970 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4971 if (little_code)
4972 given = (b[0]) | (b[1] << 8) | (given << 16);
4973 else
4974 given = (b[1]) | (b[0] << 8) | (given << 16);
4976 printer = print_insn_thumb32;
4977 size = 4;
4981 if (ifthen_address != pc)
4982 find_ifthen_state (pc, info, little_code);
4984 if (ifthen_state)
4986 if ((ifthen_state & 0xf) == 0x8)
4987 ifthen_next_state = 0;
4988 else
4989 ifthen_next_state = (ifthen_state & 0xe0)
4990 | ((ifthen_state & 0xf) << 1);
4994 if (status)
4996 info->memory_error_func (status, pc, info);
4997 return -1;
4999 if (info->flags & INSN_HAS_RELOC)
5000 /* If the instruction has a reloc associated with it, then
5001 the offset field in the instruction will actually be the
5002 addend for the reloc. (We are using REL type relocs).
5003 In such cases, we can ignore the pc when computing
5004 addresses, since the addend is not currently pc-relative. */
5005 pc = 0;
5007 printer (pc, info, given);
5009 if (is_thumb)
5011 ifthen_state = ifthen_next_state;
5012 ifthen_address += size;
5014 return size;
5018 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
5020 /* Detect BE8-ness and record it in the disassembler info. */
5021 if (info->flavour == bfd_target_elf_flavour
5022 && info->section != NULL
5023 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
5024 info->endian_code = BFD_ENDIAN_LITTLE;
5026 return print_insn (pc, info, FALSE);
5030 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
5032 return print_insn (pc, info, TRUE);
5035 void
5036 print_arm_disassembler_options (FILE *stream)
5038 int i;
5040 fprintf (stream, _("\n\
5041 The following ARM specific disassembler options are supported for use with\n\
5042 the -M switch:\n"));
5044 for (i = NUM_ARM_REGNAMES; i--;)
5045 fprintf (stream, " reg-names-%s %*c%s\n",
5046 regnames[i].name,
5047 (int)(14 - strlen (regnames[i].name)), ' ',
5048 regnames[i].description);
5050 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
5051 fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");