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