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