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