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