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