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