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