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