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