* gdb.mi/mi-var-create-rtti.exp: Create a variable of
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012
4 Free Software Foundation, Inc.
5 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
6 Modification by James G. Smith (jsmith@cygnus.co.uk)
7
8 This file is part of libopcodes.
9
10 This library is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
14
15 It is distributed in the hope that it will be useful, but WITHOUT
16 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
18 License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
23 MA 02110-1301, USA. */
24
25 #include "sysdep.h"
26
27 #include "dis-asm.h"
28 #include "opcode/arm.h"
29 #include "opintl.h"
30 #include "safe-ctype.h"
31 #include "floatformat.h"
32
33 /* FIXME: This shouldn't be done here. */
34 #include "coff/internal.h"
35 #include "libcoff.h"
36 #include "elf-bfd.h"
37 #include "elf/internal.h"
38 #include "elf/arm.h"
39
40 /* FIXME: Belongs in global header. */
41 #ifndef strneq
42 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
43 #endif
44
45 #ifndef NUM_ELEM
46 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
47 #endif
48
49 /* Cached mapping symbol state. */
50 enum map_type
51 {
52 MAP_ARM,
53 MAP_THUMB,
54 MAP_DATA
55 };
56
57 struct arm_private_data
58 {
59 /* The features to use when disassembling optional instructions. */
60 arm_feature_set features;
61
62 /* Whether any mapping symbols are present in the provided symbol
63 table. -1 if we do not know yet, otherwise 0 or 1. */
64 int has_mapping_symbols;
65
66 /* Track the last type (although this doesn't seem to be useful) */
67 enum map_type last_type;
68
69 /* Tracking symbol table information */
70 int last_mapping_sym;
71 bfd_vma last_mapping_addr;
72 };
73
74 struct opcode32
75 {
76 unsigned long arch; /* Architecture defining this insn. */
77 unsigned long value; /* If arch == 0 then value is a sentinel. */
78 unsigned long mask; /* Recognise insn if (op & mask) == value. */
79 const char * assembler; /* How to disassemble this insn. */
80 };
81
82 struct opcode16
83 {
84 unsigned long arch; /* Architecture defining this insn. */
85 unsigned short value, mask; /* Recognise insn if (op & mask) == value. */
86 const char *assembler; /* How to disassemble this insn. */
87 };
88
89 /* print_insn_coprocessor recognizes the following format control codes:
90
91 %% %
92
93 %c print condition code (always bits 28-31 in ARM mode)
94 %q print shifter argument
95 %u print condition code (unconditional in ARM mode,
96 UNPREDICTABLE if not AL in Thumb)
97 %A print address for ldc/stc/ldf/stf instruction
98 %B print vstm/vldm register list
99 %I print cirrus signed shift immediate: bits 0..3|4..6
100 %F print the COUNT field of a LFM/SFM instruction.
101 %P print floating point precision in arithmetic insn
102 %Q print floating point precision in ldf/stf insn
103 %R print floating point rounding mode
104
105 %<bitfield>c print as a condition code (for vsel)
106 %<bitfield>r print as an ARM register
107 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
108 %<bitfield>ru as %<>r but each u register must be unique.
109 %<bitfield>d print the bitfield in decimal
110 %<bitfield>k print immediate for VFPv3 conversion instruction
111 %<bitfield>x print the bitfield in hex
112 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
113 %<bitfield>f print a floating point constant if >7 else a
114 floating point register
115 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
116 %<bitfield>g print as an iWMMXt 64-bit register
117 %<bitfield>G print as an iWMMXt general purpose or control register
118 %<bitfield>D print as a NEON D register
119 %<bitfield>Q print as a NEON Q register
120
121 %y<code> print a single precision VFP reg.
122 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
123 %z<code> print a double precision VFP reg
124 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
125
126 %<bitfield>'c print specified char iff bitfield is all ones
127 %<bitfield>`c print specified char iff bitfield is all zeroes
128 %<bitfield>?ab... select from array of values in big endian order
129
130 %L print as an iWMMXt N/M width field.
131 %Z print the Immediate of a WSHUFH instruction.
132 %l like 'A' except use byte offsets for 'B' & 'H'
133 versions.
134 %i print 5-bit immediate in bits 8,3..0
135 (print "32" when 0)
136 %r print register offset address for wldt/wstr instruction. */
137
138 enum opcode_sentinel_enum
139 {
140 SENTINEL_IWMMXT_START = 1,
141 SENTINEL_IWMMXT_END,
142 SENTINEL_GENERIC_START
143 } opcode_sentinels;
144
145 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
146 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
147
148 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
149
150 static const struct opcode32 coprocessor_opcodes[] =
151 {
152 /* XScale instructions. */
153 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
154 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
155 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
156 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
157 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
158
159 /* Intel Wireless MMX technology instructions. */
160 { 0, SENTINEL_IWMMXT_START, 0, "" },
161 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
162 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
163 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
164 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
165 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
166 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
167 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
168 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
169 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
170 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
171 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
172 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
173 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
174 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
175 {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
176 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
177 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
178 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
179 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
180 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
182 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
186 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
187 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
188 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
189 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
190 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
191 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
192 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
193 {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
194 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
196 {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
197 {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
199 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
200 {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
202 {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
203 {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
205 {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
206 {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
207 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
208 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
209 {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
210 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
211 {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
212 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
213 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
214 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
215 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
216 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
217 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
218 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
219 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
220 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
221 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
222 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
223 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
224 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
225 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
226 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
227 {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
228 {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
229 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
230 {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
231 {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
232 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
233 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
234 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
235 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
236 { 0, SENTINEL_IWMMXT_END, 0, "" },
237
238 /* Floating point coprocessor (FPA) instructions. */
239 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
243 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
244 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
245 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
246 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
247 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
248 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
249 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
250 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
251 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
252 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
253 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
254 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
255 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
256 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
257 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
258 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
259 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
260 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
261 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
262 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
263 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
264 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
265 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
266 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
267 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
268 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
269 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
270 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
271 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
272 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
273 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
274 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
275 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
276 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
277 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
278 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
279 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
280 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
281 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
282
283 /* Register load/store. */
284 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
285 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
286 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
287 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
288 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
289 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
290 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
291 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
292 {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
293 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
294 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
295 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
296 {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
297 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
298 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
299 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
300
301 {FPU_VFP_EXT_V1xD, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
302 {FPU_VFP_EXT_V1xD, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
303 {FPU_VFP_EXT_V1xD, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
304 {FPU_VFP_EXT_V1xD, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
305
306 /* Data transfer between ARM and NEON registers. */
307 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
308 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
309 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
310 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
311 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
312 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
313 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
314 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
315 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
316 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
317 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
318 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
319 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
320 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
321 /* Half-precision conversion instructions. */
322 {FPU_VFP_EXT_ARMV8, 0x0eb20b40, 0x0fbf0f50, "vcvt%7?tb%c.f64.f16\t%z1, %y0"},
323 {FPU_VFP_EXT_ARMV8, 0x0eb30b40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f64\t%y1, %z0"},
324 {FPU_VFP_EXT_FP16, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
325 {FPU_VFP_EXT_FP16, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
326
327 /* Floating point coprocessor (VFP) instructions. */
328 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
329 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
330 {FPU_VFP_EXT_V1xD, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
331 {FPU_VFP_EXT_V1xD, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
332 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
333 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
334 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
335 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
336 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
337 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
338 {FPU_VFP_EXT_V1xD, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
339 {FPU_VFP_EXT_V1xD, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
340 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
341 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
342 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
343 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
344 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
345 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
346 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
347 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
348 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
349 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
350 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
351 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
352 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
353 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
354 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
355 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
356 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
357 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
358 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
359 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
360 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
361 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
362 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
363 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
364 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
365 {FPU_VFP_EXT_V3xD, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
366 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
367 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
368 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
369 {FPU_VFP_EXT_V3xD, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
370 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
371 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
372 {FPU_VFP_EXT_V3xD, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
373 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
374 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
375 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
376 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
377 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
378 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
379 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
380 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
381 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
382 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
383 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
384 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
385 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
386 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
387 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
388 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
389 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
390 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
391 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
392 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
393 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
394 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
395
396 /* Cirrus coprocessor instructions. */
397 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
398 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
399 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
400 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
401 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
402 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
403 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
404 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
405 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
406 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
407 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
408 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
409 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
410 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
411 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
412 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
413 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
414 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
415 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
416 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
417 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
418 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
419 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
420 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
421 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
422 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
423 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
424 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
425 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
426 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
427 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
428 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
429 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
430 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
431 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
432 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
433 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
434 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
435 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
436 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
437 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
438 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
439 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
440 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
441 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
442 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
443 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
444 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
445 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
446 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
447 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
448 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
449 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
450 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
451 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
452 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
453 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
454 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
455 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
456 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
457 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
458 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
459 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
460 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
461 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
462 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
463 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
464 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
465 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
466 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
467 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
468 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
469 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
470 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
471 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
473 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
475 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
476 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
477 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
478 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
479 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
480 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
481
482 /* VFP Fused multiply add instructions. */
483 {FPU_VFP_EXT_FMA, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
484 {FPU_VFP_EXT_FMA, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
485 {FPU_VFP_EXT_FMA, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
486 {FPU_VFP_EXT_FMA, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
487 {FPU_VFP_EXT_FMA, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
488 {FPU_VFP_EXT_FMA, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
489 {FPU_VFP_EXT_FMA, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
490 {FPU_VFP_EXT_FMA, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
491
492 /* FP v5. */
493 {FPU_VFP_EXT_ARMV8, 0xfe000a00, 0xff800f00, "vsel%20-21c%u.f32\t%y1, %y2, %y0"},
494 {FPU_VFP_EXT_ARMV8, 0xfe000b00, 0xff800f00, "vsel%20-21c%u.f64\t%z1, %z2, %z0"},
495 {FPU_VFP_EXT_ARMV8, 0xfe800a00, 0xffb00f40, "vmaxnm%u.f32\t%y1, %y2, %y0"},
496 {FPU_VFP_EXT_ARMV8, 0xfe800b00, 0xffb00f40, "vmaxnm%u.f64\t%z1, %z2, %z0"},
497 {FPU_VFP_EXT_ARMV8, 0xfe800a40, 0xffb00f40, "vminnm%u.f32\t%y1, %y2, %y0"},
498 {FPU_VFP_EXT_ARMV8, 0xfe800b40, 0xffb00f40, "vminnm%u.f64\t%z1, %z2, %z0"},
499 {FPU_VFP_EXT_ARMV8, 0xfebc0a40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f32\t%y1, %y0"},
500 {FPU_VFP_EXT_ARMV8, 0xfebc0b40, 0xffbc0f50, "vcvt%16-17?mpna%u.%7?su32.f64\t%y1, %z0"},
501 {FPU_VFP_EXT_ARMV8, 0x0eb60a40, 0x0fbe0f50, "vrint%7,16??xzr%c.f32\t%y1, %y0"},
502 {FPU_VFP_EXT_ARMV8, 0x0eb60b40, 0x0fbe0f50, "vrint%7,16??xzr%c.f64\t%z1, %z0"},
503 {FPU_VFP_EXT_ARMV8, 0xfeb80a40, 0xffbc0f50, "vrint%16-17?mpna%u.f32\t%y1, %y0"},
504 {FPU_VFP_EXT_ARMV8, 0xfeb80b40, 0xffbc0f50, "vrint%16-17?mpna%u.f64\t%z1, %z0"},
505
506 /* Generic coprocessor instructions. */
507 { 0, SENTINEL_GENERIC_START, 0, "" },
508 {ARM_EXT_V5E, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
509 {ARM_EXT_V5E, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
510 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
511 {ARM_EXT_V2, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
512 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
513 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
514 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
515 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
516
517 /* V6 coprocessor instructions. */
518 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
519 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
520
521 /* V5 coprocessor instructions. */
522 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
523 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
524 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
525 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
526 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
527
528 {0, 0, 0, 0}
529 };
530
531 /* Neon opcode table: This does not encode the top byte -- that is
532 checked by the print_insn_neon routine, as it depends on whether we are
533 doing thumb32 or arm32 disassembly. */
534
535 /* print_insn_neon recognizes the following format control codes:
536
537 %% %
538
539 %c print condition code
540 %u print condition code (unconditional in ARM mode,
541 UNPREDICTABLE if not AL in Thumb)
542 %A print v{st,ld}[1234] operands
543 %B print v{st,ld}[1234] any one operands
544 %C print v{st,ld}[1234] single->all operands
545 %D print scalar
546 %E print vmov, vmvn, vorr, vbic encoded constant
547 %F print vtbl,vtbx register list
548
549 %<bitfield>r print as an ARM register
550 %<bitfield>d print the bitfield in decimal
551 %<bitfield>e print the 2^N - bitfield in decimal
552 %<bitfield>D print as a NEON D register
553 %<bitfield>Q print as a NEON Q register
554 %<bitfield>R print as a NEON D or Q register
555 %<bitfield>Sn print byte scaled width limited by n
556 %<bitfield>Tn print short scaled width limited by n
557 %<bitfield>Un print long scaled width limited by n
558
559 %<bitfield>'c print specified char iff bitfield is all ones
560 %<bitfield>`c print specified char iff bitfield is all zeroes
561 %<bitfield>?ab... select from array of values in big endian order. */
562
563 static const struct opcode32 neon_opcodes[] =
564 {
565 /* Extract. */
566 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
567 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
568
569 /* Move data element to all lanes. */
570 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
571 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
572 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
573
574 /* Table lookup. */
575 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
576 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
577
578 /* Half-precision conversions. */
579 {FPU_VFP_EXT_FP16, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
580 {FPU_VFP_EXT_FP16, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
581
582 /* NEON fused multiply add instructions. */
583 {FPU_NEON_EXT_FMA, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
584 {FPU_NEON_EXT_FMA, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
585
586 /* Two registers, miscellaneous. */
587 {FPU_NEON_EXT_ARMV8, 0xf3ba0400, 0xffbf0c10, "vrint%7-9?p?m?zaxn%u.f32\t%12-15,22R, %0-3,5R"},
588 {FPU_NEON_EXT_ARMV8, 0xf3bb0000, 0xffbf0c10, "vcvt%8-9?mpna%u.%7?us32.f32\t%12-15,22R, %0-3,5R"},
589 {FPU_CRYPTO_EXT_ARMV8, 0xf3b00300, 0xffbf0fd0, "aese%u.8\t%12-15,22Q, %0-3,5Q"},
590 {FPU_CRYPTO_EXT_ARMV8, 0xf3b00340, 0xffbf0fd0, "aesd%u.8\t%12-15,22Q, %0-3,5Q"},
591 {FPU_CRYPTO_EXT_ARMV8, 0xf3b00380, 0xffbf0fd0, "aesmc%u.8\t%12-15,22Q, %0-3,5Q"},
592 {FPU_CRYPTO_EXT_ARMV8, 0xf3b003c0, 0xffbf0fd0, "aesimc%u.8\t%12-15,22Q, %0-3,5Q"},
593 {FPU_CRYPTO_EXT_ARMV8, 0xf3b902c0, 0xffbf0fd0, "sha1h%u.32\t%12-15,22Q, %0-3,5Q"},
594 {FPU_CRYPTO_EXT_ARMV8, 0xf3ba0380, 0xffbf0fd0, "sha1su1%u.32\t%12-15,22Q, %0-3,5Q"},
595 {FPU_CRYPTO_EXT_ARMV8, 0xf3ba03c0, 0xffbf0fd0, "sha256su0%u.32\t%12-15,22Q, %0-3,5Q"},
596 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
597 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
598 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
599 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
600 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
601 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
602 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
603 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
604 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
605 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
606 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
607 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
608 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
609 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
610 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
611 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
612 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
613 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
614 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
615 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
616 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
617 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
618 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
619 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
620 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
621 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
622 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
623 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
624 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
625 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
626 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
627 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
628 {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
629
630 /* Three registers of the same length. */
631 {FPU_CRYPTO_EXT_ARMV8, 0xf2000c40, 0xffb00f50, "sha1c%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
632 {FPU_CRYPTO_EXT_ARMV8, 0xf2100c40, 0xffb00f50, "sha1p%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
633 {FPU_CRYPTO_EXT_ARMV8, 0xf2200c40, 0xffb00f50, "sha1m%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
634 {FPU_CRYPTO_EXT_ARMV8, 0xf2300c40, 0xffb00f50, "sha1su0%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
635 {FPU_CRYPTO_EXT_ARMV8, 0xf3000c40, 0xffb00f50, "sha256h%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
636 {FPU_CRYPTO_EXT_ARMV8, 0xf3100c40, 0xffb00f50, "sha256h2%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
637 {FPU_CRYPTO_EXT_ARMV8, 0xf3200c40, 0xffb00f50, "sha256su1%u.32\t%12-15,22Q, %16-19,7Q, %0-3,5Q"},
638 {FPU_NEON_EXT_ARMV8, 0xf3000f10, 0xffa00f10, "vmaxnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
639 {FPU_NEON_EXT_ARMV8, 0xf3200f10, 0xffa00f10, "vminnm%u.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
641 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
642 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
643 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
644 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
645 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
646 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
647 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
648 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
649 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
650 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
651 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
652 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
653 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
654 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
655 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
656 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
657 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
658 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
659 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
660 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
661 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
662 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
663 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
664 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
665 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
666 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
667 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
668 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
669 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
670 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
671 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
672 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
673 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
674 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
675 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
676 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
677 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
678 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
679 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
680 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
681 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
682 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
683 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
684 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
685 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
686 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
687 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
688 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
689 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
690 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
691 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
692 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
693
694 /* One register and an immediate value. */
695 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
696 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
697 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
698 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
699 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
700 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
701 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
702 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
703 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
704 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
705 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
706 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
707 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
708
709 /* Two registers and a shift amount. */
710 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
711 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
712 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
713 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
714 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
715 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
716 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
717 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
718 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
719 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
720 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
721 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
722 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
723 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
724 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
725 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
726 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
727 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
728 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
729 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
730 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
731 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
732 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
733 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
734 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
735 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
736 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
737 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
738 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
739 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
740 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
741 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
742 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
743 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
744 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
745 {FPU_NEON_EXT_V1, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
746 {FPU_NEON_EXT_V1, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
747 {FPU_NEON_EXT_V1, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
748 {FPU_NEON_EXT_V1, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
749 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
750 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
751 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
752 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
753 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
754 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
755 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
756 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
757 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
758 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
759 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
760 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
761 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
762 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
763 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
764 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
765 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
766 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
767 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
768
769 /* Three registers of different lengths. */
770 {FPU_CRYPTO_EXT_ARMV8, 0xf2a00e00, 0xfeb00f50, "vmull%c.p64\t%12-15,22Q, %16-19,7D, %0-3,5D"},
771 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
772 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
773 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
774 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
775 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
776 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
777 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
778 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
779 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
780 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
781 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
782 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
783 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
784 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
785 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
786 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
787 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
788
789 /* Two registers and a scalar. */
790 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
791 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
792 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
793 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
794 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
795 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
796 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
797 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
798 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
799 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
800 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
801 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
802 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
803 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
804 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
805 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
806 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
807 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
808 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
809 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
810 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
811 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
812
813 /* Element and structure load/store. */
814 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
815 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
816 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
817 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
818 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
819 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
820 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
821 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
822 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
823 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
824 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
825 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
826 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
827 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
828 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
829 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
830 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
831 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
832 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
833
834 {0,0 ,0, 0}
835 };
836
837 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
838 ordered: they must be searched linearly from the top to obtain a correct
839 match. */
840
841 /* print_insn_arm recognizes the following format control codes:
842
843 %% %
844
845 %a print address for ldr/str instruction
846 %s print address for ldr/str halfword/signextend instruction
847 %S like %s but allow UNPREDICTABLE addressing
848 %b print branch destination
849 %c print condition code (always bits 28-31)
850 %m print register mask for ldm/stm instruction
851 %o print operand2 (immediate or register + shift)
852 %p print 'p' iff bits 12-15 are 15
853 %t print 't' iff bit 21 set and bit 24 clear
854 %B print arm BLX(1) destination
855 %C print the PSR sub type.
856 %U print barrier type.
857 %P print address for pli instruction.
858
859 %<bitfield>r print as an ARM register
860 %<bitfield>T print as an ARM register + 1
861 %<bitfield>R as %r but r15 is UNPREDICTABLE
862 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
863 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
864 %<bitfield>d print the bitfield in decimal
865 %<bitfield>W print the bitfield plus one in decimal
866 %<bitfield>x print the bitfield in hex
867 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
868
869 %<bitfield>'c print specified char iff bitfield is all ones
870 %<bitfield>`c print specified char iff bitfield is all zeroes
871 %<bitfield>?ab... select from array of values in big endian order
872
873 %e print arm SMI operand (bits 0..7,8..19).
874 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
875 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
876 %R print the SPSR/CPSR or banked register of an MRS. */
877
878 static const struct opcode32 arm_opcodes[] =
879 {
880 /* ARM instructions. */
881 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
882 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
883 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
884 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
885 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
886 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
887 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
888
889 /* V8 instructions. */
890 {ARM_EXT_V8, 0x0320f005, 0x0fffffff, "sevl"},
891 {ARM_EXT_V8, 0xe1000070, 0xfff000f0, "hlt\t0x%16-19X%12-15X%8-11X%0-3X"},
892 {ARM_EXT_V8, 0x01800e90, 0x0ff00ff0, "stlex%c\t%12-15r, %0-3r, [%16-19R]"},
893 {ARM_EXT_V8, 0x01900e9f, 0x0ff00fff, "ldaex%c\t%12-15r, [%16-19R]"},
894 {ARM_EXT_V8, 0x01a00e90, 0x0ff00ff0, "stlexd%c\t%12-15r, %0-3r, %0-3T, [%16-19R]"},
895 {ARM_EXT_V8, 0x01b00e9f, 0x0ff00fff, "ldaexd%c\t%12-15r, %12-15T, [%16-19R]"},
896 {ARM_EXT_V8, 0x01c00e90, 0x0ff00ff0, "stlexb%c\t%12-15r, %0-3r, [%16-19R]"},
897 {ARM_EXT_V8, 0x01d00e9f, 0x0ff00fff, "ldaexb%c\t%12-15r, [%16-19R]"},
898 {ARM_EXT_V8, 0x01e00e90, 0x0ff00ff0, "stlexh%c\t%12-15r, %0-3r, [%16-19R]"},
899 {ARM_EXT_V8, 0x01f00e9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
900 {ARM_EXT_V8, 0x0180fc90, 0x0ff0fff0, "stl%c\t%0-3r, [%16-19R]"},
901 {ARM_EXT_V8, 0x01900c9f, 0x0ff00fff, "lda%c\t%12-15r, [%16-19R]"},
902 {ARM_EXT_V8, 0x01c0fc90, 0x0ff0fff0, "stlb%c\t%0-3r, [%16-19R]"},
903 {ARM_EXT_V8, 0x01d00c9f, 0x0ff00fff, "ldab%c\t%12-15r, [%16-19R]"},
904 {ARM_EXT_V8, 0x01e0fc90, 0x0ff0fff0, "stlh%c\t%0-3r, [%16-19R]"},
905 {ARM_EXT_V8, 0x01f00c9f, 0x0ff00fff, "ldaexh%c\t%12-15r, [%16-19R]"},
906 /* 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 \f
1800 /* Functions. */
1801 int
1802 get_arm_regname_num_options (void)
1803 {
1804 return NUM_ARM_REGNAMES;
1805 }
1806
1807 int
1808 set_arm_regname_option (int option)
1809 {
1810 int old = regname_selected;
1811 regname_selected = option;
1812 return old;
1813 }
1814
1815 int
1816 get_arm_regnames (int option,
1817 const char **setname,
1818 const char **setdescription,
1819 const char *const **register_names)
1820 {
1821 *setname = regnames[option].name;
1822 *setdescription = regnames[option].description;
1823 *register_names = regnames[option].reg_names;
1824 return 16;
1825 }
1826
1827 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1828 Returns pointer to following character of the format string and
1829 fills in *VALUEP and *WIDTHP with the extracted value and number of
1830 bits extracted. WIDTHP can be NULL. */
1831
1832 static const char *
1833 arm_decode_bitfield (const char *ptr,
1834 unsigned long insn,
1835 unsigned long *valuep,
1836 int *widthp)
1837 {
1838 unsigned long value = 0;
1839 int width = 0;
1840
1841 do
1842 {
1843 int start, end;
1844 int bits;
1845
1846 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1847 start = start * 10 + *ptr - '0';
1848 if (*ptr == '-')
1849 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1850 end = end * 10 + *ptr - '0';
1851 else
1852 end = start;
1853 bits = end - start;
1854 if (bits < 0)
1855 abort ();
1856 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1857 width += bits + 1;
1858 }
1859 while (*ptr++ == ',');
1860 *valuep = value;
1861 if (widthp)
1862 *widthp = width;
1863 return ptr - 1;
1864 }
1865
1866 static void
1867 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1868 bfd_boolean print_shift)
1869 {
1870 func (stream, "%s", arm_regnames[given & 0xf]);
1871
1872 if ((given & 0xff0) != 0)
1873 {
1874 if ((given & 0x10) == 0)
1875 {
1876 int amount = (given & 0xf80) >> 7;
1877 int shift = (given & 0x60) >> 5;
1878
1879 if (amount == 0)
1880 {
1881 if (shift == 3)
1882 {
1883 func (stream, ", rrx");
1884 return;
1885 }
1886
1887 amount = 32;
1888 }
1889
1890 if (print_shift)
1891 func (stream, ", %s #%d", arm_shift[shift], amount);
1892 else
1893 func (stream, ", #%d", amount);
1894 }
1895 else if ((given & 0x80) == 0x80)
1896 func (stream, "\t; <illegal shifter operand>");
1897 else if (print_shift)
1898 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1899 arm_regnames[(given & 0xf00) >> 8]);
1900 else
1901 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1902 }
1903 }
1904
1905 #define W_BIT 21
1906 #define I_BIT 22
1907 #define U_BIT 23
1908 #define P_BIT 24
1909
1910 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1911 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1912 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1913 #define PRE_BIT_SET (given & (1 << P_BIT))
1914
1915 /* Print one coprocessor instruction on INFO->STREAM.
1916 Return TRUE if the instuction matched, FALSE if this is not a
1917 recognised coprocessor instruction. */
1918
1919 static bfd_boolean
1920 print_insn_coprocessor (bfd_vma pc,
1921 struct disassemble_info *info,
1922 long given,
1923 bfd_boolean thumb)
1924 {
1925 const struct opcode32 *insn;
1926 void *stream = info->stream;
1927 fprintf_ftype func = info->fprintf_func;
1928 unsigned long mask;
1929 unsigned long value = 0;
1930 struct arm_private_data *private_data = info->private_data;
1931 unsigned long allowed_arches = private_data->features.coproc;
1932 int cond;
1933
1934 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1935 {
1936 unsigned long u_reg = 16;
1937 bfd_boolean is_unpredictable = FALSE;
1938 signed long value_in_comment = 0;
1939 const char *c;
1940
1941 if (insn->arch == 0)
1942 switch (insn->value)
1943 {
1944 case SENTINEL_IWMMXT_START:
1945 if (info->mach != bfd_mach_arm_XScale
1946 && info->mach != bfd_mach_arm_iWMMXt
1947 && info->mach != bfd_mach_arm_iWMMXt2)
1948 do
1949 insn++;
1950 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1951 continue;
1952
1953 case SENTINEL_IWMMXT_END:
1954 continue;
1955
1956 case SENTINEL_GENERIC_START:
1957 allowed_arches = private_data->features.core;
1958 continue;
1959
1960 default:
1961 abort ();
1962 }
1963
1964 mask = insn->mask;
1965 value = insn->value;
1966 if (thumb)
1967 {
1968 /* The high 4 bits are 0xe for Arm conditional instructions, and
1969 0xe for arm unconditional instructions. The rest of the
1970 encoding is the same. */
1971 mask |= 0xf0000000;
1972 value |= 0xe0000000;
1973 if (ifthen_state)
1974 cond = IFTHEN_COND;
1975 else
1976 cond = COND_UNCOND;
1977 }
1978 else
1979 {
1980 /* Only match unconditional instuctions against unconditional
1981 patterns. */
1982 if ((given & 0xf0000000) == 0xf0000000)
1983 {
1984 mask |= 0xf0000000;
1985 cond = COND_UNCOND;
1986 }
1987 else
1988 {
1989 cond = (given >> 28) & 0xf;
1990 if (cond == 0xe)
1991 cond = COND_UNCOND;
1992 }
1993 }
1994
1995 if ((given & mask) != value)
1996 continue;
1997
1998 if ((insn->arch & allowed_arches) == 0)
1999 continue;
2000
2001 for (c = insn->assembler; *c; c++)
2002 {
2003 if (*c == '%')
2004 {
2005 switch (*++c)
2006 {
2007 case '%':
2008 func (stream, "%%");
2009 break;
2010
2011 case 'A':
2012 {
2013 int rn = (given >> 16) & 0xf;
2014 bfd_vma offset = given & 0xff;
2015
2016 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2017
2018 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
2019 {
2020 /* Not unindexed. The offset is scaled. */
2021 offset = offset * 4;
2022 if (NEGATIVE_BIT_SET)
2023 offset = - offset;
2024 if (rn != 15)
2025 value_in_comment = offset;
2026 }
2027
2028 if (PRE_BIT_SET)
2029 {
2030 if (offset)
2031 func (stream, ", #%d]%s",
2032 (int) offset,
2033 WRITEBACK_BIT_SET ? "!" : "");
2034 else if (NEGATIVE_BIT_SET)
2035 func (stream, ", #-0]");
2036 else
2037 func (stream, "]");
2038 }
2039 else
2040 {
2041 func (stream, "]");
2042
2043 if (WRITEBACK_BIT_SET)
2044 {
2045 if (offset)
2046 func (stream, ", #%d", (int) offset);
2047 else if (NEGATIVE_BIT_SET)
2048 func (stream, ", #-0");
2049 }
2050 else
2051 {
2052 func (stream, ", {%s%d}",
2053 (NEGATIVE_BIT_SET && !offset) ? "-" : "",
2054 (int) offset);
2055 value_in_comment = offset;
2056 }
2057 }
2058 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
2059 {
2060 func (stream, "\t; ");
2061 /* For unaligned PCs, apply off-by-alignment
2062 correction. */
2063 info->print_address_func (offset + pc
2064 + info->bytes_per_chunk * 2
2065 - (pc & 3),
2066 info);
2067 }
2068 }
2069 break;
2070
2071 case 'B':
2072 {
2073 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
2074 int offset = (given >> 1) & 0x3f;
2075
2076 if (offset == 1)
2077 func (stream, "{d%d}", regno);
2078 else if (regno + offset > 32)
2079 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
2080 else
2081 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
2082 }
2083 break;
2084
2085 case 'u':
2086 if (cond != COND_UNCOND)
2087 is_unpredictable = TRUE;
2088
2089 /* Fall through. */
2090 case 'c':
2091 func (stream, "%s", arm_conditional[cond]);
2092 break;
2093
2094 case 'I':
2095 /* Print a Cirrus/DSP shift immediate. */
2096 /* Immediates are 7bit signed ints with bits 0..3 in
2097 bits 0..3 of opcode and bits 4..6 in bits 5..7
2098 of opcode. */
2099 {
2100 int imm;
2101
2102 imm = (given & 0xf) | ((given & 0xe0) >> 1);
2103
2104 /* Is ``imm'' a negative number? */
2105 if (imm & 0x40)
2106 imm |= (-1 << 7);
2107
2108 func (stream, "%d", imm);
2109 }
2110
2111 break;
2112
2113 case 'F':
2114 switch (given & 0x00408000)
2115 {
2116 case 0:
2117 func (stream, "4");
2118 break;
2119 case 0x8000:
2120 func (stream, "1");
2121 break;
2122 case 0x00400000:
2123 func (stream, "2");
2124 break;
2125 default:
2126 func (stream, "3");
2127 }
2128 break;
2129
2130 case 'P':
2131 switch (given & 0x00080080)
2132 {
2133 case 0:
2134 func (stream, "s");
2135 break;
2136 case 0x80:
2137 func (stream, "d");
2138 break;
2139 case 0x00080000:
2140 func (stream, "e");
2141 break;
2142 default:
2143 func (stream, _("<illegal precision>"));
2144 break;
2145 }
2146 break;
2147
2148 case 'Q':
2149 switch (given & 0x00408000)
2150 {
2151 case 0:
2152 func (stream, "s");
2153 break;
2154 case 0x8000:
2155 func (stream, "d");
2156 break;
2157 case 0x00400000:
2158 func (stream, "e");
2159 break;
2160 default:
2161 func (stream, "p");
2162 break;
2163 }
2164 break;
2165
2166 case 'R':
2167 switch (given & 0x60)
2168 {
2169 case 0:
2170 break;
2171 case 0x20:
2172 func (stream, "p");
2173 break;
2174 case 0x40:
2175 func (stream, "m");
2176 break;
2177 default:
2178 func (stream, "z");
2179 break;
2180 }
2181 break;
2182
2183 case '0': case '1': case '2': case '3': case '4':
2184 case '5': case '6': case '7': case '8': case '9':
2185 {
2186 int width;
2187
2188 c = arm_decode_bitfield (c, given, &value, &width);
2189
2190 switch (*c)
2191 {
2192 case 'R':
2193 if (value == 15)
2194 is_unpredictable = TRUE;
2195 /* Fall through. */
2196 case 'r':
2197 if (c[1] == 'u')
2198 {
2199 /* Eat the 'u' character. */
2200 ++ c;
2201
2202 if (u_reg == value)
2203 is_unpredictable = TRUE;
2204 u_reg = value;
2205 }
2206 func (stream, "%s", arm_regnames[value]);
2207 break;
2208 case 'D':
2209 func (stream, "d%ld", value);
2210 break;
2211 case 'Q':
2212 if (value & 1)
2213 func (stream, "<illegal reg q%ld.5>", value >> 1);
2214 else
2215 func (stream, "q%ld", value >> 1);
2216 break;
2217 case 'd':
2218 func (stream, "%ld", value);
2219 value_in_comment = value;
2220 break;
2221 case 'k':
2222 {
2223 int from = (given & (1 << 7)) ? 32 : 16;
2224 func (stream, "%ld", from - value);
2225 }
2226 break;
2227
2228 case 'f':
2229 if (value > 7)
2230 func (stream, "#%s", arm_fp_const[value & 7]);
2231 else
2232 func (stream, "f%ld", value);
2233 break;
2234
2235 case 'w':
2236 if (width == 2)
2237 func (stream, "%s", iwmmxt_wwnames[value]);
2238 else
2239 func (stream, "%s", iwmmxt_wwssnames[value]);
2240 break;
2241
2242 case 'g':
2243 func (stream, "%s", iwmmxt_regnames[value]);
2244 break;
2245 case 'G':
2246 func (stream, "%s", iwmmxt_cregnames[value]);
2247 break;
2248
2249 case 'x':
2250 func (stream, "0x%lx", (value & 0xffffffffUL));
2251 break;
2252
2253 case 'c':
2254 switch (value)
2255 {
2256 case 0:
2257 func (stream, "eq");
2258 break;
2259
2260 case 1:
2261 func (stream, "vs");
2262 break;
2263
2264 case 2:
2265 func (stream, "ge");
2266 break;
2267
2268 case 3:
2269 func (stream, "gt");
2270 break;
2271
2272 default:
2273 func (stream, "??");
2274 break;
2275 }
2276 break;
2277
2278 case '`':
2279 c++;
2280 if (value == 0)
2281 func (stream, "%c", *c);
2282 break;
2283 case '\'':
2284 c++;
2285 if (value == ((1ul << width) - 1))
2286 func (stream, "%c", *c);
2287 break;
2288 case '?':
2289 func (stream, "%c", c[(1 << width) - (int) value]);
2290 c += 1 << width;
2291 break;
2292 default:
2293 abort ();
2294 }
2295 break;
2296
2297 case 'y':
2298 case 'z':
2299 {
2300 int single = *c++ == 'y';
2301 int regno;
2302
2303 switch (*c)
2304 {
2305 case '4': /* Sm pair */
2306 case '0': /* Sm, Dm */
2307 regno = given & 0x0000000f;
2308 if (single)
2309 {
2310 regno <<= 1;
2311 regno += (given >> 5) & 1;
2312 }
2313 else
2314 regno += ((given >> 5) & 1) << 4;
2315 break;
2316
2317 case '1': /* Sd, Dd */
2318 regno = (given >> 12) & 0x0000000f;
2319 if (single)
2320 {
2321 regno <<= 1;
2322 regno += (given >> 22) & 1;
2323 }
2324 else
2325 regno += ((given >> 22) & 1) << 4;
2326 break;
2327
2328 case '2': /* Sn, Dn */
2329 regno = (given >> 16) & 0x0000000f;
2330 if (single)
2331 {
2332 regno <<= 1;
2333 regno += (given >> 7) & 1;
2334 }
2335 else
2336 regno += ((given >> 7) & 1) << 4;
2337 break;
2338
2339 case '3': /* List */
2340 func (stream, "{");
2341 regno = (given >> 12) & 0x0000000f;
2342 if (single)
2343 {
2344 regno <<= 1;
2345 regno += (given >> 22) & 1;
2346 }
2347 else
2348 regno += ((given >> 22) & 1) << 4;
2349 break;
2350
2351 default:
2352 abort ();
2353 }
2354
2355 func (stream, "%c%d", single ? 's' : 'd', regno);
2356
2357 if (*c == '3')
2358 {
2359 int count = given & 0xff;
2360
2361 if (single == 0)
2362 count >>= 1;
2363
2364 if (--count)
2365 {
2366 func (stream, "-%c%d",
2367 single ? 's' : 'd',
2368 regno + count);
2369 }
2370
2371 func (stream, "}");
2372 }
2373 else if (*c == '4')
2374 func (stream, ", %c%d", single ? 's' : 'd',
2375 regno + 1);
2376 }
2377 break;
2378
2379 case 'L':
2380 switch (given & 0x00400100)
2381 {
2382 case 0x00000000: func (stream, "b"); break;
2383 case 0x00400000: func (stream, "h"); break;
2384 case 0x00000100: func (stream, "w"); break;
2385 case 0x00400100: func (stream, "d"); break;
2386 default:
2387 break;
2388 }
2389 break;
2390
2391 case 'Z':
2392 {
2393 /* given (20, 23) | given (0, 3) */
2394 value = ((given >> 16) & 0xf0) | (given & 0xf);
2395 func (stream, "%d", (int) value);
2396 }
2397 break;
2398
2399 case 'l':
2400 /* This is like the 'A' operator, except that if
2401 the width field "M" is zero, then the offset is
2402 *not* multiplied by four. */
2403 {
2404 int offset = given & 0xff;
2405 int multiplier = (given & 0x00000100) ? 4 : 1;
2406
2407 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2408
2409 if (multiplier > 1)
2410 {
2411 value_in_comment = offset * multiplier;
2412 if (NEGATIVE_BIT_SET)
2413 value_in_comment = - value_in_comment;
2414 }
2415
2416 if (offset)
2417 {
2418 if (PRE_BIT_SET)
2419 func (stream, ", #%s%d]%s",
2420 NEGATIVE_BIT_SET ? "-" : "",
2421 offset * multiplier,
2422 WRITEBACK_BIT_SET ? "!" : "");
2423 else
2424 func (stream, "], #%s%d",
2425 NEGATIVE_BIT_SET ? "-" : "",
2426 offset * multiplier);
2427 }
2428 else
2429 func (stream, "]");
2430 }
2431 break;
2432
2433 case 'r':
2434 {
2435 int imm4 = (given >> 4) & 0xf;
2436 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2437 int ubit = ! NEGATIVE_BIT_SET;
2438 const char *rm = arm_regnames [given & 0xf];
2439 const char *rn = arm_regnames [(given >> 16) & 0xf];
2440
2441 switch (puw_bits)
2442 {
2443 case 1:
2444 case 3:
2445 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2446 if (imm4)
2447 func (stream, ", lsl #%d", imm4);
2448 break;
2449
2450 case 4:
2451 case 5:
2452 case 6:
2453 case 7:
2454 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2455 if (imm4 > 0)
2456 func (stream, ", lsl #%d", imm4);
2457 func (stream, "]");
2458 if (puw_bits == 5 || puw_bits == 7)
2459 func (stream, "!");
2460 break;
2461
2462 default:
2463 func (stream, "INVALID");
2464 }
2465 }
2466 break;
2467
2468 case 'i':
2469 {
2470 long imm5;
2471 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2472 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2473 }
2474 break;
2475
2476 default:
2477 abort ();
2478 }
2479 }
2480 }
2481 else
2482 func (stream, "%c", *c);
2483 }
2484
2485 if (value_in_comment > 32 || value_in_comment < -16)
2486 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2487
2488 if (is_unpredictable)
2489 func (stream, UNPREDICTABLE_INSTRUCTION);
2490
2491 return TRUE;
2492 }
2493 return FALSE;
2494 }
2495
2496 /* Decodes and prints ARM addressing modes. Returns the offset
2497 used in the address, if any, if it is worthwhile printing the
2498 offset as a hexadecimal value in a comment at the end of the
2499 line of disassembly. */
2500
2501 static signed long
2502 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2503 {
2504 void *stream = info->stream;
2505 fprintf_ftype func = info->fprintf_func;
2506 bfd_vma offset = 0;
2507
2508 if (((given & 0x000f0000) == 0x000f0000)
2509 && ((given & 0x02000000) == 0))
2510 {
2511 offset = given & 0xfff;
2512
2513 func (stream, "[pc");
2514
2515 if (PRE_BIT_SET)
2516 {
2517 /* Pre-indexed. Elide offset of positive zero when
2518 non-writeback. */
2519 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2520 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2521
2522 if (NEGATIVE_BIT_SET)
2523 offset = -offset;
2524
2525 offset += pc + 8;
2526
2527 /* Cope with the possibility of write-back
2528 being used. Probably a very dangerous thing
2529 for the programmer to do, but who are we to
2530 argue ? */
2531 func (stream, "]%s", WRITEBACK_BIT_SET ? "!" : "");
2532 }
2533 else /* Post indexed. */
2534 {
2535 func (stream, "], #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2536
2537 /* Ie ignore the offset. */
2538 offset = pc + 8;
2539 }
2540
2541 func (stream, "\t; ");
2542 info->print_address_func (offset, info);
2543 offset = 0;
2544 }
2545 else
2546 {
2547 func (stream, "[%s",
2548 arm_regnames[(given >> 16) & 0xf]);
2549
2550 if (PRE_BIT_SET)
2551 {
2552 if ((given & 0x02000000) == 0)
2553 {
2554 /* Elide offset of positive zero when non-writeback. */
2555 offset = given & 0xfff;
2556 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2557 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2558 }
2559 else
2560 {
2561 func (stream, ", %s", NEGATIVE_BIT_SET ? "-" : "");
2562 arm_decode_shift (given, func, stream, TRUE);
2563 }
2564
2565 func (stream, "]%s",
2566 WRITEBACK_BIT_SET ? "!" : "");
2567 }
2568 else
2569 {
2570 if ((given & 0x02000000) == 0)
2571 {
2572 /* Always show offset. */
2573 offset = given & 0xfff;
2574 func (stream, "], #%s%d",
2575 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
2576 }
2577 else
2578 {
2579 func (stream, "], %s",
2580 NEGATIVE_BIT_SET ? "-" : "");
2581 arm_decode_shift (given, func, stream, TRUE);
2582 }
2583 }
2584 }
2585
2586 return (signed long) offset;
2587 }
2588
2589 /* Print one neon instruction on INFO->STREAM.
2590 Return TRUE if the instuction matched, FALSE if this is not a
2591 recognised neon instruction. */
2592
2593 static bfd_boolean
2594 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2595 {
2596 const struct opcode32 *insn;
2597 void *stream = info->stream;
2598 fprintf_ftype func = info->fprintf_func;
2599
2600 if (thumb)
2601 {
2602 if ((given & 0xef000000) == 0xef000000)
2603 {
2604 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2605 unsigned long bit28 = given & (1 << 28);
2606
2607 given &= 0x00ffffff;
2608 if (bit28)
2609 given |= 0xf3000000;
2610 else
2611 given |= 0xf2000000;
2612 }
2613 else if ((given & 0xff000000) == 0xf9000000)
2614 given ^= 0xf9000000 ^ 0xf4000000;
2615 else
2616 return FALSE;
2617 }
2618
2619 for (insn = neon_opcodes; insn->assembler; insn++)
2620 {
2621 if ((given & insn->mask) == insn->value)
2622 {
2623 signed long value_in_comment = 0;
2624 bfd_boolean is_unpredictable = FALSE;
2625 const char *c;
2626
2627 for (c = insn->assembler; *c; c++)
2628 {
2629 if (*c == '%')
2630 {
2631 switch (*++c)
2632 {
2633 case '%':
2634 func (stream, "%%");
2635 break;
2636
2637 case 'u':
2638 if (thumb && ifthen_state)
2639 is_unpredictable = TRUE;
2640
2641 /* Fall through. */
2642 case 'c':
2643 if (thumb && ifthen_state)
2644 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2645 break;
2646
2647 case 'A':
2648 {
2649 static const unsigned char enc[16] =
2650 {
2651 0x4, 0x14, /* st4 0,1 */
2652 0x4, /* st1 2 */
2653 0x4, /* st2 3 */
2654 0x3, /* st3 4 */
2655 0x13, /* st3 5 */
2656 0x3, /* st1 6 */
2657 0x1, /* st1 7 */
2658 0x2, /* st2 8 */
2659 0x12, /* st2 9 */
2660 0x2, /* st1 10 */
2661 0, 0, 0, 0, 0
2662 };
2663 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2664 int rn = ((given >> 16) & 0xf);
2665 int rm = ((given >> 0) & 0xf);
2666 int align = ((given >> 4) & 0x3);
2667 int type = ((given >> 8) & 0xf);
2668 int n = enc[type] & 0xf;
2669 int stride = (enc[type] >> 4) + 1;
2670 int ix;
2671
2672 func (stream, "{");
2673 if (stride > 1)
2674 for (ix = 0; ix != n; ix++)
2675 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2676 else if (n == 1)
2677 func (stream, "d%d", rd);
2678 else
2679 func (stream, "d%d-d%d", rd, rd + n - 1);
2680 func (stream, "}, [%s", arm_regnames[rn]);
2681 if (align)
2682 func (stream, " :%d", 32 << align);
2683 func (stream, "]");
2684 if (rm == 0xd)
2685 func (stream, "!");
2686 else if (rm != 0xf)
2687 func (stream, ", %s", arm_regnames[rm]);
2688 }
2689 break;
2690
2691 case 'B':
2692 {
2693 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2694 int rn = ((given >> 16) & 0xf);
2695 int rm = ((given >> 0) & 0xf);
2696 int idx_align = ((given >> 4) & 0xf);
2697 int align = 0;
2698 int size = ((given >> 10) & 0x3);
2699 int idx = idx_align >> (size + 1);
2700 int length = ((given >> 8) & 3) + 1;
2701 int stride = 1;
2702 int i;
2703
2704 if (length > 1 && size > 0)
2705 stride = (idx_align & (1 << size)) ? 2 : 1;
2706
2707 switch (length)
2708 {
2709 case 1:
2710 {
2711 int amask = (1 << size) - 1;
2712 if ((idx_align & (1 << size)) != 0)
2713 return FALSE;
2714 if (size > 0)
2715 {
2716 if ((idx_align & amask) == amask)
2717 align = 8 << size;
2718 else if ((idx_align & amask) != 0)
2719 return FALSE;
2720 }
2721 }
2722 break;
2723
2724 case 2:
2725 if (size == 2 && (idx_align & 2) != 0)
2726 return FALSE;
2727 align = (idx_align & 1) ? 16 << size : 0;
2728 break;
2729
2730 case 3:
2731 if ((size == 2 && (idx_align & 3) != 0)
2732 || (idx_align & 1) != 0)
2733 return FALSE;
2734 break;
2735
2736 case 4:
2737 if (size == 2)
2738 {
2739 if ((idx_align & 3) == 3)
2740 return FALSE;
2741 align = (idx_align & 3) * 64;
2742 }
2743 else
2744 align = (idx_align & 1) ? 32 << size : 0;
2745 break;
2746
2747 default:
2748 abort ();
2749 }
2750
2751 func (stream, "{");
2752 for (i = 0; i < length; i++)
2753 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2754 rd + i * stride, idx);
2755 func (stream, "}, [%s", arm_regnames[rn]);
2756 if (align)
2757 func (stream, " :%d", align);
2758 func (stream, "]");
2759 if (rm == 0xd)
2760 func (stream, "!");
2761 else if (rm != 0xf)
2762 func (stream, ", %s", arm_regnames[rm]);
2763 }
2764 break;
2765
2766 case 'C':
2767 {
2768 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2769 int rn = ((given >> 16) & 0xf);
2770 int rm = ((given >> 0) & 0xf);
2771 int align = ((given >> 4) & 0x1);
2772 int size = ((given >> 6) & 0x3);
2773 int type = ((given >> 8) & 0x3);
2774 int n = type + 1;
2775 int stride = ((given >> 5) & 0x1);
2776 int ix;
2777
2778 if (stride && (n == 1))
2779 n++;
2780 else
2781 stride++;
2782
2783 func (stream, "{");
2784 if (stride > 1)
2785 for (ix = 0; ix != n; ix++)
2786 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2787 else if (n == 1)
2788 func (stream, "d%d[]", rd);
2789 else
2790 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2791 func (stream, "}, [%s", arm_regnames[rn]);
2792 if (align)
2793 {
2794 align = (8 * (type + 1)) << size;
2795 if (type == 3)
2796 align = (size > 1) ? align >> 1 : align;
2797 if (type == 2 || (type == 0 && !size))
2798 func (stream, " :<bad align %d>", align);
2799 else
2800 func (stream, " :%d", align);
2801 }
2802 func (stream, "]");
2803 if (rm == 0xd)
2804 func (stream, "!");
2805 else if (rm != 0xf)
2806 func (stream, ", %s", arm_regnames[rm]);
2807 }
2808 break;
2809
2810 case 'D':
2811 {
2812 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2813 int size = (given >> 20) & 3;
2814 int reg = raw_reg & ((4 << size) - 1);
2815 int ix = raw_reg >> size >> 2;
2816
2817 func (stream, "d%d[%d]", reg, ix);
2818 }
2819 break;
2820
2821 case 'E':
2822 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2823 {
2824 int bits = 0;
2825 int cmode = (given >> 8) & 0xf;
2826 int op = (given >> 5) & 0x1;
2827 unsigned long value = 0, hival = 0;
2828 unsigned shift;
2829 int size = 0;
2830 int isfloat = 0;
2831
2832 bits |= ((given >> 24) & 1) << 7;
2833 bits |= ((given >> 16) & 7) << 4;
2834 bits |= ((given >> 0) & 15) << 0;
2835
2836 if (cmode < 8)
2837 {
2838 shift = (cmode >> 1) & 3;
2839 value = (unsigned long) bits << (8 * shift);
2840 size = 32;
2841 }
2842 else if (cmode < 12)
2843 {
2844 shift = (cmode >> 1) & 1;
2845 value = (unsigned long) bits << (8 * shift);
2846 size = 16;
2847 }
2848 else if (cmode < 14)
2849 {
2850 shift = (cmode & 1) + 1;
2851 value = (unsigned long) bits << (8 * shift);
2852 value |= (1ul << (8 * shift)) - 1;
2853 size = 32;
2854 }
2855 else if (cmode == 14)
2856 {
2857 if (op)
2858 {
2859 /* Bit replication into bytes. */
2860 int ix;
2861 unsigned long mask;
2862
2863 value = 0;
2864 hival = 0;
2865 for (ix = 7; ix >= 0; ix--)
2866 {
2867 mask = ((bits >> ix) & 1) ? 0xff : 0;
2868 if (ix <= 3)
2869 value = (value << 8) | mask;
2870 else
2871 hival = (hival << 8) | mask;
2872 }
2873 size = 64;
2874 }
2875 else
2876 {
2877 /* Byte replication. */
2878 value = (unsigned long) bits;
2879 size = 8;
2880 }
2881 }
2882 else if (!op)
2883 {
2884 /* Floating point encoding. */
2885 int tmp;
2886
2887 value = (unsigned long) (bits & 0x7f) << 19;
2888 value |= (unsigned long) (bits & 0x80) << 24;
2889 tmp = bits & 0x40 ? 0x3c : 0x40;
2890 value |= (unsigned long) tmp << 24;
2891 size = 32;
2892 isfloat = 1;
2893 }
2894 else
2895 {
2896 func (stream, "<illegal constant %.8x:%x:%x>",
2897 bits, cmode, op);
2898 size = 32;
2899 break;
2900 }
2901 switch (size)
2902 {
2903 case 8:
2904 func (stream, "#%ld\t; 0x%.2lx", value, value);
2905 break;
2906
2907 case 16:
2908 func (stream, "#%ld\t; 0x%.4lx", value, value);
2909 break;
2910
2911 case 32:
2912 if (isfloat)
2913 {
2914 unsigned char valbytes[4];
2915 double fvalue;
2916
2917 /* Do this a byte at a time so we don't have to
2918 worry about the host's endianness. */
2919 valbytes[0] = value & 0xff;
2920 valbytes[1] = (value >> 8) & 0xff;
2921 valbytes[2] = (value >> 16) & 0xff;
2922 valbytes[3] = (value >> 24) & 0xff;
2923
2924 floatformat_to_double
2925 (& floatformat_ieee_single_little, valbytes,
2926 & fvalue);
2927
2928 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2929 value);
2930 }
2931 else
2932 func (stream, "#%ld\t; 0x%.8lx",
2933 (long) (((value & 0x80000000L) != 0)
2934 ? value | ~0xffffffffL : value),
2935 value);
2936 break;
2937
2938 case 64:
2939 func (stream, "#0x%.8lx%.8lx", hival, value);
2940 break;
2941
2942 default:
2943 abort ();
2944 }
2945 }
2946 break;
2947
2948 case 'F':
2949 {
2950 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2951 int num = (given >> 8) & 0x3;
2952
2953 if (!num)
2954 func (stream, "{d%d}", regno);
2955 else if (num + regno >= 32)
2956 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2957 else
2958 func (stream, "{d%d-d%d}", regno, regno + num);
2959 }
2960 break;
2961
2962
2963 case '0': case '1': case '2': case '3': case '4':
2964 case '5': case '6': case '7': case '8': case '9':
2965 {
2966 int width;
2967 unsigned long value;
2968
2969 c = arm_decode_bitfield (c, given, &value, &width);
2970
2971 switch (*c)
2972 {
2973 case 'r':
2974 func (stream, "%s", arm_regnames[value]);
2975 break;
2976 case 'd':
2977 func (stream, "%ld", value);
2978 value_in_comment = value;
2979 break;
2980 case 'e':
2981 func (stream, "%ld", (1ul << width) - value);
2982 break;
2983
2984 case 'S':
2985 case 'T':
2986 case 'U':
2987 /* Various width encodings. */
2988 {
2989 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2990 int limit;
2991 unsigned low, high;
2992
2993 c++;
2994 if (*c >= '0' && *c <= '9')
2995 limit = *c - '0';
2996 else if (*c >= 'a' && *c <= 'f')
2997 limit = *c - 'a' + 10;
2998 else
2999 abort ();
3000 low = limit >> 2;
3001 high = limit & 3;
3002
3003 if (value < low || value > high)
3004 func (stream, "<illegal width %d>", base << value);
3005 else
3006 func (stream, "%d", base << value);
3007 }
3008 break;
3009 case 'R':
3010 if (given & (1 << 6))
3011 goto Q;
3012 /* FALLTHROUGH */
3013 case 'D':
3014 func (stream, "d%ld", value);
3015 break;
3016 case 'Q':
3017 Q:
3018 if (value & 1)
3019 func (stream, "<illegal reg q%ld.5>", value >> 1);
3020 else
3021 func (stream, "q%ld", value >> 1);
3022 break;
3023
3024 case '`':
3025 c++;
3026 if (value == 0)
3027 func (stream, "%c", *c);
3028 break;
3029 case '\'':
3030 c++;
3031 if (value == ((1ul << width) - 1))
3032 func (stream, "%c", *c);
3033 break;
3034 case '?':
3035 func (stream, "%c", c[(1 << width) - (int) value]);
3036 c += 1 << width;
3037 break;
3038 default:
3039 abort ();
3040 }
3041 break;
3042
3043 default:
3044 abort ();
3045 }
3046 }
3047 }
3048 else
3049 func (stream, "%c", *c);
3050 }
3051
3052 if (value_in_comment > 32 || value_in_comment < -16)
3053 func (stream, "\t; 0x%lx", value_in_comment);
3054
3055 if (is_unpredictable)
3056 func (stream, UNPREDICTABLE_INSTRUCTION);
3057
3058 return TRUE;
3059 }
3060 }
3061 return FALSE;
3062 }
3063
3064 /* Return the name of a v7A special register. */
3065
3066 static const char *
3067 banked_regname (unsigned reg)
3068 {
3069 switch (reg)
3070 {
3071 case 15: return "CPSR";
3072 case 32: return "R8_usr";
3073 case 33: return "R9_usr";
3074 case 34: return "R10_usr";
3075 case 35: return "R11_usr";
3076 case 36: return "R12_usr";
3077 case 37: return "SP_usr";
3078 case 38: return "LR_usr";
3079 case 40: return "R8_fiq";
3080 case 41: return "R9_fiq";
3081 case 42: return "R10_fiq";
3082 case 43: return "R11_fiq";
3083 case 44: return "R12_fiq";
3084 case 45: return "SP_fiq";
3085 case 46: return "LR_fiq";
3086 case 48: return "LR_irq";
3087 case 49: return "SP_irq";
3088 case 50: return "LR_svc";
3089 case 51: return "SP_svc";
3090 case 52: return "LR_abt";
3091 case 53: return "SP_abt";
3092 case 54: return "LR_und";
3093 case 55: return "SP_und";
3094 case 60: return "LR_mon";
3095 case 61: return "SP_mon";
3096 case 62: return "ELR_hyp";
3097 case 63: return "SP_hyp";
3098 case 79: return "SPSR";
3099 case 110: return "SPSR_fiq";
3100 case 112: return "SPSR_irq";
3101 case 114: return "SPSR_svc";
3102 case 116: return "SPSR_abt";
3103 case 118: return "SPSR_und";
3104 case 124: return "SPSR_mon";
3105 case 126: return "SPSR_hyp";
3106 default: return NULL;
3107 }
3108 }
3109
3110 /* Return the name of the DMB/DSB option. */
3111 static const char *
3112 data_barrier_option (unsigned option)
3113 {
3114 switch (option & 0xf)
3115 {
3116 case 0xf: return "sy";
3117 case 0xe: return "st";
3118 case 0xd: return "ld";
3119 case 0xb: return "ish";
3120 case 0xa: return "ishst";
3121 case 0x9: return "ishld";
3122 case 0x7: return "un";
3123 case 0x6: return "unst";
3124 case 0x5: return "nshld";
3125 case 0x3: return "osh";
3126 case 0x2: return "oshst";
3127 case 0x1: return "oshld";
3128 default: return NULL;
3129 }
3130 }
3131
3132 /* Print one ARM instruction from PC on INFO->STREAM. */
3133
3134 static void
3135 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
3136 {
3137 const struct opcode32 *insn;
3138 void *stream = info->stream;
3139 fprintf_ftype func = info->fprintf_func;
3140 struct arm_private_data *private_data = info->private_data;
3141
3142 if (print_insn_coprocessor (pc, info, given, FALSE))
3143 return;
3144
3145 if (print_insn_neon (info, given, FALSE))
3146 return;
3147
3148 for (insn = arm_opcodes; insn->assembler; insn++)
3149 {
3150 if ((given & insn->mask) != insn->value)
3151 continue;
3152
3153 if ((insn->arch & private_data->features.core) == 0)
3154 continue;
3155
3156 /* Special case: an instruction with all bits set in the condition field
3157 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
3158 or by the catchall at the end of the table. */
3159 if ((given & 0xF0000000) != 0xF0000000
3160 || (insn->mask & 0xF0000000) == 0xF0000000
3161 || (insn->mask == 0 && insn->value == 0))
3162 {
3163 unsigned long u_reg = 16;
3164 unsigned long U_reg = 16;
3165 bfd_boolean is_unpredictable = FALSE;
3166 signed long value_in_comment = 0;
3167 const char *c;
3168
3169 for (c = insn->assembler; *c; c++)
3170 {
3171 if (*c == '%')
3172 {
3173 bfd_boolean allow_unpredictable = FALSE;
3174
3175 switch (*++c)
3176 {
3177 case '%':
3178 func (stream, "%%");
3179 break;
3180
3181 case 'a':
3182 value_in_comment = print_arm_address (pc, info, given);
3183 break;
3184
3185 case 'P':
3186 /* Set P address bit and use normal address
3187 printing routine. */
3188 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
3189 break;
3190
3191 case 'S':
3192 allow_unpredictable = TRUE;
3193 case 's':
3194 if ((given & 0x004f0000) == 0x004f0000)
3195 {
3196 /* PC relative with immediate offset. */
3197 bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3198
3199 if (PRE_BIT_SET)
3200 {
3201 /* Elide positive zero offset. */
3202 if (offset || NEGATIVE_BIT_SET)
3203 func (stream, "[pc, #%s%d]\t; ",
3204 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3205 else
3206 func (stream, "[pc]\t; ");
3207 if (NEGATIVE_BIT_SET)
3208 offset = -offset;
3209 info->print_address_func (offset + pc + 8, info);
3210 }
3211 else
3212 {
3213 /* Always show the offset. */
3214 func (stream, "[pc], #%s%d",
3215 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3216 if (! allow_unpredictable)
3217 is_unpredictable = TRUE;
3218 }
3219 }
3220 else
3221 {
3222 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3223
3224 func (stream, "[%s",
3225 arm_regnames[(given >> 16) & 0xf]);
3226
3227 if (PRE_BIT_SET)
3228 {
3229 if (IMMEDIATE_BIT_SET)
3230 {
3231 /* Elide offset for non-writeback
3232 positive zero. */
3233 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3234 || offset)
3235 func (stream, ", #%s%d",
3236 NEGATIVE_BIT_SET ? "-" : "", offset);
3237
3238 if (NEGATIVE_BIT_SET)
3239 offset = -offset;
3240
3241 value_in_comment = offset;
3242 }
3243 else
3244 {
3245 /* Register Offset or Register Pre-Indexed. */
3246 func (stream, ", %s%s",
3247 NEGATIVE_BIT_SET ? "-" : "",
3248 arm_regnames[given & 0xf]);
3249
3250 /* Writing back to the register that is the source/
3251 destination of the load/store is unpredictable. */
3252 if (! allow_unpredictable
3253 && WRITEBACK_BIT_SET
3254 && ((given & 0xf) == ((given >> 12) & 0xf)))
3255 is_unpredictable = TRUE;
3256 }
3257
3258 func (stream, "]%s",
3259 WRITEBACK_BIT_SET ? "!" : "");
3260 }
3261 else
3262 {
3263 if (IMMEDIATE_BIT_SET)
3264 {
3265 /* Immediate Post-indexed. */
3266 /* PR 10924: Offset must be printed, even if it is zero. */
3267 func (stream, "], #%s%d",
3268 NEGATIVE_BIT_SET ? "-" : "", offset);
3269 if (NEGATIVE_BIT_SET)
3270 offset = -offset;
3271 value_in_comment = offset;
3272 }
3273 else
3274 {
3275 /* Register Post-indexed. */
3276 func (stream, "], %s%s",
3277 NEGATIVE_BIT_SET ? "-" : "",
3278 arm_regnames[given & 0xf]);
3279
3280 /* Writing back to the register that is the source/
3281 destination of the load/store is unpredictable. */
3282 if (! allow_unpredictable
3283 && (given & 0xf) == ((given >> 12) & 0xf))
3284 is_unpredictable = TRUE;
3285 }
3286
3287 if (! allow_unpredictable)
3288 {
3289 /* Writeback is automatically implied by post- addressing.
3290 Setting the W bit is unnecessary and ARM specify it as
3291 being unpredictable. */
3292 if (WRITEBACK_BIT_SET
3293 /* Specifying the PC register as the post-indexed
3294 registers is also unpredictable. */
3295 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3296 is_unpredictable = TRUE;
3297 }
3298 }
3299 }
3300 break;
3301
3302 case 'b':
3303 {
3304 bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3305 info->print_address_func (disp * 4 + pc + 8, info);
3306 }
3307 break;
3308
3309 case 'c':
3310 if (((given >> 28) & 0xf) != 0xe)
3311 func (stream, "%s",
3312 arm_conditional [(given >> 28) & 0xf]);
3313 break;
3314
3315 case 'm':
3316 {
3317 int started = 0;
3318 int reg;
3319
3320 func (stream, "{");
3321 for (reg = 0; reg < 16; reg++)
3322 if ((given & (1 << reg)) != 0)
3323 {
3324 if (started)
3325 func (stream, ", ");
3326 started = 1;
3327 func (stream, "%s", arm_regnames[reg]);
3328 }
3329 func (stream, "}");
3330 if (! started)
3331 is_unpredictable = TRUE;
3332 }
3333 break;
3334
3335 case 'q':
3336 arm_decode_shift (given, func, stream, FALSE);
3337 break;
3338
3339 case 'o':
3340 if ((given & 0x02000000) != 0)
3341 {
3342 unsigned int rotate = (given & 0xf00) >> 7;
3343 unsigned int immed = (given & 0xff);
3344 unsigned int a, i;
3345
3346 a = (((immed << (32 - rotate))
3347 | (immed >> rotate)) & 0xffffffff);
3348 /* If there is another encoding with smaller rotate,
3349 the rotate should be specified directly. */
3350 for (i = 0; i < 32; i += 2)
3351 if ((a << i | a >> (32 - i)) <= 0xff)
3352 break;
3353
3354 if (i != rotate)
3355 func (stream, "#%d, %d", immed, rotate);
3356 else
3357 func (stream, "#%d", a);
3358 value_in_comment = a;
3359 }
3360 else
3361 arm_decode_shift (given, func, stream, TRUE);
3362 break;
3363
3364 case 'p':
3365 if ((given & 0x0000f000) == 0x0000f000)
3366 {
3367 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3368 mechanism for setting PSR flag bits. They are
3369 obsolete in V6 onwards. */
3370 if ((private_data->features.core & ARM_EXT_V6) == 0)
3371 func (stream, "p");
3372 }
3373 break;
3374
3375 case 't':
3376 if ((given & 0x01200000) == 0x00200000)
3377 func (stream, "t");
3378 break;
3379
3380 case 'A':
3381 {
3382 int offset = given & 0xff;
3383
3384 value_in_comment = offset * 4;
3385 if (NEGATIVE_BIT_SET)
3386 value_in_comment = - value_in_comment;
3387
3388 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3389
3390 if (PRE_BIT_SET)
3391 {
3392 if (offset)
3393 func (stream, ", #%d]%s",
3394 (int) value_in_comment,
3395 WRITEBACK_BIT_SET ? "!" : "");
3396 else
3397 func (stream, "]");
3398 }
3399 else
3400 {
3401 func (stream, "]");
3402
3403 if (WRITEBACK_BIT_SET)
3404 {
3405 if (offset)
3406 func (stream, ", #%d", (int) value_in_comment);
3407 }
3408 else
3409 {
3410 func (stream, ", {%d}", (int) offset);
3411 value_in_comment = offset;
3412 }
3413 }
3414 }
3415 break;
3416
3417 case 'B':
3418 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3419 {
3420 bfd_vma address;
3421 bfd_vma offset = 0;
3422
3423 if (! NEGATIVE_BIT_SET)
3424 /* Is signed, hi bits should be ones. */
3425 offset = (-1) ^ 0x00ffffff;
3426
3427 /* Offset is (SignExtend(offset field)<<2). */
3428 offset += given & 0x00ffffff;
3429 offset <<= 2;
3430 address = offset + pc + 8;
3431
3432 if (given & 0x01000000)
3433 /* H bit allows addressing to 2-byte boundaries. */
3434 address += 2;
3435
3436 info->print_address_func (address, info);
3437 }
3438 break;
3439
3440 case 'C':
3441 if ((given & 0x02000200) == 0x200)
3442 {
3443 const char * name;
3444 unsigned sysm = (given & 0x004f0000) >> 16;
3445
3446 sysm |= (given & 0x300) >> 4;
3447 name = banked_regname (sysm);
3448
3449 if (name != NULL)
3450 func (stream, "%s", name);
3451 else
3452 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3453 }
3454 else
3455 {
3456 func (stream, "%cPSR_",
3457 (given & 0x00400000) ? 'S' : 'C');
3458 if (given & 0x80000)
3459 func (stream, "f");
3460 if (given & 0x40000)
3461 func (stream, "s");
3462 if (given & 0x20000)
3463 func (stream, "x");
3464 if (given & 0x10000)
3465 func (stream, "c");
3466 }
3467 break;
3468
3469 case 'U':
3470 if ((given & 0xf0) == 0x60)
3471 {
3472 switch (given & 0xf)
3473 {
3474 case 0xf: func (stream, "sy"); break;
3475 default:
3476 func (stream, "#%d", (int) given & 0xf);
3477 break;
3478 }
3479 }
3480 else
3481 {
3482 const char * opt = data_barrier_option (given & 0xf);
3483 if (opt != NULL)
3484 func (stream, "%s", opt);
3485 else
3486 func (stream, "#%d", (int) given & 0xf);
3487 }
3488 break;
3489
3490 case '0': case '1': case '2': case '3': case '4':
3491 case '5': case '6': case '7': case '8': case '9':
3492 {
3493 int width;
3494 unsigned long value;
3495
3496 c = arm_decode_bitfield (c, given, &value, &width);
3497
3498 switch (*c)
3499 {
3500 case 'R':
3501 if (value == 15)
3502 is_unpredictable = TRUE;
3503 /* Fall through. */
3504 case 'r':
3505 case 'T':
3506 /* We want register + 1 when decoding T. */
3507 if (*c == 'T')
3508 ++value;
3509
3510 if (c[1] == 'u')
3511 {
3512 /* Eat the 'u' character. */
3513 ++ c;
3514
3515 if (u_reg == value)
3516 is_unpredictable = TRUE;
3517 u_reg = value;
3518 }
3519 if (c[1] == 'U')
3520 {
3521 /* Eat the 'U' character. */
3522 ++ c;
3523
3524 if (U_reg == value)
3525 is_unpredictable = TRUE;
3526 U_reg = value;
3527 }
3528 func (stream, "%s", arm_regnames[value]);
3529 break;
3530 case 'd':
3531 func (stream, "%ld", value);
3532 value_in_comment = value;
3533 break;
3534 case 'b':
3535 func (stream, "%ld", value * 8);
3536 value_in_comment = value * 8;
3537 break;
3538 case 'W':
3539 func (stream, "%ld", value + 1);
3540 value_in_comment = value + 1;
3541 break;
3542 case 'x':
3543 func (stream, "0x%08lx", value);
3544
3545 /* Some SWI instructions have special
3546 meanings. */
3547 if ((given & 0x0fffffff) == 0x0FF00000)
3548 func (stream, "\t; IMB");
3549 else if ((given & 0x0fffffff) == 0x0FF00001)
3550 func (stream, "\t; IMBRange");
3551 break;
3552 case 'X':
3553 func (stream, "%01lx", value & 0xf);
3554 value_in_comment = value;
3555 break;
3556 case '`':
3557 c++;
3558 if (value == 0)
3559 func (stream, "%c", *c);
3560 break;
3561 case '\'':
3562 c++;
3563 if (value == ((1ul << width) - 1))
3564 func (stream, "%c", *c);
3565 break;
3566 case '?':
3567 func (stream, "%c", c[(1 << width) - (int) value]);
3568 c += 1 << width;
3569 break;
3570 default:
3571 abort ();
3572 }
3573 break;
3574
3575 case 'e':
3576 {
3577 int imm;
3578
3579 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3580 func (stream, "%d", imm);
3581 value_in_comment = imm;
3582 }
3583 break;
3584
3585 case 'E':
3586 /* LSB and WIDTH fields of BFI or BFC. The machine-
3587 language instruction encodes LSB and MSB. */
3588 {
3589 long msb = (given & 0x001f0000) >> 16;
3590 long lsb = (given & 0x00000f80) >> 7;
3591 long w = msb - lsb + 1;
3592
3593 if (w > 0)
3594 func (stream, "#%lu, #%lu", lsb, w);
3595 else
3596 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3597 }
3598 break;
3599
3600 case 'R':
3601 /* Get the PSR/banked register name. */
3602 {
3603 const char * name;
3604 unsigned sysm = (given & 0x004f0000) >> 16;
3605
3606 sysm |= (given & 0x300) >> 4;
3607 name = banked_regname (sysm);
3608
3609 if (name != NULL)
3610 func (stream, "%s", name);
3611 else
3612 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3613 }
3614 break;
3615
3616 case 'V':
3617 /* 16-bit unsigned immediate from a MOVT or MOVW
3618 instruction, encoded in bits 0:11 and 15:19. */
3619 {
3620 long hi = (given & 0x000f0000) >> 4;
3621 long lo = (given & 0x00000fff);
3622 long imm16 = hi | lo;
3623
3624 func (stream, "#%lu", imm16);
3625 value_in_comment = imm16;
3626 }
3627 break;
3628
3629 default:
3630 abort ();
3631 }
3632 }
3633 }
3634 else
3635 func (stream, "%c", *c);
3636 }
3637
3638 if (value_in_comment > 32 || value_in_comment < -16)
3639 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3640
3641 if (is_unpredictable)
3642 func (stream, UNPREDICTABLE_INSTRUCTION);
3643
3644 return;
3645 }
3646 }
3647 abort ();
3648 }
3649
3650 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3651
3652 static void
3653 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3654 {
3655 const struct opcode16 *insn;
3656 void *stream = info->stream;
3657 fprintf_ftype func = info->fprintf_func;
3658
3659 for (insn = thumb_opcodes; insn->assembler; insn++)
3660 if ((given & insn->mask) == insn->value)
3661 {
3662 signed long value_in_comment = 0;
3663 const char *c = insn->assembler;
3664
3665 for (; *c; c++)
3666 {
3667 int domaskpc = 0;
3668 int domasklr = 0;
3669
3670 if (*c != '%')
3671 {
3672 func (stream, "%c", *c);
3673 continue;
3674 }
3675
3676 switch (*++c)
3677 {
3678 case '%':
3679 func (stream, "%%");
3680 break;
3681
3682 case 'c':
3683 if (ifthen_state)
3684 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3685 break;
3686
3687 case 'C':
3688 if (ifthen_state)
3689 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3690 else
3691 func (stream, "s");
3692 break;
3693
3694 case 'I':
3695 {
3696 unsigned int tmp;
3697
3698 ifthen_next_state = given & 0xff;
3699 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3700 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3701 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3702 }
3703 break;
3704
3705 case 'x':
3706 if (ifthen_next_state)
3707 func (stream, "\t; unpredictable branch in IT block\n");
3708 break;
3709
3710 case 'X':
3711 if (ifthen_state)
3712 func (stream, "\t; unpredictable <IT:%s>",
3713 arm_conditional[IFTHEN_COND]);
3714 break;
3715
3716 case 'S':
3717 {
3718 long reg;
3719
3720 reg = (given >> 3) & 0x7;
3721 if (given & (1 << 6))
3722 reg += 8;
3723
3724 func (stream, "%s", arm_regnames[reg]);
3725 }
3726 break;
3727
3728 case 'D':
3729 {
3730 long reg;
3731
3732 reg = given & 0x7;
3733 if (given & (1 << 7))
3734 reg += 8;
3735
3736 func (stream, "%s", arm_regnames[reg]);
3737 }
3738 break;
3739
3740 case 'N':
3741 if (given & (1 << 8))
3742 domasklr = 1;
3743 /* Fall through. */
3744 case 'O':
3745 if (*c == 'O' && (given & (1 << 8)))
3746 domaskpc = 1;
3747 /* Fall through. */
3748 case 'M':
3749 {
3750 int started = 0;
3751 int reg;
3752
3753 func (stream, "{");
3754
3755 /* It would be nice if we could spot
3756 ranges, and generate the rS-rE format: */
3757 for (reg = 0; (reg < 8); reg++)
3758 if ((given & (1 << reg)) != 0)
3759 {
3760 if (started)
3761 func (stream, ", ");
3762 started = 1;
3763 func (stream, "%s", arm_regnames[reg]);
3764 }
3765
3766 if (domasklr)
3767 {
3768 if (started)
3769 func (stream, ", ");
3770 started = 1;
3771 func (stream, "%s", arm_regnames[14] /* "lr" */);
3772 }
3773
3774 if (domaskpc)
3775 {
3776 if (started)
3777 func (stream, ", ");
3778 func (stream, "%s", arm_regnames[15] /* "pc" */);
3779 }
3780
3781 func (stream, "}");
3782 }
3783 break;
3784
3785 case 'W':
3786 /* Print writeback indicator for a LDMIA. We are doing a
3787 writeback if the base register is not in the register
3788 mask. */
3789 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3790 func (stream, "!");
3791 break;
3792
3793 case 'b':
3794 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3795 {
3796 bfd_vma address = (pc + 4
3797 + ((given & 0x00f8) >> 2)
3798 + ((given & 0x0200) >> 3));
3799 info->print_address_func (address, info);
3800 }
3801 break;
3802
3803 case 's':
3804 /* Right shift immediate -- bits 6..10; 1-31 print
3805 as themselves, 0 prints as 32. */
3806 {
3807 long imm = (given & 0x07c0) >> 6;
3808 if (imm == 0)
3809 imm = 32;
3810 func (stream, "#%ld", imm);
3811 }
3812 break;
3813
3814 case '0': case '1': case '2': case '3': case '4':
3815 case '5': case '6': case '7': case '8': case '9':
3816 {
3817 int bitstart = *c++ - '0';
3818 int bitend = 0;
3819
3820 while (*c >= '0' && *c <= '9')
3821 bitstart = (bitstart * 10) + *c++ - '0';
3822
3823 switch (*c)
3824 {
3825 case '-':
3826 {
3827 bfd_vma reg;
3828
3829 c++;
3830 while (*c >= '0' && *c <= '9')
3831 bitend = (bitend * 10) + *c++ - '0';
3832 if (!bitend)
3833 abort ();
3834 reg = given >> bitstart;
3835 reg &= (2 << (bitend - bitstart)) - 1;
3836
3837 switch (*c)
3838 {
3839 case 'r':
3840 func (stream, "%s", arm_regnames[reg]);
3841 break;
3842
3843 case 'd':
3844 func (stream, "%ld", (long) reg);
3845 value_in_comment = reg;
3846 break;
3847
3848 case 'H':
3849 func (stream, "%ld", (long) (reg << 1));
3850 value_in_comment = reg << 1;
3851 break;
3852
3853 case 'W':
3854 func (stream, "%ld", (long) (reg << 2));
3855 value_in_comment = reg << 2;
3856 break;
3857
3858 case 'a':
3859 /* PC-relative address -- the bottom two
3860 bits of the address are dropped
3861 before the calculation. */
3862 info->print_address_func
3863 (((pc + 4) & ~3) + (reg << 2), info);
3864 value_in_comment = 0;
3865 break;
3866
3867 case 'x':
3868 func (stream, "0x%04lx", (long) reg);
3869 break;
3870
3871 case 'B':
3872 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3873 info->print_address_func (reg * 2 + pc + 4, info);
3874 value_in_comment = 0;
3875 break;
3876
3877 case 'c':
3878 func (stream, "%s", arm_conditional [reg]);
3879 break;
3880
3881 default:
3882 abort ();
3883 }
3884 }
3885 break;
3886
3887 case '\'':
3888 c++;
3889 if ((given & (1 << bitstart)) != 0)
3890 func (stream, "%c", *c);
3891 break;
3892
3893 case '?':
3894 ++c;
3895 if ((given & (1 << bitstart)) != 0)
3896 func (stream, "%c", *c++);
3897 else
3898 func (stream, "%c", *++c);
3899 break;
3900
3901 default:
3902 abort ();
3903 }
3904 }
3905 break;
3906
3907 default:
3908 abort ();
3909 }
3910 }
3911
3912 if (value_in_comment > 32 || value_in_comment < -16)
3913 func (stream, "\t; 0x%lx", value_in_comment);
3914 return;
3915 }
3916
3917 /* No match. */
3918 abort ();
3919 }
3920
3921 /* Return the name of an V7M special register. */
3922
3923 static const char *
3924 psr_name (int regno)
3925 {
3926 switch (regno)
3927 {
3928 case 0: return "APSR";
3929 case 1: return "IAPSR";
3930 case 2: return "EAPSR";
3931 case 3: return "PSR";
3932 case 5: return "IPSR";
3933 case 6: return "EPSR";
3934 case 7: return "IEPSR";
3935 case 8: return "MSP";
3936 case 9: return "PSP";
3937 case 16: return "PRIMASK";
3938 case 17: return "BASEPRI";
3939 case 18: return "BASEPRI_MAX";
3940 case 19: return "FAULTMASK";
3941 case 20: return "CONTROL";
3942 default: return "<unknown>";
3943 }
3944 }
3945
3946 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3947
3948 static void
3949 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3950 {
3951 const struct opcode32 *insn;
3952 void *stream = info->stream;
3953 fprintf_ftype func = info->fprintf_func;
3954
3955 if (print_insn_coprocessor (pc, info, given, TRUE))
3956 return;
3957
3958 if (print_insn_neon (info, given, TRUE))
3959 return;
3960
3961 for (insn = thumb32_opcodes; insn->assembler; insn++)
3962 if ((given & insn->mask) == insn->value)
3963 {
3964 bfd_boolean is_unpredictable = FALSE;
3965 signed long value_in_comment = 0;
3966 const char *c = insn->assembler;
3967
3968 for (; *c; c++)
3969 {
3970 if (*c != '%')
3971 {
3972 func (stream, "%c", *c);
3973 continue;
3974 }
3975
3976 switch (*++c)
3977 {
3978 case '%':
3979 func (stream, "%%");
3980 break;
3981
3982 case 'c':
3983 if (ifthen_state)
3984 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3985 break;
3986
3987 case 'x':
3988 if (ifthen_next_state)
3989 func (stream, "\t; unpredictable branch in IT block\n");
3990 break;
3991
3992 case 'X':
3993 if (ifthen_state)
3994 func (stream, "\t; unpredictable <IT:%s>",
3995 arm_conditional[IFTHEN_COND]);
3996 break;
3997
3998 case 'I':
3999 {
4000 unsigned int imm12 = 0;
4001
4002 imm12 |= (given & 0x000000ffu);
4003 imm12 |= (given & 0x00007000u) >> 4;
4004 imm12 |= (given & 0x04000000u) >> 15;
4005 func (stream, "#%u", imm12);
4006 value_in_comment = imm12;
4007 }
4008 break;
4009
4010 case 'M':
4011 {
4012 unsigned int bits = 0, imm, imm8, mod;
4013
4014 bits |= (given & 0x000000ffu);
4015 bits |= (given & 0x00007000u) >> 4;
4016 bits |= (given & 0x04000000u) >> 15;
4017 imm8 = (bits & 0x0ff);
4018 mod = (bits & 0xf00) >> 8;
4019 switch (mod)
4020 {
4021 case 0: imm = imm8; break;
4022 case 1: imm = ((imm8 << 16) | imm8); break;
4023 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
4024 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
4025 default:
4026 mod = (bits & 0xf80) >> 7;
4027 imm8 = (bits & 0x07f) | 0x80;
4028 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
4029 }
4030 func (stream, "#%u", imm);
4031 value_in_comment = imm;
4032 }
4033 break;
4034
4035 case 'J':
4036 {
4037 unsigned int imm = 0;
4038
4039 imm |= (given & 0x000000ffu);
4040 imm |= (given & 0x00007000u) >> 4;
4041 imm |= (given & 0x04000000u) >> 15;
4042 imm |= (given & 0x000f0000u) >> 4;
4043 func (stream, "#%u", imm);
4044 value_in_comment = imm;
4045 }
4046 break;
4047
4048 case 'K':
4049 {
4050 unsigned int imm = 0;
4051
4052 imm |= (given & 0x000f0000u) >> 16;
4053 imm |= (given & 0x00000ff0u) >> 0;
4054 imm |= (given & 0x0000000fu) << 12;
4055 func (stream, "#%u", imm);
4056 value_in_comment = imm;
4057 }
4058 break;
4059
4060 case 'V':
4061 {
4062 unsigned int imm = 0;
4063
4064 imm |= (given & 0x00000fffu);
4065 imm |= (given & 0x000f0000u) >> 4;
4066 func (stream, "#%u", imm);
4067 value_in_comment = imm;
4068 }
4069 break;
4070
4071 case 'S':
4072 {
4073 unsigned int reg = (given & 0x0000000fu);
4074 unsigned int stp = (given & 0x00000030u) >> 4;
4075 unsigned int imm = 0;
4076 imm |= (given & 0x000000c0u) >> 6;
4077 imm |= (given & 0x00007000u) >> 10;
4078
4079 func (stream, "%s", arm_regnames[reg]);
4080 switch (stp)
4081 {
4082 case 0:
4083 if (imm > 0)
4084 func (stream, ", lsl #%u", imm);
4085 break;
4086
4087 case 1:
4088 if (imm == 0)
4089 imm = 32;
4090 func (stream, ", lsr #%u", imm);
4091 break;
4092
4093 case 2:
4094 if (imm == 0)
4095 imm = 32;
4096 func (stream, ", asr #%u", imm);
4097 break;
4098
4099 case 3:
4100 if (imm == 0)
4101 func (stream, ", rrx");
4102 else
4103 func (stream, ", ror #%u", imm);
4104 }
4105 }
4106 break;
4107
4108 case 'a':
4109 {
4110 unsigned int Rn = (given & 0x000f0000) >> 16;
4111 unsigned int U = ! NEGATIVE_BIT_SET;
4112 unsigned int op = (given & 0x00000f00) >> 8;
4113 unsigned int i12 = (given & 0x00000fff);
4114 unsigned int i8 = (given & 0x000000ff);
4115 bfd_boolean writeback = FALSE, postind = FALSE;
4116 bfd_vma offset = 0;
4117
4118 func (stream, "[%s", arm_regnames[Rn]);
4119 if (U) /* 12-bit positive immediate offset. */
4120 {
4121 offset = i12;
4122 if (Rn != 15)
4123 value_in_comment = offset;
4124 }
4125 else if (Rn == 15) /* 12-bit negative immediate offset. */
4126 offset = - (int) i12;
4127 else if (op == 0x0) /* Shifted register offset. */
4128 {
4129 unsigned int Rm = (i8 & 0x0f);
4130 unsigned int sh = (i8 & 0x30) >> 4;
4131
4132 func (stream, ", %s", arm_regnames[Rm]);
4133 if (sh)
4134 func (stream, ", lsl #%u", sh);
4135 func (stream, "]");
4136 break;
4137 }
4138 else switch (op)
4139 {
4140 case 0xE: /* 8-bit positive immediate offset. */
4141 offset = i8;
4142 break;
4143
4144 case 0xC: /* 8-bit negative immediate offset. */
4145 offset = -i8;
4146 break;
4147
4148 case 0xF: /* 8-bit + preindex with wb. */
4149 offset = i8;
4150 writeback = TRUE;
4151 break;
4152
4153 case 0xD: /* 8-bit - preindex with wb. */
4154 offset = -i8;
4155 writeback = TRUE;
4156 break;
4157
4158 case 0xB: /* 8-bit + postindex. */
4159 offset = i8;
4160 postind = TRUE;
4161 break;
4162
4163 case 0x9: /* 8-bit - postindex. */
4164 offset = -i8;
4165 postind = TRUE;
4166 break;
4167
4168 default:
4169 func (stream, ", <undefined>]");
4170 goto skip;
4171 }
4172
4173 if (postind)
4174 func (stream, "], #%d", (int) offset);
4175 else
4176 {
4177 if (offset)
4178 func (stream, ", #%d", (int) offset);
4179 func (stream, writeback ? "]!" : "]");
4180 }
4181
4182 if (Rn == 15)
4183 {
4184 func (stream, "\t; ");
4185 info->print_address_func (((pc + 4) & ~3) + offset, info);
4186 }
4187 }
4188 skip:
4189 break;
4190
4191 case 'A':
4192 {
4193 unsigned int U = ! NEGATIVE_BIT_SET;
4194 unsigned int W = WRITEBACK_BIT_SET;
4195 unsigned int Rn = (given & 0x000f0000) >> 16;
4196 unsigned int off = (given & 0x000000ff);
4197
4198 func (stream, "[%s", arm_regnames[Rn]);
4199
4200 if (PRE_BIT_SET)
4201 {
4202 if (off || !U)
4203 {
4204 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4205 value_in_comment = off * 4 * U ? 1 : -1;
4206 }
4207 func (stream, "]");
4208 if (W)
4209 func (stream, "!");
4210 }
4211 else
4212 {
4213 func (stream, "], ");
4214 if (W)
4215 {
4216 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4217 value_in_comment = off * 4 * U ? 1 : -1;
4218 }
4219 else
4220 {
4221 func (stream, "{%u}", off);
4222 value_in_comment = off;
4223 }
4224 }
4225 }
4226 break;
4227
4228 case 'w':
4229 {
4230 unsigned int Sbit = (given & 0x01000000) >> 24;
4231 unsigned int type = (given & 0x00600000) >> 21;
4232
4233 switch (type)
4234 {
4235 case 0: func (stream, Sbit ? "sb" : "b"); break;
4236 case 1: func (stream, Sbit ? "sh" : "h"); break;
4237 case 2:
4238 if (Sbit)
4239 func (stream, "??");
4240 break;
4241 case 3:
4242 func (stream, "??");
4243 break;
4244 }
4245 }
4246 break;
4247
4248 case 'm':
4249 {
4250 int started = 0;
4251 int reg;
4252
4253 func (stream, "{");
4254 for (reg = 0; reg < 16; reg++)
4255 if ((given & (1 << reg)) != 0)
4256 {
4257 if (started)
4258 func (stream, ", ");
4259 started = 1;
4260 func (stream, "%s", arm_regnames[reg]);
4261 }
4262 func (stream, "}");
4263 }
4264 break;
4265
4266 case 'E':
4267 {
4268 unsigned int msb = (given & 0x0000001f);
4269 unsigned int lsb = 0;
4270
4271 lsb |= (given & 0x000000c0u) >> 6;
4272 lsb |= (given & 0x00007000u) >> 10;
4273 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4274 }
4275 break;
4276
4277 case 'F':
4278 {
4279 unsigned int width = (given & 0x0000001f) + 1;
4280 unsigned int lsb = 0;
4281
4282 lsb |= (given & 0x000000c0u) >> 6;
4283 lsb |= (given & 0x00007000u) >> 10;
4284 func (stream, "#%u, #%u", lsb, width);
4285 }
4286 break;
4287
4288 case 'b':
4289 {
4290 unsigned int S = (given & 0x04000000u) >> 26;
4291 unsigned int J1 = (given & 0x00002000u) >> 13;
4292 unsigned int J2 = (given & 0x00000800u) >> 11;
4293 bfd_vma offset = 0;
4294
4295 offset |= !S << 20;
4296 offset |= J2 << 19;
4297 offset |= J1 << 18;
4298 offset |= (given & 0x003f0000) >> 4;
4299 offset |= (given & 0x000007ff) << 1;
4300 offset -= (1 << 20);
4301
4302 info->print_address_func (pc + 4 + offset, info);
4303 }
4304 break;
4305
4306 case 'B':
4307 {
4308 unsigned int S = (given & 0x04000000u) >> 26;
4309 unsigned int I1 = (given & 0x00002000u) >> 13;
4310 unsigned int I2 = (given & 0x00000800u) >> 11;
4311 bfd_vma offset = 0;
4312
4313 offset |= !S << 24;
4314 offset |= !(I1 ^ S) << 23;
4315 offset |= !(I2 ^ S) << 22;
4316 offset |= (given & 0x03ff0000u) >> 4;
4317 offset |= (given & 0x000007ffu) << 1;
4318 offset -= (1 << 24);
4319 offset += pc + 4;
4320
4321 /* BLX target addresses are always word aligned. */
4322 if ((given & 0x00001000u) == 0)
4323 offset &= ~2u;
4324
4325 info->print_address_func (offset, info);
4326 }
4327 break;
4328
4329 case 's':
4330 {
4331 unsigned int shift = 0;
4332
4333 shift |= (given & 0x000000c0u) >> 6;
4334 shift |= (given & 0x00007000u) >> 10;
4335 if (WRITEBACK_BIT_SET)
4336 func (stream, ", asr #%u", shift);
4337 else if (shift)
4338 func (stream, ", lsl #%u", shift);
4339 /* else print nothing - lsl #0 */
4340 }
4341 break;
4342
4343 case 'R':
4344 {
4345 unsigned int rot = (given & 0x00000030) >> 4;
4346
4347 if (rot)
4348 func (stream, ", ror #%u", rot * 8);
4349 }
4350 break;
4351
4352 case 'U':
4353 if ((given & 0xf0) == 0x60)
4354 {
4355 switch (given & 0xf)
4356 {
4357 case 0xf: func (stream, "sy"); break;
4358 default:
4359 func (stream, "#%d", (int) given & 0xf);
4360 break;
4361 }
4362 }
4363 else
4364 {
4365 const char * opt = data_barrier_option (given & 0xf);
4366 if (opt != NULL)
4367 func (stream, "%s", opt);
4368 else
4369 func (stream, "#%d", (int) given & 0xf);
4370 }
4371 break;
4372
4373 case 'C':
4374 if ((given & 0xff) == 0)
4375 {
4376 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4377 if (given & 0x800)
4378 func (stream, "f");
4379 if (given & 0x400)
4380 func (stream, "s");
4381 if (given & 0x200)
4382 func (stream, "x");
4383 if (given & 0x100)
4384 func (stream, "c");
4385 }
4386 else if ((given & 0x20) == 0x20)
4387 {
4388 char const* name;
4389 unsigned sysm = (given & 0xf00) >> 8;
4390
4391 sysm |= (given & 0x30);
4392 sysm |= (given & 0x00100000) >> 14;
4393 name = banked_regname (sysm);
4394
4395 if (name != NULL)
4396 func (stream, "%s", name);
4397 else
4398 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
4399 }
4400 else
4401 {
4402 func (stream, "%s", psr_name (given & 0xff));
4403 }
4404 break;
4405
4406 case 'D':
4407 if (((given & 0xff) == 0)
4408 || ((given & 0x20) == 0x20))
4409 {
4410 char const* name;
4411 unsigned sm = (given & 0xf0000) >> 16;
4412
4413 sm |= (given & 0x30);
4414 sm |= (given & 0x00100000) >> 14;
4415 name = banked_regname (sm);
4416
4417 if (name != NULL)
4418 func (stream, "%s", name);
4419 else
4420 func (stream, "(UNDEF: %lu)", (unsigned long) sm);
4421 }
4422 else
4423 func (stream, "%s", psr_name (given & 0xff));
4424 break;
4425
4426 case '0': case '1': case '2': case '3': case '4':
4427 case '5': case '6': case '7': case '8': case '9':
4428 {
4429 int width;
4430 unsigned long val;
4431
4432 c = arm_decode_bitfield (c, given, &val, &width);
4433
4434 switch (*c)
4435 {
4436 case 'd':
4437 func (stream, "%lu", val);
4438 value_in_comment = val;
4439 break;
4440
4441 case 'W':
4442 func (stream, "%lu", val * 4);
4443 value_in_comment = val * 4;
4444 break;
4445
4446 case 'S':
4447 if (val == 13)
4448 is_unpredictable = TRUE;
4449 /* Fall through. */
4450 case 'R':
4451 if (val == 15)
4452 is_unpredictable = TRUE;
4453 /* Fall through. */
4454 case 'r':
4455 func (stream, "%s", arm_regnames[val]);
4456 break;
4457
4458 case 'c':
4459 func (stream, "%s", arm_conditional[val]);
4460 break;
4461
4462 case '\'':
4463 c++;
4464 if (val == ((1ul << width) - 1))
4465 func (stream, "%c", *c);
4466 break;
4467
4468 case '`':
4469 c++;
4470 if (val == 0)
4471 func (stream, "%c", *c);
4472 break;
4473
4474 case '?':
4475 func (stream, "%c", c[(1 << width) - (int) val]);
4476 c += 1 << width;
4477 break;
4478
4479 case 'x':
4480 func (stream, "0x%lx", val & 0xffffffffUL);
4481 break;
4482
4483 default:
4484 abort ();
4485 }
4486 }
4487 break;
4488
4489 case 'L':
4490 /* PR binutils/12534
4491 If we have a PC relative offset in an LDRD or STRD
4492 instructions then display the decoded address. */
4493 if (((given >> 16) & 0xf) == 0xf)
4494 {
4495 bfd_vma offset = (given & 0xff) * 4;
4496
4497 if ((given & (1 << 23)) == 0)
4498 offset = - offset;
4499 func (stream, "\t; ");
4500 info->print_address_func ((pc & ~3) + 4 + offset, info);
4501 }
4502 break;
4503
4504 default:
4505 abort ();
4506 }
4507 }
4508
4509 if (value_in_comment > 32 || value_in_comment < -16)
4510 func (stream, "\t; 0x%lx", value_in_comment);
4511
4512 if (is_unpredictable)
4513 func (stream, UNPREDICTABLE_INSTRUCTION);
4514
4515 return;
4516 }
4517
4518 /* No match. */
4519 abort ();
4520 }
4521
4522 /* Print data bytes on INFO->STREAM. */
4523
4524 static void
4525 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4526 struct disassemble_info *info,
4527 long given)
4528 {
4529 switch (info->bytes_per_chunk)
4530 {
4531 case 1:
4532 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4533 break;
4534 case 2:
4535 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4536 break;
4537 case 4:
4538 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4539 break;
4540 default:
4541 abort ();
4542 }
4543 }
4544
4545 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4546 being displayed in symbol relative addresses. */
4547
4548 bfd_boolean
4549 arm_symbol_is_valid (asymbol * sym,
4550 struct disassemble_info * info ATTRIBUTE_UNUSED)
4551 {
4552 const char * name;
4553
4554 if (sym == NULL)
4555 return FALSE;
4556
4557 name = bfd_asymbol_name (sym);
4558
4559 return (name && *name != '$');
4560 }
4561
4562 /* Parse an individual disassembler option. */
4563
4564 void
4565 parse_arm_disassembler_option (char *option)
4566 {
4567 if (option == NULL)
4568 return;
4569
4570 if (CONST_STRNEQ (option, "reg-names-"))
4571 {
4572 int i;
4573
4574 option += 10;
4575
4576 for (i = NUM_ARM_REGNAMES; i--;)
4577 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4578 {
4579 regname_selected = i;
4580 break;
4581 }
4582
4583 if (i < 0)
4584 /* XXX - should break 'option' at following delimiter. */
4585 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4586 }
4587 else if (CONST_STRNEQ (option, "force-thumb"))
4588 force_thumb = 1;
4589 else if (CONST_STRNEQ (option, "no-force-thumb"))
4590 force_thumb = 0;
4591 else
4592 /* XXX - should break 'option' at following delimiter. */
4593 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4594
4595 return;
4596 }
4597
4598 /* Parse the string of disassembler options, spliting it at whitespaces
4599 or commas. (Whitespace separators supported for backwards compatibility). */
4600
4601 static void
4602 parse_disassembler_options (char *options)
4603 {
4604 if (options == NULL)
4605 return;
4606
4607 while (*options)
4608 {
4609 parse_arm_disassembler_option (options);
4610
4611 /* Skip forward to next seperator. */
4612 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4613 ++ options;
4614 /* Skip forward past seperators. */
4615 while (ISSPACE (*options) || (*options == ','))
4616 ++ options;
4617 }
4618 }
4619
4620 /* Search back through the insn stream to determine if this instruction is
4621 conditionally executed. */
4622
4623 static void
4624 find_ifthen_state (bfd_vma pc,
4625 struct disassemble_info *info,
4626 bfd_boolean little)
4627 {
4628 unsigned char b[2];
4629 unsigned int insn;
4630 int status;
4631 /* COUNT is twice the number of instructions seen. It will be odd if we
4632 just crossed an instruction boundary. */
4633 int count;
4634 int it_count;
4635 unsigned int seen_it;
4636 bfd_vma addr;
4637
4638 ifthen_address = pc;
4639 ifthen_state = 0;
4640
4641 addr = pc;
4642 count = 1;
4643 it_count = 0;
4644 seen_it = 0;
4645 /* Scan backwards looking for IT instructions, keeping track of where
4646 instruction boundaries are. We don't know if something is actually an
4647 IT instruction until we find a definite instruction boundary. */
4648 for (;;)
4649 {
4650 if (addr == 0 || info->symbol_at_address_func (addr, info))
4651 {
4652 /* A symbol must be on an instruction boundary, and will not
4653 be within an IT block. */
4654 if (seen_it && (count & 1))
4655 break;
4656
4657 return;
4658 }
4659 addr -= 2;
4660 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4661 if (status)
4662 return;
4663
4664 if (little)
4665 insn = (b[0]) | (b[1] << 8);
4666 else
4667 insn = (b[1]) | (b[0] << 8);
4668 if (seen_it)
4669 {
4670 if ((insn & 0xf800) < 0xe800)
4671 {
4672 /* Addr + 2 is an instruction boundary. See if this matches
4673 the expected boundary based on the position of the last
4674 IT candidate. */
4675 if (count & 1)
4676 break;
4677 seen_it = 0;
4678 }
4679 }
4680 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4681 {
4682 /* This could be an IT instruction. */
4683 seen_it = insn;
4684 it_count = count >> 1;
4685 }
4686 if ((insn & 0xf800) >= 0xe800)
4687 count++;
4688 else
4689 count = (count + 2) | 1;
4690 /* IT blocks contain at most 4 instructions. */
4691 if (count >= 8 && !seen_it)
4692 return;
4693 }
4694 /* We found an IT instruction. */
4695 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4696 if ((ifthen_state & 0xf) == 0)
4697 ifthen_state = 0;
4698 }
4699
4700 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4701 mapping symbol. */
4702
4703 static int
4704 is_mapping_symbol (struct disassemble_info *info, int n,
4705 enum map_type *map_type)
4706 {
4707 const char *name;
4708
4709 name = bfd_asymbol_name (info->symtab[n]);
4710 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4711 && (name[2] == 0 || name[2] == '.'))
4712 {
4713 *map_type = ((name[1] == 'a') ? MAP_ARM
4714 : (name[1] == 't') ? MAP_THUMB
4715 : MAP_DATA);
4716 return TRUE;
4717 }
4718
4719 return FALSE;
4720 }
4721
4722 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4723 Returns nonzero if *MAP_TYPE was set. */
4724
4725 static int
4726 get_map_sym_type (struct disassemble_info *info,
4727 int n,
4728 enum map_type *map_type)
4729 {
4730 /* If the symbol is in a different section, ignore it. */
4731 if (info->section != NULL && info->section != info->symtab[n]->section)
4732 return FALSE;
4733
4734 return is_mapping_symbol (info, n, map_type);
4735 }
4736
4737 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4738 Returns nonzero if *MAP_TYPE was set. */
4739
4740 static int
4741 get_sym_code_type (struct disassemble_info *info,
4742 int n,
4743 enum map_type *map_type)
4744 {
4745 elf_symbol_type *es;
4746 unsigned int type;
4747
4748 /* If the symbol is in a different section, ignore it. */
4749 if (info->section != NULL && info->section != info->symtab[n]->section)
4750 return FALSE;
4751
4752 es = *(elf_symbol_type **)(info->symtab + n);
4753 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4754
4755 /* If the symbol has function type then use that. */
4756 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4757 {
4758 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4759 *map_type = MAP_THUMB;
4760 else
4761 *map_type = MAP_ARM;
4762 return TRUE;
4763 }
4764
4765 return FALSE;
4766 }
4767
4768 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4769 of the supplied arm_feature_set structure with bitmasks indicating
4770 the support base architectures and coprocessor extensions.
4771
4772 FIXME: This could more efficiently implemented as a constant array,
4773 although it would also be less robust. */
4774
4775 static void
4776 select_arm_features (unsigned long mach,
4777 arm_feature_set * features)
4778 {
4779 #undef ARM_FEATURE
4780 #define ARM_FEATURE(ARCH,CEXT) \
4781 features->core = (ARCH); \
4782 features->coproc = (CEXT) | FPU_FPA; \
4783 return
4784
4785 switch (mach)
4786 {
4787 case bfd_mach_arm_2: ARM_ARCH_V2;
4788 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4789 case bfd_mach_arm_3: ARM_ARCH_V3;
4790 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4791 case bfd_mach_arm_4: ARM_ARCH_V4;
4792 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4793 case bfd_mach_arm_5: ARM_ARCH_V5;
4794 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4795 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4796 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4797 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4798 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4799 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4800 /* If the machine type is unknown allow all
4801 architecture types and all extensions. */
4802 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4803 default:
4804 abort ();
4805 }
4806 }
4807
4808
4809 /* NOTE: There are no checks in these routines that
4810 the relevant number of data bytes exist. */
4811
4812 static int
4813 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4814 {
4815 unsigned char b[4];
4816 long given;
4817 int status;
4818 int is_thumb = FALSE;
4819 int is_data = FALSE;
4820 int little_code;
4821 unsigned int size = 4;
4822 void (*printer) (bfd_vma, struct disassemble_info *, long);
4823 bfd_boolean found = FALSE;
4824 struct arm_private_data *private_data;
4825
4826 if (info->disassembler_options)
4827 {
4828 parse_disassembler_options (info->disassembler_options);
4829
4830 /* To avoid repeated parsing of these options, we remove them here. */
4831 info->disassembler_options = NULL;
4832 }
4833
4834 /* PR 10288: Control which instructions will be disassembled. */
4835 if (info->private_data == NULL)
4836 {
4837 static struct arm_private_data private;
4838
4839 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4840 /* If the user did not use the -m command line switch then default to
4841 disassembling all types of ARM instruction.
4842
4843 The info->mach value has to be ignored as this will be based on
4844 the default archictecture for the target and/or hints in the notes
4845 section, but it will never be greater than the current largest arm
4846 machine value (iWMMXt2), which is only equivalent to the V5TE
4847 architecture. ARM architectures have advanced beyond the machine
4848 value encoding, and these newer architectures would be ignored if
4849 the machine value was used.
4850
4851 Ie the -m switch is used to restrict which instructions will be
4852 disassembled. If it is necessary to use the -m switch to tell
4853 objdump that an ARM binary is being disassembled, eg because the
4854 input is a raw binary file, but it is also desired to disassemble
4855 all ARM instructions then use "-marm". This will select the
4856 "unknown" arm architecture which is compatible with any ARM
4857 instruction. */
4858 info->mach = bfd_mach_arm_unknown;
4859
4860 /* Compute the architecture bitmask from the machine number.
4861 Note: This assumes that the machine number will not change
4862 during disassembly.... */
4863 select_arm_features (info->mach, & private.features);
4864
4865 private.has_mapping_symbols = -1;
4866 private.last_mapping_sym = -1;
4867 private.last_mapping_addr = 0;
4868
4869 info->private_data = & private;
4870 }
4871
4872 private_data = info->private_data;
4873
4874 /* Decide if our code is going to be little-endian, despite what the
4875 function argument might say. */
4876 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4877
4878 /* For ELF, consult the symbol table to determine what kind of code
4879 or data we have. */
4880 if (info->symtab_size != 0
4881 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4882 {
4883 bfd_vma addr;
4884 int n, start;
4885 int last_sym = -1;
4886 enum map_type type = MAP_ARM;
4887
4888 /* Start scanning at the start of the function, or wherever
4889 we finished last time. */
4890 /* PR 14006. When the address is 0 we are either at the start of the
4891 very first function, or else the first function in a new, unlinked
4892 executable section (eg because uf -ffunction-sections). Either way
4893 start scanning from the beginning of the symbol table, not where we
4894 left off last time. */
4895 if (pc == 0)
4896 start = 0;
4897 else
4898 {
4899 start = info->symtab_pos + 1;
4900 if (start < private_data->last_mapping_sym)
4901 start = private_data->last_mapping_sym;
4902 }
4903 found = FALSE;
4904
4905 /* First, look for mapping symbols. */
4906 if (private_data->has_mapping_symbols != 0)
4907 {
4908 /* Scan up to the location being disassembled. */
4909 for (n = start; n < info->symtab_size; n++)
4910 {
4911 addr = bfd_asymbol_value (info->symtab[n]);
4912 if (addr > pc)
4913 break;
4914 if (get_map_sym_type (info, n, &type))
4915 {
4916 last_sym = n;
4917 found = TRUE;
4918 }
4919 }
4920
4921 if (!found)
4922 {
4923 /* No mapping symbol found at this address. Look backwards
4924 for a preceding one. */
4925 for (n = start - 1; n >= 0; n--)
4926 {
4927 if (get_map_sym_type (info, n, &type))
4928 {
4929 last_sym = n;
4930 found = TRUE;
4931 break;
4932 }
4933 }
4934 }
4935
4936 if (found)
4937 private_data->has_mapping_symbols = 1;
4938
4939 /* No mapping symbols were found. A leading $d may be
4940 omitted for sections which start with data; but for
4941 compatibility with legacy and stripped binaries, only
4942 assume the leading $d if there is at least one mapping
4943 symbol in the file. */
4944 if (!found && private_data->has_mapping_symbols == -1)
4945 {
4946 /* Look for mapping symbols, in any section. */
4947 for (n = 0; n < info->symtab_size; n++)
4948 if (is_mapping_symbol (info, n, &type))
4949 {
4950 private_data->has_mapping_symbols = 1;
4951 break;
4952 }
4953 if (private_data->has_mapping_symbols == -1)
4954 private_data->has_mapping_symbols = 0;
4955 }
4956
4957 if (!found && private_data->has_mapping_symbols == 1)
4958 {
4959 type = MAP_DATA;
4960 found = TRUE;
4961 }
4962 }
4963
4964 /* Next search for function symbols to separate ARM from Thumb
4965 in binaries without mapping symbols. */
4966 if (!found)
4967 {
4968 /* Scan up to the location being disassembled. */
4969 for (n = start; n < info->symtab_size; n++)
4970 {
4971 addr = bfd_asymbol_value (info->symtab[n]);
4972 if (addr > pc)
4973 break;
4974 if (get_sym_code_type (info, n, &type))
4975 {
4976 last_sym = n;
4977 found = TRUE;
4978 }
4979 }
4980
4981 if (!found)
4982 {
4983 /* No mapping symbol found at this address. Look backwards
4984 for a preceding one. */
4985 for (n = start - 1; n >= 0; n--)
4986 {
4987 if (get_sym_code_type (info, n, &type))
4988 {
4989 last_sym = n;
4990 found = TRUE;
4991 break;
4992 }
4993 }
4994 }
4995 }
4996
4997 private_data->last_mapping_sym = last_sym;
4998 private_data->last_type = type;
4999 is_thumb = (private_data->last_type == MAP_THUMB);
5000 is_data = (private_data->last_type == MAP_DATA);
5001
5002 /* Look a little bit ahead to see if we should print out
5003 two or four bytes of data. If there's a symbol,
5004 mapping or otherwise, after two bytes then don't
5005 print more. */
5006 if (is_data)
5007 {
5008 size = 4 - (pc & 3);
5009 for (n = last_sym + 1; n < info->symtab_size; n++)
5010 {
5011 addr = bfd_asymbol_value (info->symtab[n]);
5012 if (addr > pc
5013 && (info->section == NULL
5014 || info->section == info->symtab[n]->section))
5015 {
5016 if (addr - pc < size)
5017 size = addr - pc;
5018 break;
5019 }
5020 }
5021 /* If the next symbol is after three bytes, we need to
5022 print only part of the data, so that we can use either
5023 .byte or .short. */
5024 if (size == 3)
5025 size = (pc & 1) ? 1 : 2;
5026 }
5027 }
5028
5029 if (info->symbols != NULL)
5030 {
5031 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
5032 {
5033 coff_symbol_type * cs;
5034
5035 cs = coffsymbol (*info->symbols);
5036 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
5037 || cs->native->u.syment.n_sclass == C_THUMBSTAT
5038 || cs->native->u.syment.n_sclass == C_THUMBLABEL
5039 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
5040 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
5041 }
5042 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
5043 && !found)
5044 {
5045 /* If no mapping symbol has been found then fall back to the type
5046 of the function symbol. */
5047 elf_symbol_type * es;
5048 unsigned int type;
5049
5050 es = *(elf_symbol_type **)(info->symbols);
5051 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
5052
5053 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
5054 == ST_BRANCH_TO_THUMB)
5055 || type == STT_ARM_16BIT);
5056 }
5057 }
5058
5059 if (force_thumb)
5060 is_thumb = TRUE;
5061
5062 if (is_data)
5063 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5064 else
5065 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5066
5067 info->bytes_per_line = 4;
5068
5069 /* PR 10263: Disassemble data if requested to do so by the user. */
5070 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
5071 {
5072 int i;
5073
5074 /* Size was already set above. */
5075 info->bytes_per_chunk = size;
5076 printer = print_insn_data;
5077
5078 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
5079 given = 0;
5080 if (little)
5081 for (i = size - 1; i >= 0; i--)
5082 given = b[i] | (given << 8);
5083 else
5084 for (i = 0; i < (int) size; i++)
5085 given = b[i] | (given << 8);
5086 }
5087 else if (!is_thumb)
5088 {
5089 /* In ARM mode endianness is a straightforward issue: the instruction
5090 is four bytes long and is either ordered 0123 or 3210. */
5091 printer = print_insn_arm;
5092 info->bytes_per_chunk = 4;
5093 size = 4;
5094
5095 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
5096 if (little_code)
5097 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
5098 else
5099 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
5100 }
5101 else
5102 {
5103 /* In Thumb mode we have the additional wrinkle of two
5104 instruction lengths. Fortunately, the bits that determine
5105 the length of the current instruction are always to be found
5106 in the first two bytes. */
5107 printer = print_insn_thumb16;
5108 info->bytes_per_chunk = 2;
5109 size = 2;
5110
5111 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
5112 if (little_code)
5113 given = (b[0]) | (b[1] << 8);
5114 else
5115 given = (b[1]) | (b[0] << 8);
5116
5117 if (!status)
5118 {
5119 /* These bit patterns signal a four-byte Thumb
5120 instruction. */
5121 if ((given & 0xF800) == 0xF800
5122 || (given & 0xF800) == 0xF000
5123 || (given & 0xF800) == 0xE800)
5124 {
5125 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
5126 if (little_code)
5127 given = (b[0]) | (b[1] << 8) | (given << 16);
5128 else
5129 given = (b[1]) | (b[0] << 8) | (given << 16);
5130
5131 printer = print_insn_thumb32;
5132 size = 4;
5133 }
5134 }
5135
5136 if (ifthen_address != pc)
5137 find_ifthen_state (pc, info, little_code);
5138
5139 if (ifthen_state)
5140 {
5141 if ((ifthen_state & 0xf) == 0x8)
5142 ifthen_next_state = 0;
5143 else
5144 ifthen_next_state = (ifthen_state & 0xe0)
5145 | ((ifthen_state & 0xf) << 1);
5146 }
5147 }
5148
5149 if (status)
5150 {
5151 info->memory_error_func (status, pc, info);
5152 return -1;
5153 }
5154 if (info->flags & INSN_HAS_RELOC)
5155 /* If the instruction has a reloc associated with it, then
5156 the offset field in the instruction will actually be the
5157 addend for the reloc. (We are using REL type relocs).
5158 In such cases, we can ignore the pc when computing
5159 addresses, since the addend is not currently pc-relative. */
5160 pc = 0;
5161
5162 printer (pc, info, given);
5163
5164 if (is_thumb)
5165 {
5166 ifthen_state = ifthen_next_state;
5167 ifthen_address += size;
5168 }
5169 return size;
5170 }
5171
5172 int
5173 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
5174 {
5175 /* Detect BE8-ness and record it in the disassembler info. */
5176 if (info->flavour == bfd_target_elf_flavour
5177 && info->section != NULL
5178 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
5179 info->endian_code = BFD_ENDIAN_LITTLE;
5180
5181 return print_insn (pc, info, FALSE);
5182 }
5183
5184 int
5185 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
5186 {
5187 return print_insn (pc, info, TRUE);
5188 }
5189
5190 void
5191 print_arm_disassembler_options (FILE *stream)
5192 {
5193 int i;
5194
5195 fprintf (stream, _("\n\
5196 The following ARM specific disassembler options are supported for use with\n\
5197 the -M switch:\n"));
5198
5199 for (i = NUM_ARM_REGNAMES; i--;)
5200 fprintf (stream, " reg-names-%s %*c%s\n",
5201 regnames[i].name,
5202 (int)(14 - strlen (regnames[i].name)), ' ',
5203 regnames[i].description);
5204
5205 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
5206 fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");
5207 }
This page took 0.197688 seconds and 4 git commands to generate.