e987140294ce8cf517f113ee3b7aac8a537232c3
[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, 0x092d0001, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1163 {ARM_EXT_V1, 0x092d0002, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1164 {ARM_EXT_V1, 0x092d0004, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1165 {ARM_EXT_V1, 0x092d0008, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1166 {ARM_EXT_V1, 0x092d0010, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1167 {ARM_EXT_V1, 0x092d0020, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1168 {ARM_EXT_V1, 0x092d0040, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1169 {ARM_EXT_V1, 0x092d0080, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1170 {ARM_EXT_V1, 0x092d0100, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1171 {ARM_EXT_V1, 0x092d0200, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1172 {ARM_EXT_V1, 0x092d0400, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1173 {ARM_EXT_V1, 0x092d0800, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1174 {ARM_EXT_V1, 0x092d1000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1175 {ARM_EXT_V1, 0x092d2000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1176 {ARM_EXT_V1, 0x092d4000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1177 {ARM_EXT_V1, 0x092d8000, 0x0fffffff, "stmfd%c\t%16-19R!, %m"},
1178 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1179 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1180 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1181
1182 {ARM_EXT_V1, 0x08bd0001, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1183 {ARM_EXT_V1, 0x08bd0002, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1184 {ARM_EXT_V1, 0x08bd0004, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1185 {ARM_EXT_V1, 0x08bd0008, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1186 {ARM_EXT_V1, 0x08bd0010, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1187 {ARM_EXT_V1, 0x08bd0020, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1188 {ARM_EXT_V1, 0x08bd0040, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1189 {ARM_EXT_V1, 0x08bd0080, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1190 {ARM_EXT_V1, 0x08bd0100, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1191 {ARM_EXT_V1, 0x08bd0200, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1192 {ARM_EXT_V1, 0x08bd0400, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1193 {ARM_EXT_V1, 0x08bd0800, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1194 {ARM_EXT_V1, 0x08bd1000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1195 {ARM_EXT_V1, 0x08bd2000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1196 {ARM_EXT_V1, 0x08bd4000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1197 {ARM_EXT_V1, 0x08bd8000, 0x0fffffff, "ldmfd%c\t%16-19R!, %m"},
1198 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1199 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1200 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1201
1202 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1203 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1204
1205 /* The rest. */
1206 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1207 {0, 0x00000000, 0x00000000, 0}
1208 };
1209
1210 /* print_insn_thumb16 recognizes the following format control codes:
1211
1212 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1213 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1214 %<bitfield>I print bitfield as a signed decimal
1215 (top bit of range being the sign bit)
1216 %N print Thumb register mask (with LR)
1217 %O print Thumb register mask (with PC)
1218 %M print Thumb register mask
1219 %b print CZB's 6-bit unsigned branch destination
1220 %s print Thumb right-shift immediate (6..10; 0 == 32).
1221 %c print the condition code
1222 %C print the condition code, or "s" if not conditional
1223 %x print warning if conditional an not at end of IT block"
1224 %X print "\t; unpredictable <IT:code>" if conditional
1225 %I print IT instruction suffix and operands
1226 %W print Thumb Writeback indicator for LDMIA
1227 %<bitfield>r print bitfield as an ARM register
1228 %<bitfield>d print bitfield as a decimal
1229 %<bitfield>H print (bitfield * 2) as a decimal
1230 %<bitfield>W print (bitfield * 4) as a decimal
1231 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1232 %<bitfield>B print Thumb branch destination (signed displacement)
1233 %<bitfield>c print bitfield as a condition code
1234 %<bitnum>'c print specified char iff bit is one
1235 %<bitnum>?ab print a if bit is one else print b. */
1236
1237 static const struct opcode16 thumb_opcodes[] =
1238 {
1239 /* Thumb instructions. */
1240
1241 /* ARM V6K no-argument instructions. */
1242 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1243 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1244 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1245 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1246 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1247 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1248
1249 /* ARM V6T2 instructions. */
1250 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1251 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1252 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1253
1254 /* ARM V6. */
1255 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1256 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1257 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1258 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1259 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1260 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1261 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1262 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1263 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1264 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1265 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1266
1267 /* ARM V5 ISA extends Thumb. */
1268 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1269 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1270 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1271 /* ARM V4T ISA (Thumb v1). */
1272 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1273 /* Format 4. */
1274 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1275 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1276 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1277 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1278 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1279 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1280 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1281 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1282 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1283 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1284 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1285 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1286 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1287 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1288 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1289 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1290 /* format 13 */
1291 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1292 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1293 /* format 5 */
1294 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1295 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1296 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1297 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1298 /* format 14 */
1299 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1300 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1301 /* format 2 */
1302 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1303 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1304 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1305 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1306 /* format 8 */
1307 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1308 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1309 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1310 /* format 7 */
1311 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1312 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1313 /* format 1 */
1314 {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1315 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1316 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1317 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1318 /* format 3 */
1319 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1320 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1321 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1322 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1323 /* format 6 */
1324 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1325 /* format 9 */
1326 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1327 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1328 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1329 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1330 /* format 10 */
1331 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1332 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1333 /* format 11 */
1334 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1335 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1336 /* format 12 */
1337 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1338 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1339 /* format 15 */
1340 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1341 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1342 /* format 17 */
1343 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1344 /* format 16 */
1345 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1346 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1347 /* format 18 */
1348 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1349
1350 /* The E800 .. FFFF range is unconditionally redirected to the
1351 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1352 are processed via that table. Thus, we can never encounter a
1353 bare "second half of BL/BLX(1)" instruction here. */
1354 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1355 {0, 0, 0, 0}
1356 };
1357
1358 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1359 We adopt the convention that hw1 is the high 16 bits of .value and
1360 .mask, hw2 the low 16 bits.
1361
1362 print_insn_thumb32 recognizes the following format control codes:
1363
1364 %% %
1365
1366 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1367 %M print a modified 12-bit immediate (same location)
1368 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1369 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1370 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1371 %S print a possibly-shifted Rm
1372
1373 %L print address for a ldrd/strd instruction
1374 %a print the address of a plain load/store
1375 %w print the width and signedness of a core load/store
1376 %m print register mask for ldm/stm
1377
1378 %E print the lsb and width fields of a bfc/bfi instruction
1379 %F print the lsb and width fields of a sbfx/ubfx instruction
1380 %b print a conditional branch offset
1381 %B print an unconditional branch offset
1382 %s print the shift field of an SSAT instruction
1383 %R print the rotation field of an SXT instruction
1384 %U print barrier type.
1385 %P print address for pli instruction.
1386 %c print the condition code
1387 %x print warning if conditional an not at end of IT block"
1388 %X print "\t; unpredictable <IT:code>" if conditional
1389
1390 %<bitfield>d print bitfield in decimal
1391 %<bitfield>W print bitfield*4 in decimal
1392 %<bitfield>r print bitfield as an ARM register
1393 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1394 %<bitfield>c print bitfield as a condition code
1395
1396 %<bitfield>'c print specified char iff bitfield is all ones
1397 %<bitfield>`c print specified char iff bitfield is all zeroes
1398 %<bitfield>?ab... select from array of values in big endian order
1399
1400 With one exception at the bottom (done because BL and BLX(1) need
1401 to come dead last), this table was machine-sorted first in
1402 decreasing order of number of bits set in the mask, then in
1403 increasing numeric order of mask, then in increasing numeric order
1404 of opcode. This order is not the clearest for a human reader, but
1405 is guaranteed never to catch a special-case bit pattern with a more
1406 general mask, which is important, because this instruction encoding
1407 makes heavy use of special-case bit patterns. */
1408 static const struct opcode32 thumb32_opcodes[] =
1409 {
1410 /* V7 instructions. */
1411 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1412 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1413 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1414 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1415 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1416 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1417 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1418
1419 /* Virtualization Extension instructions. */
1420 {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1421 /* We skip ERET as that is SUBS pc, lr, #0. */
1422
1423 /* MP Extension instructions. */
1424 {ARM_EXT_MP, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1425
1426 /* Security extension instructions. */
1427 {ARM_EXT_SEC, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1428
1429 /* Instructions defined in the basic V6T2 set. */
1430 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1431 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1432 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1433 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1434 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1435 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1436
1437 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1438 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1439 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1440 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1441 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1442 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1443 {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1444 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1445 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1446 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1447 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1448 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1449 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1450 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1451 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1452 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1453 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1454 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1455 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1456 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1457 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1458 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1459 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1460 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1461 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1462 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1463 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1464 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1466 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1467 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1468 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1469 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1470 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1471 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1472 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1473 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1474 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1475 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1476 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1477 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1478 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1479 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1480 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1481 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1482 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1483 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1484 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1485 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1486 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1487 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1488 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1489 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1490 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1491 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1492 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1493 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1494 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1495 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1496 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1497 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1498 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1499 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1500 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1501 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1502 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1503 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1504 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1505 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1506 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1507 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1508 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1509 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1510 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1511 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1512 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1513 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1514 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1515 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1516 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1517 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1518 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1519 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1520 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1521 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1522 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1523 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1524 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1525 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1526 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1527 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1528 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1529 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1530 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1531 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1532 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1533 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1534 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1535 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1536 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1537 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1538 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1539 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1540 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1541 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1542 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1543 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1544 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1545 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1546 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1547 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1548 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1549 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1550 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1551 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1552 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1553 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1554 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1555 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1556 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1557 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1558 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1559 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1560 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1561 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1562 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1563 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1564 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1565 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1566 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1567 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1568 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1569 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1570 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1571 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1572 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1573 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1574 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1575 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1576 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1577 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1578 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1579 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1580 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1581 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1582 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1583 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1584 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1585 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1586 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1587 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1588 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1589 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1590 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1591 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1592 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1593 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1594 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1595 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1596 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1597 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1598 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1599 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1600 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1601 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1602 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1603 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1604 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1605 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1606 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1607 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1608
1609 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1610 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1611 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1612 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1613 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1614
1615 /* These have been 32-bit since the invention of Thumb. */
1616 {ARM_EXT_V4T, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1617 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1618
1619 /* Fallback. */
1620 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1621 {0, 0, 0, 0}
1622 };
1623
1624 static const char *const arm_conditional[] =
1625 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1626 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1627
1628 static const char *const arm_fp_const[] =
1629 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1630
1631 static const char *const arm_shift[] =
1632 {"lsl", "lsr", "asr", "ror"};
1633
1634 typedef struct
1635 {
1636 const char *name;
1637 const char *description;
1638 const char *reg_names[16];
1639 }
1640 arm_regname;
1641
1642 static const arm_regname regnames[] =
1643 {
1644 { "raw" , "Select raw register names",
1645 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1646 { "gcc", "Select register names used by GCC",
1647 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1648 { "std", "Select register names used in ARM's ISA documentation",
1649 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1650 { "apcs", "Select register names used in the APCS",
1651 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1652 { "atpcs", "Select register names used in the ATPCS",
1653 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1654 { "special-atpcs", "Select special register names used in the ATPCS",
1655 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1656 };
1657
1658 static const char *const iwmmxt_wwnames[] =
1659 {"b", "h", "w", "d"};
1660
1661 static const char *const iwmmxt_wwssnames[] =
1662 {"b", "bus", "bc", "bss",
1663 "h", "hus", "hc", "hss",
1664 "w", "wus", "wc", "wss",
1665 "d", "dus", "dc", "dss"
1666 };
1667
1668 static const char *const iwmmxt_regnames[] =
1669 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1670 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1671 };
1672
1673 static const char *const iwmmxt_cregnames[] =
1674 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1675 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1676 };
1677
1678 /* Default to GCC register name set. */
1679 static unsigned int regname_selected = 1;
1680
1681 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1682 #define arm_regnames regnames[regname_selected].reg_names
1683
1684 static bfd_boolean force_thumb = FALSE;
1685
1686 /* Current IT instruction state. This contains the same state as the IT
1687 bits in the CPSR. */
1688 static unsigned int ifthen_state;
1689 /* IT state for the next instruction. */
1690 static unsigned int ifthen_next_state;
1691 /* The address of the insn for which the IT state is valid. */
1692 static bfd_vma ifthen_address;
1693 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1694
1695 \f
1696 /* Functions. */
1697 int
1698 get_arm_regname_num_options (void)
1699 {
1700 return NUM_ARM_REGNAMES;
1701 }
1702
1703 int
1704 set_arm_regname_option (int option)
1705 {
1706 int old = regname_selected;
1707 regname_selected = option;
1708 return old;
1709 }
1710
1711 int
1712 get_arm_regnames (int option,
1713 const char **setname,
1714 const char **setdescription,
1715 const char *const **register_names)
1716 {
1717 *setname = regnames[option].name;
1718 *setdescription = regnames[option].description;
1719 *register_names = regnames[option].reg_names;
1720 return 16;
1721 }
1722
1723 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1724 Returns pointer to following character of the format string and
1725 fills in *VALUEP and *WIDTHP with the extracted value and number of
1726 bits extracted. WIDTHP can be NULL. */
1727
1728 static const char *
1729 arm_decode_bitfield (const char *ptr,
1730 unsigned long insn,
1731 unsigned long *valuep,
1732 int *widthp)
1733 {
1734 unsigned long value = 0;
1735 int width = 0;
1736
1737 do
1738 {
1739 int start, end;
1740 int bits;
1741
1742 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1743 start = start * 10 + *ptr - '0';
1744 if (*ptr == '-')
1745 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1746 end = end * 10 + *ptr - '0';
1747 else
1748 end = start;
1749 bits = end - start;
1750 if (bits < 0)
1751 abort ();
1752 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1753 width += bits + 1;
1754 }
1755 while (*ptr++ == ',');
1756 *valuep = value;
1757 if (widthp)
1758 *widthp = width;
1759 return ptr - 1;
1760 }
1761
1762 static void
1763 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1764 bfd_boolean print_shift)
1765 {
1766 func (stream, "%s", arm_regnames[given & 0xf]);
1767
1768 if ((given & 0xff0) != 0)
1769 {
1770 if ((given & 0x10) == 0)
1771 {
1772 int amount = (given & 0xf80) >> 7;
1773 int shift = (given & 0x60) >> 5;
1774
1775 if (amount == 0)
1776 {
1777 if (shift == 3)
1778 {
1779 func (stream, ", rrx");
1780 return;
1781 }
1782
1783 amount = 32;
1784 }
1785
1786 if (print_shift)
1787 func (stream, ", %s #%d", arm_shift[shift], amount);
1788 else
1789 func (stream, ", #%d", amount);
1790 }
1791 else if ((given & 0x80) == 0x80)
1792 func (stream, "\t; <illegal shifter operand>");
1793 else if (print_shift)
1794 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1795 arm_regnames[(given & 0xf00) >> 8]);
1796 else
1797 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1798 }
1799 }
1800
1801 #define W_BIT 21
1802 #define I_BIT 22
1803 #define U_BIT 23
1804 #define P_BIT 24
1805
1806 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1807 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1808 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1809 #define PRE_BIT_SET (given & (1 << P_BIT))
1810
1811 /* Print one coprocessor instruction on INFO->STREAM.
1812 Return TRUE if the instuction matched, FALSE if this is not a
1813 recognised coprocessor instruction. */
1814
1815 static bfd_boolean
1816 print_insn_coprocessor (bfd_vma pc,
1817 struct disassemble_info *info,
1818 long given,
1819 bfd_boolean thumb)
1820 {
1821 const struct opcode32 *insn;
1822 void *stream = info->stream;
1823 fprintf_ftype func = info->fprintf_func;
1824 unsigned long mask;
1825 unsigned long value = 0;
1826 struct arm_private_data *private_data = info->private_data;
1827 unsigned long allowed_arches = private_data->features.coproc;
1828 int cond;
1829
1830 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1831 {
1832 unsigned long u_reg = 16;
1833 bfd_boolean is_unpredictable = FALSE;
1834 signed long value_in_comment = 0;
1835 const char *c;
1836
1837 if (insn->arch == 0)
1838 switch (insn->value)
1839 {
1840 case SENTINEL_IWMMXT_START:
1841 if (info->mach != bfd_mach_arm_XScale
1842 && info->mach != bfd_mach_arm_iWMMXt
1843 && info->mach != bfd_mach_arm_iWMMXt2)
1844 do
1845 insn++;
1846 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1847 continue;
1848
1849 case SENTINEL_IWMMXT_END:
1850 continue;
1851
1852 case SENTINEL_GENERIC_START:
1853 allowed_arches = private_data->features.core;
1854 continue;
1855
1856 default:
1857 abort ();
1858 }
1859
1860 mask = insn->mask;
1861 value = insn->value;
1862 if (thumb)
1863 {
1864 /* The high 4 bits are 0xe for Arm conditional instructions, and
1865 0xe for arm unconditional instructions. The rest of the
1866 encoding is the same. */
1867 mask |= 0xf0000000;
1868 value |= 0xe0000000;
1869 if (ifthen_state)
1870 cond = IFTHEN_COND;
1871 else
1872 cond = 16;
1873 }
1874 else
1875 {
1876 /* Only match unconditional instuctions against unconditional
1877 patterns. */
1878 if ((given & 0xf0000000) == 0xf0000000)
1879 {
1880 mask |= 0xf0000000;
1881 cond = 16;
1882 }
1883 else
1884 {
1885 cond = (given >> 28) & 0xf;
1886 if (cond == 0xe)
1887 cond = 16;
1888 }
1889 }
1890
1891 if ((given & mask) != value)
1892 continue;
1893
1894 if ((insn->arch & allowed_arches) == 0)
1895 continue;
1896
1897 for (c = insn->assembler; *c; c++)
1898 {
1899 if (*c == '%')
1900 {
1901 switch (*++c)
1902 {
1903 case '%':
1904 func (stream, "%%");
1905 break;
1906
1907 case 'A':
1908 {
1909 int rn = (given >> 16) & 0xf;
1910 bfd_vma offset = given & 0xff;
1911
1912 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1913
1914 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1915 {
1916 /* Not unindexed. The offset is scaled. */
1917 offset = offset * 4;
1918 if (NEGATIVE_BIT_SET)
1919 offset = - offset;
1920 if (rn != 15)
1921 value_in_comment = offset;
1922 }
1923
1924 if (PRE_BIT_SET)
1925 {
1926 if (offset)
1927 func (stream, ", #%d]%s",
1928 offset,
1929 WRITEBACK_BIT_SET ? "!" : "");
1930 else if (NEGATIVE_BIT_SET)
1931 func (stream, ", #-0]");
1932 else
1933 func (stream, "]");
1934 }
1935 else
1936 {
1937 func (stream, "]");
1938
1939 if (WRITEBACK_BIT_SET)
1940 {
1941 if (offset)
1942 func (stream, ", #%d", offset);
1943 else if (NEGATIVE_BIT_SET)
1944 func (stream, ", #-0");
1945 }
1946 else
1947 {
1948 func (stream, ", {%s%d}",
1949 (NEGATIVE_BIT_SET && !offset) ? "-" : "",
1950 offset);
1951 value_in_comment = offset;
1952 }
1953 }
1954 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1955 {
1956 func (stream, "\t; ");
1957 /* For unaligned PCs, apply off-by-alignment
1958 correction. */
1959 info->print_address_func (offset + pc
1960 + info->bytes_per_chunk * 2
1961 - (pc & 3),
1962 info);
1963 }
1964 }
1965 break;
1966
1967 case 'B':
1968 {
1969 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1970 int offset = (given >> 1) & 0x3f;
1971
1972 if (offset == 1)
1973 func (stream, "{d%d}", regno);
1974 else if (regno + offset > 32)
1975 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1976 else
1977 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1978 }
1979 break;
1980
1981 case 'c':
1982 func (stream, "%s", arm_conditional[cond]);
1983 break;
1984
1985 case 'I':
1986 /* Print a Cirrus/DSP shift immediate. */
1987 /* Immediates are 7bit signed ints with bits 0..3 in
1988 bits 0..3 of opcode and bits 4..6 in bits 5..7
1989 of opcode. */
1990 {
1991 int imm;
1992
1993 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1994
1995 /* Is ``imm'' a negative number? */
1996 if (imm & 0x40)
1997 imm |= (-1 << 7);
1998
1999 func (stream, "%d", imm);
2000 }
2001
2002 break;
2003
2004 case 'F':
2005 switch (given & 0x00408000)
2006 {
2007 case 0:
2008 func (stream, "4");
2009 break;
2010 case 0x8000:
2011 func (stream, "1");
2012 break;
2013 case 0x00400000:
2014 func (stream, "2");
2015 break;
2016 default:
2017 func (stream, "3");
2018 }
2019 break;
2020
2021 case 'P':
2022 switch (given & 0x00080080)
2023 {
2024 case 0:
2025 func (stream, "s");
2026 break;
2027 case 0x80:
2028 func (stream, "d");
2029 break;
2030 case 0x00080000:
2031 func (stream, "e");
2032 break;
2033 default:
2034 func (stream, _("<illegal precision>"));
2035 break;
2036 }
2037 break;
2038
2039 case 'Q':
2040 switch (given & 0x00408000)
2041 {
2042 case 0:
2043 func (stream, "s");
2044 break;
2045 case 0x8000:
2046 func (stream, "d");
2047 break;
2048 case 0x00400000:
2049 func (stream, "e");
2050 break;
2051 default:
2052 func (stream, "p");
2053 break;
2054 }
2055 break;
2056
2057 case 'R':
2058 switch (given & 0x60)
2059 {
2060 case 0:
2061 break;
2062 case 0x20:
2063 func (stream, "p");
2064 break;
2065 case 0x40:
2066 func (stream, "m");
2067 break;
2068 default:
2069 func (stream, "z");
2070 break;
2071 }
2072 break;
2073
2074 case '0': case '1': case '2': case '3': case '4':
2075 case '5': case '6': case '7': case '8': case '9':
2076 {
2077 int width;
2078
2079 c = arm_decode_bitfield (c, given, &value, &width);
2080
2081 switch (*c)
2082 {
2083 case 'R':
2084 if (value == 15)
2085 is_unpredictable = TRUE;
2086 /* Fall through. */
2087 case 'r':
2088 if (c[1] == 'u')
2089 {
2090 /* Eat the 'u' character. */
2091 ++ c;
2092
2093 if (u_reg == value)
2094 is_unpredictable = TRUE;
2095 u_reg = value;
2096 }
2097 func (stream, "%s", arm_regnames[value]);
2098 break;
2099 case 'D':
2100 func (stream, "d%ld", value);
2101 break;
2102 case 'Q':
2103 if (value & 1)
2104 func (stream, "<illegal reg q%ld.5>", value >> 1);
2105 else
2106 func (stream, "q%ld", value >> 1);
2107 break;
2108 case 'd':
2109 func (stream, "%ld", value);
2110 value_in_comment = value;
2111 break;
2112 case 'k':
2113 {
2114 int from = (given & (1 << 7)) ? 32 : 16;
2115 func (stream, "%ld", from - value);
2116 }
2117 break;
2118
2119 case 'f':
2120 if (value > 7)
2121 func (stream, "#%s", arm_fp_const[value & 7]);
2122 else
2123 func (stream, "f%ld", value);
2124 break;
2125
2126 case 'w':
2127 if (width == 2)
2128 func (stream, "%s", iwmmxt_wwnames[value]);
2129 else
2130 func (stream, "%s", iwmmxt_wwssnames[value]);
2131 break;
2132
2133 case 'g':
2134 func (stream, "%s", iwmmxt_regnames[value]);
2135 break;
2136 case 'G':
2137 func (stream, "%s", iwmmxt_cregnames[value]);
2138 break;
2139
2140 case 'x':
2141 func (stream, "0x%lx", (value & 0xffffffffUL));
2142 break;
2143
2144 case '`':
2145 c++;
2146 if (value == 0)
2147 func (stream, "%c", *c);
2148 break;
2149 case '\'':
2150 c++;
2151 if (value == ((1ul << width) - 1))
2152 func (stream, "%c", *c);
2153 break;
2154 case '?':
2155 func (stream, "%c", c[(1 << width) - (int) value]);
2156 c += 1 << width;
2157 break;
2158 default:
2159 abort ();
2160 }
2161 break;
2162
2163 case 'y':
2164 case 'z':
2165 {
2166 int single = *c++ == 'y';
2167 int regno;
2168
2169 switch (*c)
2170 {
2171 case '4': /* Sm pair */
2172 case '0': /* Sm, Dm */
2173 regno = given & 0x0000000f;
2174 if (single)
2175 {
2176 regno <<= 1;
2177 regno += (given >> 5) & 1;
2178 }
2179 else
2180 regno += ((given >> 5) & 1) << 4;
2181 break;
2182
2183 case '1': /* Sd, Dd */
2184 regno = (given >> 12) & 0x0000000f;
2185 if (single)
2186 {
2187 regno <<= 1;
2188 regno += (given >> 22) & 1;
2189 }
2190 else
2191 regno += ((given >> 22) & 1) << 4;
2192 break;
2193
2194 case '2': /* Sn, Dn */
2195 regno = (given >> 16) & 0x0000000f;
2196 if (single)
2197 {
2198 regno <<= 1;
2199 regno += (given >> 7) & 1;
2200 }
2201 else
2202 regno += ((given >> 7) & 1) << 4;
2203 break;
2204
2205 case '3': /* List */
2206 func (stream, "{");
2207 regno = (given >> 12) & 0x0000000f;
2208 if (single)
2209 {
2210 regno <<= 1;
2211 regno += (given >> 22) & 1;
2212 }
2213 else
2214 regno += ((given >> 22) & 1) << 4;
2215 break;
2216
2217 default:
2218 abort ();
2219 }
2220
2221 func (stream, "%c%d", single ? 's' : 'd', regno);
2222
2223 if (*c == '3')
2224 {
2225 int count = given & 0xff;
2226
2227 if (single == 0)
2228 count >>= 1;
2229
2230 if (--count)
2231 {
2232 func (stream, "-%c%d",
2233 single ? 's' : 'd',
2234 regno + count);
2235 }
2236
2237 func (stream, "}");
2238 }
2239 else if (*c == '4')
2240 func (stream, ", %c%d", single ? 's' : 'd',
2241 regno + 1);
2242 }
2243 break;
2244
2245 case 'L':
2246 switch (given & 0x00400100)
2247 {
2248 case 0x00000000: func (stream, "b"); break;
2249 case 0x00400000: func (stream, "h"); break;
2250 case 0x00000100: func (stream, "w"); break;
2251 case 0x00400100: func (stream, "d"); break;
2252 default:
2253 break;
2254 }
2255 break;
2256
2257 case 'Z':
2258 {
2259 /* given (20, 23) | given (0, 3) */
2260 value = ((given >> 16) & 0xf0) | (given & 0xf);
2261 func (stream, "%d", value);
2262 }
2263 break;
2264
2265 case 'l':
2266 /* This is like the 'A' operator, except that if
2267 the width field "M" is zero, then the offset is
2268 *not* multiplied by four. */
2269 {
2270 int offset = given & 0xff;
2271 int multiplier = (given & 0x00000100) ? 4 : 1;
2272
2273 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2274
2275 if (multiplier > 1)
2276 {
2277 value_in_comment = offset * multiplier;
2278 if (NEGATIVE_BIT_SET)
2279 value_in_comment = - value_in_comment;
2280 }
2281
2282 if (offset)
2283 {
2284 if (PRE_BIT_SET)
2285 func (stream, ", #%s%d]%s",
2286 NEGATIVE_BIT_SET ? "-" : "",
2287 offset * multiplier,
2288 WRITEBACK_BIT_SET ? "!" : "");
2289 else
2290 func (stream, "], #%s%d",
2291 NEGATIVE_BIT_SET ? "-" : "",
2292 offset * multiplier);
2293 }
2294 else
2295 func (stream, "]");
2296 }
2297 break;
2298
2299 case 'r':
2300 {
2301 int imm4 = (given >> 4) & 0xf;
2302 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2303 int ubit = ! NEGATIVE_BIT_SET;
2304 const char *rm = arm_regnames [given & 0xf];
2305 const char *rn = arm_regnames [(given >> 16) & 0xf];
2306
2307 switch (puw_bits)
2308 {
2309 case 1:
2310 case 3:
2311 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2312 if (imm4)
2313 func (stream, ", lsl #%d", imm4);
2314 break;
2315
2316 case 4:
2317 case 5:
2318 case 6:
2319 case 7:
2320 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2321 if (imm4 > 0)
2322 func (stream, ", lsl #%d", imm4);
2323 func (stream, "]");
2324 if (puw_bits == 5 || puw_bits == 7)
2325 func (stream, "!");
2326 break;
2327
2328 default:
2329 func (stream, "INVALID");
2330 }
2331 }
2332 break;
2333
2334 case 'i':
2335 {
2336 long imm5;
2337 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2338 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2339 }
2340 break;
2341
2342 default:
2343 abort ();
2344 }
2345 }
2346 }
2347 else
2348 func (stream, "%c", *c);
2349 }
2350
2351 if (value_in_comment > 32 || value_in_comment < -16)
2352 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2353
2354 if (is_unpredictable)
2355 func (stream, UNPREDICTABLE_INSTRUCTION);
2356
2357 return TRUE;
2358 }
2359 return FALSE;
2360 }
2361
2362 /* Decodes and prints ARM addressing modes. Returns the offset
2363 used in the address, if any, if it is worthwhile printing the
2364 offset as a hexadecimal value in a comment at the end of the
2365 line of disassembly. */
2366
2367 static signed long
2368 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2369 {
2370 void *stream = info->stream;
2371 fprintf_ftype func = info->fprintf_func;
2372 bfd_vma offset = 0;
2373
2374 if (((given & 0x000f0000) == 0x000f0000)
2375 && ((given & 0x02000000) == 0))
2376 {
2377 offset = given & 0xfff;
2378
2379 func (stream, "[pc");
2380
2381 if (PRE_BIT_SET)
2382 {
2383 /* Pre-indexed. Elide offset of positive zero when
2384 non-writeback. */
2385 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2386 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", offset);
2387
2388 if (NEGATIVE_BIT_SET)
2389 offset = -offset;
2390
2391 offset += pc + 8;
2392
2393 /* Cope with the possibility of write-back
2394 being used. Probably a very dangerous thing
2395 for the programmer to do, but who are we to
2396 argue ? */
2397 func (stream, "]%s", WRITEBACK_BIT_SET ? "!" : "");
2398 }
2399 else /* Post indexed. */
2400 {
2401 func (stream, "], #%s%d", NEGATIVE_BIT_SET ? "-" : "", offset);
2402
2403 /* Ie ignore the offset. */
2404 offset = pc + 8;
2405 }
2406
2407 func (stream, "\t; ");
2408 info->print_address_func (offset, info);
2409 offset = 0;
2410 }
2411 else
2412 {
2413 func (stream, "[%s",
2414 arm_regnames[(given >> 16) & 0xf]);
2415
2416 if (PRE_BIT_SET)
2417 {
2418 if ((given & 0x02000000) == 0)
2419 {
2420 /* Elide offset of positive zero when non-writeback. */
2421 offset = given & 0xfff;
2422 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET || offset)
2423 func (stream, ", #%s%d", NEGATIVE_BIT_SET ? "-" : "", offset);
2424 }
2425 else
2426 {
2427 func (stream, ", %s", NEGATIVE_BIT_SET ? "-" : "");
2428 arm_decode_shift (given, func, stream, TRUE);
2429 }
2430
2431 func (stream, "]%s",
2432 WRITEBACK_BIT_SET ? "!" : "");
2433 }
2434 else
2435 {
2436 if ((given & 0x02000000) == 0)
2437 {
2438 /* Always show offset. */
2439 offset = given & 0xfff;
2440 func (stream, "], #%s%d",
2441 NEGATIVE_BIT_SET ? "-" : "", offset);
2442 }
2443 else
2444 {
2445 func (stream, "], %s",
2446 NEGATIVE_BIT_SET ? "-" : "");
2447 arm_decode_shift (given, func, stream, TRUE);
2448 }
2449 }
2450 }
2451
2452 return (signed long) offset;
2453 }
2454
2455 /* Print one neon instruction on INFO->STREAM.
2456 Return TRUE if the instuction matched, FALSE if this is not a
2457 recognised neon instruction. */
2458
2459 static bfd_boolean
2460 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2461 {
2462 const struct opcode32 *insn;
2463 void *stream = info->stream;
2464 fprintf_ftype func = info->fprintf_func;
2465
2466 if (thumb)
2467 {
2468 if ((given & 0xef000000) == 0xef000000)
2469 {
2470 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2471 unsigned long bit28 = given & (1 << 28);
2472
2473 given &= 0x00ffffff;
2474 if (bit28)
2475 given |= 0xf3000000;
2476 else
2477 given |= 0xf2000000;
2478 }
2479 else if ((given & 0xff000000) == 0xf9000000)
2480 given ^= 0xf9000000 ^ 0xf4000000;
2481 else
2482 return FALSE;
2483 }
2484
2485 for (insn = neon_opcodes; insn->assembler; insn++)
2486 {
2487 if ((given & insn->mask) == insn->value)
2488 {
2489 signed long value_in_comment = 0;
2490 const char *c;
2491
2492 for (c = insn->assembler; *c; c++)
2493 {
2494 if (*c == '%')
2495 {
2496 switch (*++c)
2497 {
2498 case '%':
2499 func (stream, "%%");
2500 break;
2501
2502 case 'c':
2503 if (thumb && ifthen_state)
2504 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2505 break;
2506
2507 case 'A':
2508 {
2509 static const unsigned char enc[16] =
2510 {
2511 0x4, 0x14, /* st4 0,1 */
2512 0x4, /* st1 2 */
2513 0x4, /* st2 3 */
2514 0x3, /* st3 4 */
2515 0x13, /* st3 5 */
2516 0x3, /* st1 6 */
2517 0x1, /* st1 7 */
2518 0x2, /* st2 8 */
2519 0x12, /* st2 9 */
2520 0x2, /* st1 10 */
2521 0, 0, 0, 0, 0
2522 };
2523 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2524 int rn = ((given >> 16) & 0xf);
2525 int rm = ((given >> 0) & 0xf);
2526 int align = ((given >> 4) & 0x3);
2527 int type = ((given >> 8) & 0xf);
2528 int n = enc[type] & 0xf;
2529 int stride = (enc[type] >> 4) + 1;
2530 int ix;
2531
2532 func (stream, "{");
2533 if (stride > 1)
2534 for (ix = 0; ix != n; ix++)
2535 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2536 else if (n == 1)
2537 func (stream, "d%d", rd);
2538 else
2539 func (stream, "d%d-d%d", rd, rd + n - 1);
2540 func (stream, "}, [%s", arm_regnames[rn]);
2541 if (align)
2542 func (stream, " :%d", 32 << align);
2543 func (stream, "]");
2544 if (rm == 0xd)
2545 func (stream, "!");
2546 else if (rm != 0xf)
2547 func (stream, ", %s", arm_regnames[rm]);
2548 }
2549 break;
2550
2551 case 'B':
2552 {
2553 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2554 int rn = ((given >> 16) & 0xf);
2555 int rm = ((given >> 0) & 0xf);
2556 int idx_align = ((given >> 4) & 0xf);
2557 int align = 0;
2558 int size = ((given >> 10) & 0x3);
2559 int idx = idx_align >> (size + 1);
2560 int length = ((given >> 8) & 3) + 1;
2561 int stride = 1;
2562 int i;
2563
2564 if (length > 1 && size > 0)
2565 stride = (idx_align & (1 << size)) ? 2 : 1;
2566
2567 switch (length)
2568 {
2569 case 1:
2570 {
2571 int amask = (1 << size) - 1;
2572 if ((idx_align & (1 << size)) != 0)
2573 return FALSE;
2574 if (size > 0)
2575 {
2576 if ((idx_align & amask) == amask)
2577 align = 8 << size;
2578 else if ((idx_align & amask) != 0)
2579 return FALSE;
2580 }
2581 }
2582 break;
2583
2584 case 2:
2585 if (size == 2 && (idx_align & 2) != 0)
2586 return FALSE;
2587 align = (idx_align & 1) ? 16 << size : 0;
2588 break;
2589
2590 case 3:
2591 if ((size == 2 && (idx_align & 3) != 0)
2592 || (idx_align & 1) != 0)
2593 return FALSE;
2594 break;
2595
2596 case 4:
2597 if (size == 2)
2598 {
2599 if ((idx_align & 3) == 3)
2600 return FALSE;
2601 align = (idx_align & 3) * 64;
2602 }
2603 else
2604 align = (idx_align & 1) ? 32 << size : 0;
2605 break;
2606
2607 default:
2608 abort ();
2609 }
2610
2611 func (stream, "{");
2612 for (i = 0; i < length; i++)
2613 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2614 rd + i * stride, idx);
2615 func (stream, "}, [%s", arm_regnames[rn]);
2616 if (align)
2617 func (stream, " :%d", align);
2618 func (stream, "]");
2619 if (rm == 0xd)
2620 func (stream, "!");
2621 else if (rm != 0xf)
2622 func (stream, ", %s", arm_regnames[rm]);
2623 }
2624 break;
2625
2626 case 'C':
2627 {
2628 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2629 int rn = ((given >> 16) & 0xf);
2630 int rm = ((given >> 0) & 0xf);
2631 int align = ((given >> 4) & 0x1);
2632 int size = ((given >> 6) & 0x3);
2633 int type = ((given >> 8) & 0x3);
2634 int n = type + 1;
2635 int stride = ((given >> 5) & 0x1);
2636 int ix;
2637
2638 if (stride && (n == 1))
2639 n++;
2640 else
2641 stride++;
2642
2643 func (stream, "{");
2644 if (stride > 1)
2645 for (ix = 0; ix != n; ix++)
2646 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2647 else if (n == 1)
2648 func (stream, "d%d[]", rd);
2649 else
2650 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2651 func (stream, "}, [%s", arm_regnames[rn]);
2652 if (align)
2653 {
2654 align = (8 * (type + 1)) << size;
2655 if (type == 3)
2656 align = (size > 1) ? align >> 1 : align;
2657 if (type == 2 || (type == 0 && !size))
2658 func (stream, " :<bad align %d>", align);
2659 else
2660 func (stream, " :%d", align);
2661 }
2662 func (stream, "]");
2663 if (rm == 0xd)
2664 func (stream, "!");
2665 else if (rm != 0xf)
2666 func (stream, ", %s", arm_regnames[rm]);
2667 }
2668 break;
2669
2670 case 'D':
2671 {
2672 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2673 int size = (given >> 20) & 3;
2674 int reg = raw_reg & ((4 << size) - 1);
2675 int ix = raw_reg >> size >> 2;
2676
2677 func (stream, "d%d[%d]", reg, ix);
2678 }
2679 break;
2680
2681 case 'E':
2682 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2683 {
2684 int bits = 0;
2685 int cmode = (given >> 8) & 0xf;
2686 int op = (given >> 5) & 0x1;
2687 unsigned long value = 0, hival = 0;
2688 unsigned shift;
2689 int size = 0;
2690 int isfloat = 0;
2691
2692 bits |= ((given >> 24) & 1) << 7;
2693 bits |= ((given >> 16) & 7) << 4;
2694 bits |= ((given >> 0) & 15) << 0;
2695
2696 if (cmode < 8)
2697 {
2698 shift = (cmode >> 1) & 3;
2699 value = (unsigned long) bits << (8 * shift);
2700 size = 32;
2701 }
2702 else if (cmode < 12)
2703 {
2704 shift = (cmode >> 1) & 1;
2705 value = (unsigned long) bits << (8 * shift);
2706 size = 16;
2707 }
2708 else if (cmode < 14)
2709 {
2710 shift = (cmode & 1) + 1;
2711 value = (unsigned long) bits << (8 * shift);
2712 value |= (1ul << (8 * shift)) - 1;
2713 size = 32;
2714 }
2715 else if (cmode == 14)
2716 {
2717 if (op)
2718 {
2719 /* Bit replication into bytes. */
2720 int ix;
2721 unsigned long mask;
2722
2723 value = 0;
2724 hival = 0;
2725 for (ix = 7; ix >= 0; ix--)
2726 {
2727 mask = ((bits >> ix) & 1) ? 0xff : 0;
2728 if (ix <= 3)
2729 value = (value << 8) | mask;
2730 else
2731 hival = (hival << 8) | mask;
2732 }
2733 size = 64;
2734 }
2735 else
2736 {
2737 /* Byte replication. */
2738 value = (unsigned long) bits;
2739 size = 8;
2740 }
2741 }
2742 else if (!op)
2743 {
2744 /* Floating point encoding. */
2745 int tmp;
2746
2747 value = (unsigned long) (bits & 0x7f) << 19;
2748 value |= (unsigned long) (bits & 0x80) << 24;
2749 tmp = bits & 0x40 ? 0x3c : 0x40;
2750 value |= (unsigned long) tmp << 24;
2751 size = 32;
2752 isfloat = 1;
2753 }
2754 else
2755 {
2756 func (stream, "<illegal constant %.8x:%x:%x>",
2757 bits, cmode, op);
2758 size = 32;
2759 break;
2760 }
2761 switch (size)
2762 {
2763 case 8:
2764 func (stream, "#%ld\t; 0x%.2lx", value, value);
2765 break;
2766
2767 case 16:
2768 func (stream, "#%ld\t; 0x%.4lx", value, value);
2769 break;
2770
2771 case 32:
2772 if (isfloat)
2773 {
2774 unsigned char valbytes[4];
2775 double fvalue;
2776
2777 /* Do this a byte at a time so we don't have to
2778 worry about the host's endianness. */
2779 valbytes[0] = value & 0xff;
2780 valbytes[1] = (value >> 8) & 0xff;
2781 valbytes[2] = (value >> 16) & 0xff;
2782 valbytes[3] = (value >> 24) & 0xff;
2783
2784 floatformat_to_double
2785 (& floatformat_ieee_single_little, valbytes,
2786 & fvalue);
2787
2788 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2789 value);
2790 }
2791 else
2792 func (stream, "#%ld\t; 0x%.8lx",
2793 (long) (((value & 0x80000000L) != 0)
2794 ? value | ~0xffffffffL : value),
2795 value);
2796 break;
2797
2798 case 64:
2799 func (stream, "#0x%.8lx%.8lx", hival, value);
2800 break;
2801
2802 default:
2803 abort ();
2804 }
2805 }
2806 break;
2807
2808 case 'F':
2809 {
2810 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2811 int num = (given >> 8) & 0x3;
2812
2813 if (!num)
2814 func (stream, "{d%d}", regno);
2815 else if (num + regno >= 32)
2816 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2817 else
2818 func (stream, "{d%d-d%d}", regno, regno + num);
2819 }
2820 break;
2821
2822
2823 case '0': case '1': case '2': case '3': case '4':
2824 case '5': case '6': case '7': case '8': case '9':
2825 {
2826 int width;
2827 unsigned long value;
2828
2829 c = arm_decode_bitfield (c, given, &value, &width);
2830
2831 switch (*c)
2832 {
2833 case 'r':
2834 func (stream, "%s", arm_regnames[value]);
2835 break;
2836 case 'd':
2837 func (stream, "%ld", value);
2838 value_in_comment = value;
2839 break;
2840 case 'e':
2841 func (stream, "%ld", (1ul << width) - value);
2842 break;
2843
2844 case 'S':
2845 case 'T':
2846 case 'U':
2847 /* Various width encodings. */
2848 {
2849 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2850 int limit;
2851 unsigned low, high;
2852
2853 c++;
2854 if (*c >= '0' && *c <= '9')
2855 limit = *c - '0';
2856 else if (*c >= 'a' && *c <= 'f')
2857 limit = *c - 'a' + 10;
2858 else
2859 abort ();
2860 low = limit >> 2;
2861 high = limit & 3;
2862
2863 if (value < low || value > high)
2864 func (stream, "<illegal width %d>", base << value);
2865 else
2866 func (stream, "%d", base << value);
2867 }
2868 break;
2869 case 'R':
2870 if (given & (1 << 6))
2871 goto Q;
2872 /* FALLTHROUGH */
2873 case 'D':
2874 func (stream, "d%ld", value);
2875 break;
2876 case 'Q':
2877 Q:
2878 if (value & 1)
2879 func (stream, "<illegal reg q%ld.5>", value >> 1);
2880 else
2881 func (stream, "q%ld", value >> 1);
2882 break;
2883
2884 case '`':
2885 c++;
2886 if (value == 0)
2887 func (stream, "%c", *c);
2888 break;
2889 case '\'':
2890 c++;
2891 if (value == ((1ul << width) - 1))
2892 func (stream, "%c", *c);
2893 break;
2894 case '?':
2895 func (stream, "%c", c[(1 << width) - (int) value]);
2896 c += 1 << width;
2897 break;
2898 default:
2899 abort ();
2900 }
2901 break;
2902
2903 default:
2904 abort ();
2905 }
2906 }
2907 }
2908 else
2909 func (stream, "%c", *c);
2910 }
2911
2912 if (value_in_comment > 32 || value_in_comment < -16)
2913 func (stream, "\t; 0x%lx", value_in_comment);
2914
2915 return TRUE;
2916 }
2917 }
2918 return FALSE;
2919 }
2920
2921 /* Return the name of a v7A special register. */
2922
2923 static const char *
2924 banked_regname (unsigned reg)
2925 {
2926 switch (reg)
2927 {
2928 case 15: return "CPSR";
2929 case 32: return "R8_usr";
2930 case 33: return "R9_usr";
2931 case 34: return "R10_usr";
2932 case 35: return "R11_usr";
2933 case 36: return "R12_usr";
2934 case 37: return "SP_usr";
2935 case 38: return "LR_usr";
2936 case 40: return "R8_fiq";
2937 case 41: return "R9_fiq";
2938 case 42: return "R10_fiq";
2939 case 43: return "R11_fiq";
2940 case 44: return "R12_fiq";
2941 case 45: return "SP_fiq";
2942 case 46: return "LR_fiq";
2943 case 48: return "LR_irq";
2944 case 49: return "SP_irq";
2945 case 50: return "LR_svc";
2946 case 51: return "SP_svc";
2947 case 52: return "LR_abt";
2948 case 53: return "SP_abt";
2949 case 54: return "LR_und";
2950 case 55: return "SP_und";
2951 case 60: return "LR_mon";
2952 case 61: return "SP_mon";
2953 case 62: return "ELR_hyp";
2954 case 63: return "SP_hyp";
2955 case 79: return "SPSR";
2956 case 110: return "SPSR_fiq";
2957 case 112: return "SPSR_irq";
2958 case 114: return "SPSR_svc";
2959 case 116: return "SPSR_abt";
2960 case 118: return "SPSR_und";
2961 case 124: return "SPSR_mon";
2962 case 126: return "SPSR_hyp";
2963 default: return NULL;
2964 }
2965 }
2966
2967 /* Print one ARM instruction from PC on INFO->STREAM. */
2968
2969 static void
2970 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2971 {
2972 const struct opcode32 *insn;
2973 void *stream = info->stream;
2974 fprintf_ftype func = info->fprintf_func;
2975 struct arm_private_data *private_data = info->private_data;
2976
2977 if (print_insn_coprocessor (pc, info, given, FALSE))
2978 return;
2979
2980 if (print_insn_neon (info, given, FALSE))
2981 return;
2982
2983 for (insn = arm_opcodes; insn->assembler; insn++)
2984 {
2985 if ((given & insn->mask) != insn->value)
2986 continue;
2987
2988 if ((insn->arch & private_data->features.core) == 0)
2989 continue;
2990
2991 /* Special case: an instruction with all bits set in the condition field
2992 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2993 or by the catchall at the end of the table. */
2994 if ((given & 0xF0000000) != 0xF0000000
2995 || (insn->mask & 0xF0000000) == 0xF0000000
2996 || (insn->mask == 0 && insn->value == 0))
2997 {
2998 unsigned long u_reg = 16;
2999 unsigned long U_reg = 16;
3000 bfd_boolean is_unpredictable = FALSE;
3001 signed long value_in_comment = 0;
3002 const char *c;
3003
3004 for (c = insn->assembler; *c; c++)
3005 {
3006 if (*c == '%')
3007 {
3008 bfd_boolean allow_unpredictable = FALSE;
3009
3010 switch (*++c)
3011 {
3012 case '%':
3013 func (stream, "%%");
3014 break;
3015
3016 case 'a':
3017 value_in_comment = print_arm_address (pc, info, given);
3018 break;
3019
3020 case 'P':
3021 /* Set P address bit and use normal address
3022 printing routine. */
3023 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
3024 break;
3025
3026 case 'S':
3027 allow_unpredictable = TRUE;
3028 case 's':
3029 if ((given & 0x004f0000) == 0x004f0000)
3030 {
3031 /* PC relative with immediate offset. */
3032 bfd_vma offset = ((given & 0xf00) >> 4) | (given & 0xf);
3033
3034 if (PRE_BIT_SET)
3035 {
3036 /* Elide positive zero offset. */
3037 if (offset || NEGATIVE_BIT_SET)
3038 func (stream, "[pc, #%s%d]\t; ",
3039 NEGATIVE_BIT_SET ? "-" : "", offset);
3040 else
3041 func (stream, "[pc]\t; ");
3042 if (NEGATIVE_BIT_SET)
3043 offset = -offset;
3044 info->print_address_func (offset + pc + 8, info);
3045 }
3046 else
3047 {
3048 /* Always show the offset. */
3049 func (stream, "[pc], #%s%d",
3050 NEGATIVE_BIT_SET ? "-" : "", offset);
3051 if (! allow_unpredictable)
3052 is_unpredictable = TRUE;
3053 }
3054 }
3055 else
3056 {
3057 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3058
3059 func (stream, "[%s",
3060 arm_regnames[(given >> 16) & 0xf]);
3061
3062 if (PRE_BIT_SET)
3063 {
3064 if (IMMEDIATE_BIT_SET)
3065 {
3066 /* Elide offset for non-writeback
3067 positive zero. */
3068 if (WRITEBACK_BIT_SET || NEGATIVE_BIT_SET
3069 || offset)
3070 func (stream, ", #%s%d",
3071 NEGATIVE_BIT_SET ? "-" : "", offset);
3072
3073 if (NEGATIVE_BIT_SET)
3074 offset = -offset;
3075
3076 value_in_comment = offset;
3077 }
3078 else
3079 {
3080 /* Register Offset or Register Pre-Indexed. */
3081 func (stream, ", %s%s",
3082 NEGATIVE_BIT_SET ? "-" : "",
3083 arm_regnames[given & 0xf]);
3084
3085 /* Writing back to the register that is the source/
3086 destination of the load/store is unpredictable. */
3087 if (! allow_unpredictable
3088 && WRITEBACK_BIT_SET
3089 && ((given & 0xf) == ((given >> 12) & 0xf)))
3090 is_unpredictable = TRUE;
3091 }
3092
3093 func (stream, "]%s",
3094 WRITEBACK_BIT_SET ? "!" : "");
3095 }
3096 else
3097 {
3098 if (IMMEDIATE_BIT_SET)
3099 {
3100 /* Immediate Post-indexed. */
3101 /* PR 10924: Offset must be printed, even if it is zero. */
3102 func (stream, "], #%s%d",
3103 NEGATIVE_BIT_SET ? "-" : "", offset);
3104 if (NEGATIVE_BIT_SET)
3105 offset = -offset;
3106 value_in_comment = offset;
3107 }
3108 else
3109 {
3110 /* Register Post-indexed. */
3111 func (stream, "], %s%s",
3112 NEGATIVE_BIT_SET ? "-" : "",
3113 arm_regnames[given & 0xf]);
3114
3115 /* Writing back to the register that is the source/
3116 destination of the load/store is unpredictable. */
3117 if (! allow_unpredictable
3118 && (given & 0xf) == ((given >> 12) & 0xf))
3119 is_unpredictable = TRUE;
3120 }
3121
3122 if (! allow_unpredictable)
3123 {
3124 /* Writeback is automatically implied by post- addressing.
3125 Setting the W bit is unnecessary and ARM specify it as
3126 being unpredictable. */
3127 if (WRITEBACK_BIT_SET
3128 /* Specifying the PC register as the post-indexed
3129 registers is also unpredictable. */
3130 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3131 is_unpredictable = TRUE;
3132 }
3133 }
3134 }
3135 break;
3136
3137 case 'b':
3138 {
3139 bfd_vma disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3140 info->print_address_func (disp * 4 + pc + 8, info);
3141 }
3142 break;
3143
3144 case 'c':
3145 if (((given >> 28) & 0xf) != 0xe)
3146 func (stream, "%s",
3147 arm_conditional [(given >> 28) & 0xf]);
3148 break;
3149
3150 case 'm':
3151 {
3152 int started = 0;
3153 int reg;
3154
3155 func (stream, "{");
3156 for (reg = 0; reg < 16; reg++)
3157 if ((given & (1 << reg)) != 0)
3158 {
3159 if (started)
3160 func (stream, ", ");
3161 started = 1;
3162 func (stream, "%s", arm_regnames[reg]);
3163 }
3164 func (stream, "}");
3165 if (! started)
3166 is_unpredictable = TRUE;
3167 }
3168 break;
3169
3170 case 'q':
3171 arm_decode_shift (given, func, stream, FALSE);
3172 break;
3173
3174 case 'o':
3175 if ((given & 0x02000000) != 0)
3176 {
3177 unsigned int rotate = (given & 0xf00) >> 7;
3178 unsigned int immed = (given & 0xff);
3179 unsigned int a, i;
3180
3181 a = (((immed << (32 - rotate))
3182 | (immed >> rotate)) & 0xffffffff);
3183 /* If there is another encoding with smaller rotate,
3184 the rotate should be specified directly. */
3185 for (i = 0; i < 32; i += 2)
3186 if ((a << i | a >> (32 - i)) <= 0xff)
3187 break;
3188
3189 if (i != rotate)
3190 func (stream, "#%d, %d", immed, rotate);
3191 else
3192 func (stream, "#%d", a);
3193 value_in_comment = a;
3194 }
3195 else
3196 arm_decode_shift (given, func, stream, TRUE);
3197 break;
3198
3199 case 'p':
3200 if ((given & 0x0000f000) == 0x0000f000)
3201 {
3202 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3203 mechanism for setting PSR flag bits. They are
3204 obsolete in V6 onwards. */
3205 if ((private_data->features.core & ARM_EXT_V6) == 0)
3206 func (stream, "p");
3207 }
3208 break;
3209
3210 case 't':
3211 if ((given & 0x01200000) == 0x00200000)
3212 func (stream, "t");
3213 break;
3214
3215 case 'A':
3216 {
3217 int offset = given & 0xff;
3218
3219 value_in_comment = offset * 4;
3220 if (NEGATIVE_BIT_SET)
3221 value_in_comment = - value_in_comment;
3222
3223 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3224
3225 if (PRE_BIT_SET)
3226 {
3227 if (offset)
3228 func (stream, ", #%d]%s",
3229 value_in_comment,
3230 WRITEBACK_BIT_SET ? "!" : "");
3231 else
3232 func (stream, "]");
3233 }
3234 else
3235 {
3236 func (stream, "]");
3237
3238 if (WRITEBACK_BIT_SET)
3239 {
3240 if (offset)
3241 func (stream, ", #%d", value_in_comment);
3242 }
3243 else
3244 {
3245 func (stream, ", {%d}", offset);
3246 value_in_comment = offset;
3247 }
3248 }
3249 }
3250 break;
3251
3252 case 'B':
3253 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3254 {
3255 bfd_vma address;
3256 bfd_vma offset = 0;
3257
3258 if (! NEGATIVE_BIT_SET)
3259 /* Is signed, hi bits should be ones. */
3260 offset = (-1) ^ 0x00ffffff;
3261
3262 /* Offset is (SignExtend(offset field)<<2). */
3263 offset += given & 0x00ffffff;
3264 offset <<= 2;
3265 address = offset + pc + 8;
3266
3267 if (given & 0x01000000)
3268 /* H bit allows addressing to 2-byte boundaries. */
3269 address += 2;
3270
3271 info->print_address_func (address, info);
3272 }
3273 break;
3274
3275 case 'C':
3276 if ((given & 0x02000200) == 0x200)
3277 {
3278 const char * name;
3279 unsigned sysm = (given & 0x004f0000) >> 16;
3280
3281 sysm |= (given & 0x300) >> 4;
3282 name = banked_regname (sysm);
3283
3284 if (name != NULL)
3285 func (stream, "%s", name);
3286 else
3287 func (stream, "(UNDEF: %lu)", sysm);
3288 }
3289 else
3290 {
3291 func (stream, "%cPSR_",
3292 (given & 0x00400000) ? 'S' : 'C');
3293 if (given & 0x80000)
3294 func (stream, "f");
3295 if (given & 0x40000)
3296 func (stream, "s");
3297 if (given & 0x20000)
3298 func (stream, "x");
3299 if (given & 0x10000)
3300 func (stream, "c");
3301 }
3302 break;
3303
3304 case 'U':
3305 if ((given & 0xf0) == 0x60)
3306 {
3307 switch (given & 0xf)
3308 {
3309 case 0xf: func (stream, "sy"); break;
3310 default:
3311 func (stream, "#%d", (int) given & 0xf);
3312 break;
3313 }
3314 }
3315 else
3316 {
3317 switch (given & 0xf)
3318 {
3319 case 0xf: func (stream, "sy"); break;
3320 case 0x7: func (stream, "un"); break;
3321 case 0xe: func (stream, "st"); break;
3322 case 0x6: func (stream, "unst"); break;
3323 case 0xb: func (stream, "ish"); break;
3324 case 0xa: func (stream, "ishst"); break;
3325 case 0x3: func (stream, "osh"); break;
3326 case 0x2: func (stream, "oshst"); break;
3327 default:
3328 func (stream, "#%d", (int) given & 0xf);
3329 break;
3330 }
3331 }
3332 break;
3333
3334 case '0': case '1': case '2': case '3': case '4':
3335 case '5': case '6': case '7': case '8': case '9':
3336 {
3337 int width;
3338 unsigned long value;
3339
3340 c = arm_decode_bitfield (c, given, &value, &width);
3341
3342 switch (*c)
3343 {
3344 case 'R':
3345 if (value == 15)
3346 is_unpredictable = TRUE;
3347 /* Fall through. */
3348 case 'r':
3349 if (c[1] == 'u')
3350 {
3351 /* Eat the 'u' character. */
3352 ++ c;
3353
3354 if (u_reg == value)
3355 is_unpredictable = TRUE;
3356 u_reg = value;
3357 }
3358 if (c[1] == 'U')
3359 {
3360 /* Eat the 'U' character. */
3361 ++ c;
3362
3363 if (U_reg == value)
3364 is_unpredictable = TRUE;
3365 U_reg = value;
3366 }
3367 func (stream, "%s", arm_regnames[value]);
3368 break;
3369 case 'd':
3370 func (stream, "%ld", value);
3371 value_in_comment = value;
3372 break;
3373 case 'b':
3374 func (stream, "%ld", value * 8);
3375 value_in_comment = value * 8;
3376 break;
3377 case 'W':
3378 func (stream, "%ld", value + 1);
3379 value_in_comment = value + 1;
3380 break;
3381 case 'x':
3382 func (stream, "0x%08lx", value);
3383
3384 /* Some SWI instructions have special
3385 meanings. */
3386 if ((given & 0x0fffffff) == 0x0FF00000)
3387 func (stream, "\t; IMB");
3388 else if ((given & 0x0fffffff) == 0x0FF00001)
3389 func (stream, "\t; IMBRange");
3390 break;
3391 case 'X':
3392 func (stream, "%01lx", value & 0xf);
3393 value_in_comment = value;
3394 break;
3395 case '`':
3396 c++;
3397 if (value == 0)
3398 func (stream, "%c", *c);
3399 break;
3400 case '\'':
3401 c++;
3402 if (value == ((1ul << width) - 1))
3403 func (stream, "%c", *c);
3404 break;
3405 case '?':
3406 func (stream, "%c", c[(1 << width) - (int) value]);
3407 c += 1 << width;
3408 break;
3409 default:
3410 abort ();
3411 }
3412 break;
3413
3414 case 'e':
3415 {
3416 int imm;
3417
3418 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3419 func (stream, "%d", imm);
3420 value_in_comment = imm;
3421 }
3422 break;
3423
3424 case 'E':
3425 /* LSB and WIDTH fields of BFI or BFC. The machine-
3426 language instruction encodes LSB and MSB. */
3427 {
3428 long msb = (given & 0x001f0000) >> 16;
3429 long lsb = (given & 0x00000f80) >> 7;
3430 long w = msb - lsb + 1;
3431
3432 if (w > 0)
3433 func (stream, "#%lu, #%lu", lsb, w);
3434 else
3435 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3436 }
3437 break;
3438
3439 case 'R':
3440 /* Get the PSR/banked register name. */
3441 {
3442 const char * name;
3443 unsigned sysm = (given & 0x004f0000) >> 16;
3444
3445 sysm |= (given & 0x300) >> 4;
3446 name = banked_regname (sysm);
3447
3448 if (name != NULL)
3449 func (stream, "%s", name);
3450 else
3451 func (stream, "(UNDEF: %lu)", sysm);
3452 }
3453 break;
3454
3455 case 'V':
3456 /* 16-bit unsigned immediate from a MOVT or MOVW
3457 instruction, encoded in bits 0:11 and 15:19. */
3458 {
3459 long hi = (given & 0x000f0000) >> 4;
3460 long lo = (given & 0x00000fff);
3461 long imm16 = hi | lo;
3462
3463 func (stream, "#%lu", imm16);
3464 value_in_comment = imm16;
3465 }
3466 break;
3467
3468 default:
3469 abort ();
3470 }
3471 }
3472 }
3473 else
3474 func (stream, "%c", *c);
3475 }
3476
3477 if (value_in_comment > 32 || value_in_comment < -16)
3478 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3479
3480 if (is_unpredictable)
3481 func (stream, UNPREDICTABLE_INSTRUCTION);
3482
3483 return;
3484 }
3485 }
3486 abort ();
3487 }
3488
3489 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3490
3491 static void
3492 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3493 {
3494 const struct opcode16 *insn;
3495 void *stream = info->stream;
3496 fprintf_ftype func = info->fprintf_func;
3497
3498 for (insn = thumb_opcodes; insn->assembler; insn++)
3499 if ((given & insn->mask) == insn->value)
3500 {
3501 signed long value_in_comment = 0;
3502 const char *c = insn->assembler;
3503
3504 for (; *c; c++)
3505 {
3506 int domaskpc = 0;
3507 int domasklr = 0;
3508
3509 if (*c != '%')
3510 {
3511 func (stream, "%c", *c);
3512 continue;
3513 }
3514
3515 switch (*++c)
3516 {
3517 case '%':
3518 func (stream, "%%");
3519 break;
3520
3521 case 'c':
3522 if (ifthen_state)
3523 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3524 break;
3525
3526 case 'C':
3527 if (ifthen_state)
3528 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3529 else
3530 func (stream, "s");
3531 break;
3532
3533 case 'I':
3534 {
3535 unsigned int tmp;
3536
3537 ifthen_next_state = given & 0xff;
3538 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3539 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3540 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3541 }
3542 break;
3543
3544 case 'x':
3545 if (ifthen_next_state)
3546 func (stream, "\t; unpredictable branch in IT block\n");
3547 break;
3548
3549 case 'X':
3550 if (ifthen_state)
3551 func (stream, "\t; unpredictable <IT:%s>",
3552 arm_conditional[IFTHEN_COND]);
3553 break;
3554
3555 case 'S':
3556 {
3557 long reg;
3558
3559 reg = (given >> 3) & 0x7;
3560 if (given & (1 << 6))
3561 reg += 8;
3562
3563 func (stream, "%s", arm_regnames[reg]);
3564 }
3565 break;
3566
3567 case 'D':
3568 {
3569 long reg;
3570
3571 reg = given & 0x7;
3572 if (given & (1 << 7))
3573 reg += 8;
3574
3575 func (stream, "%s", arm_regnames[reg]);
3576 }
3577 break;
3578
3579 case 'N':
3580 if (given & (1 << 8))
3581 domasklr = 1;
3582 /* Fall through. */
3583 case 'O':
3584 if (*c == 'O' && (given & (1 << 8)))
3585 domaskpc = 1;
3586 /* Fall through. */
3587 case 'M':
3588 {
3589 int started = 0;
3590 int reg;
3591
3592 func (stream, "{");
3593
3594 /* It would be nice if we could spot
3595 ranges, and generate the rS-rE format: */
3596 for (reg = 0; (reg < 8); reg++)
3597 if ((given & (1 << reg)) != 0)
3598 {
3599 if (started)
3600 func (stream, ", ");
3601 started = 1;
3602 func (stream, "%s", arm_regnames[reg]);
3603 }
3604
3605 if (domasklr)
3606 {
3607 if (started)
3608 func (stream, ", ");
3609 started = 1;
3610 func (stream, arm_regnames[14] /* "lr" */);
3611 }
3612
3613 if (domaskpc)
3614 {
3615 if (started)
3616 func (stream, ", ");
3617 func (stream, arm_regnames[15] /* "pc" */);
3618 }
3619
3620 func (stream, "}");
3621 }
3622 break;
3623
3624 case 'W':
3625 /* Print writeback indicator for a LDMIA. We are doing a
3626 writeback if the base register is not in the register
3627 mask. */
3628 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3629 func (stream, "!");
3630 break;
3631
3632 case 'b':
3633 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3634 {
3635 bfd_vma address = (pc + 4
3636 + ((given & 0x00f8) >> 2)
3637 + ((given & 0x0200) >> 3));
3638 info->print_address_func (address, info);
3639 }
3640 break;
3641
3642 case 's':
3643 /* Right shift immediate -- bits 6..10; 1-31 print
3644 as themselves, 0 prints as 32. */
3645 {
3646 long imm = (given & 0x07c0) >> 6;
3647 if (imm == 0)
3648 imm = 32;
3649 func (stream, "#%ld", imm);
3650 }
3651 break;
3652
3653 case '0': case '1': case '2': case '3': case '4':
3654 case '5': case '6': case '7': case '8': case '9':
3655 {
3656 int bitstart = *c++ - '0';
3657 int bitend = 0;
3658
3659 while (*c >= '0' && *c <= '9')
3660 bitstart = (bitstart * 10) + *c++ - '0';
3661
3662 switch (*c)
3663 {
3664 case '-':
3665 {
3666 bfd_vma reg;
3667
3668 c++;
3669 while (*c >= '0' && *c <= '9')
3670 bitend = (bitend * 10) + *c++ - '0';
3671 if (!bitend)
3672 abort ();
3673 reg = given >> bitstart;
3674 reg &= (2 << (bitend - bitstart)) - 1;
3675
3676 switch (*c)
3677 {
3678 case 'r':
3679 func (stream, "%s", arm_regnames[reg]);
3680 break;
3681
3682 case 'd':
3683 func (stream, "%ld", reg);
3684 value_in_comment = reg;
3685 break;
3686
3687 case 'H':
3688 func (stream, "%ld", reg << 1);
3689 value_in_comment = reg << 1;
3690 break;
3691
3692 case 'W':
3693 func (stream, "%ld", reg << 2);
3694 value_in_comment = reg << 2;
3695 break;
3696
3697 case 'a':
3698 /* PC-relative address -- the bottom two
3699 bits of the address are dropped
3700 before the calculation. */
3701 info->print_address_func
3702 (((pc + 4) & ~3) + (reg << 2), info);
3703 value_in_comment = 0;
3704 break;
3705
3706 case 'x':
3707 func (stream, "0x%04lx", reg);
3708 break;
3709
3710 case 'B':
3711 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3712 info->print_address_func (reg * 2 + pc + 4, info);
3713 value_in_comment = 0;
3714 break;
3715
3716 case 'c':
3717 func (stream, "%s", arm_conditional [reg]);
3718 break;
3719
3720 default:
3721 abort ();
3722 }
3723 }
3724 break;
3725
3726 case '\'':
3727 c++;
3728 if ((given & (1 << bitstart)) != 0)
3729 func (stream, "%c", *c);
3730 break;
3731
3732 case '?':
3733 ++c;
3734 if ((given & (1 << bitstart)) != 0)
3735 func (stream, "%c", *c++);
3736 else
3737 func (stream, "%c", *++c);
3738 break;
3739
3740 default:
3741 abort ();
3742 }
3743 }
3744 break;
3745
3746 default:
3747 abort ();
3748 }
3749 }
3750
3751 if (value_in_comment > 32 || value_in_comment < -16)
3752 func (stream, "\t; 0x%lx", value_in_comment);
3753 return;
3754 }
3755
3756 /* No match. */
3757 abort ();
3758 }
3759
3760 /* Return the name of an V7M special register. */
3761
3762 static const char *
3763 psr_name (int regno)
3764 {
3765 switch (regno)
3766 {
3767 case 0: return "APSR";
3768 case 1: return "IAPSR";
3769 case 2: return "EAPSR";
3770 case 3: return "PSR";
3771 case 5: return "IPSR";
3772 case 6: return "EPSR";
3773 case 7: return "IEPSR";
3774 case 8: return "MSP";
3775 case 9: return "PSP";
3776 case 16: return "PRIMASK";
3777 case 17: return "BASEPRI";
3778 case 18: return "BASEPRI_MAX";
3779 case 19: return "FAULTMASK";
3780 case 20: return "CONTROL";
3781 default: return "<unknown>";
3782 }
3783 }
3784
3785 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3786
3787 static void
3788 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3789 {
3790 const struct opcode32 *insn;
3791 void *stream = info->stream;
3792 fprintf_ftype func = info->fprintf_func;
3793
3794 if (print_insn_coprocessor (pc, info, given, TRUE))
3795 return;
3796
3797 if (print_insn_neon (info, given, TRUE))
3798 return;
3799
3800 for (insn = thumb32_opcodes; insn->assembler; insn++)
3801 if ((given & insn->mask) == insn->value)
3802 {
3803 bfd_boolean is_unpredictable = FALSE;
3804 signed long value_in_comment = 0;
3805 const char *c = insn->assembler;
3806
3807 for (; *c; c++)
3808 {
3809 if (*c != '%')
3810 {
3811 func (stream, "%c", *c);
3812 continue;
3813 }
3814
3815 switch (*++c)
3816 {
3817 case '%':
3818 func (stream, "%%");
3819 break;
3820
3821 case 'c':
3822 if (ifthen_state)
3823 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3824 break;
3825
3826 case 'x':
3827 if (ifthen_next_state)
3828 func (stream, "\t; unpredictable branch in IT block\n");
3829 break;
3830
3831 case 'X':
3832 if (ifthen_state)
3833 func (stream, "\t; unpredictable <IT:%s>",
3834 arm_conditional[IFTHEN_COND]);
3835 break;
3836
3837 case 'I':
3838 {
3839 unsigned int imm12 = 0;
3840
3841 imm12 |= (given & 0x000000ffu);
3842 imm12 |= (given & 0x00007000u) >> 4;
3843 imm12 |= (given & 0x04000000u) >> 15;
3844 func (stream, "#%u", imm12);
3845 value_in_comment = imm12;
3846 }
3847 break;
3848
3849 case 'M':
3850 {
3851 unsigned int bits = 0, imm, imm8, mod;
3852
3853 bits |= (given & 0x000000ffu);
3854 bits |= (given & 0x00007000u) >> 4;
3855 bits |= (given & 0x04000000u) >> 15;
3856 imm8 = (bits & 0x0ff);
3857 mod = (bits & 0xf00) >> 8;
3858 switch (mod)
3859 {
3860 case 0: imm = imm8; break;
3861 case 1: imm = ((imm8 << 16) | imm8); break;
3862 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3863 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3864 default:
3865 mod = (bits & 0xf80) >> 7;
3866 imm8 = (bits & 0x07f) | 0x80;
3867 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3868 }
3869 func (stream, "#%u", imm);
3870 value_in_comment = imm;
3871 }
3872 break;
3873
3874 case 'J':
3875 {
3876 unsigned int imm = 0;
3877
3878 imm |= (given & 0x000000ffu);
3879 imm |= (given & 0x00007000u) >> 4;
3880 imm |= (given & 0x04000000u) >> 15;
3881 imm |= (given & 0x000f0000u) >> 4;
3882 func (stream, "#%u", imm);
3883 value_in_comment = imm;
3884 }
3885 break;
3886
3887 case 'K':
3888 {
3889 unsigned int imm = 0;
3890
3891 imm |= (given & 0x000f0000u) >> 16;
3892 imm |= (given & 0x00000ff0u) >> 0;
3893 imm |= (given & 0x0000000fu) << 12;
3894 func (stream, "#%u", imm);
3895 value_in_comment = imm;
3896 }
3897 break;
3898
3899 case 'V':
3900 {
3901 unsigned int imm = 0;
3902
3903 imm |= (given & 0x00000fffu);
3904 imm |= (given & 0x000f0000u) >> 4;
3905 func (stream, "#%u", imm);
3906 value_in_comment = imm;
3907 }
3908 break;
3909
3910 case 'S':
3911 {
3912 unsigned int reg = (given & 0x0000000fu);
3913 unsigned int stp = (given & 0x00000030u) >> 4;
3914 unsigned int imm = 0;
3915 imm |= (given & 0x000000c0u) >> 6;
3916 imm |= (given & 0x00007000u) >> 10;
3917
3918 func (stream, "%s", arm_regnames[reg]);
3919 switch (stp)
3920 {
3921 case 0:
3922 if (imm > 0)
3923 func (stream, ", lsl #%u", imm);
3924 break;
3925
3926 case 1:
3927 if (imm == 0)
3928 imm = 32;
3929 func (stream, ", lsr #%u", imm);
3930 break;
3931
3932 case 2:
3933 if (imm == 0)
3934 imm = 32;
3935 func (stream, ", asr #%u", imm);
3936 break;
3937
3938 case 3:
3939 if (imm == 0)
3940 func (stream, ", rrx");
3941 else
3942 func (stream, ", ror #%u", imm);
3943 }
3944 }
3945 break;
3946
3947 case 'a':
3948 {
3949 unsigned int Rn = (given & 0x000f0000) >> 16;
3950 unsigned int U = ! NEGATIVE_BIT_SET;
3951 unsigned int op = (given & 0x00000f00) >> 8;
3952 unsigned int i12 = (given & 0x00000fff);
3953 unsigned int i8 = (given & 0x000000ff);
3954 bfd_boolean writeback = FALSE, postind = FALSE;
3955 bfd_vma offset = 0;
3956
3957 func (stream, "[%s", arm_regnames[Rn]);
3958 if (U) /* 12-bit positive immediate offset. */
3959 {
3960 offset = i12;
3961 if (Rn != 15)
3962 value_in_comment = offset;
3963 }
3964 else if (Rn == 15) /* 12-bit negative immediate offset. */
3965 offset = - (int) i12;
3966 else if (op == 0x0) /* Shifted register offset. */
3967 {
3968 unsigned int Rm = (i8 & 0x0f);
3969 unsigned int sh = (i8 & 0x30) >> 4;
3970
3971 func (stream, ", %s", arm_regnames[Rm]);
3972 if (sh)
3973 func (stream, ", lsl #%u", sh);
3974 func (stream, "]");
3975 break;
3976 }
3977 else switch (op)
3978 {
3979 case 0xE: /* 8-bit positive immediate offset. */
3980 offset = i8;
3981 break;
3982
3983 case 0xC: /* 8-bit negative immediate offset. */
3984 offset = -i8;
3985 break;
3986
3987 case 0xF: /* 8-bit + preindex with wb. */
3988 offset = i8;
3989 writeback = TRUE;
3990 break;
3991
3992 case 0xD: /* 8-bit - preindex with wb. */
3993 offset = -i8;
3994 writeback = TRUE;
3995 break;
3996
3997 case 0xB: /* 8-bit + postindex. */
3998 offset = i8;
3999 postind = TRUE;
4000 break;
4001
4002 case 0x9: /* 8-bit - postindex. */
4003 offset = -i8;
4004 postind = TRUE;
4005 break;
4006
4007 default:
4008 func (stream, ", <undefined>]");
4009 goto skip;
4010 }
4011
4012 if (postind)
4013 func (stream, "], #%d", offset);
4014 else
4015 {
4016 if (offset)
4017 func (stream, ", #%d", offset);
4018 func (stream, writeback ? "]!" : "]");
4019 }
4020
4021 if (Rn == 15)
4022 {
4023 func (stream, "\t; ");
4024 info->print_address_func (((pc + 4) & ~3) + offset, info);
4025 }
4026 }
4027 skip:
4028 break;
4029
4030 case 'A':
4031 {
4032 unsigned int U = ! NEGATIVE_BIT_SET;
4033 unsigned int W = WRITEBACK_BIT_SET;
4034 unsigned int Rn = (given & 0x000f0000) >> 16;
4035 unsigned int off = (given & 0x000000ff);
4036
4037 func (stream, "[%s", arm_regnames[Rn]);
4038
4039 if (PRE_BIT_SET)
4040 {
4041 if (off || !U)
4042 {
4043 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
4044 value_in_comment = off * 4 * U ? 1 : -1;
4045 }
4046 func (stream, "]");
4047 if (W)
4048 func (stream, "!");
4049 }
4050 else
4051 {
4052 func (stream, "], ");
4053 if (W)
4054 {
4055 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4056 value_in_comment = off * 4 * U ? 1 : -1;
4057 }
4058 else
4059 {
4060 func (stream, "{%u}", off);
4061 value_in_comment = off;
4062 }
4063 }
4064 }
4065 break;
4066
4067 case 'w':
4068 {
4069 unsigned int Sbit = (given & 0x01000000) >> 24;
4070 unsigned int type = (given & 0x00600000) >> 21;
4071
4072 switch (type)
4073 {
4074 case 0: func (stream, Sbit ? "sb" : "b"); break;
4075 case 1: func (stream, Sbit ? "sh" : "h"); break;
4076 case 2:
4077 if (Sbit)
4078 func (stream, "??");
4079 break;
4080 case 3:
4081 func (stream, "??");
4082 break;
4083 }
4084 }
4085 break;
4086
4087 case 'm':
4088 {
4089 int started = 0;
4090 int reg;
4091
4092 func (stream, "{");
4093 for (reg = 0; reg < 16; reg++)
4094 if ((given & (1 << reg)) != 0)
4095 {
4096 if (started)
4097 func (stream, ", ");
4098 started = 1;
4099 func (stream, "%s", arm_regnames[reg]);
4100 }
4101 func (stream, "}");
4102 }
4103 break;
4104
4105 case 'E':
4106 {
4107 unsigned int msb = (given & 0x0000001f);
4108 unsigned int lsb = 0;
4109
4110 lsb |= (given & 0x000000c0u) >> 6;
4111 lsb |= (given & 0x00007000u) >> 10;
4112 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4113 }
4114 break;
4115
4116 case 'F':
4117 {
4118 unsigned int width = (given & 0x0000001f) + 1;
4119 unsigned int lsb = 0;
4120
4121 lsb |= (given & 0x000000c0u) >> 6;
4122 lsb |= (given & 0x00007000u) >> 10;
4123 func (stream, "#%u, #%u", lsb, width);
4124 }
4125 break;
4126
4127 case 'b':
4128 {
4129 unsigned int S = (given & 0x04000000u) >> 26;
4130 unsigned int J1 = (given & 0x00002000u) >> 13;
4131 unsigned int J2 = (given & 0x00000800u) >> 11;
4132 bfd_vma offset = 0;
4133
4134 offset |= !S << 20;
4135 offset |= J2 << 19;
4136 offset |= J1 << 18;
4137 offset |= (given & 0x003f0000) >> 4;
4138 offset |= (given & 0x000007ff) << 1;
4139 offset -= (1 << 20);
4140
4141 info->print_address_func (pc + 4 + offset, info);
4142 }
4143 break;
4144
4145 case 'B':
4146 {
4147 unsigned int S = (given & 0x04000000u) >> 26;
4148 unsigned int I1 = (given & 0x00002000u) >> 13;
4149 unsigned int I2 = (given & 0x00000800u) >> 11;
4150 bfd_vma offset = 0;
4151
4152 offset |= !S << 24;
4153 offset |= !(I1 ^ S) << 23;
4154 offset |= !(I2 ^ S) << 22;
4155 offset |= (given & 0x03ff0000u) >> 4;
4156 offset |= (given & 0x000007ffu) << 1;
4157 offset -= (1 << 24);
4158 offset += pc + 4;
4159
4160 /* BLX target addresses are always word aligned. */
4161 if ((given & 0x00001000u) == 0)
4162 offset &= ~2u;
4163
4164 info->print_address_func (offset, info);
4165 }
4166 break;
4167
4168 case 's':
4169 {
4170 unsigned int shift = 0;
4171
4172 shift |= (given & 0x000000c0u) >> 6;
4173 shift |= (given & 0x00007000u) >> 10;
4174 if (WRITEBACK_BIT_SET)
4175 func (stream, ", asr #%u", shift);
4176 else if (shift)
4177 func (stream, ", lsl #%u", shift);
4178 /* else print nothing - lsl #0 */
4179 }
4180 break;
4181
4182 case 'R':
4183 {
4184 unsigned int rot = (given & 0x00000030) >> 4;
4185
4186 if (rot)
4187 func (stream, ", ror #%u", rot * 8);
4188 }
4189 break;
4190
4191 case 'U':
4192 if ((given & 0xf0) == 0x60)
4193 {
4194 switch (given & 0xf)
4195 {
4196 case 0xf: func (stream, "sy"); break;
4197 default:
4198 func (stream, "#%d", (int) given & 0xf);
4199 break;
4200 }
4201 }
4202 else
4203 {
4204 switch (given & 0xf)
4205 {
4206 case 0xf: func (stream, "sy"); break;
4207 case 0x7: func (stream, "un"); break;
4208 case 0xe: func (stream, "st"); break;
4209 case 0x6: func (stream, "unst"); break;
4210 case 0xb: func (stream, "ish"); break;
4211 case 0xa: func (stream, "ishst"); break;
4212 case 0x3: func (stream, "osh"); break;
4213 case 0x2: func (stream, "oshst"); break;
4214 default:
4215 func (stream, "#%d", (int) given & 0xf);
4216 break;
4217 }
4218 }
4219 break;
4220
4221 case 'C':
4222 if ((given & 0xff) == 0)
4223 {
4224 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4225 if (given & 0x800)
4226 func (stream, "f");
4227 if (given & 0x400)
4228 func (stream, "s");
4229 if (given & 0x200)
4230 func (stream, "x");
4231 if (given & 0x100)
4232 func (stream, "c");
4233 }
4234 else if ((given & 0x20) == 0x20)
4235 {
4236 char const* name;
4237 unsigned sysm = (given & 0xf00) >> 8;
4238
4239 sysm |= (given & 0x30);
4240 sysm |= (given & 0x00100000) >> 14;
4241 name = banked_regname (sysm);
4242
4243 if (name != NULL)
4244 func (stream, "%s", name);
4245 else
4246 func (stream, "(UNDEF: %lu)", sysm);
4247 }
4248 else
4249 {
4250 func (stream, psr_name (given & 0xff));
4251 }
4252 break;
4253
4254 case 'D':
4255 if (((given & 0xff) == 0)
4256 || ((given & 0x20) == 0x20))
4257 {
4258 char const* name;
4259 unsigned sm = (given & 0xf0000) >> 16;
4260
4261 sm |= (given & 0x30);
4262 sm |= (given & 0x00100000) >> 14;
4263 name = banked_regname (sm);
4264
4265 if (name != NULL)
4266 func (stream, "%s", name);
4267 else
4268 func (stream, "(UNDEF: %lu)", sm);
4269 }
4270 else
4271 func (stream, psr_name (given & 0xff));
4272 break;
4273
4274 case '0': case '1': case '2': case '3': case '4':
4275 case '5': case '6': case '7': case '8': case '9':
4276 {
4277 int width;
4278 unsigned long val;
4279
4280 c = arm_decode_bitfield (c, given, &val, &width);
4281
4282 switch (*c)
4283 {
4284 case 'd':
4285 func (stream, "%lu", val);
4286 value_in_comment = val;
4287 break;
4288
4289 case 'W':
4290 func (stream, "%lu", val * 4);
4291 value_in_comment = val * 4;
4292 break;
4293
4294 case 'R':
4295 if (val == 15)
4296 is_unpredictable = TRUE;
4297 /* Fall through. */
4298 case 'r':
4299 func (stream, "%s", arm_regnames[val]);
4300 break;
4301
4302 case 'c':
4303 func (stream, "%s", arm_conditional[val]);
4304 break;
4305
4306 case '\'':
4307 c++;
4308 if (val == ((1ul << width) - 1))
4309 func (stream, "%c", *c);
4310 break;
4311
4312 case '`':
4313 c++;
4314 if (val == 0)
4315 func (stream, "%c", *c);
4316 break;
4317
4318 case '?':
4319 func (stream, "%c", c[(1 << width) - (int) val]);
4320 c += 1 << width;
4321 break;
4322
4323 case 'x':
4324 func (stream, "0x%lx", val & 0xffffffffUL);
4325 break;
4326
4327 default:
4328 abort ();
4329 }
4330 }
4331 break;
4332
4333 case 'L':
4334 /* PR binutils/12534
4335 If we have a PC relative offset in an LDRD or STRD
4336 instructions then display the decoded address. */
4337 if (((given >> 16) & 0xf) == 0xf)
4338 {
4339 bfd_vma offset = (given & 0xff) * 4;
4340
4341 if ((given & (1 << 23)) == 0)
4342 offset = - offset;
4343 func (stream, "\t; ");
4344 info->print_address_func ((pc & ~3) + 4 + offset, info);
4345 }
4346 break;
4347
4348 default:
4349 abort ();
4350 }
4351 }
4352
4353 if (value_in_comment > 32 || value_in_comment < -16)
4354 func (stream, "\t; 0x%lx", value_in_comment);
4355
4356 if (is_unpredictable)
4357 func (stream, UNPREDICTABLE_INSTRUCTION);
4358
4359 return;
4360 }
4361
4362 /* No match. */
4363 abort ();
4364 }
4365
4366 /* Print data bytes on INFO->STREAM. */
4367
4368 static void
4369 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4370 struct disassemble_info *info,
4371 long given)
4372 {
4373 switch (info->bytes_per_chunk)
4374 {
4375 case 1:
4376 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4377 break;
4378 case 2:
4379 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4380 break;
4381 case 4:
4382 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4383 break;
4384 default:
4385 abort ();
4386 }
4387 }
4388
4389 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4390 being displayed in symbol relative addresses. */
4391
4392 bfd_boolean
4393 arm_symbol_is_valid (asymbol * sym,
4394 struct disassemble_info * info ATTRIBUTE_UNUSED)
4395 {
4396 const char * name;
4397
4398 if (sym == NULL)
4399 return FALSE;
4400
4401 name = bfd_asymbol_name (sym);
4402
4403 return (name && *name != '$');
4404 }
4405
4406 /* Parse an individual disassembler option. */
4407
4408 void
4409 parse_arm_disassembler_option (char *option)
4410 {
4411 if (option == NULL)
4412 return;
4413
4414 if (CONST_STRNEQ (option, "reg-names-"))
4415 {
4416 int i;
4417
4418 option += 10;
4419
4420 for (i = NUM_ARM_REGNAMES; i--;)
4421 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4422 {
4423 regname_selected = i;
4424 break;
4425 }
4426
4427 if (i < 0)
4428 /* XXX - should break 'option' at following delimiter. */
4429 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4430 }
4431 else if (CONST_STRNEQ (option, "force-thumb"))
4432 force_thumb = 1;
4433 else if (CONST_STRNEQ (option, "no-force-thumb"))
4434 force_thumb = 0;
4435 else
4436 /* XXX - should break 'option' at following delimiter. */
4437 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4438
4439 return;
4440 }
4441
4442 /* Parse the string of disassembler options, spliting it at whitespaces
4443 or commas. (Whitespace separators supported for backwards compatibility). */
4444
4445 static void
4446 parse_disassembler_options (char *options)
4447 {
4448 if (options == NULL)
4449 return;
4450
4451 while (*options)
4452 {
4453 parse_arm_disassembler_option (options);
4454
4455 /* Skip forward to next seperator. */
4456 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4457 ++ options;
4458 /* Skip forward past seperators. */
4459 while (ISSPACE (*options) || (*options == ','))
4460 ++ options;
4461 }
4462 }
4463
4464 /* Search back through the insn stream to determine if this instruction is
4465 conditionally executed. */
4466
4467 static void
4468 find_ifthen_state (bfd_vma pc,
4469 struct disassemble_info *info,
4470 bfd_boolean little)
4471 {
4472 unsigned char b[2];
4473 unsigned int insn;
4474 int status;
4475 /* COUNT is twice the number of instructions seen. It will be odd if we
4476 just crossed an instruction boundary. */
4477 int count;
4478 int it_count;
4479 unsigned int seen_it;
4480 bfd_vma addr;
4481
4482 ifthen_address = pc;
4483 ifthen_state = 0;
4484
4485 addr = pc;
4486 count = 1;
4487 it_count = 0;
4488 seen_it = 0;
4489 /* Scan backwards looking for IT instructions, keeping track of where
4490 instruction boundaries are. We don't know if something is actually an
4491 IT instruction until we find a definite instruction boundary. */
4492 for (;;)
4493 {
4494 if (addr == 0 || info->symbol_at_address_func (addr, info))
4495 {
4496 /* A symbol must be on an instruction boundary, and will not
4497 be within an IT block. */
4498 if (seen_it && (count & 1))
4499 break;
4500
4501 return;
4502 }
4503 addr -= 2;
4504 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4505 if (status)
4506 return;
4507
4508 if (little)
4509 insn = (b[0]) | (b[1] << 8);
4510 else
4511 insn = (b[1]) | (b[0] << 8);
4512 if (seen_it)
4513 {
4514 if ((insn & 0xf800) < 0xe800)
4515 {
4516 /* Addr + 2 is an instruction boundary. See if this matches
4517 the expected boundary based on the position of the last
4518 IT candidate. */
4519 if (count & 1)
4520 break;
4521 seen_it = 0;
4522 }
4523 }
4524 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4525 {
4526 /* This could be an IT instruction. */
4527 seen_it = insn;
4528 it_count = count >> 1;
4529 }
4530 if ((insn & 0xf800) >= 0xe800)
4531 count++;
4532 else
4533 count = (count + 2) | 1;
4534 /* IT blocks contain at most 4 instructions. */
4535 if (count >= 8 && !seen_it)
4536 return;
4537 }
4538 /* We found an IT instruction. */
4539 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4540 if ((ifthen_state & 0xf) == 0)
4541 ifthen_state = 0;
4542 }
4543
4544 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4545 mapping symbol. */
4546
4547 static int
4548 is_mapping_symbol (struct disassemble_info *info, int n,
4549 enum map_type *map_type)
4550 {
4551 const char *name;
4552
4553 name = bfd_asymbol_name (info->symtab[n]);
4554 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4555 && (name[2] == 0 || name[2] == '.'))
4556 {
4557 *map_type = ((name[1] == 'a') ? MAP_ARM
4558 : (name[1] == 't') ? MAP_THUMB
4559 : MAP_DATA);
4560 return TRUE;
4561 }
4562
4563 return FALSE;
4564 }
4565
4566 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4567 Returns nonzero if *MAP_TYPE was set. */
4568
4569 static int
4570 get_map_sym_type (struct disassemble_info *info,
4571 int n,
4572 enum map_type *map_type)
4573 {
4574 /* If the symbol is in a different section, ignore it. */
4575 if (info->section != NULL && info->section != info->symtab[n]->section)
4576 return FALSE;
4577
4578 return is_mapping_symbol (info, n, map_type);
4579 }
4580
4581 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4582 Returns nonzero if *MAP_TYPE was set. */
4583
4584 static int
4585 get_sym_code_type (struct disassemble_info *info,
4586 int n,
4587 enum map_type *map_type)
4588 {
4589 elf_symbol_type *es;
4590 unsigned int type;
4591
4592 /* If the symbol is in a different section, ignore it. */
4593 if (info->section != NULL && info->section != info->symtab[n]->section)
4594 return FALSE;
4595
4596 es = *(elf_symbol_type **)(info->symtab + n);
4597 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4598
4599 /* If the symbol has function type then use that. */
4600 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4601 {
4602 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4603 *map_type = MAP_THUMB;
4604 else
4605 *map_type = MAP_ARM;
4606 return TRUE;
4607 }
4608
4609 return FALSE;
4610 }
4611
4612 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4613 of the supplied arm_feature_set structure with bitmasks indicating
4614 the support base architectures and coprocessor extensions.
4615
4616 FIXME: This could more efficiently implemented as a constant array,
4617 although it would also be less robust. */
4618
4619 static void
4620 select_arm_features (unsigned long mach,
4621 arm_feature_set * features)
4622 {
4623 #undef ARM_FEATURE
4624 #define ARM_FEATURE(ARCH,CEXT) \
4625 features->core = (ARCH); \
4626 features->coproc = (CEXT) | FPU_FPA; \
4627 return
4628
4629 switch (mach)
4630 {
4631 case bfd_mach_arm_2: ARM_ARCH_V2;
4632 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4633 case bfd_mach_arm_3: ARM_ARCH_V3;
4634 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4635 case bfd_mach_arm_4: ARM_ARCH_V4;
4636 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4637 case bfd_mach_arm_5: ARM_ARCH_V5;
4638 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4639 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4640 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4641 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4642 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4643 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4644 /* If the machine type is unknown allow all
4645 architecture types and all extensions. */
4646 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4647 default:
4648 abort ();
4649 }
4650 }
4651
4652
4653 /* NOTE: There are no checks in these routines that
4654 the relevant number of data bytes exist. */
4655
4656 static int
4657 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4658 {
4659 unsigned char b[4];
4660 long given;
4661 int status;
4662 int is_thumb = FALSE;
4663 int is_data = FALSE;
4664 int little_code;
4665 unsigned int size = 4;
4666 void (*printer) (bfd_vma, struct disassemble_info *, long);
4667 bfd_boolean found = FALSE;
4668 struct arm_private_data *private_data;
4669
4670 if (info->disassembler_options)
4671 {
4672 parse_disassembler_options (info->disassembler_options);
4673
4674 /* To avoid repeated parsing of these options, we remove them here. */
4675 info->disassembler_options = NULL;
4676 }
4677
4678 /* PR 10288: Control which instructions will be disassembled. */
4679 if (info->private_data == NULL)
4680 {
4681 static struct arm_private_data private;
4682
4683 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4684 /* If the user did not use the -m command line switch then default to
4685 disassembling all types of ARM instruction.
4686
4687 The info->mach value has to be ignored as this will be based on
4688 the default archictecture for the target and/or hints in the notes
4689 section, but it will never be greater than the current largest arm
4690 machine value (iWMMXt2), which is only equivalent to the V5TE
4691 architecture. ARM architectures have advanced beyond the machine
4692 value encoding, and these newer architectures would be ignored if
4693 the machine value was used.
4694
4695 Ie the -m switch is used to restrict which instructions will be
4696 disassembled. If it is necessary to use the -m switch to tell
4697 objdump that an ARM binary is being disassembled, eg because the
4698 input is a raw binary file, but it is also desired to disassemble
4699 all ARM instructions then use "-marm". This will select the
4700 "unknown" arm architecture which is compatible with any ARM
4701 instruction. */
4702 info->mach = bfd_mach_arm_unknown;
4703
4704 /* Compute the architecture bitmask from the machine number.
4705 Note: This assumes that the machine number will not change
4706 during disassembly.... */
4707 select_arm_features (info->mach, & private.features);
4708
4709 private.has_mapping_symbols = -1;
4710 private.last_mapping_sym = -1;
4711 private.last_mapping_addr = 0;
4712
4713 info->private_data = & private;
4714 }
4715
4716 private_data = info->private_data;
4717
4718 /* Decide if our code is going to be little-endian, despite what the
4719 function argument might say. */
4720 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4721
4722 /* For ELF, consult the symbol table to determine what kind of code
4723 or data we have. */
4724 if (info->symtab_size != 0
4725 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4726 {
4727 bfd_vma addr;
4728 int n, start;
4729 int last_sym = -1;
4730 enum map_type type = MAP_ARM;
4731
4732 /* Start scanning at the start of the function, or wherever
4733 we finished last time. */
4734 /* PR 14006. When the address is 0 we are either at the start of the
4735 very first function, or else the first function in a new, unlinked
4736 executable section (eg because uf -ffunction-sections). Either way
4737 start scanning from the beginning of the symbol table, not where we
4738 left off last time. */
4739 if (pc == 0)
4740 start = 0;
4741 else
4742 {
4743 start = info->symtab_pos + 1;
4744 if (start < private_data->last_mapping_sym)
4745 start = private_data->last_mapping_sym;
4746 }
4747 found = FALSE;
4748
4749 /* First, look for mapping symbols. */
4750 if (private_data->has_mapping_symbols != 0)
4751 {
4752 /* Scan up to the location being disassembled. */
4753 for (n = start; n < info->symtab_size; n++)
4754 {
4755 addr = bfd_asymbol_value (info->symtab[n]);
4756 if (addr > pc)
4757 break;
4758 if (get_map_sym_type (info, n, &type))
4759 {
4760 last_sym = n;
4761 found = TRUE;
4762 }
4763 }
4764
4765 if (!found)
4766 {
4767 /* No mapping symbol found at this address. Look backwards
4768 for a preceding one. */
4769 for (n = start - 1; n >= 0; n--)
4770 {
4771 if (get_map_sym_type (info, n, &type))
4772 {
4773 last_sym = n;
4774 found = TRUE;
4775 break;
4776 }
4777 }
4778 }
4779
4780 if (found)
4781 private_data->has_mapping_symbols = 1;
4782
4783 /* No mapping symbols were found. A leading $d may be
4784 omitted for sections which start with data; but for
4785 compatibility with legacy and stripped binaries, only
4786 assume the leading $d if there is at least one mapping
4787 symbol in the file. */
4788 if (!found && private_data->has_mapping_symbols == -1)
4789 {
4790 /* Look for mapping symbols, in any section. */
4791 for (n = 0; n < info->symtab_size; n++)
4792 if (is_mapping_symbol (info, n, &type))
4793 {
4794 private_data->has_mapping_symbols = 1;
4795 break;
4796 }
4797 if (private_data->has_mapping_symbols == -1)
4798 private_data->has_mapping_symbols = 0;
4799 }
4800
4801 if (!found && private_data->has_mapping_symbols == 1)
4802 {
4803 type = MAP_DATA;
4804 found = TRUE;
4805 }
4806 }
4807
4808 /* Next search for function symbols to separate ARM from Thumb
4809 in binaries without mapping symbols. */
4810 if (!found)
4811 {
4812 /* Scan up to the location being disassembled. */
4813 for (n = start; n < info->symtab_size; n++)
4814 {
4815 addr = bfd_asymbol_value (info->symtab[n]);
4816 if (addr > pc)
4817 break;
4818 if (get_sym_code_type (info, n, &type))
4819 {
4820 last_sym = n;
4821 found = TRUE;
4822 }
4823 }
4824
4825 if (!found)
4826 {
4827 /* No mapping symbol found at this address. Look backwards
4828 for a preceding one. */
4829 for (n = start - 1; n >= 0; n--)
4830 {
4831 if (get_sym_code_type (info, n, &type))
4832 {
4833 last_sym = n;
4834 found = TRUE;
4835 break;
4836 }
4837 }
4838 }
4839 }
4840
4841 private_data->last_mapping_sym = last_sym;
4842 private_data->last_type = type;
4843 is_thumb = (private_data->last_type == MAP_THUMB);
4844 is_data = (private_data->last_type == MAP_DATA);
4845
4846 /* Look a little bit ahead to see if we should print out
4847 two or four bytes of data. If there's a symbol,
4848 mapping or otherwise, after two bytes then don't
4849 print more. */
4850 if (is_data)
4851 {
4852 size = 4 - (pc & 3);
4853 for (n = last_sym + 1; n < info->symtab_size; n++)
4854 {
4855 addr = bfd_asymbol_value (info->symtab[n]);
4856 if (addr > pc
4857 && (info->section == NULL
4858 || info->section == info->symtab[n]->section))
4859 {
4860 if (addr - pc < size)
4861 size = addr - pc;
4862 break;
4863 }
4864 }
4865 /* If the next symbol is after three bytes, we need to
4866 print only part of the data, so that we can use either
4867 .byte or .short. */
4868 if (size == 3)
4869 size = (pc & 1) ? 1 : 2;
4870 }
4871 }
4872
4873 if (info->symbols != NULL)
4874 {
4875 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4876 {
4877 coff_symbol_type * cs;
4878
4879 cs = coffsymbol (*info->symbols);
4880 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4881 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4882 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4883 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4884 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4885 }
4886 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4887 && !found)
4888 {
4889 /* If no mapping symbol has been found then fall back to the type
4890 of the function symbol. */
4891 elf_symbol_type * es;
4892 unsigned int type;
4893
4894 es = *(elf_symbol_type **)(info->symbols);
4895 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4896
4897 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
4898 == ST_BRANCH_TO_THUMB)
4899 || type == STT_ARM_16BIT);
4900 }
4901 }
4902
4903 if (force_thumb)
4904 is_thumb = TRUE;
4905
4906 if (is_data)
4907 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4908 else
4909 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4910
4911 info->bytes_per_line = 4;
4912
4913 /* PR 10263: Disassemble data if requested to do so by the user. */
4914 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4915 {
4916 int i;
4917
4918 /* Size was already set above. */
4919 info->bytes_per_chunk = size;
4920 printer = print_insn_data;
4921
4922 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4923 given = 0;
4924 if (little)
4925 for (i = size - 1; i >= 0; i--)
4926 given = b[i] | (given << 8);
4927 else
4928 for (i = 0; i < (int) size; i++)
4929 given = b[i] | (given << 8);
4930 }
4931 else if (!is_thumb)
4932 {
4933 /* In ARM mode endianness is a straightforward issue: the instruction
4934 is four bytes long and is either ordered 0123 or 3210. */
4935 printer = print_insn_arm;
4936 info->bytes_per_chunk = 4;
4937 size = 4;
4938
4939 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4940 if (little_code)
4941 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4942 else
4943 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4944 }
4945 else
4946 {
4947 /* In Thumb mode we have the additional wrinkle of two
4948 instruction lengths. Fortunately, the bits that determine
4949 the length of the current instruction are always to be found
4950 in the first two bytes. */
4951 printer = print_insn_thumb16;
4952 info->bytes_per_chunk = 2;
4953 size = 2;
4954
4955 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4956 if (little_code)
4957 given = (b[0]) | (b[1] << 8);
4958 else
4959 given = (b[1]) | (b[0] << 8);
4960
4961 if (!status)
4962 {
4963 /* These bit patterns signal a four-byte Thumb
4964 instruction. */
4965 if ((given & 0xF800) == 0xF800
4966 || (given & 0xF800) == 0xF000
4967 || (given & 0xF800) == 0xE800)
4968 {
4969 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4970 if (little_code)
4971 given = (b[0]) | (b[1] << 8) | (given << 16);
4972 else
4973 given = (b[1]) | (b[0] << 8) | (given << 16);
4974
4975 printer = print_insn_thumb32;
4976 size = 4;
4977 }
4978 }
4979
4980 if (ifthen_address != pc)
4981 find_ifthen_state (pc, info, little_code);
4982
4983 if (ifthen_state)
4984 {
4985 if ((ifthen_state & 0xf) == 0x8)
4986 ifthen_next_state = 0;
4987 else
4988 ifthen_next_state = (ifthen_state & 0xe0)
4989 | ((ifthen_state & 0xf) << 1);
4990 }
4991 }
4992
4993 if (status)
4994 {
4995 info->memory_error_func (status, pc, info);
4996 return -1;
4997 }
4998 if (info->flags & INSN_HAS_RELOC)
4999 /* If the instruction has a reloc associated with it, then
5000 the offset field in the instruction will actually be the
5001 addend for the reloc. (We are using REL type relocs).
5002 In such cases, we can ignore the pc when computing
5003 addresses, since the addend is not currently pc-relative. */
5004 pc = 0;
5005
5006 printer (pc, info, given);
5007
5008 if (is_thumb)
5009 {
5010 ifthen_state = ifthen_next_state;
5011 ifthen_address += size;
5012 }
5013 return size;
5014 }
5015
5016 int
5017 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
5018 {
5019 /* Detect BE8-ness and record it in the disassembler info. */
5020 if (info->flavour == bfd_target_elf_flavour
5021 && info->section != NULL
5022 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
5023 info->endian_code = BFD_ENDIAN_LITTLE;
5024
5025 return print_insn (pc, info, FALSE);
5026 }
5027
5028 int
5029 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
5030 {
5031 return print_insn (pc, info, TRUE);
5032 }
5033
5034 void
5035 print_arm_disassembler_options (FILE *stream)
5036 {
5037 int i;
5038
5039 fprintf (stream, _("\n\
5040 The following ARM specific disassembler options are supported for use with\n\
5041 the -M switch:\n"));
5042
5043 for (i = NUM_ARM_REGNAMES; i--;)
5044 fprintf (stream, " reg-names-%s %*c%s\n",
5045 regnames[i].name,
5046 (int)(14 - strlen (regnames[i].name)), ' ',
5047 regnames[i].description);
5048
5049 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
5050 fprintf (stream, " no-force-thumb Examine preceding label to determine an insn's type\n\n");
5051 }
This page took 0.185803 seconds and 4 git commands to generate.