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