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