arm-dis.c revision 1.1.1.4 1 /* Instruction printing code for the ARM
2 Copyright (C) 1994-2015 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 if (NEGATIVE_BIT_SET)
2588 offset = -offset;
2589 }
2590
2591 return (signed long) offset;
2592 }
2593
2594 /* Print one neon instruction on INFO->STREAM.
2595 Return TRUE if the instuction matched, FALSE if this is not a
2596 recognised neon instruction. */
2597
2598 static bfd_boolean
2599 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2600 {
2601 const struct opcode32 *insn;
2602 void *stream = info->stream;
2603 fprintf_ftype func = info->fprintf_func;
2604
2605 if (thumb)
2606 {
2607 if ((given & 0xef000000) == 0xef000000)
2608 {
2609 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2610 unsigned long bit28 = given & (1 << 28);
2611
2612 given &= 0x00ffffff;
2613 if (bit28)
2614 given |= 0xf3000000;
2615 else
2616 given |= 0xf2000000;
2617 }
2618 else if ((given & 0xff000000) == 0xf9000000)
2619 given ^= 0xf9000000 ^ 0xf4000000;
2620 else
2621 return FALSE;
2622 }
2623
2624 for (insn = neon_opcodes; insn->assembler; insn++)
2625 {
2626 if ((given & insn->mask) == insn->value)
2627 {
2628 signed long value_in_comment = 0;
2629 bfd_boolean is_unpredictable = FALSE;
2630 const char *c;
2631
2632 for (c = insn->assembler; *c; c++)
2633 {
2634 if (*c == '%')
2635 {
2636 switch (*++c)
2637 {
2638 case '%':
2639 func (stream, "%%");
2640 break;
2641
2642 case 'u':
2643 if (thumb && ifthen_state)
2644 is_unpredictable = TRUE;
2645
2646 /* Fall through. */
2647 case 'c':
2648 if (thumb && ifthen_state)
2649 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2650 break;
2651
2652 case 'A':
2653 {
2654 static const unsigned char enc[16] =
2655 {
2656 0x4, 0x14, /* st4 0,1 */
2657 0x4, /* st1 2 */
2658 0x4, /* st2 3 */
2659 0x3, /* st3 4 */
2660 0x13, /* st3 5 */
2661 0x3, /* st1 6 */
2662 0x1, /* st1 7 */
2663 0x2, /* st2 8 */
2664 0x12, /* st2 9 */
2665 0x2, /* st1 10 */
2666 0, 0, 0, 0, 0
2667 };
2668 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2669 int rn = ((given >> 16) & 0xf);
2670 int rm = ((given >> 0) & 0xf);
2671 int align = ((given >> 4) & 0x3);
2672 int type = ((given >> 8) & 0xf);
2673 int n = enc[type] & 0xf;
2674 int stride = (enc[type] >> 4) + 1;
2675 int ix;
2676
2677 func (stream, "{");
2678 if (stride > 1)
2679 for (ix = 0; ix != n; ix++)
2680 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2681 else if (n == 1)
2682 func (stream, "d%d", rd);
2683 else
2684 func (stream, "d%d-d%d", rd, rd + n - 1);
2685 func (stream, "}, [%s", arm_regnames[rn]);
2686 if (align)
2687 func (stream, " :%d", 32 << align);
2688 func (stream, "]");
2689 if (rm == 0xd)
2690 func (stream, "!");
2691 else if (rm != 0xf)
2692 func (stream, ", %s", arm_regnames[rm]);
2693 }
2694 break;
2695
2696 case 'B':
2697 {
2698 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2699 int rn = ((given >> 16) & 0xf);
2700 int rm = ((given >> 0) & 0xf);
2701 int idx_align = ((given >> 4) & 0xf);
2702 int align = 0;
2703 int size = ((given >> 10) & 0x3);
2704 int idx = idx_align >> (size + 1);
2705 int length = ((given >> 8) & 3) + 1;
2706 int stride = 1;
2707 int i;
2708
2709 if (length > 1 && size > 0)
2710 stride = (idx_align & (1 << size)) ? 2 : 1;
2711
2712 switch (length)
2713 {
2714 case 1:
2715 {
2716 int amask = (1 << size) - 1;
2717 if ((idx_align & (1 << size)) != 0)
2718 return FALSE;
2719 if (size > 0)
2720 {
2721 if ((idx_align & amask) == amask)
2722 align = 8 << size;
2723 else if ((idx_align & amask) != 0)
2724 return FALSE;
2725 }
2726 }
2727 break;
2728
2729 case 2:
2730 if (size == 2 && (idx_align & 2) != 0)
2731 return FALSE;
2732 align = (idx_align & 1) ? 16 << size : 0;
2733 break;
2734
2735 case 3:
2736 if ((size == 2 && (idx_align & 3) != 0)
2737 || (idx_align & 1) != 0)
2738 return FALSE;
2739 break;
2740
2741 case 4:
2742 if (size == 2)
2743 {
2744 if ((idx_align & 3) == 3)
2745 return FALSE;
2746 align = (idx_align & 3) * 64;
2747 }
2748 else
2749 align = (idx_align & 1) ? 32 << size : 0;
2750 break;
2751
2752 default:
2753 abort ();
2754 }
2755
2756 func (stream, "{");
2757 for (i = 0; i < length; i++)
2758 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2759 rd + i * stride, idx);
2760 func (stream, "}, [%s", arm_regnames[rn]);
2761 if (align)
2762 func (stream, " :%d", align);
2763 func (stream, "]");
2764 if (rm == 0xd)
2765 func (stream, "!");
2766 else if (rm != 0xf)
2767 func (stream, ", %s", arm_regnames[rm]);
2768 }
2769 break;
2770
2771 case 'C':
2772 {
2773 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2774 int rn = ((given >> 16) & 0xf);
2775 int rm = ((given >> 0) & 0xf);
2776 int align = ((given >> 4) & 0x1);
2777 int size = ((given >> 6) & 0x3);
2778 int type = ((given >> 8) & 0x3);
2779 int n = type + 1;
2780 int stride = ((given >> 5) & 0x1);
2781 int ix;
2782
2783 if (stride && (n == 1))
2784 n++;
2785 else
2786 stride++;
2787
2788 func (stream, "{");
2789 if (stride > 1)
2790 for (ix = 0; ix != n; ix++)
2791 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2792 else if (n == 1)
2793 func (stream, "d%d[]", rd);
2794 else
2795 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2796 func (stream, "}, [%s", arm_regnames[rn]);
2797 if (align)
2798 {
2799 align = (8 * (type + 1)) << size;
2800 if (type == 3)
2801 align = (size > 1) ? align >> 1 : align;
2802 if (type == 2 || (type == 0 && !size))
2803 func (stream, " :<bad align %d>", align);
2804 else
2805 func (stream, " :%d", align);
2806 }
2807 func (stream, "]");
2808 if (rm == 0xd)
2809 func (stream, "!");
2810 else if (rm != 0xf)
2811 func (stream, ", %s", arm_regnames[rm]);
2812 }
2813 break;
2814
2815 case 'D':
2816 {
2817 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2818 int size = (given >> 20) & 3;
2819 int reg = raw_reg & ((4 << size) - 1);
2820 int ix = raw_reg >> size >> 2;
2821
2822 func (stream, "d%d[%d]", reg, ix);
2823 }
2824 break;
2825
2826 case 'E':
2827 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2828 {
2829 int bits = 0;
2830 int cmode = (given >> 8) & 0xf;
2831 int op = (given >> 5) & 0x1;
2832 unsigned long value = 0, hival = 0;
2833 unsigned shift;
2834 int size = 0;
2835 int isfloat = 0;
2836
2837 bits |= ((given >> 24) & 1) << 7;
2838 bits |= ((given >> 16) & 7) << 4;
2839 bits |= ((given >> 0) & 15) << 0;
2840
2841 if (cmode < 8)
2842 {
2843 shift = (cmode >> 1) & 3;
2844 value = (unsigned long) bits << (8 * shift);
2845 size = 32;
2846 }
2847 else if (cmode < 12)
2848 {
2849 shift = (cmode >> 1) & 1;
2850 value = (unsigned long) bits << (8 * shift);
2851 size = 16;
2852 }
2853 else if (cmode < 14)
2854 {
2855 shift = (cmode & 1) + 1;
2856 value = (unsigned long) bits << (8 * shift);
2857 value |= (1ul << (8 * shift)) - 1;
2858 size = 32;
2859 }
2860 else if (cmode == 14)
2861 {
2862 if (op)
2863 {
2864 /* Bit replication into bytes. */
2865 int ix;
2866 unsigned long mask;
2867
2868 value = 0;
2869 hival = 0;
2870 for (ix = 7; ix >= 0; ix--)
2871 {
2872 mask = ((bits >> ix) & 1) ? 0xff : 0;
2873 if (ix <= 3)
2874 value = (value << 8) | mask;
2875 else
2876 hival = (hival << 8) | mask;
2877 }
2878 size = 64;
2879 }
2880 else
2881 {
2882 /* Byte replication. */
2883 value = (unsigned long) bits;
2884 size = 8;
2885 }
2886 }
2887 else if (!op)
2888 {
2889 /* Floating point encoding. */
2890 int tmp;
2891
2892 value = (unsigned long) (bits & 0x7f) << 19;
2893 value |= (unsigned long) (bits & 0x80) << 24;
2894 tmp = bits & 0x40 ? 0x3c : 0x40;
2895 value |= (unsigned long) tmp << 24;
2896 size = 32;
2897 isfloat = 1;
2898 }
2899 else
2900 {
2901 func (stream, "<illegal constant %.8x:%x:%x>",
2902 bits, cmode, op);
2903 size = 32;
2904 break;
2905 }
2906 switch (size)
2907 {
2908 case 8:
2909 func (stream, "#%ld\t; 0x%.2lx", value, value);
2910 break;
2911
2912 case 16:
2913 func (stream, "#%ld\t; 0x%.4lx", value, value);
2914 break;
2915
2916 case 32:
2917 if (isfloat)
2918 {
2919 unsigned char valbytes[4];
2920 double fvalue;
2921
2922 /* Do this a byte at a time so we don't have to
2923 worry about the host's endianness. */
2924 valbytes[0] = value & 0xff;
2925 valbytes[1] = (value >> 8) & 0xff;
2926 valbytes[2] = (value >> 16) & 0xff;
2927 valbytes[3] = (value >> 24) & 0xff;
2928
2929 floatformat_to_double
2930 (& floatformat_ieee_single_little, valbytes,
2931 & fvalue);
2932
2933 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2934 value);
2935 }
2936 else
2937 func (stream, "#%ld\t; 0x%.8lx",
2938 (long) (((value & 0x80000000L) != 0)
2939 ? value | ~0xffffffffL : value),
2940 value);
2941 break;
2942
2943 case 64:
2944 func (stream, "#0x%.8lx%.8lx", hival, value);
2945 break;
2946
2947 default:
2948 abort ();
2949 }
2950 }
2951 break;
2952
2953 case 'F':
2954 {
2955 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2956 int num = (given >> 8) & 0x3;
2957
2958 if (!num)
2959 func (stream, "{d%d}", regno);
2960 else if (num + regno >= 32)
2961 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2962 else
2963 func (stream, "{d%d-d%d}", regno, regno + num);
2964 }
2965 break;
2966
2967
2968 case '0': case '1': case '2': case '3': case '4':
2969 case '5': case '6': case '7': case '8': case '9':
2970 {
2971 int width;
2972 unsigned long value;
2973
2974 c = arm_decode_bitfield (c, given, &value, &width);
2975
2976 switch (*c)
2977 {
2978 case 'r':
2979 func (stream, "%s", arm_regnames[value]);
2980 break;
2981 case 'd':
2982 func (stream, "%ld", value);
2983 value_in_comment = value;
2984 break;
2985 case 'e':
2986 func (stream, "%ld", (1ul << width) - value);
2987 break;
2988
2989 case 'S':
2990 case 'T':
2991 case 'U':
2992 /* Various width encodings. */
2993 {
2994 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2995 int limit;
2996 unsigned low, high;
2997
2998 c++;
2999 if (*c >= '0' && *c <= '9')
3000 limit = *c - '0';
3001 else if (*c >= 'a' && *c <= 'f')
3002 limit = *c - 'a' + 10;
3003 else
3004 abort ();
3005 low = limit >> 2;
3006 high = limit & 3;
3007
3008 if (value < low || value > high)
3009 func (stream, "<illegal width %d>", base << value);
3010 else
3011 func (stream, "%d", base << value);
3012 }
3013 break;
3014 case 'R':
3015 if (given & (1 << 6))
3016 goto Q;
3017 /* FALLTHROUGH */
3018 case 'D':
3019 func (stream, "d%ld", value);
3020 break;
3021 case 'Q':
3022 Q:
3023 if (value & 1)
3024 func (stream, "<illegal reg q%ld.5>", value >> 1);
3025 else
3026 func (stream, "q%ld", value >> 1);
3027 break;
3028
3029 case '`':
3030 c++;
3031 if (value == 0)
3032 func (stream, "%c", *c);
3033 break;
3034 case '\'':
3035 c++;
3036 if (value == ((1ul << width) - 1))
3037 func (stream, "%c", *c);
3038 break;
3039 case '?':
3040 func (stream, "%c", c[(1 << width) - (int) value]);
3041 c += 1 << width;
3042 break;
3043 default:
3044 abort ();
3045 }
3046 break;
3047
3048 default:
3049 abort ();
3050 }
3051 }
3052 }
3053 else
3054 func (stream, "%c", *c);
3055 }
3056
3057 if (value_in_comment > 32 || value_in_comment < -16)
3058 func (stream, "\t; 0x%lx", value_in_comment);
3059
3060 if (is_unpredictable)
3061 func (stream, UNPREDICTABLE_INSTRUCTION);
3062
3063 return TRUE;
3064 }
3065 }
3066 return FALSE;
3067 }
3068
3069 /* Return the name of a v7A special register. */
3070
3071 static const char *
3072 banked_regname (unsigned reg)
3073 {
3074 switch (reg)
3075 {
3076 case 15: return "CPSR";
3077 case 32: return "R8_usr";
3078 case 33: return "R9_usr";
3079 case 34: return "R10_usr";
3080 case 35: return "R11_usr";
3081 case 36: return "R12_usr";
3082 case 37: return "SP_usr";
3083 case 38: return "LR_usr";
3084 case 40: return "R8_fiq";
3085 case 41: return "R9_fiq";
3086 case 42: return "R10_fiq";
3087 case 43: return "R11_fiq";
3088 case 44: return "R12_fiq";
3089 case 45: return "SP_fiq";
3090 case 46: return "LR_fiq";
3091 case 48: return "LR_irq";
3092 case 49: return "SP_irq";
3093 case 50: return "LR_svc";
3094 case 51: return "SP_svc";
3095 case 52: return "LR_abt";
3096 case 53: return "SP_abt";
3097 case 54: return "LR_und";
3098 case 55: return "SP_und";
3099 case 60: return "LR_mon";
3100 case 61: return "SP_mon";
3101 case 62: return "ELR_hyp";
3102 case 63: return "SP_hyp";
3103 case 79: return "SPSR";
3104 case 110: return "SPSR_fiq";
3105 case 112: return "SPSR_irq";
3106 case 114: return "SPSR_svc";
3107 case 116: return "SPSR_abt";
3108 case 118: return "SPSR_und";
3109 case 124: return "SPSR_mon";
3110 case 126: return "SPSR_hyp";
3111 default: return NULL;
3112 }
3113 }
3114
3115 /* Return the name of the DMB/DSB option. */
3116 static const char *
3117 data_barrier_option (unsigned option)
3118 {
3119 switch (option & 0xf)
3120 {
3121 case 0xf: return "sy";
3122 case 0xe: return "st";
3123 case 0xd: return "ld";
3124 case 0xb: return "ish";
3125 case 0xa: return "ishst";
3126 case 0x9: return "ishld";
3127 case 0x7: return "un";
3128 case 0x6: return "unst";
3129 case 0x5: return "nshld";
3130 case 0x3: return "osh";
3131 case 0x2: return "oshst";
3132 case 0x1: return "oshld";
3133 default: return NULL;
3134 }
3135 }
3136
3137 /* Print one ARM instruction from PC on INFO->STREAM. */
3138
3139 static void
3140 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
3141 {
3142 const struct opcode32 *insn;
3143 void *stream = info->stream;
3144 fprintf_ftype func = info->fprintf_func;
3145 struct arm_private_data *private_data = info->private_data;
3146
3147 if (print_insn_coprocessor (pc, info, given, FALSE))
3148 return;
3149
3150 if (print_insn_neon (info, given, FALSE))
3151 return;
3152
3153 for (insn = arm_opcodes; insn->assembler; insn++)
3154 {
3155 if ((given & insn->mask) != insn->value)
3156 continue;
3157
3158 if ((insn->arch & private_data->features.core) == 0)
3159 continue;
3160
3161 /* Special case: an instruction with all bits set in the condition field
3162 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
3163 or by the catchall at the end of the table. */
3164 if ((given & 0xF0000000) != 0xF0000000
3165 || (insn->mask & 0xF0000000) == 0xF0000000
3166 || (insn->mask == 0 && insn->value == 0))
3167 {
3168 unsigned long u_reg = 16;
3169 unsigned long U_reg = 16;
3170 bfd_boolean is_unpredictable = FALSE;
3171 signed long value_in_comment = 0;
3172 const char *c;
3173
3174 for (c = insn->assembler; *c; c++)
3175 {
3176 if (*c == '%')
3177 {
3178 bfd_boolean allow_unpredictable = FALSE;
3179
3180 switch (*++c)
3181 {
3182 case '%':
3183 func (stream, "%%");
3184 break;
3185
3186 case 'a':
3187 value_in_comment = print_arm_address (pc, info, given);
3188 break;
3189
3190 case 'P':
3191 /* Set P address bit and use normal address
3192 printing routine. */
3193 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
3194 break;
3195
3196 case 'S':
3197 allow_unpredictable = TRUE;
3198 case 's':
3199 if ((given & 0x004f0000) == 0x004f0000)
3200 {
3201 /* PC relative with immediate offset. */
3202 bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3203
3204 if (PRE_BIT_SET)
3205 {
3206 /* Elide positive zero offset. */
3207 if (offset || NEGATIVE_BIT_SET)
3208 func (stream, "[pc, #%s%d]\t; ",
3209 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3210 else
3211 func (stream, "[pc]\t; ");
3212 if (NEGATIVE_BIT_SET)
3213 offset = -offset;
3214 info->print_address_func (offset + pc + 8, info);
3215 }
3216 else
3217 {
3218 /* Always show the offset. */
3219 func (stream, "[pc], #%s%d",
3220 NEGATIVE_BIT_SET ? "-" : "", (int) offset);
3221 if (! allow_unpredictable)
3222 is_unpredictable = TRUE;
3223 }
3224 }
3225 else
3226 {
3227 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3228
3229 func (stream, "[%s",
3230 arm_regnames[(given >> 16) & 0xf]);
3231
3232 if (PRE_BIT_SET)
3233 {
3234 if (IMMEDIATE_BIT_SET)
3235 {
3236 /* Elide offset for non-writeback
3237 positive zero. */
3238 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3239 || offset)
3240 func (stream, ", #%s%d",
3241 NEGATIVE_BIT_SET ? "-" : "", offset);
3242
3243 if (NEGATIVE_BIT_SET)
3244 offset = -offset;
3245
3246 value_in_comment = offset;
3247 }
3248 else
3249 {
3250 /* Register Offset or Register Pre-Indexed. */
3251 func (stream, ", %s%s",
3252 NEGATIVE_BIT_SET ? "-" : "",
3253 arm_regnames[given & 0xf]);
3254
3255 /* Writing back to the register that is the source/
3256 destination of the load/store is unpredictable. */
3257 if (! allow_unpredictable
3258 && WRITEBACK_BIT_SET
3259 && ((given & 0xf) == ((given >> 12) & 0xf)))
3260 is_unpredictable = TRUE;
3261 }
3262
3263 func (stream, "]%s",
3264 WRITEBACK_BIT_SET ? "!" : "");
3265 }
3266 else
3267 {
3268 if (IMMEDIATE_BIT_SET)
3269 {
3270 /* Immediate Post-indexed. */
3271 /* PR 10924: Offset must be printed, even if it is zero. */
3272 func (stream, "], #%s%d",
3273 NEGATIVE_BIT_SET ? "-" : "", offset);
3274 if (NEGATIVE_BIT_SET)
3275 offset = -offset;
3276 value_in_comment = offset;
3277 }
3278 else
3279 {
3280 /* Register Post-indexed. */
3281 func (stream, "], %s%s",
3282 NEGATIVE_BIT_SET ? "-" : "",
3283 arm_regnames[given & 0xf]);
3284
3285 /* Writing back to the register that is the source/
3286 destination of the load/store is unpredictable. */
3287 if (! allow_unpredictable
3288 && (given & 0xf) == ((given >> 12) & 0xf))
3289 is_unpredictable = TRUE;
3290 }
3291
3292 if (! allow_unpredictable)
3293 {
3294 /* Writeback is automatically implied by post- addressing.
3295 Setting the W bit is unnecessary and ARM specify it as
3296 being unpredictable. */
3297 if (WRITEBACK_BIT_SET
3298 /* Specifying the PC register as the post-indexed
3299 registers is also unpredictable. */
3300 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3301 is_unpredictable = TRUE;
3302 }
3303 }
3304 }
3305 break;
3306
3307 case 'b':
3308 {
3309 bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3310 info->print_address_func (disp * 4 + pc + 8, info);
3311 }
3312 break;
3313
3314 case 'c':
3315 if (((given >> 28) & 0xf) != 0xe)
3316 func (stream, "%s",
3317 arm_conditional [(given >> 28) & 0xf]);
3318 break;
3319
3320 case 'm':
3321 {
3322 int started = 0;
3323 int reg;
3324
3325 func (stream, "{");
3326 for (reg = 0; reg < 16; reg++)
3327 if ((given & (1 << reg)) != 0)
3328 {
3329 if (started)
3330 func (stream, ", ");
3331 started = 1;
3332 func (stream, "%s", arm_regnames[reg]);
3333 }
3334 func (stream, "}");
3335 if (! started)
3336 is_unpredictable = TRUE;
3337 }
3338 break;
3339
3340 case 'q':
3341 arm_decode_shift (given, func, stream, FALSE);
3342 break;
3343
3344 case 'o':
3345 if ((given & 0x02000000) != 0)
3346 {
3347 unsigned int rotate = (given & 0xf00) >> 7;
3348 unsigned int immed = (given & 0xff);
3349 unsigned int a, i;
3350
3351 a = (((immed << (32 - rotate))
3352 | (immed >> rotate)) & 0xffffffff);
3353 /* If there is another encoding with smaller rotate,
3354 the rotate should be specified directly. */
3355 for (i = 0; i < 32; i += 2)
3356 if ((a << i | a >> (32 - i)) <= 0xff)
3357 break;
3358
3359 if (i != rotate)
3360 func (stream, "#%d, %d", immed, rotate);
3361 else
3362 func (stream, "#%d", a);
3363 value_in_comment = a;
3364 }
3365 else
3366 arm_decode_shift (given, func, stream, TRUE);
3367 break;
3368
3369 case 'p':
3370 if ((given & 0x0000f000) == 0x0000f000)
3371 {
3372 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3373 mechanism for setting PSR flag bits. They are
3374 obsolete in V6 onwards. */
3375 if ((private_data->features.core & ARM_EXT_V6) == 0)
3376 func (stream, "p");
3377 }
3378 break;
3379
3380 case 't':
3381 if ((given & 0x01200000) == 0x00200000)
3382 func (stream, "t");
3383 break;
3384
3385 case 'A':
3386 {
3387 int offset = given & 0xff;
3388
3389 value_in_comment = offset * 4;
3390 if (NEGATIVE_BIT_SET)
3391 value_in_comment = - value_in_comment;
3392
3393 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3394
3395 if (PRE_BIT_SET)
3396 {
3397 if (offset)
3398 func (stream, ", #%d]%s",
3399 (int) value_in_comment,
3400 WRITEBACK_BIT_SET ? "!" : "");
3401 else
3402 func (stream, "]");
3403 }
3404 else
3405 {
3406 func (stream, "]");
3407
3408 if (WRITEBACK_BIT_SET)
3409 {
3410 if (offset)
3411 func (stream, ", #%d", (int) value_in_comment);
3412 }
3413 else
3414 {
3415 func (stream, ", {%d}", (int) offset);
3416 value_in_comment = offset;
3417 }
3418 }
3419 }
3420 break;
3421
3422 case 'B':
3423 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3424 {
3425 bfd_vma address;
3426 bfd_vma offset = 0;
3427
3428 if (! NEGATIVE_BIT_SET)
3429 /* Is signed, hi bits should be ones. */
3430 offset = (-1) ^ 0x00ffffff;
3431
3432 /* Offset is (SignExtend(offset field)<<2). */
3433 offset += given & 0x00ffffff;
3434 offset <<= 2;
3435 address = offset + pc + 8;
3436
3437 if (given & 0x01000000)
3438 /* H bit allows addressing to 2-byte boundaries. */
3439 address += 2;
3440
3441 info->print_address_func (address, info);
3442 }
3443 break;
3444
3445 case 'C':
3446 if ((given & 0x02000200) == 0x200)
3447 {
3448 const char * name;
3449 unsigned sysm = (given & 0x004f0000) >> 16;
3450
3451 sysm |= (given & 0x300) >> 4;
3452 name = banked_regname (sysm);
3453
3454 if (name != NULL)
3455 func (stream, "%s", name);
3456 else
3457 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3458 }
3459 else
3460 {
3461 func (stream, "%cPSR_",
3462 (given & 0x00400000) ? 'S' : 'C');
3463 if (given & 0x80000)
3464 func (stream, "f");
3465 if (given & 0x40000)
3466 func (stream, "s");
3467 if (given & 0x20000)
3468 func (stream, "x");
3469 if (given & 0x10000)
3470 func (stream, "c");
3471 }
3472 break;
3473
3474 case 'U':
3475 if ((given & 0xf0) == 0x60)
3476 {
3477 switch (given & 0xf)
3478 {
3479 case 0xf: func (stream, "sy"); break;
3480 default:
3481 func (stream, "#%d", (int) given & 0xf);
3482 break;
3483 }
3484 }
3485 else
3486 {
3487 const char * opt = data_barrier_option (given & 0xf);
3488 if (opt != NULL)
3489 func (stream, "%s", opt);
3490 else
3491 func (stream, "#%d", (int) given & 0xf);
3492 }
3493 break;
3494
3495 case '0': case '1': case '2': case '3': case '4':
3496 case '5': case '6': case '7': case '8': case '9':
3497 {
3498 int width;
3499 unsigned long value;
3500
3501 c = arm_decode_bitfield (c, given, &value, &width);
3502
3503 switch (*c)
3504 {
3505 case 'R':
3506 if (value == 15)
3507 is_unpredictable = TRUE;
3508 /* Fall through. */
3509 case 'r':
3510 case 'T':
3511 /* We want register + 1 when decoding T. */
3512 if (*c == 'T')
3513 ++value;
3514
3515 if (c[1] == 'u')
3516 {
3517 /* Eat the 'u' character. */
3518 ++ c;
3519
3520 if (u_reg == value)
3521 is_unpredictable = TRUE;
3522 u_reg = value;
3523 }
3524 if (c[1] == 'U')
3525 {
3526 /* Eat the 'U' character. */
3527 ++ c;
3528
3529 if (U_reg == value)
3530 is_unpredictable = TRUE;
3531 U_reg = value;
3532 }
3533 func (stream, "%s", arm_regnames[value]);
3534 break;
3535 case 'd':
3536 func (stream, "%ld", value);
3537 value_in_comment = value;
3538 break;
3539 case 'b':
3540 func (stream, "%ld", value * 8);
3541 value_in_comment = value * 8;
3542 break;
3543 case 'W':
3544 func (stream, "%ld", value + 1);
3545 value_in_comment = value + 1;
3546 break;
3547 case 'x':
3548 func (stream, "0x%08lx", value);
3549
3550 /* Some SWI instructions have special
3551 meanings. */
3552 if ((given & 0x0fffffff) == 0x0FF00000)
3553 func (stream, "\t; IMB");
3554 else if ((given & 0x0fffffff) == 0x0FF00001)
3555 func (stream, "\t; IMBRange");
3556 break;
3557 case 'X':
3558 func (stream, "%01lx", value & 0xf);
3559 value_in_comment = value;
3560 break;
3561 case '`':
3562 c++;
3563 if (value == 0)
3564 func (stream, "%c", *c);
3565 break;
3566 case '\'':
3567 c++;
3568 if (value == ((1ul << width) - 1))
3569 func (stream, "%c", *c);
3570 break;
3571 case '?':
3572 func (stream, "%c", c[(1 << width) - (int) value]);
3573 c += 1 << width;
3574 break;
3575 default:
3576 abort ();
3577 }
3578 break;
3579
3580 case 'e':
3581 {
3582 int imm;
3583
3584 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3585 func (stream, "%d", imm);
3586 value_in_comment = imm;
3587 }
3588 break;
3589
3590 case 'E':
3591 /* LSB and WIDTH fields of BFI or BFC. The machine-
3592 language instruction encodes LSB and MSB. */
3593 {
3594 long msb = (given & 0x001f0000) >> 16;
3595 long lsb = (given & 0x00000f80) >> 7;
3596 long w = msb - lsb + 1;
3597
3598 if (w > 0)
3599 func (stream, "#%lu, #%lu", lsb, w);
3600 else
3601 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3602 }
3603 break;
3604
3605 case 'R':
3606 /* Get the PSR/banked register name. */
3607 {
3608 const char * name;
3609 unsigned sysm = (given & 0x004f0000) >> 16;
3610
3611 sysm |= (given & 0x300) >> 4;
3612 name = banked_regname (sysm);
3613
3614 if (name != NULL)
3615 func (stream, "%s", name);
3616 else
3617 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
3618 }
3619 break;
3620
3621 case 'V':
3622 /* 16-bit unsigned immediate from a MOVT or MOVW
3623 instruction, encoded in bits 0:11 and 15:19. */
3624 {
3625 long hi = (given & 0x000f0000) >> 4;
3626 long lo = (given & 0x00000fff);
3627 long imm16 = hi | lo;
3628
3629 func (stream, "#%lu", imm16);
3630 value_in_comment = imm16;
3631 }
3632 break;
3633
3634 default:
3635 abort ();
3636 }
3637 }
3638 }
3639 else
3640 func (stream, "%c", *c);
3641 }
3642
3643 if (value_in_comment > 32 || value_in_comment < -16)
3644 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3645
3646 if (is_unpredictable)
3647 func (stream, UNPREDICTABLE_INSTRUCTION);
3648
3649 return;
3650 }
3651 }
3652 abort ();
3653 }
3654
3655 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3656
3657 static void
3658 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3659 {
3660 const struct opcode16 *insn;
3661 void *stream = info->stream;
3662 fprintf_ftype func = info->fprintf_func;
3663
3664 for (insn = thumb_opcodes; insn->assembler; insn++)
3665 if ((given & insn->mask) == insn->value)
3666 {
3667 signed long value_in_comment = 0;
3668 const char *c = insn->assembler;
3669
3670 for (; *c; c++)
3671 {
3672 int domaskpc = 0;
3673 int domasklr = 0;
3674
3675 if (*c != '%')
3676 {
3677 func (stream, "%c", *c);
3678 continue;
3679 }
3680
3681 switch (*++c)
3682 {
3683 case '%':
3684 func (stream, "%%");
3685 break;
3686
3687 case 'c':
3688 if (ifthen_state)
3689 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3690 break;
3691
3692 case 'C':
3693 if (ifthen_state)
3694 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3695 else
3696 func (stream, "s");
3697 break;
3698
3699 case 'I':
3700 {
3701 unsigned int tmp;
3702
3703 ifthen_next_state = given & 0xff;
3704 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3705 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3706 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3707 }
3708 break;
3709
3710 case 'x':
3711 if (ifthen_next_state)
3712 func (stream, "\t; unpredictable branch in IT block\n");
3713 break;
3714
3715 case 'X':
3716 if (ifthen_state)
3717 func (stream, "\t; unpredictable <IT:%s>",
3718 arm_conditional[IFTHEN_COND]);
3719 break;
3720
3721 case 'S':
3722 {
3723 long reg;
3724
3725 reg = (given >> 3) & 0x7;
3726 if (given & (1 << 6))
3727 reg += 8;
3728
3729 func (stream, "%s", arm_regnames[reg]);
3730 }
3731 break;
3732
3733 case 'D':
3734 {
3735 long reg;
3736
3737 reg = given & 0x7;
3738 if (given & (1 << 7))
3739 reg += 8;
3740
3741 func (stream, "%s", arm_regnames[reg]);
3742 }
3743 break;
3744
3745 case 'N':
3746 if (given & (1 << 8))
3747 domasklr = 1;
3748 /* Fall through. */
3749 case 'O':
3750 if (*c == 'O' && (given & (1 << 8)))
3751 domaskpc = 1;
3752 /* Fall through. */
3753 case 'M':
3754 {
3755 int started = 0;
3756 int reg;
3757
3758 func (stream, "{");
3759
3760 /* It would be nice if we could spot
3761 ranges, and generate the rS-rE format: */
3762 for (reg = 0; (reg < 8); reg++)
3763 if ((given & (1 << reg)) != 0)
3764 {
3765 if (started)
3766 func (stream, ", ");
3767 started = 1;
3768 func (stream, "%s", arm_regnames[reg]);
3769 }
3770
3771 if (domasklr)
3772 {
3773 if (started)
3774 func (stream, ", ");
3775 started = 1;
3776 func (stream, "%s", arm_regnames[14] /* "lr" */);
3777 }
3778
3779 if (domaskpc)
3780 {
3781 if (started)
3782 func (stream, ", ");
3783 func (stream, "%s", arm_regnames[15] /* "pc" */);
3784 }
3785
3786 func (stream, "}");
3787 }
3788 break;
3789
3790 case 'W':
3791 /* Print writeback indicator for a LDMIA. We are doing a
3792 writeback if the base register is not in the register
3793 mask. */
3794 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3795 func (stream, "!");
3796 break;
3797
3798 case 'b':
3799 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3800 {
3801 bfd_vma address = (pc + 4
3802 + ((given & 0x00f8) >> 2)
3803 + ((given & 0x0200) >> 3));
3804 info->print_address_func (address, info);
3805 }
3806 break;
3807
3808 case 's':
3809 /* Right shift immediate -- bits 6..10; 1-31 print
3810 as themselves, 0 prints as 32. */
3811 {
3812 long imm = (given & 0x07c0) >> 6;
3813 if (imm == 0)
3814 imm = 32;
3815 func (stream, "#%ld", imm);
3816 }
3817 break;
3818
3819 case '0': case '1': case '2': case '3': case '4':
3820 case '5': case '6': case '7': case '8': case '9':
3821 {
3822 int bitstart = *c++ - '0';
3823 int bitend = 0;
3824
3825 while (*c >= '0' && *c <= '9')
3826 bitstart = (bitstart * 10) + *c++ - '0';
3827
3828 switch (*c)
3829 {
3830 case '-':
3831 {
3832 bfd_vma reg;
3833
3834 c++;
3835 while (*c >= '0' && *c <= '9')
3836 bitend = (bitend * 10) + *c++ - '0';
3837 if (!bitend)
3838 abort ();
3839 reg = given >> bitstart;
3840 reg &= (2 << (bitend - bitstart)) - 1;
3841
3842 switch (*c)
3843 {
3844 case 'r':
3845 func (stream, "%s", arm_regnames[reg]);
3846 break;
3847
3848 case 'd':
3849 func (stream, "%ld", (long) reg);
3850 value_in_comment = reg;
3851 break;
3852
3853 case 'H':
3854 func (stream, "%ld", (long) (reg << 1));
3855 value_in_comment = reg << 1;
3856 break;
3857
3858 case 'W':
3859 func (stream, "%ld", (long) (reg << 2));
3860 value_in_comment = reg << 2;
3861 break;
3862
3863 case 'a':
3864 /* PC-relative address -- the bottom two
3865 bits of the address are dropped
3866 before the calculation. */
3867 info->print_address_func
3868 (((pc + 4) & ~3) + (reg << 2), info);
3869 value_in_comment = 0;
3870 break;
3871
3872 case 'x':
3873 func (stream, "0x%04lx", (long) reg);
3874 break;
3875
3876 case 'B':
3877 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3878 info->print_address_func (reg * 2 + pc + 4, info);
3879 value_in_comment = 0;
3880 break;
3881
3882 case 'c':
3883 func (stream, "%s", arm_conditional [reg]);
3884 break;
3885
3886 default:
3887 abort ();
3888 }
3889 }
3890 break;
3891
3892 case '\'':
3893 c++;
3894 if ((given & (1 << bitstart)) != 0)
3895 func (stream, "%c", *c);
3896 break;
3897
3898 case '?':
3899 ++c;
3900 if ((given & (1 << bitstart)) != 0)
3901 func (stream, "%c", *c++);
3902 else
3903 func (stream, "%c", *++c);
3904 break;
3905
3906 default:
3907 abort ();
3908 }
3909 }
3910 break;
3911
3912 default:
3913 abort ();
3914 }
3915 }
3916
3917 if (value_in_comment > 32 || value_in_comment < -16)
3918 func (stream, "\t; 0x%lx", value_in_comment);
3919 return;
3920 }
3921
3922 /* No match. */
3923 abort ();
3924 }
3925
3926 /* Return the name of an V7M special register. */
3927
3928 static const char *
3929 psr_name (int regno)
3930 {
3931 switch (regno)
3932 {
3933 case 0: return "APSR";
3934 case 1: return "IAPSR";
3935 case 2: return "EAPSR";
3936 case 3: return "PSR";
3937 case 5: return "IPSR";
3938 case 6: return "EPSR";
3939 case 7: return "IEPSR";
3940 case 8: return "MSP";
3941 case 9: return "PSP";
3942 case 16: return "PRIMASK";
3943 case 17: return "BASEPRI";
3944 case 18: return "BASEPRI_MAX";
3945 case 19: return "FAULTMASK";
3946 case 20: return "CONTROL";
3947 default: return "<unknown>";
3948 }
3949 }
3950
3951 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3952
3953 static void
3954 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3955 {
3956 const struct opcode32 *insn;
3957 void *stream = info->stream;
3958 fprintf_ftype func = info->fprintf_func;
3959
3960 if (print_insn_coprocessor (pc, info, given, TRUE))
3961 return;
3962
3963 if (print_insn_neon (info, given, TRUE))
3964 return;
3965
3966 for (insn = thumb32_opcodes; insn->assembler; insn++)
3967 if ((given & insn->mask) == insn->value)
3968 {
3969 bfd_boolean is_unpredictable = FALSE;
3970 signed long value_in_comment = 0;
3971 const char *c = insn->assembler;
3972
3973 for (; *c; c++)
3974 {
3975 if (*c != '%')
3976 {
3977 func (stream, "%c", *c);
3978 continue;
3979 }
3980
3981 switch (*++c)
3982 {
3983 case '%':
3984 func (stream, "%%");
3985 break;
3986
3987 case 'c':
3988 if (ifthen_state)
3989 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3990 break;
3991
3992 case 'x':
3993 if (ifthen_next_state)
3994 func (stream, "\t; unpredictable branch in IT block\n");
3995 break;
3996
3997 case 'X':
3998 if (ifthen_state)
3999 func (stream, "\t; unpredictable <IT:%s>",
4000 arm_conditional[IFTHEN_COND]);
4001 break;
4002
4003 case 'I':
4004 {
4005 unsigned int imm12 = 0;
4006
4007 imm12 |= (given & 0x000000ffu);
4008 imm12 |= (given & 0x00007000u) >> 4;
4009 imm12 |= (given & 0x04000000u) >> 15;
4010 func (stream, "#%u", imm12);
4011 value_in_comment = imm12;
4012 }
4013 break;
4014
4015 case 'M':
4016 {
4017 unsigned int bits = 0, imm, imm8, mod;
4018
4019 bits |= (given & 0x000000ffu);
4020 bits |= (given & 0x00007000u) >> 4;
4021 bits |= (given & 0x04000000u) >> 15;
4022 imm8 = (bits & 0x0ff);
4023 mod = (bits & 0xf00) >> 8;
4024 switch (mod)
4025 {
4026 case 0: imm = imm8; break;
4027 case 1: imm = ((imm8 << 16) | imm8); break;
4028 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
4029 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
4030 default:
4031 mod = (bits & 0xf80) >> 7;
4032 imm8 = (bits & 0x07f) | 0x80;
4033 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
4034 }
4035 func (stream, "#%u", imm);
4036 value_in_comment = imm;
4037 }
4038 break;
4039
4040 case 'J':
4041 {
4042 unsigned int imm = 0;
4043
4044 imm |= (given & 0x000000ffu);
4045 imm |= (given & 0x00007000u) >> 4;
4046 imm |= (given & 0x04000000u) >> 15;
4047 imm |= (given & 0x000f0000u) >> 4;
4048 func (stream, "#%u", imm);
4049 value_in_comment = imm;
4050 }
4051 break;
4052
4053 case 'K':
4054 {
4055 unsigned int imm = 0;
4056
4057 imm |= (given & 0x000f0000u) >> 16;
4058 imm |= (given & 0x00000ff0u) >> 0;
4059 imm |= (given & 0x0000000fu) << 12;
4060 func (stream, "#%u", imm);
4061 value_in_comment = imm;
4062 }
4063 break;
4064
4065 case 'H':
4066 {
4067 unsigned int imm = 0;
4068
4069 imm |= (given & 0x000f0000u) >> 4;
4070 imm |= (given & 0x00000fffu) >> 0;
4071 func (stream, "#%u", imm);
4072 value_in_comment = imm;
4073 }
4074 break;
4075
4076 case 'V':
4077 {
4078 unsigned int imm = 0;
4079
4080 imm |= (given & 0x00000fffu);
4081 imm |= (given & 0x000f0000u) >> 4;
4082 func (stream, "#%u", imm);
4083 value_in_comment = imm;
4084 }
4085 break;
4086
4087 case 'S':
4088 {
4089 unsigned int reg = (given & 0x0000000fu);
4090 unsigned int stp = (given & 0x00000030u) >> 4;
4091 unsigned int imm = 0;
4092 imm |= (given & 0x000000c0u) >> 6;
4093 imm |= (given & 0x00007000u) >> 10;
4094
4095 func (stream, "%s", arm_regnames[reg]);
4096 switch (stp)
4097 {
4098 case 0:
4099 if (imm > 0)
4100 func (stream, ", lsl #%u", imm);
4101 break;
4102
4103 case 1:
4104 if (imm == 0)
4105 imm = 32;
4106 func (stream, ", lsr #%u", imm);
4107 break;
4108
4109 case 2:
4110 if (imm == 0)
4111 imm = 32;
4112 func (stream, ", asr #%u", imm);
4113 break;
4114
4115 case 3:
4116 if (imm == 0)
4117 func (stream, ", rrx");
4118 else
4119 func (stream, ", ror #%u", imm);
4120 }
4121 }
4122 break;
4123
4124 case 'a':
4125 {
4126 unsigned int Rn = (given & 0x000f0000) >> 16;
4127 unsigned int U = ! NEGATIVE_BIT_SET;
4128 unsigned int op = (given & 0x00000f00) >> 8;
4129 unsigned int i12 = (given & 0x00000fff);
4130 unsigned int i8 = (given & 0x000000ff);
4131 bfd_boolean writeback = FALSE, postind = FALSE;
4132 bfd_vma offset = 0;
4133
4134 func (stream, "[%s", arm_regnames[Rn]);
4135 if (U) /* 12-bit positive immediate offset. */
4136 {
4137 offset = i12;
4138 if (Rn != 15)
4139 value_in_comment = offset;
4140 }
4141 else if (Rn == 15) /* 12-bit negative immediate offset. */
4142 offset = - (int) i12;
4143 else if (op == 0x0) /* Shifted register offset. */
4144 {
4145 unsigned int Rm = (i8 & 0x0f);
4146 unsigned int sh = (i8 & 0x30) >> 4;
4147
4148 func (stream, ", %s", arm_regnames[Rm]);
4149 if (sh)
4150 func (stream, ", lsl #%u", sh);
4151 func (stream, "]");
4152 break;
4153 }
4154 else switch (op)
4155 {
4156 case 0xE: /* 8-bit positive immediate offset. */
4157 offset = i8;
4158 break;
4159
4160 case 0xC: /* 8-bit negative immediate offset. */
4161 offset = -i8;
4162 break;
4163
4164 case 0xF: /* 8-bit + preindex with wb. */
4165 offset = i8;
4166 writeback = TRUE;
4167 break;
4168
4169 case 0xD: /* 8-bit - preindex with wb. */
4170 offset = -i8;
4171 writeback = TRUE;
4172 break;
4173
4174 case 0xB: /* 8-bit + postindex. */
4175 offset = i8;
4176 postind = TRUE;
4177 break;
4178
4179 case 0x9: /* 8-bit - postindex. */
4180 offset = -i8;
4181 postind = TRUE;
4182 break;
4183
4184 default:
4185 func (stream, ", <undefined>]");
4186 goto skip;
4187 }
4188
4189 if (postind)
4190 func (stream, "], #%d", (int) offset);
4191 else
4192 {
4193 if (offset)
4194 func (stream, ", #%d", (int) offset);
4195 func (stream, writeback ? "]!" : "]");
4196 }
4197
4198 if (Rn == 15)
4199 {
4200 func (stream, "\t; ");
4201 info->print_address_func (((pc + 4) & ~3) + offset, info);
4202 }
4203 }
4204 skip:
4205 break;
4206
4207 case 'A':
4208 {
4209 unsigned int U = ! NEGATIVE_BIT_SET;
4210 unsigned int W = WRITEBACK_BIT_SET;
4211 unsigned int Rn = (given & 0x000f0000) >> 16;
4212 unsigned int off = (given & 0x000000ff);
4213
4214 func (stream, "[%s", arm_regnames[Rn]);
4215
4216 if (PRE_BIT_SET)
4217 {
4218 if (off || !U)
4219 {
4220 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4221 value_in_comment = off * 4 * U ? 1 : -1;
4222 }
4223 func (stream, "]");
4224 if (W)
4225 func (stream, "!");
4226 }
4227 else
4228 {
4229 func (stream, "], ");
4230 if (W)
4231 {
4232 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4233 value_in_comment = off * 4 * U ? 1 : -1;
4234 }
4235 else
4236 {
4237 func (stream, "{%u}", off);
4238 value_in_comment = off;
4239 }
4240 }
4241 }
4242 break;
4243
4244 case 'w':
4245 {
4246 unsigned int Sbit = (given & 0x01000000) >> 24;
4247 unsigned int type = (given & 0x00600000) >> 21;
4248
4249 switch (type)
4250 {
4251 case 0: func (stream, Sbit ? "sb" : "b"); break;
4252 case 1: func (stream, Sbit ? "sh" : "h"); break;
4253 case 2:
4254 if (Sbit)
4255 func (stream, "??");
4256 break;
4257 case 3:
4258 func (stream, "??");
4259 break;
4260 }
4261 }
4262 break;
4263
4264 case 'm':
4265 {
4266 int started = 0;
4267 int reg;
4268
4269 func (stream, "{");
4270 for (reg = 0; reg < 16; reg++)
4271 if ((given & (1 << reg)) != 0)
4272 {
4273 if (started)
4274 func (stream, ", ");
4275 started = 1;
4276 func (stream, "%s", arm_regnames[reg]);
4277 }
4278 func (stream, "}");
4279 }
4280 break;
4281
4282 case 'E':
4283 {
4284 unsigned int msb = (given & 0x0000001f);
4285 unsigned int lsb = 0;
4286
4287 lsb |= (given & 0x000000c0u) >> 6;
4288 lsb |= (given & 0x00007000u) >> 10;
4289 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4290 }
4291 break;
4292
4293 case 'F':
4294 {
4295 unsigned int width = (given & 0x0000001f) + 1;
4296 unsigned int lsb = 0;
4297
4298 lsb |= (given & 0x000000c0u) >> 6;
4299 lsb |= (given & 0x00007000u) >> 10;
4300 func (stream, "#%u, #%u", lsb, width);
4301 }
4302 break;
4303
4304 case 'b':
4305 {
4306 unsigned int S = (given & 0x04000000u) >> 26;
4307 unsigned int J1 = (given & 0x00002000u) >> 13;
4308 unsigned int J2 = (given & 0x00000800u) >> 11;
4309 bfd_vma offset = 0;
4310
4311 offset |= !S << 20;
4312 offset |= J2 << 19;
4313 offset |= J1 << 18;
4314 offset |= (given & 0x003f0000) >> 4;
4315 offset |= (given & 0x000007ff) << 1;
4316 offset -= (1 << 20);
4317
4318 info->print_address_func (pc + 4 + offset, info);
4319 }
4320 break;
4321
4322 case 'B':
4323 {
4324 unsigned int S = (given & 0x04000000u) >> 26;
4325 unsigned int I1 = (given & 0x00002000u) >> 13;
4326 unsigned int I2 = (given & 0x00000800u) >> 11;
4327 bfd_vma offset = 0;
4328
4329 offset |= !S << 24;
4330 offset |= !(I1 ^ S) << 23;
4331 offset |= !(I2 ^ S) << 22;
4332 offset |= (given & 0x03ff0000u) >> 4;
4333 offset |= (given & 0x000007ffu) << 1;
4334 offset -= (1 << 24);
4335 offset += pc + 4;
4336
4337 /* BLX target addresses are always word aligned. */
4338 if ((given & 0x00001000u) == 0)
4339 offset &= ~2u;
4340
4341 info->print_address_func (offset, info);
4342 }
4343 break;
4344
4345 case 's':
4346 {
4347 unsigned int shift = 0;
4348
4349 shift |= (given & 0x000000c0u) >> 6;
4350 shift |= (given & 0x00007000u) >> 10;
4351 if (WRITEBACK_BIT_SET)
4352 func (stream, ", asr #%u", shift);
4353 else if (shift)
4354 func (stream, ", lsl #%u", shift);
4355 /* else print nothing - lsl #0 */
4356 }
4357 break;
4358
4359 case 'R':
4360 {
4361 unsigned int rot = (given & 0x00000030) >> 4;
4362
4363 if (rot)
4364 func (stream, ", ror #%u", rot * 8);
4365 }
4366 break;
4367
4368 case 'U':
4369 if ((given & 0xf0) == 0x60)
4370 {
4371 switch (given & 0xf)
4372 {
4373 case 0xf: func (stream, "sy"); break;
4374 default:
4375 func (stream, "#%d", (int) given & 0xf);
4376 break;
4377 }
4378 }
4379 else
4380 {
4381 const char * opt = data_barrier_option (given & 0xf);
4382 if (opt != NULL)
4383 func (stream, "%s", opt);
4384 else
4385 func (stream, "#%d", (int) given & 0xf);
4386 }
4387 break;
4388
4389 case 'C':
4390 if ((given & 0xff) == 0)
4391 {
4392 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4393 if (given & 0x800)
4394 func (stream, "f");
4395 if (given & 0x400)
4396 func (stream, "s");
4397 if (given & 0x200)
4398 func (stream, "x");
4399 if (given & 0x100)
4400 func (stream, "c");
4401 }
4402 else if ((given & 0x20) == 0x20)
4403 {
4404 char const* name;
4405 unsigned sysm = (given & 0xf00) >> 8;
4406
4407 sysm |= (given & 0x30);
4408 sysm |= (given & 0x00100000) >> 14;
4409 name = banked_regname (sysm);
4410
4411 if (name != NULL)
4412 func (stream, "%s", name);
4413 else
4414 func (stream, "(UNDEF: %lu)", (unsigned long) sysm);
4415 }
4416 else
4417 {
4418 func (stream, "%s", psr_name (given & 0xff));
4419 }
4420 break;
4421
4422 case 'D':
4423 if (((given & 0xff) == 0)
4424 || ((given & 0x20) == 0x20))
4425 {
4426 char const* name;
4427 unsigned sm = (given & 0xf0000) >> 16;
4428
4429 sm |= (given & 0x30);
4430 sm |= (given & 0x00100000) >> 14;
4431 name = banked_regname (sm);
4432
4433 if (name != NULL)
4434 func (stream, "%s", name);
4435 else
4436 func (stream, "(UNDEF: %lu)", (unsigned long) sm);
4437 }
4438 else
4439 func (stream, "%s", psr_name (given & 0xff));
4440 break;
4441
4442 case '0': case '1': case '2': case '3': case '4':
4443 case '5': case '6': case '7': case '8': case '9':
4444 {
4445 int width;
4446 unsigned long val;
4447
4448 c = arm_decode_bitfield (c, given, &val, &width);
4449
4450 switch (*c)
4451 {
4452 case 'd':
4453 func (stream, "%lu", val);
4454 value_in_comment = val;
4455 break;
4456
4457 case 'W':
4458 func (stream, "%lu", val * 4);
4459 value_in_comment = val * 4;
4460 break;
4461
4462 case 'S':
4463 if (val == 13)
4464 is_unpredictable = TRUE;
4465 /* Fall through. */
4466 case 'R':
4467 if (val == 15)
4468 is_unpredictable = TRUE;
4469 /* Fall through. */
4470 case 'r':
4471 func (stream, "%s", arm_regnames[val]);
4472 break;
4473
4474 case 'c':
4475 func (stream, "%s", arm_conditional[val]);
4476 break;
4477
4478 case '\'':
4479 c++;
4480 if (val == ((1ul << width) - 1))
4481 func (stream, "%c", *c);
4482 break;
4483
4484 case '`':
4485 c++;
4486 if (val == 0)
4487 func (stream, "%c", *c);
4488 break;
4489
4490 case '?':
4491 func (stream, "%c", c[(1 << width) - (int) val]);
4492 c += 1 << width;
4493 break;
4494
4495 case 'x':
4496 func (stream, "0x%lx", val & 0xffffffffUL);
4497 break;
4498
4499 default:
4500 abort ();
4501 }
4502 }
4503 break;
4504
4505 case 'L':
4506 /* PR binutils/12534
4507 If we have a PC relative offset in an LDRD or STRD
4508 instructions then display the decoded address. */
4509 if (((given >> 16) & 0xf) == 0xf)
4510 {
4511 bfd_vma offset = (given & 0xff) * 4;
4512
4513 if ((given & (1 << 23)) == 0)
4514 offset = - offset;
4515 func (stream, "\t; ");
4516 info->print_address_func ((pc & ~3) + 4 + offset, info);
4517 }
4518 break;
4519
4520 default:
4521 abort ();
4522 }
4523 }
4524
4525 if (value_in_comment > 32 || value_in_comment < -16)
4526 func (stream, "\t; 0x%lx", value_in_comment);
4527
4528 if (is_unpredictable)
4529 func (stream, UNPREDICTABLE_INSTRUCTION);
4530
4531 return;
4532 }
4533
4534 /* No match. */
4535 abort ();
4536 }
4537
4538 /* Print data bytes on INFO->STREAM. */
4539
4540 static void
4541 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4542 struct disassemble_info *info,
4543 long given)
4544 {
4545 switch (info->bytes_per_chunk)
4546 {
4547 case 1:
4548 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4549 break;
4550 case 2:
4551 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4552 break;
4553 case 4:
4554 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4555 break;
4556 default:
4557 abort ();
4558 }
4559 }
4560
4561 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4562 being displayed in symbol relative addresses. */
4563
4564 bfd_boolean
4565 arm_symbol_is_valid (asymbol * sym,
4566 struct disassemble_info * info ATTRIBUTE_UNUSED)
4567 {
4568 const char * name;
4569
4570 if (sym == NULL)
4571 return FALSE;
4572
4573 name = bfd_asymbol_name (sym);
4574
4575 return (name && *name != '$');
4576 }
4577
4578 /* Parse an individual disassembler option. */
4579
4580 void
4581 parse_arm_disassembler_option (char *option)
4582 {
4583 if (option == NULL)
4584 return;
4585
4586 if (CONST_STRNEQ (option, "reg-names-"))
4587 {
4588 int i;
4589
4590 option += 10;
4591
4592 for (i = NUM_ARM_REGNAMES; i--;)
4593 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4594 {
4595 regname_selected = i;
4596 break;
4597 }
4598
4599 if (i < 0)
4600 /* XXX - should break 'option' at following delimiter. */
4601 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4602 }
4603 else if (CONST_STRNEQ (option, "force-thumb"))
4604 force_thumb = 1;
4605 else if (CONST_STRNEQ (option, "no-force-thumb"))
4606 force_thumb = 0;
4607 else
4608 /* XXX - should break 'option' at following delimiter. */
4609 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4610
4611 return;
4612 }
4613
4614 /* Parse the string of disassembler options, spliting it at whitespaces
4615 or commas. (Whitespace separators supported for backwards compatibility). */
4616
4617 static void
4618 parse_disassembler_options (char *options)
4619 {
4620 if (options == NULL)
4621 return;
4622
4623 while (*options)
4624 {
4625 parse_arm_disassembler_option (options);
4626
4627 /* Skip forward to next seperator. */
4628 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4629 ++ options;
4630 /* Skip forward past seperators. */
4631 while (ISSPACE (*options) || (*options == ','))
4632 ++ options;
4633 }
4634 }
4635
4636 /* Search back through the insn stream to determine if this instruction is
4637 conditionally executed. */
4638
4639 static void
4640 find_ifthen_state (bfd_vma pc,
4641 struct disassemble_info *info,
4642 bfd_boolean little)
4643 {
4644 unsigned char b[2];
4645 unsigned int insn;
4646 int status;
4647 /* COUNT is twice the number of instructions seen. It will be odd if we
4648 just crossed an instruction boundary. */
4649 int count;
4650 int it_count;
4651 unsigned int seen_it;
4652 bfd_vma addr;
4653
4654 ifthen_address = pc;
4655 ifthen_state = 0;
4656
4657 addr = pc;
4658 count = 1;
4659 it_count = 0;
4660 seen_it = 0;
4661 /* Scan backwards looking for IT instructions, keeping track of where
4662 instruction boundaries are. We don't know if something is actually an
4663 IT instruction until we find a definite instruction boundary. */
4664 for (;;)
4665 {
4666 if (addr == 0 || info->symbol_at_address_func (addr, info))
4667 {
4668 /* A symbol must be on an instruction boundary, and will not
4669 be within an IT block. */
4670 if (seen_it && (count & 1))
4671 break;
4672
4673 return;
4674 }
4675 addr -= 2;
4676 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4677 if (status)
4678 return;
4679
4680 if (little)
4681 insn = (b[0]) | (b[1] << 8);
4682 else
4683 insn = (b[1]) | (b[0] << 8);
4684 if (seen_it)
4685 {
4686 if ((insn & 0xf800) < 0xe800)
4687 {
4688 /* Addr + 2 is an instruction boundary. See if this matches
4689 the expected boundary based on the position of the last
4690 IT candidate. */
4691 if (count & 1)
4692 break;
4693 seen_it = 0;
4694 }
4695 }
4696 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4697 {
4698 /* This could be an IT instruction. */
4699 seen_it = insn;
4700 it_count = count >> 1;
4701 }
4702 if ((insn & 0xf800) >= 0xe800)
4703 count++;
4704 else
4705 count = (count + 2) | 1;
4706 /* IT blocks contain at most 4 instructions. */
4707 if (count >= 8 && !seen_it)
4708 return;
4709 }
4710 /* We found an IT instruction. */
4711 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4712 if ((ifthen_state & 0xf) == 0)
4713 ifthen_state = 0;
4714 }
4715
4716 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4717 mapping symbol. */
4718
4719 static int
4720 is_mapping_symbol (struct disassemble_info *info, int n,
4721 enum map_type *map_type)
4722 {
4723 const char *name;
4724
4725 name = bfd_asymbol_name (info->symtab[n]);
4726 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4727 && (name[2] == 0 || name[2] == '.'))
4728 {
4729 *map_type = ((name[1] == 'a') ? MAP_ARM
4730 : (name[1] == 't') ? MAP_THUMB
4731 : MAP_DATA);
4732 return TRUE;
4733 }
4734
4735 return FALSE;
4736 }
4737
4738 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4739 Returns nonzero if *MAP_TYPE was set. */
4740
4741 static int
4742 get_map_sym_type (struct disassemble_info *info,
4743 int n,
4744 enum map_type *map_type)
4745 {
4746 /* If the symbol is in a different section, ignore it. */
4747 if (info->section != NULL && info->section != info->symtab[n]->section)
4748 return FALSE;
4749
4750 return is_mapping_symbol (info, n, map_type);
4751 }
4752
4753 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4754 Returns nonzero if *MAP_TYPE was set. */
4755
4756 static int
4757 get_sym_code_type (struct disassemble_info *info,
4758 int n,
4759 enum map_type *map_type)
4760 {
4761 elf_symbol_type *es;
4762 unsigned int type;
4763
4764 /* If the symbol is in a different section, ignore it. */
4765 if (info->section != NULL && info->section != info->symtab[n]->section)
4766 return FALSE;
4767
4768 es = *(elf_symbol_type **)(info->symtab + n);
4769 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4770
4771 /* If the symbol has function type then use that. */
4772 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4773 {
4774 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4775 *map_type = MAP_THUMB;
4776 else
4777 *map_type = MAP_ARM;
4778 return TRUE;
4779 }
4780
4781 return FALSE;
4782 }
4783
4784 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4785 of the supplied arm_feature_set structure with bitmasks indicating
4786 the support base architectures and coprocessor extensions.
4787
4788 FIXME: This could more efficiently implemented as a constant array,
4789 although it would also be less robust. */
4790
4791 static void
4792 select_arm_features (unsigned long mach,
4793 arm_feature_set * features)
4794 {
4795 #undef ARM_FEATURE
4796 #define ARM_FEATURE(ARCH,CEXT) \
4797 features->core = (ARCH); \
4798 features->coproc = (CEXT) | FPU_FPA; \
4799 return
4800
4801 switch (mach)
4802 {
4803 case bfd_mach_arm_2: ARM_ARCH_V2;
4804 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4805 case bfd_mach_arm_3: ARM_ARCH_V3;
4806 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4807 case bfd_mach_arm_4: ARM_ARCH_V4;
4808 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4809 case bfd_mach_arm_5: ARM_ARCH_V5;
4810 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4811 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4812 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4813 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4814 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4815 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4816 /* If the machine type is unknown allow all
4817 architecture types and all extensions. */
4818 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4819 default:
4820 abort ();
4821 }
4822 }
4823
4824
4825 /* NOTE: There are no checks in these routines that
4826 the relevant number of data bytes exist. */
4827
4828 static int
4829 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4830 {
4831 unsigned char b[4];
4832 long given;
4833 int status;
4834 int is_thumb = FALSE;
4835 int is_data = FALSE;
4836 int little_code;
4837 unsigned int size = 4;
4838 void (*printer) (bfd_vma, struct disassemble_info *, long);
4839 bfd_boolean found = FALSE;
4840 struct arm_private_data *private_data;
4841
4842 if (info->disassembler_options)
4843 {
4844 parse_disassembler_options (info->disassembler_options);
4845
4846 /* To avoid repeated parsing of these options, we remove them here. */
4847 info->disassembler_options = NULL;
4848 }
4849
4850 /* PR 10288: Control which instructions will be disassembled. */
4851 if (info->private_data == NULL)
4852 {
4853 static struct arm_private_data private;
4854
4855 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4856 /* If the user did not use the -m command line switch then default to
4857 disassembling all types of ARM instruction.
4858
4859 The info->mach value has to be ignored as this will be based on
4860 the default archictecture for the target and/or hints in the notes
4861 section, but it will never be greater than the current largest arm
4862 machine value (iWMMXt2), which is only equivalent to the V5TE
4863 architecture. ARM architectures have advanced beyond the machine
4864 value encoding, and these newer architectures would be ignored if
4865 the machine value was used.
4866
4867 Ie the -m switch is used to restrict which instructions will be
4868 disassembled. If it is necessary to use the -m switch to tell
4869 objdump that an ARM binary is being disassembled, eg because the
4870 input is a raw binary file, but it is also desired to disassemble
4871 all ARM instructions then use "-marm". This will select the
4872 "unknown" arm architecture which is compatible with any ARM
4873 instruction. */
4874 info->mach = bfd_mach_arm_unknown;
4875
4876 /* Compute the architecture bitmask from the machine number.
4877 Note: This assumes that the machine number will not change
4878 during disassembly.... */
4879 select_arm_features (info->mach, & private.features);
4880
4881 private.has_mapping_symbols = -1;
4882 private.last_mapping_sym = -1;
4883 private.last_mapping_addr = 0;
4884
4885 info->private_data = & private;
4886 }
4887
4888 private_data = info->private_data;
4889
4890 /* Decide if our code is going to be little-endian, despite what the
4891 function argument might say. */
4892 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4893
4894 /* For ELF, consult the symbol table to determine what kind of code
4895 or data we have. */
4896 if (info->symtab_size != 0
4897 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4898 {
4899 bfd_vma addr;
4900 int n, start;
4901 int last_sym = -1;
4902 enum map_type type = MAP_ARM;
4903
4904 /* Start scanning at the start of the function, or wherever
4905 we finished last time. */
4906 /* PR 14006. When the address is 0 we are either at the start of the
4907 very first function, or else the first function in a new, unlinked
4908 executable section (eg because uf -ffunction-sections). Either way
4909 start scanning from the beginning of the symbol table, not where we
4910 left off last time. */
4911 if (pc == 0)
4912 start = 0;
4913 else
4914 {
4915 start = info->symtab_pos + 1;
4916 if (start < private_data->last_mapping_sym)
4917 start = private_data->last_mapping_sym;
4918 }
4919 found = FALSE;
4920
4921 /* First, look for mapping symbols. */
4922 if (private_data->has_mapping_symbols != 0)
4923 {
4924 /* Scan up to the location being disassembled. */
4925 for (n = start; n < info->symtab_size; n++)
4926 {
4927 addr = bfd_asymbol_value (info->symtab[n]);
4928 if (addr > pc)
4929 break;
4930 if (get_map_sym_type (info, n, &type))
4931 {
4932 last_sym = n;
4933 found = TRUE;
4934 }
4935 }
4936
4937 if (!found)
4938 {
4939 /* No mapping symbol found at this address. Look backwards
4940 for a preceding one. */
4941 for (n = start - 1; n >= 0; n--)
4942 {
4943 if (get_map_sym_type (info, n, &type))
4944 {
4945 last_sym = n;
4946 found = TRUE;
4947 break;
4948 }
4949 }
4950 }
4951
4952 if (found)
4953 private_data->has_mapping_symbols = 1;
4954
4955 /* No mapping symbols were found. A leading $d may be
4956 omitted for sections which start with data; but for
4957 compatibility with legacy and stripped binaries, only
4958 assume the leading $d if there is at least one mapping
4959 symbol in the file. */
4960 if (!found && private_data->has_mapping_symbols == -1)
4961 {
4962 /* Look for mapping symbols, in any section. */
4963 for (n = 0; n < info->symtab_size; n++)
4964 if (is_mapping_symbol (info, n, &type))
4965 {
4966 private_data->has_mapping_symbols = 1;
4967 break;
4968 }
4969 if (private_data->has_mapping_symbols == -1)
4970 private_data->has_mapping_symbols = 0;
4971 }
4972
4973 if (!found && private_data->has_mapping_symbols == 1)
4974 {
4975 type = MAP_DATA;
4976 found = TRUE;
4977 }
4978 }
4979
4980 /* Next search for function symbols to separate ARM from Thumb
4981 in binaries without mapping symbols. */
4982 if (!found)
4983 {
4984 /* Scan up to the location being disassembled. */
4985 for (n = start; n < info->symtab_size; n++)
4986 {
4987 addr = bfd_asymbol_value (info->symtab[n]);
4988 if (addr > pc)
4989 break;
4990 if (get_sym_code_type (info, n, &type))
4991 {
4992 last_sym = n;
4993 found = TRUE;
4994 }
4995 }
4996
4997 if (!found)
4998 {
4999 /* No mapping symbol found at this address. Look backwards
5000 for a preceding one. */
5001 for (n = start - 1; n >= 0; n--)
5002 {
5003 if (get_sym_code_type (info, n, &type))
5004 {
5005 last_sym = n;
5006 found = TRUE;
5007 break;
5008 }
5009 }
5010 }
5011 }
5012
5013 private_data->last_mapping_sym = last_sym;
5014 private_data->last_type = type;
5015 is_thumb = (private_data->last_type == MAP_THUMB);
5016 is_data = (private_data->last_type == MAP_DATA);
5017
5018 /* Look a little bit ahead to see if we should print out
5019 two or four bytes of data. If there's a symbol,
5020 mapping or otherwise, after two bytes then don't
5021 print more. */
5022 if (is_data)
5023 {
5024 size = 4 - (pc & 3);
5025 for (n = last_sym + 1; n < info->symtab_size; n++)
5026 {
5027 addr = bfd_asymbol_value (info->symtab[n]);
5028 if (addr > pc
5029 && (info->section == NULL
5030 || info->section == info->symtab[n]->section))
5031 {
5032 if (addr - pc < size)
5033 size = addr - pc;
5034 break;
5035 }
5036 }
5037 /* If the next symbol is after three bytes, we need to
5038 print only part of the data, so that we can use either
5039 .byte or .short. */
5040 if (size == 3)
5041 size = (pc & 1) ? 1 : 2;
5042 }
5043 }
5044
5045 if (info->symbols != NULL)
5046 {
5047 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
5048 {
5049 coff_symbol_type * cs;
5050
5051 cs = coffsymbol (*info->symbols);
5052 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
5053 || cs->native->u.syment.n_sclass == C_THUMBSTAT
5054 || cs->native->u.syment.n_sclass == C_THUMBLABEL
5055 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
5056 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
5057 }
5058 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
5059 && !found)
5060 {
5061 /* If no mapping symbol has been found then fall back to the type
5062 of the function symbol. */
5063 elf_symbol_type * es;
5064 unsigned int type;
5065
5066 es = *(elf_symbol_type **)(info->symbols);
5067 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
5068
5069 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
5070 == ST_BRANCH_TO_THUMB)
5071 || type == STT_ARM_16BIT);
5072 }
5073 }
5074
5075 if (force_thumb)
5076 is_thumb = TRUE;
5077
5078 if (is_data)
5079 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5080 else
5081 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
5082
5083 info->bytes_per_line = 4;
5084
5085 /* PR 10263: Disassemble data if requested to do so by the user. */
5086 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
5087 {
5088 int i;
5089
5090 /* Size was already set above. */
5091 info->bytes_per_chunk = size;
5092 printer = print_insn_data;
5093
5094 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
5095 given = 0;
5096 if (little)
5097 for (i = size - 1; i >= 0; i--)
5098 given = b[i] | (given << 8);
5099 else
5100 for (i = 0; i < (int) size; i++)
5101 given = b[i] | (given << 8);
5102 }
5103 else if (!is_thumb)
5104 {
5105 /* In ARM mode endianness is a straightforward issue: the instruction
5106 is four bytes long and is either ordered 0123 or 3210. */
5107 printer = print_insn_arm;
5108 info->bytes_per_chunk = 4;
5109 size = 4;
5110
5111 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
5112 if (little_code)
5113 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
5114 else
5115 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
5116 }
5117 else
5118 {
5119 /* In Thumb mode we have the additional wrinkle of two
5120 instruction lengths. Fortunately, the bits that determine
5121 the length of the current instruction are always to be found
5122 in the first two bytes. */
5123 printer = print_insn_thumb16;
5124 info->bytes_per_chunk = 2;
5125 size = 2;
5126
5127 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
5128 if (little_code)
5129 given = (b[0]) | (b[1] << 8);
5130 else
5131 given = (b[1]) | (b[0] << 8);
5132
5133 if (!status)
5134 {
5135 /* These bit patterns signal a four-byte Thumb
5136 instruction. */
5137 if ((given & 0xF800) == 0xF800
5138 || (given & 0xF800) == 0xF000
5139 || (given & 0xF800) == 0xE800)
5140 {
5141 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
5142 if (little_code)
5143 given = (b[0]) | (b[1] << 8) | (given << 16);
5144 else
5145 given = (b[1]) | (b[0] << 8) | (given << 16);
5146
5147 printer = print_insn_thumb32;
5148 size = 4;
5149 }
5150 }
5151
5152 if (ifthen_address != pc)
5153 find_ifthen_state (pc, info, little_code);
5154
5155 if (ifthen_state)
5156 {
5157 if ((ifthen_state & 0xf) == 0x8)
5158 ifthen_next_state = 0;
5159 else
5160 ifthen_next_state = (ifthen_state & 0xe0)
5161 | ((ifthen_state & 0xf) << 1);
5162 }
5163 }
5164
5165 if (status)
5166 {
5167 info->memory_error_func (status, pc, info);
5168 return -1;
5169 }
5170 if (info->flags & INSN_HAS_RELOC)
5171 /* If the instruction has a reloc associated with it, then
5172 the offset field in the instruction will actually be the
5173 addend for the reloc. (We are using REL type relocs).
5174 In such cases, we can ignore the pc when computing
5175 addresses, since the addend is not currently pc-relative. */
5176 pc = 0;
5177
5178 printer (pc, info, given);
5179
5180 if (is_thumb)
5181 {
5182 ifthen_state = ifthen_next_state;
5183 ifthen_address += size;
5184 }
5185 return size;
5186 }
5187
5188 int
5189 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
5190 {
5191 /* Detect BE8-ness and record it in the disassembler info. */
5192 if (info->flavour == bfd_target_elf_flavour
5193 && info->section != NULL
5194 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
5195 info->endian_code = BFD_ENDIAN_LITTLE;
5196
5197 return print_insn (pc, info, FALSE);
5198 }
5199
5200 int
5201 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
5202 {
5203 return print_insn (pc, info, TRUE);
5204 }
5205
5206 void
5207 print_arm_disassembler_options (FILE *stream)
5208 {
5209 int i;
5210
5211 fprintf (stream, _("\n\
5212 The following ARM specific disassembler options are supported for use with\n\
5213 the -M switch:\n"));
5214
5215 for (i = NUM_ARM_REGNAMES; i--;)
5216 fprintf (stream, " reg-names-%s %*c%s\n",
5217 regnames[i].name,
5218 (int)(14 - strlen (regnames[i].name)), ' ',
5219 regnames[i].description);
5220
5221 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
5222 fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");
5223 }
5224