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