arm-dis.c revision 1.1.1.1.2.1 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 (at) pegasus.esprit.ec.org)
6 Modification by James G. Smith (jsmith (at) 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 /* CRC32 instructions. */
907 {CRC_EXT_ARMV8, 0xe1000040, 0xfff00ff0, "crc32b\t%12-15R, %16-19R, %0-3R"},
908 {CRC_EXT_ARMV8, 0xe1200040, 0xfff00ff0, "crc32h\t%12-15R, %16-19R, %0-3R"},
909 {CRC_EXT_ARMV8, 0xe1400040, 0xfff00ff0, "crc32w\t%12-15R, %16-19R, %0-3R"},
910 {CRC_EXT_ARMV8, 0xe1000240, 0xfff00ff0, "crc32cb\t%12-15R, %16-19R, %0-3R"},
911 {CRC_EXT_ARMV8, 0xe1200240, 0xfff00ff0, "crc32ch\t%12-15R, %16-19R, %0-3R"},
912 {CRC_EXT_ARMV8, 0xe1400240, 0xfff00ff0, "crc32cw\t%12-15R, %16-19R, %0-3R"},
913
914 /* Virtualization Extension instructions. */
915 {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
916 {ARM_EXT_VIRT, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
917
918 /* Integer Divide Extension instructions. */
919 {ARM_EXT_ADIV, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
920 {ARM_EXT_ADIV, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
921
922 /* MP Extension instructions. */
923 {ARM_EXT_MP, 0xf410f000, 0xfc70f000, "pldw\t%a"},
924
925 /* V7 instructions. */
926 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
927 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
928 {ARM_EXT_V8, 0xf57ff051, 0xfffffff3, "dmb\t%U"},
929 {ARM_EXT_V8, 0xf57ff041, 0xfffffff3, "dsb\t%U"},
930 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
931 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
932 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
933
934 /* ARM V6T2 instructions. */
935 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
936 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
937 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
938 {ARM_EXT_V6T2, 0x002000b0, 0x0f3000f0, "strht%c\t%12-15R, %S"},
939
940 {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
941 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
942
943 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
944 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
945 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
946 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
947
948 /* ARM Security extension instructions. */
949 {ARM_EXT_SEC, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
950
951 /* ARM V6K instructions. */
952 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
953 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
954 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
955 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
956 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
957 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
958 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
959
960 /* ARM V6K NOP hints. */
961 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
962 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
963 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
964 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
965 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
966
967 /* ARM V6 instructions. */
968 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
969 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
970 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
971 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
972 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
973 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
974 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
975 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
976 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
977 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
978 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
979 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
980 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
981 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
982 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
983 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
984 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
985 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
986 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
987 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
988 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
989 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
990 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
991 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
992 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
993 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
994 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
995 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
996 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
997 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
998 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
999 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
1000 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
1001 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
1002 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
1003 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
1004 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
1005 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
1006 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
1007 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
1008 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
1009 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
1010 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
1011 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
1012 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
1013 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
1014 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
1015 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
1016 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
1017 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
1018 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
1019 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
1020 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
1021 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
1022 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
1023 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
1024 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
1025 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
1026 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
1027 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
1028 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
1029 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
1030 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
1031 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
1032 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
1033 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
1034 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
1035 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
1036 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
1037 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
1038 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
1039 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
1040 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
1041 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
1042 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
1043 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1044 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1045 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1046 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
1047 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1048 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1049 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1050 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
1051 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1052 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1053 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1054 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
1055 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1056 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1057 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1058 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
1059 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1060 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1061 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
1062 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
1063 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
1064 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
1065 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
1066 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
1067 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
1068 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
1069 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
1070 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1071 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1072 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1073 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1074 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
1075 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1076 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1077 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
1078 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
1079 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
1080 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
1081 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
1082 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1083 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1084 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1085 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1086 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1087 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1088 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1089 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1090
1091 /* V5J instruction. */
1092 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1093
1094 /* V5 Instructions. */
1095 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1096 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
1097 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1098 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1099
1100 /* V5E "El Segundo" Instructions. */
1101 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1102 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1103 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
1104 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1105 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1106 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1107 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1108
1109 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1110 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1111
1112 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1113 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1114 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1115 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1116
1117 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1118 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1119 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1120 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1121
1122 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1123 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1124
1125 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1126 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1127 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1128 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1129
1130 /* ARM Instructions. */
1131 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1132
1133 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1134 {ARM_EXT_V1, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1135 {ARM_EXT_V1, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1136 {ARM_EXT_V1, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1137 {ARM_EXT_V1, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1138 {ARM_EXT_V1, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1139
1140 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1141 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1142 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1143 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1144
1145 {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
1146 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1147 {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
1148 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1149
1150 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1151 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1152 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1153
1154 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1155 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1156 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1157
1158 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1159 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1160 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1161
1162 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1163 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1164 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1165
1166 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1167 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1168 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1169
1170 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1171 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1172 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1173
1174 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1175 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1176 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1177
1178 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1179 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1180 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1181
1182 {ARM_EXT_VIRT, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1183 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1184 {ARM_EXT_V3, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1185
1186 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1187 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1188 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1189
1190 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1191 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1192 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1193
1194 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1195 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1196 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1197
1198 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1199 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1200 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1201
1202 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1203 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1204 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1205
1206 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1207 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1208 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1209 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1210 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1211 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1212 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1213
1214 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1215 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1216 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1217
1218 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1219 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1220 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1221
1222 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1223 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1224
1225 {ARM_EXT_V1, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1226
1227 {ARM_EXT_V1, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1228 {ARM_EXT_V1, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1229
1230 {ARM_EXT_V1, 0x092d0001, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1231 {ARM_EXT_V1, 0x092d0002, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1232 {ARM_EXT_V1, 0x092d0004, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1233 {ARM_EXT_V1, 0x092d0008, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1234 {ARM_EXT_V1, 0x092d0010, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1235 {ARM_EXT_V1, 0x092d0020, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1236 {ARM_EXT_V1, 0x092d0040, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1237 {ARM_EXT_V1, 0x092d0080, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1238 {ARM_EXT_V1, 0x092d0100, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1239 {ARM_EXT_V1, 0x092d0200, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1240 {ARM_EXT_V1, 0x092d0400, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1241 {ARM_EXT_V1, 0x092d0800, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1242 {ARM_EXT_V1, 0x092d1000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1243 {ARM_EXT_V1, 0x092d2000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1244 {ARM_EXT_V1, 0x092d4000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1245 {ARM_EXT_V1, 0x092d8000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1246 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1247 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1248 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1249
1250 {ARM_EXT_V1, 0x08bd0001, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1251 {ARM_EXT_V1, 0x08bd0002, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1252 {ARM_EXT_V1, 0x08bd0004, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1253 {ARM_EXT_V1, 0x08bd0008, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1254 {ARM_EXT_V1, 0x08bd0010, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1255 {ARM_EXT_V1, 0x08bd0020, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1256 {ARM_EXT_V1, 0x08bd0040, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1257 {ARM_EXT_V1, 0x08bd0080, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1258 {ARM_EXT_V1, 0x08bd0100, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1259 {ARM_EXT_V1, 0x08bd0200, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1260 {ARM_EXT_V1, 0x08bd0400, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1261 {ARM_EXT_V1, 0x08bd0800, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1262 {ARM_EXT_V1, 0x08bd1000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1263 {ARM_EXT_V1, 0x08bd2000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1264 {ARM_EXT_V1, 0x08bd4000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1265 {ARM_EXT_V1, 0x08bd8000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1266 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1267 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1268 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1269
1270 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1271 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1272
1273 /* The rest. */
1274 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1275 {0, 0x00000000, 0x00000000, 0}
1276 };
1277
1278 /* print_insn_thumb16 recognizes the following format control codes:
1279
1280 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1281 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1282 %<bitfield>I print bitfield as a signed decimal
1283 (top bit of range being the sign bit)
1284 %N print Thumb register mask (with LR)
1285 %O print Thumb register mask (with PC)
1286 %M print Thumb register mask
1287 %b print CZB's 6-bit unsigned branch destination
1288 %s print Thumb right-shift immediate (6..10; 0 == 32).
1289 %c print the condition code
1290 %C print the condition code, or "s" if not conditional
1291 %x print warning if conditional an not at end of IT block"
1292 %X print "\t; unpredictable <IT:code>" if conditional
1293 %I print IT instruction suffix and operands
1294 %W print Thumb Writeback indicator for LDMIA
1295 %<bitfield>r print bitfield as an ARM register
1296 %<bitfield>d print bitfield as a decimal
1297 %<bitfield>H print (bitfield * 2) as a decimal
1298 %<bitfield>W print (bitfield * 4) as a decimal
1299 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1300 %<bitfield>B print Thumb branch destination (signed displacement)
1301 %<bitfield>c print bitfield as a condition code
1302 %<bitnum>'c print specified char iff bit is one
1303 %<bitnum>?ab print a if bit is one else print b. */
1304
1305 static const struct opcode16 thumb_opcodes[] =
1306 {
1307 /* Thumb instructions. */
1308
1309 /* ARM V8 instructions. */
1310 {ARM_EXT_V8, 0xbf50, 0xffff, "sevl%c"},
1311 {ARM_EXT_V8, 0xba80, 0xffc0, "hlt\t%0-5x"},
1312
1313 /* ARM V6K no-argument instructions. */
1314 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1315 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1316 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1317 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1318 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1319 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1320
1321 /* ARM V6T2 instructions. */
1322 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1323 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1324 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1325
1326 /* ARM V6. */
1327 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1328 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1329 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1330 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1331 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1332 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1333 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1334 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1335 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1336 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1337 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1338
1339 /* ARM V5 ISA extends Thumb. */
1340 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1341 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1342 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1343 /* ARM V4T ISA (Thumb v1). */
1344 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1345 /* Format 4. */
1346 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1347 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1348 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1349 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1350 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1351 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1352 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1353 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1354 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1355 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1356 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1357 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1358 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1359 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1360 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1361 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1362 /* format 13 */
1363 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1364 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1365 /* format 5 */
1366 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1367 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1368 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1369 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1370 /* format 14 */
1371 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1372 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1373 /* format 2 */
1374 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1375 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1376 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1377 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1378 /* format 8 */
1379 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1380 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1381 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1382 /* format 7 */
1383 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1384 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1385 /* format 1 */
1386 {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1387 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1388 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1389 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1390 /* format 3 */
1391 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1392 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1393 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1394 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1395 /* format 6 */
1396 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1397 /* format 9 */
1398 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1399 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1400 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1401 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1402 /* format 10 */
1403 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1404 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1405 /* format 11 */
1406 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1407 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1408 /* format 12 */
1409 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1410 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1411 /* format 15 */
1412 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1413 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1414 /* format 17 */
1415 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1416 /* format 16 */
1417 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1418 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1419 /* format 18 */
1420 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1421
1422 /* The E800 .. FFFF range is unconditionally redirected to the
1423 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1424 are processed via that table. Thus, we can never encounter a
1425 bare "second half of BL/BLX(1)" instruction here. */
1426 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1427 {0, 0, 0, 0}
1428 };
1429
1430 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1431 We adopt the convention that hw1 is the high 16 bits of .value and
1432 .mask, hw2 the low 16 bits.
1433
1434 print_insn_thumb32 recognizes the following format control codes:
1435
1436 %% %
1437
1438 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1439 %M print a modified 12-bit immediate (same location)
1440 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1441 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1442 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1443 %S print a possibly-shifted Rm
1444
1445 %L print address for a ldrd/strd instruction
1446 %a print the address of a plain load/store
1447 %w print the width and signedness of a core load/store
1448 %m print register mask for ldm/stm
1449
1450 %E print the lsb and width fields of a bfc/bfi instruction
1451 %F print the lsb and width fields of a sbfx/ubfx instruction
1452 %b print a conditional branch offset
1453 %B print an unconditional branch offset
1454 %s print the shift field of an SSAT instruction
1455 %R print the rotation field of an SXT instruction
1456 %U print barrier type.
1457 %P print address for pli instruction.
1458 %c print the condition code
1459 %x print warning if conditional an not at end of IT block"
1460 %X print "\t; unpredictable <IT:code>" if conditional
1461
1462 %<bitfield>d print bitfield in decimal
1463 %<bitfield>W print bitfield*4 in decimal
1464 %<bitfield>r print bitfield as an ARM register
1465 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
1466 %<bitfield>S as %<>R but r13 is UNPREDICTABLE
1467 %<bitfield>c print bitfield as a condition code
1468
1469 %<bitfield>'c print specified char iff bitfield is all ones
1470 %<bitfield>`c print specified char iff bitfield is all zeroes
1471 %<bitfield>?ab... select from array of values in big endian order
1472
1473 With one exception at the bottom (done because BL and BLX(1) need
1474 to come dead last), this table was machine-sorted first in
1475 decreasing order of number of bits set in the mask, then in
1476 increasing numeric order of mask, then in increasing numeric order
1477 of opcode. This order is not the clearest for a human reader, but
1478 is guaranteed never to catch a special-case bit pattern with a more
1479 general mask, which is important, because this instruction encoding
1480 makes heavy use of special-case bit patterns. */
1481 static const struct opcode32 thumb32_opcodes[] =
1482 {
1483 /* V8 instructions. */
1484 {ARM_EXT_V8, 0xf3af8005, 0xffffffff, "sevl%c.w"},
1485 {ARM_EXT_V8, 0xf78f8000, 0xfffffffc, "dcps%0-1d"},
1486 {ARM_EXT_V8, 0xe8c00f8f, 0xfff00fff, "stlb%c\t%12-15r, [%16-19R]"},
1487 {ARM_EXT_V8, 0xe8c00f9f, 0xfff00fff, "stlh%c\t%12-15r, [%16-19R]"},
1488 {ARM_EXT_V8, 0xe8c00faf, 0xfff00fff, "stl%c\t%12-15r, [%16-19R]"},
1489 {ARM_EXT_V8, 0xe8c00fc0, 0xfff00ff0, "stlexb%c\t%0-3r, %12-15r, [%16-19R]"},
1490 {ARM_EXT_V8, 0xe8c00fd0, 0xfff00ff0, "stlexh%c\t%0-3r, %12-15r, [%16-19R]"},
1491 {ARM_EXT_V8, 0xe8c00fe0, 0xfff00ff0, "stlex%c\t%0-3r, %12-15r, [%16-19R]"},
1492 {ARM_EXT_V8, 0xe8c000f0, 0xfff000f0, "stlexd%c\t%0-3r, %12-15r, %8-11r, [%16-19R]"},
1493 {ARM_EXT_V8, 0xe8d00f8f, 0xfff00fff, "ldab%c\t%12-15r, [%16-19R]"},
1494 {ARM_EXT_V8, 0xe8d00f9f, 0xfff00fff, "ldah%c\t%12-15r, [%16-19R]"},
1495 {ARM_EXT_V8, 0xe8d00faf, 0xfff00fff, "lda%c\t%12-15r, [%16-19R]"},
1496 {ARM_EXT_V8, 0xe8d00fcf, 0xfff00fff, "ldaexb%c\t%12-15r, [%16-19R]"},
1497 {ARM_EXT_V8, 0xe8d00fdf, 0xfff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
1498 {ARM_EXT_V8, 0xe8d00fef, 0xfff00fff, "ldaex%c\t%12-15r, [%16-19R]"},
1499 {ARM_EXT_V8, 0xe8d000ff, 0xfff000ff, "ldaexd%c\t%12-15r, %8-11r, [%16-19R]"},
1500
1501 /* CRC32 instructions. */
1502 {CRC_EXT_ARMV8, 0xfac0f080, 0xfff0f0f0, "crc32b\t%8-11S, %16-19S, %0-3S"},
1503 {CRC_EXT_ARMV8, 0xfac0f090, 0xfff0f0f0, "crc32h\t%9-11S, %16-19S, %0-3S"},
1504 {CRC_EXT_ARMV8, 0xfac0f0a0, 0xfff0f0f0, "crc32w\t%8-11S, %16-19S, %0-3S"},
1505 {CRC_EXT_ARMV8, 0xfad0f080, 0xfff0f0f0, "crc32cb\t%8-11S, %16-19S, %0-3S"},
1506 {CRC_EXT_ARMV8, 0xfad0f090, 0xfff0f0f0, "crc32ch\t%8-11S, %16-19S, %0-3S"},
1507 {CRC_EXT_ARMV8, 0xfad0f0a0, 0xfff0f0f0, "crc32cw\t%8-11S, %16-19S, %0-3S"},
1508
1509 /* V7 instructions. */
1510 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1511 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1512 {ARM_EXT_V8, 0xf3bf8f51, 0xfffffff3, "dmb%c\t%U"},
1513 {ARM_EXT_V8, 0xf3bf8f41, 0xfffffff3, "dsb%c\t%U"},
1514 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1515 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1516 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1517 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1518 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1519
1520 /* Virtualization Extension instructions. */
1521 {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1522 /* We skip ERET as that is SUBS pc, lr, #0. */
1523
1524 /* MP Extension instructions. */
1525 {ARM_EXT_MP, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1526
1527 /* Security extension instructions. */
1528 {ARM_EXT_SEC, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1529
1530 /* Instructions defined in the basic V6T2 set. */
1531 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1532 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1533 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1534 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1535 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1536 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1537
1538 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1539 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1540 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1541 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1542 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1543 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1544 {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1545 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1546 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1547 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1548 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1549 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1550 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1551 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1552 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1553 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1554 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1555 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1556 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1557 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1558 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1559 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1560 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1561 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1562 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1563 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1564 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1565 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1566 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1567 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1568 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1569 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1570 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1571 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1572 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1573 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1574 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1575 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1576 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1577 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1578 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1579 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1580 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1581 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1582 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1583 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1584 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1585 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1586 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1587 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1588 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1589 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1590 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1591 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1592 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1593 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1594 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1595 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1596 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1597 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1598 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1599 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1600 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1601 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1602 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1603 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1604 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1605 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1606 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1607 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1608 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1609 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1610 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1611 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1612 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1613 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1614 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1615 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1616 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1617 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1618 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1619 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1620 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1621 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1622 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1623 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1624 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1625 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1626 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1627 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1628 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1629 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1630 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1631 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1632 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1633 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1634 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1635 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1636 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1637 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1638 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1639 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1640 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1641 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1642 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1643 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1644 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1645 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1646 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1647 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1648 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1649 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1650 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1651 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1652 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1653 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1654 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1655 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1656 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1657 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1658 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1659 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1660 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1661 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1662 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1663 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1664 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1665 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1666 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1667 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1668 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1669 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1670 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1671 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1672 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1673 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1674 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1675 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1676 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1677 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1678 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1679 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1680 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1681 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1682 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1683 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1684 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1685 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1686 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1687 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1688 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1689 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1690 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1691 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1692 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1693 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1694 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1695 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1696 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1697 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1698 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1699 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1700 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1701 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1702 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1703 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1704 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1705 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1706 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1707 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1708 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1709
1710 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1711 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1712 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1713 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1714 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1715
1716 /* These have been 32-bit since the invention of Thumb. */
1717 {ARM_EXT_V4T, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1718 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1719
1720 /* Fallback. */
1721 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1722 {0, 0, 0, 0}
1723 };
1724
1725 static const char *const arm_conditional[] =
1726 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1727 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1728
1729 static const char *const arm_fp_const[] =
1730 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1731
1732 static const char *const arm_shift[] =
1733 {"lsl", "lsr", "asr", "ror"};
1734
1735 typedef struct
1736 {
1737 const char *name;
1738 const char *description;
1739 const char *reg_names[16];
1740 }
1741 arm_regname;
1742
1743 static const arm_regname regnames[] =
1744 {
1745 { "raw" , "Select raw register names",
1746 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1747 { "gcc", "Select register names used by GCC",
1748 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1749 { "std", "Select register names used in ARM's ISA documentation",
1750 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1751 { "apcs", "Select register names used in the APCS",
1752 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1753 { "atpcs", "Select register names used in the ATPCS",
1754 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1755 { "special-atpcs", "Select special register names used in the ATPCS",
1756 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1757 };
1758
1759 static const char *const iwmmxt_wwnames[] =
1760 {"b", "h", "w", "d"};
1761
1762 static const char *const iwmmxt_wwssnames[] =
1763 {"b", "bus", "bc", "bss",
1764 "h", "hus", "hc", "hss",
1765 "w", "wus", "wc", "wss",
1766 "d", "dus", "dc", "dss"
1767 };
1768
1769 static const char *const iwmmxt_regnames[] =
1770 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1771 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1772 };
1773
1774 static const char *const iwmmxt_cregnames[] =
1775 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1776 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1777 };
1778
1779 /* Default to GCC register name set. */
1780 static unsigned int regname_selected = 1;
1781
1782 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1783 #define arm_regnames regnames[regname_selected].reg_names
1784
1785 static bfd_boolean force_thumb = FALSE;
1786
1787 /* Current IT instruction state. This contains the same state as the IT
1788 bits in the CPSR. */
1789 static unsigned int ifthen_state;
1790 /* IT state for the next instruction. */
1791 static unsigned int ifthen_next_state;
1792 /* The address of the insn for which the IT state is valid. */
1793 static bfd_vma ifthen_address;
1794 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1795 /* Indicates that the current Conditional state is unconditional or outside
1796 an IT block. */
1797 #define COND_UNCOND 16
1798
1799
1800 /* Functions. */
1802 int
1803 get_arm_regname_num_options (void)
1804 {
1805 return NUM_ARM_REGNAMES;
1806 }
1807
1808 int
1809 set_arm_regname_option (int option)
1810 {
1811 int old = regname_selected;
1812 regname_selected = option;
1813 return old;
1814 }
1815
1816 int
1817 get_arm_regnames (int option,
1818 const char **setname,
1819 const char **setdescription,
1820 const char *const **register_names)
1821 {
1822 *setname = regnames[option].name;
1823 *setdescription = regnames[option].description;
1824 *register_names = regnames[option].reg_names;
1825 return 16;
1826 }
1827
1828 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1829 Returns pointer to following character of the format string and
1830 fills in *VALUEP and *WIDTHP with the extracted value and number of
1831 bits extracted. WIDTHP can be NULL. */
1832
1833 static const char *
1834 arm_decode_bitfield (const char *ptr,
1835 unsigned long insn,
1836 unsigned long *valuep,
1837 int *widthp)
1838 {
1839 unsigned long value = 0;
1840 int width = 0;
1841
1842 do
1843 {
1844 int start, end;
1845 int bits;
1846
1847 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1848 start = start * 10 + *ptr - '0';
1849 if (*ptr == '-')
1850 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1851 end = end * 10 + *ptr - '0';
1852 else
1853 end = start;
1854 bits = end - start;
1855 if (bits < 0)
1856 abort ();
1857 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1858 width += bits + 1;
1859 }
1860 while (*ptr++ == ',');
1861 *valuep = value;
1862 if (widthp)
1863 *widthp = width;
1864 return ptr - 1;
1865 }
1866
1867 static void
1868 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1869 bfd_boolean print_shift)
1870 {
1871 func (stream, "%s", arm_regnames[given & 0xf]);
1872
1873 if ((given & 0xff0) != 0)
1874 {
1875 if ((given & 0x10) == 0)
1876 {
1877 int amount = (given & 0xf80) >> 7;
1878 int shift = (given & 0x60) >> 5;
1879
1880 if (amount == 0)
1881 {
1882 if (shift == 3)
1883 {
1884 func (stream, ", rrx");
1885 return;
1886 }
1887
1888 amount = 32;
1889 }
1890
1891 if (print_shift)
1892 func (stream, ", %s #%d", arm_shift[shift], amount);
1893 else
1894 func (stream, ", #%d", amount);
1895 }
1896 else if ((given & 0x80) == 0x80)
1897 func (stream, "\t; <illegal shifter operand>");
1898 else if (print_shift)
1899 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1900 arm_regnames[(given & 0xf00) >> 8]);
1901 else
1902 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1903 }
1904 }
1905
1906 #define W_BIT 21
1907 #define I_BIT 22
1908 #define U_BIT 23
1909 #define P_BIT 24
1910
1911 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1912 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1913 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1914 #define PRE_BIT_SET (given & (1 << P_BIT))
1915
1916 /* Print one coprocessor instruction on INFO->STREAM.
1917 Return TRUE if the instuction matched, FALSE if this is not a
1918 recognised coprocessor instruction. */
1919
1920 static bfd_boolean
1921 print_insn_coprocessor (bfd_vma pc,
1922 struct disassemble_info *info,
1923 long given,
1924 bfd_boolean thumb)
1925 {
1926 const struct opcode32 *insn;
1927 void *stream = info->stream;
1928 fprintf_ftype func = info->fprintf_func;
1929 unsigned long mask;
1930 unsigned long value = 0;
1931 struct arm_private_data *private_data = info->private_data;
1932 unsigned long allowed_arches = private_data->features.coproc;
1933 int cond;
1934
1935 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1936 {
1937 unsigned long u_reg = 16;
1938 bfd_boolean is_unpredictable = FALSE;
1939 signed long value_in_comment = 0;
1940 const char *c;
1941
1942 if (insn->arch == 0)
1943 switch (insn->value)
1944 {
1945 case SENTINEL_IWMMXT_START:
1946 if (info->mach != bfd_mach_arm_XScale
1947 && info->mach != bfd_mach_arm_iWMMXt
1948 && info->mach != bfd_mach_arm_iWMMXt2)
1949 do
1950 insn++;
1951 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1952 continue;
1953
1954 case SENTINEL_IWMMXT_END:
1955 continue;
1956
1957 case SENTINEL_GENERIC_START:
1958 allowed_arches = private_data->features.core;
1959 continue;
1960
1961 default:
1962 abort ();
1963 }
1964
1965 mask = insn->mask;
1966 value = insn->value;
1967 if (thumb)
1968 {
1969 /* The high 4 bits are 0xe for Arm conditional instructions, and
1970 0xe for arm unconditional instructions. The rest of the
1971 encoding is the same. */
1972 mask |= 0xf0000000;
1973 value |= 0xe0000000;
1974 if (ifthen_state)
1975 cond = IFTHEN_COND;
1976 else
1977 cond = COND_UNCOND;
1978 }
1979 else
1980 {
1981 /* Only match unconditional instuctions against unconditional
1982 patterns. */
1983 if ((given & 0xf0000000) == 0xf0000000)
1984 {
1985 mask |= 0xf0000000;
1986 cond = COND_UNCOND;
1987 }
1988 else
1989 {
1990 cond = (given >> 28) & 0xf;
1991 if (cond == 0xe)
1992 cond = COND_UNCOND;
1993 }
1994 }
1995
1996 if ((given & mask) != value)
1997 continue;
1998
1999 if ((insn->arch & allowed_arches) == 0)
2000 continue;
2001
2002 for (c = insn->assembler; *c; c++)
2003 {
2004 if (*c == '%')
2005 {
2006 switch (*++c)
2007 {
2008 case '%':
2009 func (stream, "%%");
2010 break;
2011
2012 case 'A':
2013 {
2014 int rn = (given >> 16) & 0xf;
2015 bfd_vma offset = given & 0xff;
2016
2017 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2018
2019 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
2020 {
2021 /* Not unindexed. The offset is scaled. */
2022 offset = offset * 4;
2023 if (NEGATIVE_BIT_SET)
2024 offset = - offset;
2025 if (rn != 15)
2026 value_in_comment = offset;
2027 }
2028
2029 if (PRE_BIT_SET)
2030 {
2031 if (offset)
2032 func (stream, ", #%d]%s",
2033 (int) offset,
2034 WRITEBACK_BIT_SET ? "!" : "");
2035 else if (NEGATIVE_BIT_SET)
2036 func (stream, ", #-0]");
2037 else
2038 func (stream, "]");
2039 }
2040 else
2041 {
2042 func (stream, "]");
2043
2044 if (WRITEBACK_BIT_SET)
2045 {
2046 if (offset)
2047 func (stream, ", #%d", (int) offset);
2048 else if (NEGATIVE_BIT_SET)
2049 func (stream, ", #-0");
2050 }
2051 else
2052 {
2053 func (stream, ", {%s%d}",
2054 (NEGATIVE_BIT_SET && !offset) ? "-" : "",
2055 (int) offset);
2056 value_in_comment = offset;
2057 }
2058 }
2059 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
2060 {
2061 func (stream, "\t; ");
2062 /* For unaligned PCs, apply off-by-alignment
2063 correction. */
2064 info->print_address_func (offset + pc
2065 + info->bytes_per_chunk * 2
2066 - (pc & 3),
2067 info);
2068 }
2069 }
2070 break;
2071
2072 case 'B':
2073 {
2074 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
2075 int offset = (given >> 1) & 0x3f;
2076
2077 if (offset == 1)
2078 func (stream, "{d%d}", regno);
2079 else if (regno + offset > 32)
2080 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
2081 else
2082 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
2083 }
2084 break;
2085
2086 case 'u':
2087 if (cond != COND_UNCOND)
2088 is_unpredictable = TRUE;
2089
2090 /* Fall through. */
2091 case 'c':
2092 func (stream, "%s", arm_conditional[cond]);
2093 break;
2094
2095 case 'I':
2096 /* Print a Cirrus/DSP shift immediate. */
2097 /* Immediates are 7bit signed ints with bits 0..3 in
2098 bits 0..3 of opcode and bits 4..6 in bits 5..7
2099 of opcode. */
2100 {
2101 int imm;
2102
2103 imm = (given & 0xf) | ((given & 0xe0) >> 1);
2104
2105 /* Is ``imm'' a negative number? */
2106 if (imm & 0x40)
2107 imm |= (-1 << 7);
2108
2109 func (stream, "%d", imm);
2110 }
2111
2112 break;
2113
2114 case 'F':
2115 switch (given & 0x00408000)
2116 {
2117 case 0:
2118 func (stream, "4");
2119 break;
2120 case 0x8000:
2121 func (stream, "1");
2122 break;
2123 case 0x00400000:
2124 func (stream, "2");
2125 break;
2126 default:
2127 func (stream, "3");
2128 }
2129 break;
2130
2131 case 'P':
2132 switch (given & 0x00080080)
2133 {
2134 case 0:
2135 func (stream, "s");
2136 break;
2137 case 0x80:
2138 func (stream, "d");
2139 break;
2140 case 0x00080000:
2141 func (stream, "e");
2142 break;
2143 default:
2144 func (stream, _("<illegal precision>"));
2145 break;
2146 }
2147 break;
2148
2149 case 'Q':
2150 switch (given & 0x00408000)
2151 {
2152 case 0:
2153 func (stream, "s");
2154 break;
2155 case 0x8000:
2156 func (stream, "d");
2157 break;
2158 case 0x00400000:
2159 func (stream, "e");
2160 break;
2161 default:
2162 func (stream, "p");
2163 break;
2164 }
2165 break;
2166
2167 case 'R':
2168 switch (given & 0x60)
2169 {
2170 case 0:
2171 break;
2172 case 0x20:
2173 func (stream, "p");
2174 break;
2175 case 0x40:
2176 func (stream, "m");
2177 break;
2178 default:
2179 func (stream, "z");
2180 break;
2181 }
2182 break;
2183
2184 case '0': case '1': case '2': case '3': case '4':
2185 case '5': case '6': case '7': case '8': case '9':
2186 {
2187 int width;
2188
2189 c = arm_decode_bitfield (c, given, &value, &width);
2190
2191 switch (*c)
2192 {
2193 case 'R':
2194 if (value == 15)
2195 is_unpredictable = TRUE;
2196 /* Fall through. */
2197 case 'r':
2198 if (c[1] == 'u')
2199 {
2200 /* Eat the 'u' character. */
2201 ++ c;
2202
2203 if (u_reg == value)
2204 is_unpredictable = TRUE;
2205 u_reg = value;
2206 }
2207 func (stream, "%s", arm_regnames[value]);
2208 break;
2209 case 'D':
2210 func (stream, "d%ld", value);
2211 break;
2212 case 'Q':
2213 if (value & 1)
2214 func (stream, "<illegal reg q%ld.5>", value >> 1);
2215 else
2216 func (stream, "q%ld", value >> 1);
2217 break;
2218 case 'd':
2219 func (stream, "%ld", value);
2220 value_in_comment = value;
2221 break;
2222 case 'k':
2223 {
2224 int from = (given & (1 << 7)) ? 32 : 16;
2225 func (stream, "%ld", from - value);
2226 }
2227 break;
2228
2229 case 'f':
2230 if (value > 7)
2231 func (stream, "#%s", arm_fp_const[value & 7]);
2232 else
2233 func (stream, "f%ld", value);
2234 break;
2235
2236 case 'w':
2237 if (width == 2)
2238 func (stream, "%s", iwmmxt_wwnames[value]);
2239 else
2240 func (stream, "%s", iwmmxt_wwssnames[value]);
2241 break;
2242
2243 case 'g':
2244 func (stream, "%s", iwmmxt_regnames[value]);
2245 break;
2246 case 'G':
2247 func (stream, "%s", iwmmxt_cregnames[value]);
2248 break;
2249
2250 case 'x':
2251 func (stream, "0x%lx", (value & 0xffffffffUL));
2252 break;
2253
2254 case 'c':
2255 switch (value)
2256 {
2257 case 0:
2258 func (stream, "eq");
2259 break;
2260
2261 case 1:
2262 func (stream, "vs");
2263 break;
2264
2265 case 2:
2266 func (stream, "ge");
2267 break;
2268
2269 case 3:
2270 func (stream, "gt");
2271 break;
2272
2273 default:
2274 func (stream, "??");
2275 break;
2276 }
2277 break;
2278
2279 case '`':
2280 c++;
2281 if (value == 0)
2282 func (stream, "%c", *c);
2283 break;
2284 case '\'':
2285 c++;
2286 if (value == ((1ul << width) - 1))
2287 func (stream, "%c", *c);
2288 break;
2289 case '?':
2290 func (stream, "%c", c[(1 << width) - (int) value]);
2291 c += 1 << width;
2292 break;
2293 default:
2294 abort ();
2295 }
2296 break;
2297
2298 case 'y':
2299 case 'z':
2300 {
2301 int single = *c++ == 'y';
2302 int regno;
2303
2304 switch (*c)
2305 {
2306 case '4': /* Sm pair */
2307 case '0': /* Sm, Dm */
2308 regno = given & 0x0000000f;
2309 if (single)
2310 {
2311 regno <<= 1;
2312 regno += (given >> 5) & 1;
2313 }
2314 else
2315 regno += ((given >> 5) & 1) << 4;
2316 break;
2317
2318 case '1': /* Sd, Dd */
2319 regno = (given >> 12) & 0x0000000f;
2320 if (single)
2321 {
2322 regno <<= 1;
2323 regno += (given >> 22) & 1;
2324 }
2325 else
2326 regno += ((given >> 22) & 1) << 4;
2327 break;
2328
2329 case '2': /* Sn, Dn */
2330 regno = (given >> 16) & 0x0000000f;
2331 if (single)
2332 {
2333 regno <<= 1;
2334 regno += (given >> 7) & 1;
2335 }
2336 else
2337 regno += ((given >> 7) & 1) << 4;
2338 break;
2339
2340 case '3': /* List */
2341 func (stream, "{");
2342 regno = (given >> 12) & 0x0000000f;
2343 if (single)
2344 {
2345 regno <<= 1;
2346 regno += (given >> 22) & 1;
2347 }
2348 else
2349 regno += ((given >> 22) & 1) << 4;
2350 break;
2351
2352 default:
2353 abort ();
2354 }
2355
2356 func (stream, "%c%d", single ? 's' : 'd', regno);
2357
2358 if (*c == '3')
2359 {
2360 int count = given & 0xff;
2361
2362 if (single == 0)
2363 count >>= 1;
2364
2365 if (--count)
2366 {
2367 func (stream, "-%c%d",
2368 single ? 's' : 'd',
2369 regno + count);
2370 }
2371
2372 func (stream, "}");
2373 }
2374 else if (*c == '4')
2375 func (stream, ", %c%d", single ? 's' : 'd',
2376 regno + 1);
2377 }
2378 break;
2379
2380 case 'L':
2381 switch (given & 0x00400100)
2382 {
2383 case 0x00000000: func (stream, "b"); break;
2384 case 0x00400000: func (stream, "h"); break;
2385 case 0x00000100: func (stream, "w"); break;
2386 case 0x00400100: func (stream, "d"); break;
2387 default:
2388 break;
2389 }
2390 break;
2391
2392 case 'Z':
2393 {
2394 /* given (20, 23) | given (0, 3) */
2395 value = ((given >> 16) & 0xf0) | (given & 0xf);
2396 func (stream, "%d", (int) value);
2397 }
2398 break;
2399
2400 case 'l':
2401 /* This is like the 'A' operator, except that if
2402 the width field "M" is zero, then the offset is
2403 *not* multiplied by four. */
2404 {
2405 int offset = given & 0xff;
2406 int multiplier = (given & 0x00000100) ? 4 : 1;
2407
2408 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2409
2410 if (multiplier > 1)
2411 {
2412 value_in_comment = offset * multiplier;
2413 if (NEGATIVE_BIT_SET)
2414 value_in_comment = - value_in_comment;
2415 }
2416
2417 if (offset)
2418 {
2419 if (PRE_BIT_SET)
2420 func (stream, ", #%s%d]%s",
2421 NEGATIVE_BIT_SET ? "-" : "",
2422 offset * multiplier,
2423 WRITEBACK_BIT_SET ? "!" : "");
2424 else
2425 func (stream, "], #%s%d",
2426 NEGATIVE_BIT_SET ? "-" : "",
2427 offset * multiplier);
2428 }
2429 else
2430 func (stream, "]");
2431 }
2432 break;
2433
2434 case 'r':
2435 {
2436 int imm4 = (given >> 4) & 0xf;
2437 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2438 int ubit = ! NEGATIVE_BIT_SET;
2439 const char *rm = arm_regnames [given & 0xf];
2440 const char *rn = arm_regnames [(given >> 16) & 0xf];
2441
2442 switch (puw_bits)
2443 {
2444 case 1:
2445 case 3:
2446 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2447 if (imm4)
2448 func (stream, ", lsl #%d", imm4);
2449 break;
2450
2451 case 4:
2452 case 5:
2453 case 6:
2454 case 7:
2455 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2456 if (imm4 > 0)
2457 func (stream, ", lsl #%d", imm4);
2458 func (stream, "]");
2459 if (puw_bits == 5 || puw_bits == 7)
2460 func (stream, "!");
2461 break;
2462
2463 default:
2464 func (stream, "INVALID");
2465 }
2466 }
2467 break;
2468
2469 case 'i':
2470 {
2471 long imm5;
2472 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2473 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2474 }
2475 break;
2476
2477 default:
2478 abort ();
2479 }
2480 }
2481 }
2482 else
2483 func (stream, "%c", *c);
2484 }
2485
2486 if (value_in_comment > 32 || value_in_comment < -16)
2487 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2488
2489 if (is_unpredictable)
2490 func (stream, UNPREDICTABLE_INSTRUCTION);
2491
2492 return TRUE;
2493 }
2494 return FALSE;
2495 }
2496
2497 /* Decodes and prints ARM addressing modes. Returns the offset
2498 used in the address, if any, if it is worthwhile printing the
2499 offset as a hexadecimal value in a comment at the end of the
2500 line of disassembly. */
2501
2502 static signed long
2503 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2504 {
2505 void *stream = info->stream;
2506 fprintf_ftype func = info->fprintf_func;
2507 bfd_vma offset = 0;
2508
2509 if (((given & 0x000f0000) == 0x000f0000)
2510 && ((given & 0x02000000) == 0))
2511 {
2512 offset = given & 0xfff;
2513
2514 func (stream, "[pc");
2515
2516 if (PRE_BIT_SET)
2517 {
2518 /* Pre-indexed. Elide offset of positive zero when
2519 non-writeback. */
2520 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2521 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2522
2523 if (NEGATIVE_BIT_SET)
2524 offset = -offset;
2525
2526 offset += pc + 8;
2527
2528 /* Cope with the possibility of write-back
2529 being used. Probably a very dangerous thing
2530 for the programmer to do, but who are we to
2531 argue ? */
2532 func (stream, "]%s", WRITEBACK_BIT_SET ? "!" : "");
2533 }
2534 else /* Post indexed. */
2535 {
2536 func (stream, "], #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2537
2538 /* Ie ignore the offset. */
2539 offset = pc + 8;
2540 }
2541
2542 func (stream, "\t; ");
2543 info->print_address_func (offset, info);
2544 offset = 0;
2545 }
2546 else
2547 {
2548 func (stream, "[%s",
2549 arm_regnames[(given >> 16) & 0xf]);
2550
2551 if (PRE_BIT_SET)
2552 {
2553 if ((given & 0x02000000) == 0)
2554 {
2555 /* Elide offset of positive zero when non-writeback. */
2556 offset = given & 0xfff;
2557 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2558 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2559 }
2560 else
2561 {
2562 func (stream, ", %s", NEGATIVE_BIT_SET ? "-" : "");
2563 arm_decode_shift (given, func, stream, TRUE);
2564 }
2565
2566 func (stream, "]%s",
2567 WRITEBACK_BIT_SET ? "!" : "");
2568 }
2569 else
2570 {
2571 if ((given & 0x02000000) == 0)
2572 {
2573 /* Always show offset. */
2574 offset = given & 0xfff;
2575 func (stream, "], #%s%d",
2576 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2577 }
2578 else
2579 {
2580 func (stream, "], %s",
2581 NEGATIVE_BIT_SET ? "-" : "");
2582 arm_decode_shift (given, func, stream, TRUE);
2583 }
2584 }
2585 }
2586
2587 return (signed long) offset;
2588 }
2589
2590 /* Print one neon instruction on INFO->STREAM.
2591 Return TRUE if the instuction matched, FALSE if this is not a
2592 recognised neon instruction. */
2593
2594 static bfd_boolean
2595 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2596 {
2597 const struct opcode32 *insn;
2598 void *stream = info->stream;
2599 fprintf_ftype func = info->fprintf_func;
2600
2601 if (thumb)
2602 {
2603 if ((given & 0xef000000) == 0xef000000)
2604 {
2605 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2606 unsigned long bit28 = given & (1 << 28);
2607
2608 given &= 0x00ffffff;
2609 if (bit28)
2610 given |= 0xf3000000;
2611 else
2612 given |= 0xf2000000;
2613 }
2614 else if ((given & 0xff000000) == 0xf9000000)
2615 given ^= 0xf9000000 ^ 0xf4000000;
2616 else
2617 return FALSE;
2618 }
2619
2620 for (insn = neon_opcodes; insn->assembler; insn++)
2621 {
2622 if ((given & insn->mask) == insn->value)
2623 {
2624 signed long value_in_comment = 0;
2625 bfd_boolean is_unpredictable = FALSE;
2626 const char *c;
2627
2628 for (c = insn->assembler; *c; c++)
2629 {
2630 if (*c == '%')
2631 {
2632 switch (*++c)
2633 {
2634 case '%':
2635 func (stream, "%%");
2636 break;
2637
2638 case 'u':
2639 if (thumb && ifthen_state)
2640 is_unpredictable = TRUE;
2641
2642 /* Fall through. */
2643 case 'c':
2644 if (thumb && ifthen_state)
2645 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2646 break;
2647
2648 case 'A':
2649 {
2650 static const unsigned char enc[16] =
2651 {
2652 0x4, 0x14, /* st4 0,1 */
2653 0x4, /* st1 2 */
2654 0x4, /* st2 3 */
2655 0x3, /* st3 4 */
2656 0x13, /* st3 5 */
2657 0x3, /* st1 6 */
2658 0x1, /* st1 7 */
2659 0x2, /* st2 8 */
2660 0x12, /* st2 9 */
2661 0x2, /* st1 10 */
2662 0, 0, 0, 0, 0
2663 };
2664 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2665 int rn = ((given >> 16) & 0xf);
2666 int rm = ((given >> 0) & 0xf);
2667 int align = ((given >> 4) & 0x3);
2668 int type = ((given >> 8) & 0xf);
2669 int n = enc[type] & 0xf;
2670 int stride = (enc[type] >> 4) + 1;
2671 int ix;
2672
2673 func (stream, "{");
2674 if (stride > 1)
2675 for (ix = 0; ix != n; ix++)
2676 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2677 else if (n == 1)
2678 func (stream, "d%d", rd);
2679 else
2680 func (stream, "d%d-d%d", rd, rd + n - 1);
2681 func (stream, "}, [%s", arm_regnames[rn]);
2682 if (align)
2683 func (stream, " :%d", 32 << align);
2684 func (stream, "]");
2685 if (rm == 0xd)
2686 func (stream, "!");
2687 else if (rm != 0xf)
2688 func (stream, ", %s", arm_regnames[rm]);
2689 }
2690 break;
2691
2692 case 'B':
2693 {
2694 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2695 int rn = ((given >> 16) & 0xf);
2696 int rm = ((given >> 0) & 0xf);
2697 int idx_align = ((given >> 4) & 0xf);
2698 int align = 0;
2699 int size = ((given >> 10) & 0x3);
2700 int idx = idx_align >> (size + 1);
2701 int length = ((given >> 8) & 3) + 1;
2702 int stride = 1;
2703 int i;
2704
2705 if (length > 1 && size > 0)
2706 stride = (idx_align & (1 << size)) ? 2 : 1;
2707
2708 switch (length)
2709 {
2710 case 1:
2711 {
2712 int amask = (1 << size) - 1;
2713 if ((idx_align & (1 << size)) != 0)
2714 return FALSE;
2715 if (size > 0)
2716 {
2717 if ((idx_align & amask) == amask)
2718 align = 8 << size;
2719 else if ((idx_align & amask) != 0)
2720 return FALSE;
2721 }
2722 }
2723 break;
2724
2725 case 2:
2726 if (size == 2 && (idx_align & 2) != 0)
2727 return FALSE;
2728 align = (idx_align & 1) ? 16 << size : 0;
2729 break;
2730
2731 case 3:
2732 if ((size == 2 && (idx_align & 3) != 0)
2733 || (idx_align & 1) != 0)
2734 return FALSE;
2735 break;
2736
2737 case 4:
2738 if (size == 2)
2739 {
2740 if ((idx_align & 3) == 3)
2741 return FALSE;
2742 align = (idx_align & 3) * 64;
2743 }
2744 else
2745 align = (idx_align & 1) ? 32 << size : 0;
2746 break;
2747
2748 default:
2749 abort ();
2750 }
2751
2752 func (stream, "{");
2753 for (i = 0; i < length; i++)
2754 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2755 rd + i * stride, idx);
2756 func (stream, "}, [%s", arm_regnames[rn]);
2757 if (align)
2758 func (stream, " :%d", align);
2759 func (stream, "]");
2760 if (rm == 0xd)
2761 func (stream, "!");
2762 else if (rm != 0xf)
2763 func (stream, ", %s", arm_regnames[rm]);
2764 }
2765 break;
2766
2767 case 'C':
2768 {
2769 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2770 int rn = ((given >> 16) & 0xf);
2771 int rm = ((given >> 0) & 0xf);
2772 int align = ((given >> 4) & 0x1);
2773 int size = ((given >> 6) & 0x3);
2774 int type = ((given >> 8) & 0x3);
2775 int n = type + 1;
2776 int stride = ((given >> 5) & 0x1);
2777 int ix;
2778
2779 if (stride && (n == 1))
2780 n++;
2781 else
2782 stride++;
2783
2784 func (stream, "{");
2785 if (stride > 1)
2786 for (ix = 0; ix != n; ix++)
2787 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2788 else if (n == 1)
2789 func (stream, "d%d[]", rd);
2790 else
2791 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2792 func (stream, "}, [%s", arm_regnames[rn]);
2793 if (align)
2794 {
2795 align = (8 * (type + 1)) << size;
2796 if (type == 3)
2797 align = (size > 1) ? align >> 1 : align;
2798 if (type == 2 || (type == 0 && !size))
2799 func (stream, " :<bad align %d>", align);
2800 else
2801 func (stream, " :%d", align);
2802 }
2803 func (stream, "]");
2804 if (rm == 0xd)
2805 func (stream, "!");
2806 else if (rm != 0xf)
2807 func (stream, ", %s", arm_regnames[rm]);
2808 }
2809 break;
2810
2811 case 'D':
2812 {
2813 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2814 int size = (given >> 20) & 3;
2815 int reg = raw_reg & ((4 << size) - 1);
2816 int ix = raw_reg >> size >> 2;
2817
2818 func (stream, "d%d[%d]", reg, ix);
2819 }
2820 break;
2821
2822 case 'E':
2823 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2824 {
2825 int bits = 0;
2826 int cmode = (given >> 8) & 0xf;
2827 int op = (given >> 5) & 0x1;
2828 unsigned long value = 0, hival = 0;
2829 unsigned shift;
2830 int size = 0;
2831 int isfloat = 0;
2832
2833 bits |= ((given >> 24) & 1) << 7;
2834 bits |= ((given >> 16) & 7) << 4;
2835 bits |= ((given >> 0) & 15) << 0;
2836
2837 if (cmode < 8)
2838 {
2839 shift = (cmode >> 1) & 3;
2840 value = (unsigned long) bits << (8 * shift);
2841 size = 32;
2842 }
2843 else if (cmode < 12)
2844 {
2845 shift = (cmode >> 1) & 1;
2846 value = (unsigned long) bits << (8 * shift);
2847 size = 16;
2848 }
2849 else if (cmode < 14)
2850 {
2851 shift = (cmode & 1) + 1;
2852 value = (unsigned long) bits << (8 * shift);
2853 value |= (1ul << (8 * shift)) - 1;
2854 size = 32;
2855 }
2856 else if (cmode == 14)
2857 {
2858 if (op)
2859 {
2860 /* Bit replication into bytes. */
2861 int ix;
2862 unsigned long mask;
2863
2864 value = 0;
2865 hival = 0;
2866 for (ix = 7; ix >= 0; ix--)
2867 {
2868 mask = ((bits >> ix) & 1) ? 0xff : 0;
2869 if (ix <= 3)
2870 value = (value << 8) | mask;
2871 else
2872 hival = (hival << 8) | mask;
2873 }
2874 size = 64;
2875 }
2876 else
2877 {
2878 /* Byte replication. */
2879 value = (unsigned long) bits;
2880 size = 8;
2881 }
2882 }
2883 else if (!op)
2884 {
2885 /* Floating point encoding. */
2886 int tmp;
2887
2888 value = (unsigned long) (bits & 0x7f) << 19;
2889 value |= (unsigned long) (bits & 0x80) << 24;
2890 tmp = bits & 0x40 ? 0x3c : 0x40;
2891 value |= (unsigned long) tmp << 24;
2892 size = 32;
2893 isfloat = 1;
2894 }
2895 else
2896 {
2897 func (stream, "<illegal constant %.8x:%x:%x>",
2898 bits, cmode, op);
2899 size = 32;
2900 break;
2901 }
2902 switch (size)
2903 {
2904 case 8:
2905 func (stream, "#%ld\t; 0x%.2lx", value, value);
2906 break;
2907
2908 case 16:
2909 func (stream, "#%ld\t; 0x%.4lx", value, value);
2910 break;
2911
2912 case 32:
2913 if (isfloat)
2914 {
2915 unsigned char valbytes[4];
2916 double fvalue;
2917
2918 /* Do this a byte at a time so we don't have to
2919 worry about the host's endianness. */
2920 valbytes[0] = value & 0xff;
2921 valbytes[1] = (value >> 8) & 0xff;
2922 valbytes[2] = (value >> 16) & 0xff;
2923 valbytes[3] = (value >> 24) & 0xff;
2924
2925 floatformat_to_double
2926 (& floatformat_ieee_single_little, valbytes,
2927 & fvalue);
2928
2929 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2930 value);
2931 }
2932 else
2933 func (stream, "#%ld\t; 0x%.8lx",
2934 (long) (((value & 0x80000000L) != 0)
2935 ? value | ~0xffffffffL : value),
2936 value);
2937 break;
2938
2939 case 64:
2940 func (stream, "#0x%.8lx%.8lx", hival, value);
2941 break;
2942
2943 default:
2944 abort ();
2945 }
2946 }
2947 break;
2948
2949 case 'F':
2950 {
2951 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2952 int num = (given >> 8) & 0x3;
2953
2954 if (!num)
2955 func (stream, "{d%d}", regno);
2956 else if (num + regno >= 32)
2957 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2958 else
2959 func (stream, "{d%d-d%d}", regno, regno + num);
2960 }
2961 break;
2962
2963
2964 case '0': case '1': case '2': case '3': case '4':
2965 case '5': case '6': case '7': case '8': case '9':
2966 {
2967 int width;
2968 unsigned long value;
2969
2970 c = arm_decode_bitfield (c, given, &value, &width);
2971
2972 switch (*c)
2973 {
2974 case 'r':
2975 func (stream, "%s", arm_regnames[value]);
2976 break;
2977 case 'd':
2978 func (stream, "%ld", value);
2979 value_in_comment = value;
2980 break;
2981 case 'e':
2982 func (stream, "%ld", (1ul << width) - value);
2983 break;
2984
2985 case 'S':
2986 case 'T':
2987 case 'U':
2988 /* Various width encodings. */
2989 {
2990 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2991 int limit;
2992 unsigned low, high;
2993
2994 c++;
2995 if (*c >= '0' && *c <= '9')
2996 limit = *c - '0';
2997 else if (*c >= 'a' && *c <= 'f')
2998 limit = *c - 'a' + 10;
2999 else
3000 abort ();
3001 low = limit >> 2;
3002 high = limit & 3;
3003
3004 if (value < low || value > high)
3005 func (stream, "<illegal width %d>", base << value);
3006 else
3007 func (stream, "%d", base << value);
3008 }
3009 break;
3010 case 'R':
3011 if (given & (1 << 6))
3012 goto Q;
3013 /* FALLTHROUGH */
3014 case 'D':
3015 func (stream, "d%ld", value);
3016 break;
3017 case 'Q':
3018 Q:
3019 if (value & 1)
3020 func (stream, "<illegal reg q%ld.5>", value >> 1);
3021 else
3022 func (stream, "q%ld", value >> 1);
3023 break;
3024
3025 case '`':
3026 c++;
3027 if (value == 0)
3028 func (stream, "%c", *c);
3029 break;
3030 case '\'':
3031 c++;
3032 if (value == ((1ul << width) - 1))
3033 func (stream, "%c", *c);
3034 break;
3035 case '?':
3036 func (stream, "%c", c[(1 << width) - (int) value]);
3037 c += 1 << width;
3038 break;
3039 default:
3040 abort ();
3041 }
3042 break;
3043
3044 default:
3045 abort ();
3046 }
3047 }
3048 }
3049 else
3050 func (stream, "%c", *c);
3051 }
3052
3053 if (value_in_comment > 32 || value_in_comment < -16)
3054 func (stream, "\t; 0x%lx", value_in_comment);
3055
3056 if (is_unpredictable)
3057 func (stream, UNPREDICTABLE_INSTRUCTION);
3058
3059 return TRUE;
3060 }
3061 }
3062 return FALSE;
3063 }
3064
3065 /* Return the name of a v7A special register. */
3066
3067 static const char *
3068 banked_regname (unsigned reg)
3069 {
3070 switch (reg)
3071 {
3072 case 15: return "CPSR";
3073 case 32: return "R8_usr";
3074 case 33: return "R9_usr";
3075 case 34: return "R10_usr";
3076 case 35: return "R11_usr";
3077 case 36: return "R12_usr";
3078 case 37: return "SP_usr";
3079 case 38: return "LR_usr";
3080 case 40: return "R8_fiq";
3081 case 41: return "R9_fiq";
3082 case 42: return "R10_fiq";
3083 case 43: return "R11_fiq";
3084 case 44: return "R12_fiq";
3085 case 45: return "SP_fiq";
3086 case 46: return "LR_fiq";
3087 case 48: return "LR_irq";
3088 case 49: return "SP_irq";
3089 case 50: return "LR_svc";
3090 case 51: return "SP_svc";
3091 case 52: return "LR_abt";
3092 case 53: return "SP_abt";
3093 case 54: return "LR_und";
3094 case 55: return "SP_und";
3095 case 60: return "LR_mon";
3096 case 61: return "SP_mon";
3097 case 62: return "ELR_hyp";
3098 case 63: return "SP_hyp";
3099 case 79: return "SPSR";
3100 case 110: return "SPSR_fiq";
3101 case 112: return "SPSR_irq";
3102 case 114: return "SPSR_svc";
3103 case 116: return "SPSR_abt";
3104 case 118: return "SPSR_und";
3105 case 124: return "SPSR_mon";
3106 case 126: return "SPSR_hyp";
3107 default: return NULL;
3108 }
3109 }
3110
3111 /* Return the name of the DMB/DSB option. */
3112 static const char *
3113 data_barrier_option (unsigned option)
3114 {
3115 switch (option & 0xf)
3116 {
3117 case 0xf: return "sy";
3118 case 0xe: return "st";
3119 case 0xd: return "ld";
3120 case 0xb: return "ish";
3121 case 0xa: return "ishst";
3122 case 0x9: return "ishld";
3123 case 0x7: return "un";
3124 case 0x6: return "unst";
3125 case 0x5: return "nshld";
3126 case 0x3: return "osh";
3127 case 0x2: return "oshst";
3128 case 0x1: return "oshld";
3129 default: return NULL;
3130 }
3131 }
3132
3133 /* Print one ARM instruction from PC on INFO->STREAM. */
3134
3135 static void
3136 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
3137 {
3138 const struct opcode32 *insn;
3139 void *stream = info->stream;
3140 fprintf_ftype func = info->fprintf_func;
3141 struct arm_private_data *private_data = info->private_data;
3142
3143 if (print_insn_coprocessor (pc, info, given, FALSE))
3144 return;
3145
3146 if (print_insn_neon (info, given, FALSE))
3147 return;
3148
3149 for (insn = arm_opcodes; insn->assembler; insn++)
3150 {
3151 if ((given & insn->mask) != insn->value)
3152 continue;
3153
3154 if ((insn->arch & private_data->features.core) == 0)
3155 continue;
3156
3157 /* Special case: an instruction with all bits set in the condition field
3158 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
3159 or by the catchall at the end of the table. */
3160 if ((given & 0xF0000000) != 0xF0000000
3161 || (insn->mask & 0xF0000000) == 0xF0000000
3162 || (insn->mask == 0 && insn->value == 0))
3163 {
3164 unsigned long u_reg = 16;
3165 unsigned long U_reg = 16;
3166 bfd_boolean is_unpredictable = FALSE;
3167 signed long value_in_comment = 0;
3168 const char *c;
3169
3170 for (c = insn->assembler; *c; c++)
3171 {
3172 if (*c == '%')
3173 {
3174 bfd_boolean allow_unpredictable = FALSE;
3175
3176 switch (*++c)
3177 {
3178 case '%':
3179 func (stream, "%%");
3180 break;
3181
3182 case 'a':
3183 value_in_comment = print_arm_address (pc, info, given);
3184 break;
3185
3186 case 'P':
3187 /* Set P address bit and use normal address
3188 printing routine. */
3189 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
3190 break;
3191
3192 case 'S':
3193 allow_unpredictable = TRUE;
3194 case 's':
3195 if ((given & 0x004f0000) == 0x004f0000)
3196 {
3197 /* PC relative with immediate offset. */
3198 bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3199
3200 if (PRE_BIT_SET)
3201 {
3202 /* Elide positive zero offset. */
3203 if (offset || NEGATIVE_BIT_SET)
3204 func (stream, "[pc, #%s%d]\t; ",
3205 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3206 else
3207 func (stream, "[pc]\t; ");
3208 if (NEGATIVE_BIT_SET)
3209 offset = -offset;
3210 info->print_address_func (offset + pc + 8, info);
3211 }
3212 else
3213 {
3214 /* Always show the offset. */
3215 func (stream, "[pc], #%s%d",
3216 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3217 if (! allow_unpredictable)
3218 is_unpredictable = TRUE;
3219 }
3220 }
3221 else
3222 {
3223 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3224
3225 func (stream, "[%s",
3226 arm_regnames[(given >> 16) & 0xf]);
3227
3228 if (PRE_BIT_SET)
3229 {
3230 if (IMMEDIATE_BIT_SET)
3231 {
3232 /* Elide offset for non-writeback
3233 positive zero. */
3234 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3235 || offset)
3236 func (stream, ", #%s%d",
3237 NEGATIVE_BIT_SET ? "-" : "", offset);
3238
3239 if (NEGATIVE_BIT_SET)
3240 offset = -offset;
3241
3242 value_in_comment = offset;
3243 }
3244 else
3245 {
3246 /* Register Offset or Register Pre-Indexed. */
3247 func (stream, ", %s%s",
3248 NEGATIVE_BIT_SET ? "-" : "",
3249 arm_regnames[given & 0xf]);
3250
3251 /* Writing back to the register that is the source/
3252 destination of the load/store is unpredictable. */
3253 if (! allow_unpredictable
3254 && WRITEBACK_BIT_SET
3255 && ((given & 0xf) == ((given >> 12) & 0xf)))
3256 is_unpredictable = TRUE;
3257 }
3258
3259 func (stream, "]%s",
3260 WRITEBACK_BIT_SET ? "!" : "");
3261 }
3262 else
3263 {
3264 if (IMMEDIATE_BIT_SET)
3265 {
3266 /* Immediate Post-indexed. */
3267 /* PR 10924: Offset must be printed, even if it is zero. */
3268 func (stream, "], #%s%d",
3269 NEGATIVE_BIT_SET ? "-" : "", offset);
3270 if (NEGATIVE_BIT_SET)
3271 offset = -offset;
3272 value_in_comment = offset;
3273 }
3274 else
3275 {
3276 /* Register Post-indexed. */
3277 func (stream, "], %s%s",
3278 NEGATIVE_BIT_SET ? "-" : "",
3279 arm_regnames[given & 0xf]);
3280
3281 /* Writing back to the register that is the source/
3282 destination of the load/store is unpredictable. */
3283 if (! allow_unpredictable
3284 && (given & 0xf) == ((given >> 12) & 0xf))
3285 is_unpredictable = TRUE;
3286 }
3287
3288 if (! allow_unpredictable)
3289 {
3290 /* Writeback is automatically implied by post- addressing.
3291 Setting the W bit is unnecessary and ARM specify it as
3292 being unpredictable. */
3293 if (WRITEBACK_BIT_SET
3294 /* Specifying the PC register as the post-indexed
3295 registers is also unpredictable. */
3296 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3297 is_unpredictable = TRUE;
3298 }
3299 }
3300 }
3301 break;
3302
3303 case 'b':
3304 {
3305 bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3306 info->print_address_func (disp * 4 + pc + 8, info);
3307 }
3308 break;
3309
3310 case 'c':
3311 if (((given >> 28) & 0xf) != 0xe)
3312 func (stream, "%s",
3313 arm_conditional [(given >> 28) & 0xf]);
3314 break;
3315
3316 case 'm':
3317 {
3318 int started = 0;
3319 int reg;
3320
3321 func (stream, "{");
3322 for (reg = 0; reg < 16; reg++)
3323 if ((given & (1 << reg)) != 0)
3324 {
3325 if (started)
3326 func (stream, ", ");
3327 started = 1;
3328 func (stream, "%s", arm_regnames[reg]);
3329 }
3330 func (stream, "}");
3331 if (! started)
3332 is_unpredictable = TRUE;
3333 }
3334 break;
3335
3336 case 'q':
3337 arm_decode_shift (given, func, stream, FALSE);
3338 break;
3339
3340 case 'o':
3341 if ((given & 0x02000000) != 0)
3342 {
3343 unsigned int rotate = (given & 0xf00) >> 7;
3344 unsigned int immed = (given & 0xff);
3345 unsigned int a, i;
3346
3347 a = (((immed << (32 - rotate))
3348 | (immed >> rotate)) & 0xffffffff);
3349 /* If there is another encoding with smaller rotate,
3350 the rotate should be specified directly. */
3351 for (i = 0; i < 32; i += 2)
3352 if ((a << i | a >> (32 - i)) <= 0xff)
3353 break;
3354
3355 if (i != rotate)
3356 func (stream, "#%d, %d", immed, rotate);
3357 else
3358 func (stream, "#%d", a);
3359 value_in_comment = a;
3360 }
3361 else
3362 arm_decode_shift (given, func, stream, TRUE);
3363 break;
3364
3365 case 'p':
3366 if ((given & 0x0000f000) == 0x0000f000)
3367 {
3368 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3369 mechanism for setting PSR flag bits. They are
3370 obsolete in V6 onwards. */
3371 if ((private_data->features.core & ARM_EXT_V6) == 0)
3372 func (stream, "p");
3373 }
3374 break;
3375
3376 case 't':
3377 if ((given & 0x01200000) == 0x00200000)
3378 func (stream, "t");
3379 break;
3380
3381 case 'A':
3382 {
3383 int offset = given & 0xff;
3384
3385 value_in_comment = offset * 4;
3386 if (NEGATIVE_BIT_SET)
3387 value_in_comment = - value_in_comment;
3388
3389 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3390
3391 if (PRE_BIT_SET)
3392 {
3393 if (offset)
3394 func (stream, ", #%d]%s",
3395 (int) value_in_comment,
3396 WRITEBACK_BIT_SET ? "!" : "");
3397 else
3398 func (stream, "]");
3399 }
3400 else
3401 {
3402 func (stream, "]");
3403
3404 if (WRITEBACK_BIT_SET)
3405 {
3406 if (offset)
3407 func (stream, ", #%d", (int) value_in_comment);
3408 }
3409 else
3410 {
3411 func (stream, ", {%d}", (int) offset);
3412 value_in_comment = offset;
3413 }
3414 }
3415 }
3416 break;
3417
3418 case 'B':
3419 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3420 {
3421 bfd_vma address;
3422 bfd_vma offset = 0;
3423
3424 if (! NEGATIVE_BIT_SET)
3425 /* Is signed, hi bits should be ones. */
3426 offset = (-1) ^ 0x00ffffff;
3427
3428 /* Offset is (SignExtend(offset field)<<2). */
3429 offset += given & 0x00ffffff;
3430 offset <<= 2;
3431 address = offset + pc + 8;
3432
3433 if (given & 0x01000000)
3434 /* H bit allows addressing to 2-byte boundaries. */
3435 address += 2;
3436
3437 info->print_address_func (address, info);
3438 }
3439 break;
3440
3441 case 'C':
3442 if ((given & 0x02000200) == 0x200)
3443 {
3444 const char * name;
3445 unsigned sysm = (given & 0x004f0000) >> 16;
3446
3447 sysm |= (given & 0x300) >> 4;
3448 name = banked_regname (sysm);
3449
3450 if (name != NULL)
3451 func (stream, "%s", name);
3452 else
3453 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3454 }
3455 else
3456 {
3457 func (stream, "%cPSR_",
3458 (given & 0x00400000) ? 'S' : 'C');
3459 if (given & 0x80000)
3460 func (stream, "f");
3461 if (given & 0x40000)
3462 func (stream, "s");
3463 if (given & 0x20000)
3464 func (stream, "x");
3465 if (given & 0x10000)
3466 func (stream, "c");
3467 }
3468 break;
3469
3470 case 'U':
3471 if ((given & 0xf0) == 0x60)
3472 {
3473 switch (given & 0xf)
3474 {
3475 case 0xf: func (stream, "sy"); break;
3476 default:
3477 func (stream, "#%d", (int) given & 0xf);
3478 break;
3479 }
3480 }
3481 else
3482 {
3483 const char * opt = data_barrier_option (given & 0xf);
3484 if (opt != NULL)
3485 func (stream, "%s", opt);
3486 else
3487 func (stream, "#%d", (int) given & 0xf);
3488 }
3489 break;
3490
3491 case '0': case '1': case '2': case '3': case '4':
3492 case '5': case '6': case '7': case '8': case '9':
3493 {
3494 int width;
3495 unsigned long value;
3496
3497 c = arm_decode_bitfield (c, given, &value, &width);
3498
3499 switch (*c)
3500 {
3501 case 'R':
3502 if (value == 15)
3503 is_unpredictable = TRUE;
3504 /* Fall through. */
3505 case 'r':
3506 case 'T':
3507 /* We want register + 1 when decoding T. */
3508 if (*c == 'T')
3509 ++value;
3510
3511 if (c[1] == 'u')
3512 {
3513 /* Eat the 'u' character. */
3514 ++ c;
3515
3516 if (u_reg == value)
3517 is_unpredictable = TRUE;
3518 u_reg = value;
3519 }
3520 if (c[1] == 'U')
3521 {
3522 /* Eat the 'U' character. */
3523 ++ c;
3524
3525 if (U_reg == value)
3526 is_unpredictable = TRUE;
3527 U_reg = value;
3528 }
3529 func (stream, "%s", arm_regnames[value]);
3530 break;
3531 case 'd':
3532 func (stream, "%ld", value);
3533 value_in_comment = value;
3534 break;
3535 case 'b':
3536 func (stream, "%ld", value * 8);
3537 value_in_comment = value * 8;
3538 break;
3539 case 'W':
3540 func (stream, "%ld", value + 1);
3541 value_in_comment = value + 1;
3542 break;
3543 case 'x':
3544 func (stream, "0x%08lx", value);
3545
3546 /* Some SWI instructions have special
3547 meanings. */
3548 if ((given & 0x0fffffff) == 0x0FF00000)
3549 func (stream, "\t; IMB");
3550 else if ((given & 0x0fffffff) == 0x0FF00001)
3551 func (stream, "\t; IMBRange");
3552 break;
3553 case 'X':
3554 func (stream, "%01lx", value & 0xf);
3555 value_in_comment = value;
3556 break;
3557 case '`':
3558 c++;
3559 if (value == 0)
3560 func (stream, "%c", *c);
3561 break;
3562 case '\'':
3563 c++;
3564 if (value == ((1ul << width) - 1))
3565 func (stream, "%c", *c);
3566 break;
3567 case '?':
3568 func (stream, "%c", c[(1 << width) - (int) value]);
3569 c += 1 << width;
3570 break;
3571 default:
3572 abort ();
3573 }
3574 break;
3575
3576 case 'e':
3577 {
3578 int imm;
3579
3580 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3581 func (stream, "%d", imm);
3582 value_in_comment = imm;
3583 }
3584 break;
3585
3586 case 'E':
3587 /* LSB and WIDTH fields of BFI or BFC. The machine-
3588 language instruction encodes LSB and MSB. */
3589 {
3590 long msb = (given & 0x001f0000) >> 16;
3591 long lsb = (given & 0x00000f80) >> 7;
3592 long w = msb - lsb + 1;
3593
3594 if (w > 0)
3595 func (stream, "#%lu, #%lu", lsb, w);
3596 else
3597 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3598 }
3599 break;
3600
3601 case 'R':
3602 /* Get the PSR/banked register name. */
3603 {
3604 const char * name;
3605 unsigned sysm = (given & 0x004f0000) >> 16;
3606
3607 sysm |= (given & 0x300) >> 4;
3608 name = banked_regname (sysm);
3609
3610 if (name != NULL)
3611 func (stream, "%s", name);
3612 else
3613 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3614 }
3615 break;
3616
3617 case 'V':
3618 /* 16-bit unsigned immediate from a MOVT or MOVW
3619 instruction, encoded in bits 0:11 and 15:19. */
3620 {
3621 long hi = (given & 0x000f0000) >> 4;
3622 long lo = (given & 0x00000fff);
3623 long imm16 = hi | lo;
3624
3625 func (stream, "#%lu", imm16);
3626 value_in_comment = imm16;
3627 }
3628 break;
3629
3630 default:
3631 abort ();
3632 }
3633 }
3634 }
3635 else
3636 func (stream, "%c", *c);
3637 }
3638
3639 if (value_in_comment > 32 || value_in_comment < -16)
3640 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3641
3642 if (is_unpredictable)
3643 func (stream, UNPREDICTABLE_INSTRUCTION);
3644
3645 return;
3646 }
3647 }
3648 abort ();
3649 }
3650
3651 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3652
3653 static void
3654 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3655 {
3656 const struct opcode16 *insn;
3657 void *stream = info->stream;
3658 fprintf_ftype func = info->fprintf_func;
3659
3660 for (insn = thumb_opcodes; insn->assembler; insn++)
3661 if ((given & insn->mask) == insn->value)
3662 {
3663 signed long value_in_comment = 0;
3664 const char *c = insn->assembler;
3665
3666 for (; *c; c++)
3667 {
3668 int domaskpc = 0;
3669 int domasklr = 0;
3670
3671 if (*c != '%')
3672 {
3673 func (stream, "%c", *c);
3674 continue;
3675 }
3676
3677 switch (*++c)
3678 {
3679 case '%':
3680 func (stream, "%%");
3681 break;
3682
3683 case 'c':
3684 if (ifthen_state)
3685 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3686 break;
3687
3688 case 'C':
3689 if (ifthen_state)
3690 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3691 else
3692 func (stream, "s");
3693 break;
3694
3695 case 'I':
3696 {
3697 unsigned int tmp;
3698
3699 ifthen_next_state = given & 0xff;
3700 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3701 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3702 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3703 }
3704 break;
3705
3706 case 'x':
3707 if (ifthen_next_state)
3708 func (stream, "\t; unpredictable branch in IT block\n");
3709 break;
3710
3711 case 'X':
3712 if (ifthen_state)
3713 func (stream, "\t; unpredictable <IT:%s>",
3714 arm_conditional[IFTHEN_COND]);
3715 break;
3716
3717 case 'S':
3718 {
3719 long reg;
3720
3721 reg = (given >> 3) & 0x7;
3722 if (given & (1 << 6))
3723 reg += 8;
3724
3725 func (stream, "%s", arm_regnames[reg]);
3726 }
3727 break;
3728
3729 case 'D':
3730 {
3731 long reg;
3732
3733 reg = given & 0x7;
3734 if (given & (1 << 7))
3735 reg += 8;
3736
3737 func (stream, "%s", arm_regnames[reg]);
3738 }
3739 break;
3740
3741 case 'N':
3742 if (given & (1 << 8))
3743 domasklr = 1;
3744 /* Fall through. */
3745 case 'O':
3746 if (*c == 'O' && (given & (1 << 8)))
3747 domaskpc = 1;
3748 /* Fall through. */
3749 case 'M':
3750 {
3751 int started = 0;
3752 int reg;
3753
3754 func (stream, "{");
3755
3756 /* It would be nice if we could spot
3757 ranges, and generate the rS-rE format: */
3758 for (reg = 0; (reg < 8); reg++)
3759 if ((given & (1 << reg)) != 0)
3760 {
3761 if (started)
3762 func (stream, ", ");
3763 started = 1;
3764 func (stream, "%s", arm_regnames[reg]);
3765 }
3766
3767 if (domasklr)
3768 {
3769 if (started)
3770 func (stream, ", ");
3771 started = 1;
3772 func (stream, "%s", arm_regnames[14] /* "lr" */);
3773 }
3774
3775 if (domaskpc)
3776 {
3777 if (started)
3778 func (stream, ", ");
3779 func (stream, "%s", arm_regnames[15] /* "pc" */);
3780 }
3781
3782 func (stream, "}");
3783 }
3784 break;
3785
3786 case 'W':
3787 /* Print writeback indicator for a LDMIA. We are doing a
3788 writeback if the base register is not in the register
3789 mask. */
3790 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3791 func (stream, "!");
3792 break;
3793
3794 case 'b':
3795 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3796 {
3797 bfd_vma address = (pc + 4
3798 + ((given & 0x00f8) >> 2)
3799 + ((given & 0x0200) >> 3));
3800 info->print_address_func (address, info);
3801 }
3802 break;
3803
3804 case 's':
3805 /* Right shift immediate -- bits 6..10; 1-31 print
3806 as themselves, 0 prints as 32. */
3807 {
3808 long imm = (given & 0x07c0) >> 6;
3809 if (imm == 0)
3810 imm = 32;
3811 func (stream, "#%ld", imm);
3812 }
3813 break;
3814
3815 case '0': case '1': case '2': case '3': case '4':
3816 case '5': case '6': case '7': case '8': case '9':
3817 {
3818 int bitstart = *c++ - '0';
3819 int bitend = 0;
3820
3821 while (*c >= '0' && *c <= '9')
3822 bitstart = (bitstart * 10) + *c++ - '0';
3823
3824 switch (*c)
3825 {
3826 case '-':
3827 {
3828 bfd_vma reg;
3829
3830 c++;
3831 while (*c >= '0' && *c <= '9')
3832 bitend = (bitend * 10) + *c++ - '0';
3833 if (!bitend)
3834 abort ();
3835 reg = given >> bitstart;
3836 reg &= (2 << (bitend - bitstart)) - 1;
3837
3838 switch (*c)
3839 {
3840 case 'r':
3841 func (stream, "%s", arm_regnames[reg]);
3842 break;
3843
3844 case 'd':
3845 func (stream, "%ld", (long) reg);
3846 value_in_comment = reg;
3847 break;
3848
3849 case 'H':
3850 func (stream, "%ld", (long) (reg << 1));
3851 value_in_comment = reg << 1;
3852 break;
3853
3854 case 'W':
3855 func (stream, "%ld", (long) (reg << 2));
3856 value_in_comment = reg << 2;
3857 break;
3858
3859 case 'a':
3860 /* PC-relative address -- the bottom two
3861 bits of the address are dropped
3862 before the calculation. */
3863 info->print_address_func
3864 (((pc + 4) & ~3) + (reg << 2), info);
3865 value_in_comment = 0;
3866 break;
3867
3868 case 'x':
3869 func (stream, "0x%04lx", (long) reg);
3870 break;
3871
3872 case 'B':
3873 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3874 info->print_address_func (reg * 2 + pc + 4, info);
3875 value_in_comment = 0;
3876 break;
3877
3878 case 'c':
3879 func (stream, "%s", arm_conditional [reg]);
3880 break;
3881
3882 default:
3883 abort ();
3884 }
3885 }
3886 break;
3887
3888 case '\'':
3889 c++;
3890 if ((given & (1 << bitstart)) != 0)
3891 func (stream, "%c", *c);
3892 break;
3893
3894 case '?':
3895 ++c;
3896 if ((given & (1 << bitstart)) != 0)
3897 func (stream, "%c", *c++);
3898 else
3899 func (stream, "%c", *++c);
3900 break;
3901
3902 default:
3903 abort ();
3904 }
3905 }
3906 break;
3907
3908 default:
3909 abort ();
3910 }
3911 }
3912
3913 if (value_in_comment > 32 || value_in_comment < -16)
3914 func (stream, "\t; 0x%lx", value_in_comment);
3915 return;
3916 }
3917
3918 /* No match. */
3919 abort ();
3920 }
3921
3922 /* Return the name of an V7M special register. */
3923
3924 static const char *
3925 psr_name (int regno)
3926 {
3927 switch (regno)
3928 {
3929 case 0: return "APSR";
3930 case 1: return "IAPSR";
3931 case 2: return "EAPSR";
3932 case 3: return "PSR";
3933 case 5: return "IPSR";
3934 case 6: return "EPSR";
3935 case 7: return "IEPSR";
3936 case 8: return "MSP";
3937 case 9: return "PSP";
3938 case 16: return "PRIMASK";
3939 case 17: return "BASEPRI";
3940 case 18: return "BASEPRI_MAX";
3941 case 19: return "FAULTMASK";
3942 case 20: return "CONTROL";
3943 default: return "<unknown>";
3944 }
3945 }
3946
3947 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3948
3949 static void
3950 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3951 {
3952 const struct opcode32 *insn;
3953 void *stream = info->stream;
3954 fprintf_ftype func = info->fprintf_func;
3955
3956 if (print_insn_coprocessor (pc, info, given, TRUE))
3957 return;
3958
3959 if (print_insn_neon (info, given, TRUE))
3960 return;
3961
3962 for (insn = thumb32_opcodes; insn->assembler; insn++)
3963 if ((given & insn->mask) == insn->value)
3964 {
3965 bfd_boolean is_unpredictable = FALSE;
3966 signed long value_in_comment = 0;
3967 const char *c = insn->assembler;
3968
3969 for (; *c; c++)
3970 {
3971 if (*c != '%')
3972 {
3973 func (stream, "%c", *c);
3974 continue;
3975 }
3976
3977 switch (*++c)
3978 {
3979 case '%':
3980 func (stream, "%%");
3981 break;
3982
3983 case 'c':
3984 if (ifthen_state)
3985 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3986 break;
3987
3988 case 'x':
3989 if (ifthen_next_state)
3990 func (stream, "\t; unpredictable branch in IT block\n");
3991 break;
3992
3993 case 'X':
3994 if (ifthen_state)
3995 func (stream, "\t; unpredictable <IT:%s>",
3996 arm_conditional[IFTHEN_COND]);
3997 break;
3998
3999 case 'I':
4000 {
4001 unsigned int imm12 = 0;
4002
4003 imm12 |= (given & 0x000000ffu);
4004 imm12 |= (given & 0x00007000u) >> 4;
4005 imm12 |= (given & 0x04000000u) >> 15;
4006 func (stream, "#%u", imm12);
4007 value_in_comment = imm12;
4008 }
4009 break;
4010
4011 case 'M':
4012 {
4013 unsigned int bits = 0, imm, imm8, mod;
4014
4015 bits |= (given & 0x000000ffu);
4016 bits |= (given & 0x00007000u) >> 4;
4017 bits |= (given & 0x04000000u) >> 15;
4018 imm8 = (bits & 0x0ff);
4019 mod = (bits & 0xf00) >> 8;
4020 switch (mod)
4021 {
4022 case 0: imm = imm8; break;
4023 case 1: imm = ((imm8 << 16) | imm8); break;
4024 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
4025 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
4026 default:
4027 mod = (bits & 0xf80) >> 7;
4028 imm8 = (bits & 0x07f) | 0x80;
4029 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
4030 }
4031 func (stream, "#%u", imm);
4032 value_in_comment = imm;
4033 }
4034 break;
4035
4036 case 'J':
4037 {
4038 unsigned int imm = 0;
4039
4040 imm |= (given & 0x000000ffu);
4041 imm |= (given & 0x00007000u) >> 4;
4042 imm |= (given & 0x04000000u) >> 15;
4043 imm |= (given & 0x000f0000u) >> 4;
4044 func (stream, "#%u", imm);
4045 value_in_comment = imm;
4046 }
4047 break;
4048
4049 case 'K':
4050 {
4051 unsigned int imm = 0;
4052
4053 imm |= (given & 0x000f0000u) >> 16;
4054 imm |= (given & 0x00000ff0u) >> 0;
4055 imm |= (given & 0x0000000fu) << 12;
4056 func (stream, "#%u", imm);
4057 value_in_comment = imm;
4058 }
4059 break;
4060
4061 case 'V':
4062 {
4063 unsigned int imm = 0;
4064
4065 imm |= (given & 0x00000fffu);
4066 imm |= (given & 0x000f0000u) >> 4;
4067 func (stream, "#%u", imm);
4068 value_in_comment = imm;
4069 }
4070 break;
4071
4072 case 'S':
4073 {
4074 unsigned int reg = (given & 0x0000000fu);
4075 unsigned int stp = (given & 0x00000030u) >> 4;
4076 unsigned int imm = 0;
4077 imm |= (given & 0x000000c0u) >> 6;
4078 imm |= (given & 0x00007000u) >> 10;
4079
4080 func (stream, "%s", arm_regnames[reg]);
4081 switch (stp)
4082 {
4083 case 0:
4084 if (imm > 0)
4085 func (stream, ", lsl #%u", imm);
4086 break;
4087
4088 case 1:
4089 if (imm == 0)
4090 imm = 32;
4091 func (stream, ", lsr #%u", imm);
4092 break;
4093
4094 case 2:
4095 if (imm == 0)
4096 imm = 32;
4097 func (stream, ", asr #%u", imm);
4098 break;
4099
4100 case 3:
4101 if (imm == 0)
4102 func (stream, ", rrx");
4103 else
4104 func (stream, ", ror #%u", imm);
4105 }
4106 }
4107 break;
4108
4109 case 'a':
4110 {
4111 unsigned int Rn = (given & 0x000f0000) >> 16;
4112 unsigned int U = ! NEGATIVE_BIT_SET;
4113 unsigned int op = (given & 0x00000f00) >> 8;
4114 unsigned int i12 = (given & 0x00000fff);
4115 unsigned int i8 = (given & 0x000000ff);
4116 bfd_boolean writeback = FALSE, postind = FALSE;
4117 bfd_vma offset = 0;
4118
4119 func (stream, "[%s", arm_regnames[Rn]);
4120 if (U) /* 12-bit positive immediate offset. */
4121 {
4122 offset = i12;
4123 if (Rn != 15)
4124 value_in_comment = offset;
4125 }
4126 else if (Rn == 15) /* 12-bit negative immediate offset. */
4127 offset = - (int) i12;
4128 else if (op == 0x0) /* Shifted register offset. */
4129 {
4130 unsigned int Rm = (i8 & 0x0f);
4131 unsigned int sh = (i8 & 0x30) >> 4;
4132
4133 func (stream, ", %s", arm_regnames[Rm]);
4134 if (sh)
4135 func (stream, ", lsl #%u", sh);
4136 func (stream, "]");
4137 break;
4138 }
4139 else switch (op)
4140 {
4141 case 0xE: /* 8-bit positive immediate offset. */
4142 offset = i8;
4143 break;
4144
4145 case 0xC: /* 8-bit negative immediate offset. */
4146 offset = -i8;
4147 break;
4148
4149 case 0xF: /* 8-bit + preindex with wb. */
4150 offset = i8;
4151 writeback = TRUE;
4152 break;
4153
4154 case 0xD: /* 8-bit - preindex with wb. */
4155 offset = -i8;
4156 writeback = TRUE;
4157 break;
4158
4159 case 0xB: /* 8-bit + postindex. */
4160 offset = i8;
4161 postind = TRUE;
4162 break;
4163
4164 case 0x9: /* 8-bit - postindex. */
4165 offset = -i8;
4166 postind = TRUE;
4167 break;
4168
4169 default:
4170 func (stream, ", <undefined>]");
4171 goto skip;
4172 }
4173
4174 if (postind)
4175 func (stream, "], #%d", (int) offset);
4176 else
4177 {
4178 if (offset)
4179 func (stream, ", #%d", (int) offset);
4180 func (stream, writeback ? "]!" : "]");
4181 }
4182
4183 if (Rn == 15)
4184 {
4185 func (stream, "\t; ");
4186 info->print_address_func (((pc + 4) & ~3) + offset, info);
4187 }
4188 }
4189 skip:
4190 break;
4191
4192 case 'A':
4193 {
4194 unsigned int U = ! NEGATIVE_BIT_SET;
4195 unsigned int W = WRITEBACK_BIT_SET;
4196 unsigned int Rn = (given & 0x000f0000) >> 16;
4197 unsigned int off = (given & 0x000000ff);
4198
4199 func (stream, "[%s", arm_regnames[Rn]);
4200
4201 if (PRE_BIT_SET)
4202 {
4203 if (off || !U)
4204 {
4205 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4206 value_in_comment = off * 4 * U ? 1 : -1;
4207 }
4208 func (stream, "]");
4209 if (W)
4210 func (stream, "!");
4211 }
4212 else
4213 {
4214 func (stream, "], ");
4215 if (W)
4216 {
4217 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4218 value_in_comment = off * 4 * U ? 1 : -1;
4219 }
4220 else
4221 {
4222 func (stream, "{%u}", off);
4223 value_in_comment = off;
4224 }
4225 }
4226 }
4227 break;
4228
4229 case 'w':
4230 {
4231 unsigned int Sbit = (given & 0x01000000) >> 24;
4232 unsigned int type = (given & 0x00600000) >> 21;
4233
4234 switch (type)
4235 {
4236 case 0: func (stream, Sbit ? "sb" : "b"); break;
4237 case 1: func (stream, Sbit ? "sh" : "h"); break;
4238 case 2:
4239 if (Sbit)
4240 func (stream, "??");
4241 break;
4242 case 3:
4243 func (stream, "??");
4244 break;
4245 }
4246 }
4247 break;
4248
4249 case 'm':
4250 {
4251 int started = 0;
4252 int reg;
4253
4254 func (stream, "{");
4255 for (reg = 0; reg < 16; reg++)
4256 if ((given & (1 << reg)) != 0)
4257 {
4258 if (started)
4259 func (stream, ", ");
4260 started = 1;
4261 func (stream, "%s", arm_regnames[reg]);
4262 }
4263 func (stream, "}");
4264 }
4265 break;
4266
4267 case 'E':
4268 {
4269 unsigned int msb = (given & 0x0000001f);
4270 unsigned int lsb = 0;
4271
4272 lsb |= (given & 0x000000c0u) >> 6;
4273 lsb |= (given & 0x00007000u) >> 10;
4274 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4275 }
4276 break;
4277
4278 case 'F':
4279 {
4280 unsigned int width = (given & 0x0000001f) + 1;
4281 unsigned int lsb = 0;
4282
4283 lsb |= (given & 0x000000c0u) >> 6;
4284 lsb |= (given & 0x00007000u) >> 10;
4285 func (stream, "#%u, #%u", lsb, width);
4286 }
4287 break;
4288
4289 case 'b':
4290 {
4291 unsigned int S = (given & 0x04000000u) >> 26;
4292 unsigned int J1 = (given & 0x00002000u) >> 13;
4293 unsigned int J2 = (given & 0x00000800u) >> 11;
4294 bfd_vma offset = 0;
4295
4296 offset |= !S << 20;
4297 offset |= J2 << 19;
4298 offset |= J1 << 18;
4299 offset |= (given & 0x003f0000) >> 4;
4300 offset |= (given & 0x000007ff) << 1;
4301 offset -= (1 << 20);
4302
4303 info->print_address_func (pc + 4 + offset, info);
4304 }
4305 break;
4306
4307 case 'B':
4308 {
4309 unsigned int S = (given & 0x04000000u) >> 26;
4310 unsigned int I1 = (given & 0x00002000u) >> 13;
4311 unsigned int I2 = (given & 0x00000800u) >> 11;
4312 bfd_vma offset = 0;
4313
4314 offset |= !S << 24;
4315 offset |= !(I1 ^ S) << 23;
4316 offset |= !(I2 ^ S) << 22;
4317 offset |= (given & 0x03ff0000u) >> 4;
4318 offset |= (given & 0x000007ffu) << 1;
4319 offset -= (1 << 24);
4320 offset += pc + 4;
4321
4322 /* BLX target addresses are always word aligned. */
4323 if ((given & 0x00001000u) == 0)
4324 offset &= ~2u;
4325
4326 info->print_address_func (offset, info);
4327 }
4328 break;
4329
4330 case 's':
4331 {
4332 unsigned int shift = 0;
4333
4334 shift |= (given & 0x000000c0u) >> 6;
4335 shift |= (given & 0x00007000u) >> 10;
4336 if (WRITEBACK_BIT_SET)
4337 func (stream, ", asr #%u", shift);
4338 else if (shift)
4339 func (stream, ", lsl #%u", shift);
4340 /* else print nothing - lsl #0 */
4341 }
4342 break;
4343
4344 case 'R':
4345 {
4346 unsigned int rot = (given & 0x00000030) >> 4;
4347
4348 if (rot)
4349 func (stream, ", ror #%u", rot * 8);
4350 }
4351 break;
4352
4353 case 'U':
4354 if ((given & 0xf0) == 0x60)
4355 {
4356 switch (given & 0xf)
4357 {
4358 case 0xf: func (stream, "sy"); break;
4359 default:
4360 func (stream, "#%d", (int) given & 0xf);
4361 break;
4362 }
4363 }
4364 else
4365 {
4366 const char * opt = data_barrier_option (given & 0xf);
4367 if (opt != NULL)
4368 func (stream, "%s", opt);
4369 else
4370 func (stream, "#%d", (int) given & 0xf);
4371 }
4372 break;
4373
4374 case 'C':
4375 if ((given & 0xff) == 0)
4376 {
4377 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4378 if (given & 0x800)
4379 func (stream, "f");
4380 if (given & 0x400)
4381 func (stream, "s");
4382 if (given & 0x200)
4383 func (stream, "x");
4384 if (given & 0x100)
4385 func (stream, "c");
4386 }
4387 else if ((given & 0x20) == 0x20)
4388 {
4389 char const* name;
4390 unsigned sysm = (given & 0xf00) >> 8;
4391
4392 sysm |= (given & 0x30);
4393 sysm |= (given & 0x00100000) >> 14;
4394 name = banked_regname (sysm);
4395
4396 if (name != NULL)
4397 func (stream, "%s", name);
4398 else
4399 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
4400 }
4401 else
4402 {
4403 func (stream, "%s", psr_name (given & 0xff));
4404 }
4405 break;
4406
4407 case 'D':
4408 if (((given & 0xff) == 0)
4409 || ((given & 0x20) == 0x20))
4410 {
4411 char const* name;
4412 unsigned sm = (given & 0xf0000) >> 16;
4413
4414 sm |= (given & 0x30);
4415 sm |= (given & 0x00100000) >> 14;
4416 name = banked_regname (sm);
4417
4418 if (name != NULL)
4419 func (stream, "%s", name);
4420 else
4421 func (stream, "(UNDEF: %lu)", (unsigned long) sm);
4422 }
4423 else
4424 func (stream, "%s", psr_name (given & 0xff));
4425 break;
4426
4427 case '0': case '1': case '2': case '3': case '4':
4428 case '5': case '6': case '7': case '8': case '9':
4429 {
4430 int width;
4431 unsigned long val;
4432
4433 c = arm_decode_bitfield (c, given, &val, &width);
4434
4435 switch (*c)
4436 {
4437 case 'd':
4438 func (stream, "%lu", val);
4439 value_in_comment = val;
4440 break;
4441
4442 case 'W':
4443 func (stream, "%lu", val * 4);
4444 value_in_comment = val * 4;
4445 break;
4446
4447 case 'S':
4448 if (val == 13)
4449 is_unpredictable = TRUE;
4450 /* Fall through. */
4451 case 'R':
4452 if (val == 15)
4453 is_unpredictable = TRUE;
4454 /* Fall through. */
4455 case 'r':
4456 func (stream, "%s", arm_regnames[val]);
4457 break;
4458
4459 case 'c':
4460 func (stream, "%s", arm_conditional[val]);
4461 break;
4462
4463 case '\'':
4464 c++;
4465 if (val == ((1ul << width) - 1))
4466 func (stream, "%c", *c);
4467 break;
4468
4469 case '`':
4470 c++;
4471 if (val == 0)
4472 func (stream, "%c", *c);
4473 break;
4474
4475 case '?':
4476 func (stream, "%c", c[(1 << width) - (int) val]);
4477 c += 1 << width;
4478 break;
4479
4480 case 'x':
4481 func (stream, "0x%lx", val & 0xffffffffUL);
4482 break;
4483
4484 default:
4485 abort ();
4486 }
4487 }
4488 break;
4489
4490 case 'L':
4491 /* PR binutils/12534
4492 If we have a PC relative offset in an LDRD or STRD
4493 instructions then display the decoded address. */
4494 if (((given >> 16) & 0xf) == 0xf)
4495 {
4496 bfd_vma offset = (given & 0xff) * 4;
4497
4498 if ((given & (1 << 23)) == 0)
4499 offset = - offset;
4500 func (stream, "\t; ");
4501 info->print_address_func ((pc & ~3) + 4 + offset, info);
4502 }
4503 break;
4504
4505 default:
4506 abort ();
4507 }
4508 }
4509
4510 if (value_in_comment > 32 || value_in_comment < -16)
4511 func (stream, "\t; 0x%lx", value_in_comment);
4512
4513 if (is_unpredictable)
4514 func (stream, UNPREDICTABLE_INSTRUCTION);
4515
4516 return;
4517 }
4518
4519 /* No match. */
4520 abort ();
4521 }
4522
4523 /* Print data bytes on INFO->STREAM. */
4524
4525 static void
4526 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4527 struct disassemble_info *info,
4528 long given)
4529 {
4530 switch (info->bytes_per_chunk)
4531 {
4532 case 1:
4533 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4534 break;
4535 case 2:
4536 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4537 break;
4538 case 4:
4539 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4540 break;
4541 default:
4542 abort ();
4543 }
4544 }
4545
4546 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4547 being displayed in symbol relative addresses. */
4548
4549 bfd_boolean
4550 arm_symbol_is_valid (asymbol * sym,
4551 struct disassemble_info * info ATTRIBUTE_UNUSED)
4552 {
4553 const char * name;
4554
4555 if (sym == NULL)
4556 return FALSE;
4557
4558 name = bfd_asymbol_name (sym);
4559
4560 return (name && *name != '$');
4561 }
4562
4563 /* Parse an individual disassembler option. */
4564
4565 void
4566 parse_arm_disassembler_option (char *option)
4567 {
4568 if (option == NULL)
4569 return;
4570
4571 if (CONST_STRNEQ (option, "reg-names-"))
4572 {
4573 int i;
4574
4575 option += 10;
4576
4577 for (i = NUM_ARM_REGNAMES; i--;)
4578 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4579 {
4580 regname_selected = i;
4581 break;
4582 }
4583
4584 if (i < 0)
4585 /* XXX - should break 'option' at following delimiter. */
4586 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4587 }
4588 else if (CONST_STRNEQ (option, "force-thumb"))
4589 force_thumb = 1;
4590 else if (CONST_STRNEQ (option, "no-force-thumb"))
4591 force_thumb = 0;
4592 else
4593 /* XXX - should break 'option' at following delimiter. */
4594 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4595
4596 return;
4597 }
4598
4599 /* Parse the string of disassembler options, spliting it at whitespaces
4600 or commas. (Whitespace separators supported for backwards compatibility). */
4601
4602 static void
4603 parse_disassembler_options (char *options)
4604 {
4605 if (options == NULL)
4606 return;
4607
4608 while (*options)
4609 {
4610 parse_arm_disassembler_option (options);
4611
4612 /* Skip forward to next seperator. */
4613 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4614 ++ options;
4615 /* Skip forward past seperators. */
4616 while (ISSPACE (*options) || (*options == ','))
4617 ++ options;
4618 }
4619 }
4620
4621 /* Search back through the insn stream to determine if this instruction is
4622 conditionally executed. */
4623
4624 static void
4625 find_ifthen_state (bfd_vma pc,
4626 struct disassemble_info *info,
4627 bfd_boolean little)
4628 {
4629 unsigned char b[2];
4630 unsigned int insn;
4631 int status;
4632 /* COUNT is twice the number of instructions seen. It will be odd if we
4633 just crossed an instruction boundary. */
4634 int count;
4635 int it_count;
4636 unsigned int seen_it;
4637 bfd_vma addr;
4638
4639 ifthen_address = pc;
4640 ifthen_state = 0;
4641
4642 addr = pc;
4643 count = 1;
4644 it_count = 0;
4645 seen_it = 0;
4646 /* Scan backwards looking for IT instructions, keeping track of where
4647 instruction boundaries are. We don't know if something is actually an
4648 IT instruction until we find a definite instruction boundary. */
4649 for (;;)
4650 {
4651 if (addr == 0 || info->symbol_at_address_func (addr, info))
4652 {
4653 /* A symbol must be on an instruction boundary, and will not
4654 be within an IT block. */
4655 if (seen_it && (count & 1))
4656 break;
4657
4658 return;
4659 }
4660 addr -= 2;
4661 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4662 if (status)
4663 return;
4664
4665 if (little)
4666 insn = (b[0]) | (b[1] << 8);
4667 else
4668 insn = (b[1]) | (b[0] << 8);
4669 if (seen_it)
4670 {
4671 if ((insn & 0xf800) < 0xe800)
4672 {
4673 /* Addr + 2 is an instruction boundary. See if this matches
4674 the expected boundary based on the position of the last
4675 IT candidate. */
4676 if (count & 1)
4677 break;
4678 seen_it = 0;
4679 }
4680 }
4681 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4682 {
4683 /* This could be an IT instruction. */
4684 seen_it = insn;
4685 it_count = count >> 1;
4686 }
4687 if ((insn & 0xf800) >= 0xe800)
4688 count++;
4689 else
4690 count = (count + 2) | 1;
4691 /* IT blocks contain at most 4 instructions. */
4692 if (count >= 8 && !seen_it)
4693 return;
4694 }
4695 /* We found an IT instruction. */
4696 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4697 if ((ifthen_state & 0xf) == 0)
4698 ifthen_state = 0;
4699 }
4700
4701 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4702 mapping symbol. */
4703
4704 static int
4705 is_mapping_symbol (struct disassemble_info *info, int n,
4706 enum map_type *map_type)
4707 {
4708 const char *name;
4709
4710 name = bfd_asymbol_name (info->symtab[n]);
4711 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4712 && (name[2] == 0 || name[2] == '.'))
4713 {
4714 *map_type = ((name[1] == 'a') ? MAP_ARM
4715 : (name[1] == 't') ? MAP_THUMB
4716 : MAP_DATA);
4717 return TRUE;
4718 }
4719
4720 return FALSE;
4721 }
4722
4723 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4724 Returns nonzero if *MAP_TYPE was set. */
4725
4726 static int
4727 get_map_sym_type (struct disassemble_info *info,
4728 int n,
4729 enum map_type *map_type)
4730 {
4731 /* If the symbol is in a different section, ignore it. */
4732 if (info->section != NULL && info->section != info->symtab[n]->section)
4733 return FALSE;
4734
4735 return is_mapping_symbol (info, n, map_type);
4736 }
4737
4738 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4739 Returns nonzero if *MAP_TYPE was set. */
4740
4741 static int
4742 get_sym_code_type (struct disassemble_info *info,
4743 int n,
4744 enum map_type *map_type)
4745 {
4746 elf_symbol_type *es;
4747 unsigned int type;
4748
4749 /* If the symbol is in a different section, ignore it. */
4750 if (info->section != NULL && info->section != info->symtab[n]->section)
4751 return FALSE;
4752
4753 es = *(elf_symbol_type **)(info->symtab + n);
4754 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4755
4756 /* If the symbol has function type then use that. */
4757 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4758 {
4759 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4760 *map_type = MAP_THUMB;
4761 else
4762 *map_type = MAP_ARM;
4763 return TRUE;
4764 }
4765
4766 return FALSE;
4767 }
4768
4769 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4770 of the supplied arm_feature_set structure with bitmasks indicating
4771 the support base architectures and coprocessor extensions.
4772
4773 FIXME: This could more efficiently implemented as a constant array,
4774 although it would also be less robust. */
4775
4776 static void
4777 select_arm_features (unsigned long mach,
4778 arm_feature_set * features)
4779 {
4780 #undef ARM_FEATURE
4781 #define ARM_FEATURE(ARCH,CEXT) \
4782 features->core = (ARCH); \
4783 features->coproc = (CEXT) | FPU_FPA; \
4784 return
4785
4786 switch (mach)
4787 {
4788 case bfd_mach_arm_2: ARM_ARCH_V2;
4789 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4790 case bfd_mach_arm_3: ARM_ARCH_V3;
4791 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4792 case bfd_mach_arm_4: ARM_ARCH_V4;
4793 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4794 case bfd_mach_arm_5: ARM_ARCH_V5;
4795 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4796 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4797 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4798 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4799 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4800 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4801 /* If the machine type is unknown allow all
4802 architecture types and all extensions. */
4803 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4804 default:
4805 abort ();
4806 }
4807 }
4808
4809
4810 /* NOTE: There are no checks in these routines that
4811 the relevant number of data bytes exist. */
4812
4813 static int
4814 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4815 {
4816 unsigned char b[4];
4817 long given;
4818 int status;
4819 int is_thumb = FALSE;
4820 int is_data = FALSE;
4821 int little_code;
4822 unsigned int size = 4;
4823 void (*printer) (bfd_vma, struct disassemble_info *, long);
4824 bfd_boolean found = FALSE;
4825 struct arm_private_data *private_data;
4826
4827 if (info->disassembler_options)
4828 {
4829 parse_disassembler_options (info->disassembler_options);
4830
4831 /* To avoid repeated parsing of these options, we remove them here. */
4832 info->disassembler_options = NULL;
4833 }
4834
4835 /* PR 10288: Control which instructions will be disassembled. */
4836 if (info->private_data == NULL)
4837 {
4838 static struct arm_private_data private;
4839
4840 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4841 /* If the user did not use the -m command line switch then default to
4842 disassembling all types of ARM instruction.
4843
4844 The info->mach value has to be ignored as this will be based on
4845 the default archictecture for the target and/or hints in the notes
4846 section, but it will never be greater than the current largest arm
4847 machine value (iWMMXt2), which is only equivalent to the V5TE
4848 architecture. ARM architectures have advanced beyond the machine
4849 value encoding, and these newer architectures would be ignored if
4850 the machine value was used.
4851
4852 Ie the -m switch is used to restrict which instructions will be
4853 disassembled. If it is necessary to use the -m switch to tell
4854 objdump that an ARM binary is being disassembled, eg because the
4855 input is a raw binary file, but it is also desired to disassemble
4856 all ARM instructions then use "-marm". This will select the
4857 "unknown" arm architecture which is compatible with any ARM
4858 instruction. */
4859 info->mach = bfd_mach_arm_unknown;
4860
4861 /* Compute the architecture bitmask from the machine number.
4862 Note: This assumes that the machine number will not change
4863 during disassembly.... */
4864 select_arm_features (info->mach, & private.features);
4865
4866 private.has_mapping_symbols = -1;
4867 private.last_mapping_sym = -1;
4868 private.last_mapping_addr = 0;
4869
4870 info->private_data = & private;
4871 }
4872
4873 private_data = info->private_data;
4874
4875 /* Decide if our code is going to be little-endian, despite what the
4876 function argument might say. */
4877 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4878
4879 /* For ELF, consult the symbol table to determine what kind of code
4880 or data we have. */
4881 if (info->symtab_size != 0
4882 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4883 {
4884 bfd_vma addr;
4885 int n, start;
4886 int last_sym = -1;
4887 enum map_type type = MAP_ARM;
4888
4889 /* Start scanning at the start of the function, or wherever
4890 we finished last time. */
4891 /* PR 14006. When the address is 0 we are either at the start of the
4892 very first function, or else the first function in a new, unlinked
4893 executable section (eg because uf -ffunction-sections). Either way
4894 start scanning from the beginning of the symbol table, not where we
4895 left off last time. */
4896 if (pc == 0)
4897 start = 0;
4898 else
4899 {
4900 start = info->symtab_pos + 1;
4901 if (start < private_data->last_mapping_sym)
4902 start = private_data->last_mapping_sym;
4903 }
4904 found = FALSE;
4905
4906 /* First, look for mapping symbols. */
4907 if (private_data->has_mapping_symbols != 0)
4908 {
4909 /* Scan up to the location being disassembled. */
4910 for (n = start; n < info->symtab_size; n++)
4911 {
4912 addr = bfd_asymbol_value (info->symtab[n]);
4913 if (addr > pc)
4914 break;
4915 if (get_map_sym_type (info, n, &type))
4916 {
4917 last_sym = n;
4918 found = TRUE;
4919 }
4920 }
4921
4922 if (!found)
4923 {
4924 /* No mapping symbol found at this address. Look backwards
4925 for a preceding one. */
4926 for (n = start - 1; n >= 0; n--)
4927 {
4928 if (get_map_sym_type (info, n, &type))
4929 {
4930 last_sym = n;
4931 found = TRUE;
4932 break;
4933 }
4934 }
4935 }
4936
4937 if (found)
4938 private_data->has_mapping_symbols = 1;
4939
4940 /* No mapping symbols were found. A leading $d may be
4941 omitted for sections which start with data; but for
4942 compatibility with legacy and stripped binaries, only
4943 assume the leading $d if there is at least one mapping
4944 symbol in the file. */
4945 if (!found && private_data->has_mapping_symbols == -1)
4946 {
4947 /* Look for mapping symbols, in any section. */
4948 for (n = 0; n < info->symtab_size; n++)
4949 if (is_mapping_symbol (info, n, &type))
4950 {
4951 private_data->has_mapping_symbols = 1;
4952 break;
4953 }
4954 if (private_data->has_mapping_symbols == -1)
4955 private_data->has_mapping_symbols = 0;
4956 }
4957
4958 if (!found && private_data->has_mapping_symbols == 1)
4959 {
4960 type = MAP_DATA;
4961 found = TRUE;
4962 }
4963 }
4964
4965 /* Next search for function symbols to separate ARM from Thumb
4966 in binaries without mapping symbols. */
4967 if (!found)
4968 {
4969 /* Scan up to the location being disassembled. */
4970 for (n = start; n < info->symtab_size; n++)
4971 {
4972 addr = bfd_asymbol_value (info->symtab[n]);
4973 if (addr > pc)
4974 break;
4975 if (get_sym_code_type (info, n, &type))
4976 {
4977 last_sym = n;
4978 found = TRUE;
4979 }
4980 }
4981
4982 if (!found)
4983 {
4984 /* No mapping symbol found at this address. Look backwards
4985 for a preceding one. */
4986 for (n = start - 1; n >= 0; n--)
4987 {
4988 if (get_sym_code_type (info, n, &type))
4989 {
4990 last_sym = n;
4991 found = TRUE;
4992 break;
4993 }
4994 }
4995 }
4996 }
4997
4998 private_data->last_mapping_sym = last_sym;
4999 private_data->last_type = type;
5000 is_thumb = (private_data->last_type == MAP_THUMB);
5001 is_data = (private_data->last_type == MAP_DATA);
5002
5003 /* Look a little bit ahead to see if we should print out
5004 two or four bytes of data. If there's a symbol,
5005 mapping or otherwise, after two bytes then don't
5006 print more. */
5007 if (is_data)
5008 {
5009 size = 4 - (pc & 3);
5010 for (n = last_sym + 1; n < info->symtab_size; n++)
5011 {
5012 addr = bfd_asymbol_value (info->symtab[n]);
5013 if (addr > pc
5014 && (info->section == NULL
5015 || info->section == info->symtab[n]->section))
5016 {
5017 if (addr - pc < size)
5018 size = addr - pc;
5019 break;
5020 }
5021 }
5022 /* If the next symbol is after three bytes, we need to
5023 print only part of the data, so that we can use either
5024 .byte or .short. */
5025 if (size == 3)
5026 size = (pc & 1) ? 1 : 2;
5027 }
5028 }
5029
5030 if (info->symbols != NULL)
5031 {
5032 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
5033 {
5034 coff_symbol_type * cs;
5035
5036 cs = coffsymbol (*info->symbols);
5037 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
5038 || cs->native->u.syment.n_sclass == C_THUMBSTAT
5039 || cs->native->u.syment.n_sclass == C_THUMBLABEL
5040 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
5041 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
5042 }
5043 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
5044 && !found)
5045 {
5046 /* If no mapping symbol has been found then fall back to the type
5047 of the function symbol. */
5048 elf_symbol_type * es;
5049 unsigned int type;
5050
5051 es = *(elf_symbol_type **)(info->symbols);
5052 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
5053
5054 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
5055 == ST_BRANCH_TO_THUMB)
5056 || type == STT_ARM_16BIT);
5057 }
5058 }
5059
5060 if (force_thumb)
5061 is_thumb = TRUE;
5062
5063 if (is_data)
5064 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5065 else
5066 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5067
5068 info->bytes_per_line = 4;
5069
5070 /* PR 10263: Disassemble data if requested to do so by the user. */
5071 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
5072 {
5073 int i;
5074
5075 /* Size was already set above. */
5076 info->bytes_per_chunk = size;
5077 printer = print_insn_data;
5078
5079 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
5080 given = 0;
5081 if (little)
5082 for (i = size - 1; i >= 0; i--)
5083 given = b[i] | (given << 8);
5084 else
5085 for (i = 0; i < (int) size; i++)
5086 given = b[i] | (given << 8);
5087 }
5088 else if (!is_thumb)
5089 {
5090 /* In ARM mode endianness is a straightforward issue: the instruction
5091 is four bytes long and is either ordered 0123 or 3210. */
5092 printer = print_insn_arm;
5093 info->bytes_per_chunk = 4;
5094 size = 4;
5095
5096 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
5097 if (little_code)
5098 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
5099 else
5100 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
5101 }
5102 else
5103 {
5104 /* In Thumb mode we have the additional wrinkle of two
5105 instruction lengths. Fortunately, the bits that determine
5106 the length of the current instruction are always to be found
5107 in the first two bytes. */
5108 printer = print_insn_thumb16;
5109 info->bytes_per_chunk = 2;
5110 size = 2;
5111
5112 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
5113 if (little_code)
5114 given = (b[0]) | (b[1] << 8);
5115 else
5116 given = (b[1]) | (b[0] << 8);
5117
5118 if (!status)
5119 {
5120 /* These bit patterns signal a four-byte Thumb
5121 instruction. */
5122 if ((given & 0xF800) == 0xF800
5123 || (given & 0xF800) == 0xF000
5124 || (given & 0xF800) == 0xE800)
5125 {
5126 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
5127 if (little_code)
5128 given = (b[0]) | (b[1] << 8) | (given << 16);
5129 else
5130 given = (b[1]) | (b[0] << 8) | (given << 16);
5131
5132 printer = print_insn_thumb32;
5133 size = 4;
5134 }
5135 }
5136
5137 if (ifthen_address != pc)
5138 find_ifthen_state (pc, info, little_code);
5139
5140 if (ifthen_state)
5141 {
5142 if ((ifthen_state & 0xf) == 0x8)
5143 ifthen_next_state = 0;
5144 else
5145 ifthen_next_state = (ifthen_state & 0xe0)
5146 | ((ifthen_state & 0xf) << 1);
5147 }
5148 }
5149
5150 if (status)
5151 {
5152 info->memory_error_func (status, pc, info);
5153 return -1;
5154 }
5155 if (info->flags & INSN_HAS_RELOC)
5156 /* If the instruction has a reloc associated with it, then
5157 the offset field in the instruction will actually be the
5158 addend for the reloc. (We are using REL type relocs).
5159 In such cases, we can ignore the pc when computing
5160 addresses, since the addend is not currently pc-relative. */
5161 pc = 0;
5162
5163 printer (pc, info, given);
5164
5165 if (is_thumb)
5166 {
5167 ifthen_state = ifthen_next_state;
5168 ifthen_address += size;
5169 }
5170 return size;
5171 }
5172
5173 int
5174 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
5175 {
5176 /* Detect BE8-ness and record it in the disassembler info. */
5177 if (info->flavour == bfd_target_elf_flavour
5178 && info->section != NULL
5179 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
5180 info->endian_code = BFD_ENDIAN_LITTLE;
5181
5182 return print_insn (pc, info, FALSE);
5183 }
5184
5185 int
5186 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
5187 {
5188 return print_insn (pc, info, TRUE);
5189 }
5190
5191 void
5192 print_arm_disassembler_options (FILE *stream)
5193 {
5194 int i;
5195
5196 fprintf (stream, _("\n\
5197 The following ARM specific disassembler options are supported for use with\n\
5198 the -M switch:\n"));
5199
5200 for (i = NUM_ARM_REGNAMES; i--;)
5201 fprintf (stream, " reg-names-%s %*c%s\n",
5202 regnames[i].name,
5203 (int)(14 - strlen (regnames[i].name)), ' ',
5204 regnames[i].description);
5205
5206 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
5207 fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");
5208 }
5209