bfd/
[binutils.git] / opcodes / arm-dis.c
blobef80304d22dec9d6d20a3dbde0075a16c3dc35f9
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
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.
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.
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. */
23 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
29 #include "floatformat.h"
31 /* FIXME: This shouldn't be done here. */
32 #include "coff/internal.h"
33 #include "libcoff.h"
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
38 /* FIXME: Belongs in global header. */
39 #ifndef strneq
40 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
41 #endif
43 #ifndef NUM_ELEM
44 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
45 #endif
47 struct opcode32
49 unsigned long arch; /* Architecture defining this insn. */
50 unsigned long value, mask; /* Recognise insn if (op&mask)==value. */
51 const char *assembler; /* How to disassemble this insn. */
54 struct opcode16
56 unsigned long arch; /* Architecture defining this insn. */
57 unsigned short value, mask; /* Recognise insn if (op&mask)==value. */
58 const char *assembler; /* How to disassemble this insn. */
61 /* print_insn_coprocessor recognizes the following format control codes:
63 %% %
65 %c print condition code (always bits 28-31)
66 %A print address for ldc/stc/ldf/stf instruction
67 %B print vstm/vldm register list
68 %C print vstr/vldr address operand
69 %I print cirrus signed shift immediate: bits 0..3|4..6
70 %F print the COUNT field of a LFM/SFM instruction.
71 %P print floating point precision in arithmetic insn
72 %Q print floating point precision in ldf/stf insn
73 %R print floating point rounding mode
75 %<bitfield>r print as an ARM register
76 %<bitfield>d print the bitfield in decimal
77 %<bitfield>k print immediate for VFPv3 conversion instruction
78 %<bitfield>x print the bitfield in hex
79 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
80 %<bitfield>f print a floating point constant if >7 else a
81 floating point register
82 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
83 %<bitfield>g print as an iWMMXt 64-bit register
84 %<bitfield>G print as an iWMMXt general purpose or control register
85 %<bitfield>D print as a NEON D register
86 %<bitfield>Q print as a NEON Q register
88 %y<code> print a single precision VFP reg.
89 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
90 %z<code> print a double precision VFP reg
91 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
93 %<bitfield>'c print specified char iff bitfield is all ones
94 %<bitfield>`c print specified char iff bitfield is all zeroes
95 %<bitfield>?ab... select from array of values in big endian order
97 %L print as an iWMMXt N/M width field.
98 %Z print the Immediate of a WSHUFH instruction.
99 %l like 'A' except use byte offsets for 'B' & 'H'
100 versions. */
102 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
104 static const struct opcode32 coprocessor_opcodes[] =
106 /* XScale instructions. */
107 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
108 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
109 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
110 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
111 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
113 /* Intel Wireless MMX technology instructions. */
114 #define FIRST_IWMMXT_INSN 0x0e130130
115 #define IWMMXT_INSN_COUNT 47
116 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
117 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
118 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
119 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
120 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
121 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
122 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
123 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
124 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
125 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
126 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
127 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
128 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
129 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
130 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
131 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
132 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
133 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
134 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
135 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
136 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
137 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
138 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
139 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
140 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
141 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
142 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
143 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
144 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
145 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
146 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
147 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
148 {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
149 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
150 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
151 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
152 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
153 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
154 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
155 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
156 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
157 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
158 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
159 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
160 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
161 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
162 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
163 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
164 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
166 /* Floating point coprocessor (FPA) instructions */
167 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
168 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
169 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
170 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
171 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
172 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
173 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
174 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
175 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
176 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
177 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
178 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
179 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
180 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
181 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
182 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
183 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
184 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
185 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
186 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
187 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
188 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
189 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
190 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
191 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
192 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
193 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
194 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
195 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
196 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
197 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
198 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
199 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
200 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
201 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
202 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
203 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
204 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
205 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
206 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
207 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
208 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
209 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
211 /* Register load/store */
212 {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
213 {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
214 {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
215 {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
216 {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
217 {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
219 /* Data transfer between ARM and NEON registers */
220 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
221 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
222 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
223 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
224 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
225 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
226 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
227 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
228 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
229 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
230 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
231 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
232 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
233 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
235 /* Floating point coprocessor (VFP) instructions */
236 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
237 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
238 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
239 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
240 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
241 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
242 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
243 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
244 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
245 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
246 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
247 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
248 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
249 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
250 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
251 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
252 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
253 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
254 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
255 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
256 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
257 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
258 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
259 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
260 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
261 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
262 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
263 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
264 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
265 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
266 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
267 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
268 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
269 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
270 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
271 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
272 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
273 {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
274 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
275 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
276 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
277 {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
278 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
279 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
280 {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%16-19,0-3d"},
281 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%16-19,0-3d"},
282 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %y4"},
283 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
284 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
285 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
286 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
287 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
288 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
289 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
290 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
291 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
292 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
293 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
294 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
295 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
296 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
297 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
298 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
299 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
300 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
301 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
302 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
303 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
304 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
305 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
306 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
307 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
308 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
309 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
310 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
311 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
312 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
313 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
314 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
316 /* Cirrus coprocessor instructions. */
317 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
318 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
319 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
320 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
321 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
322 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
323 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
324 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
325 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
326 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
327 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
328 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
329 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
330 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
331 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
332 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
333 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
334 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
335 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
336 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
337 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
338 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
339 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
340 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
341 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
342 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
343 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
344 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
345 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
346 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
347 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
348 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
349 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
350 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
351 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
352 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
353 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
354 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
355 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
356 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
357 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
358 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
359 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
360 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
361 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
362 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
363 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
364 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
365 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
366 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
367 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
368 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
369 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
370 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
371 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
372 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
373 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
374 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
375 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
376 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
377 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
378 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
379 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
380 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
381 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
382 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
383 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
384 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
385 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
386 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
387 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
388 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
389 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
390 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
391 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
392 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
393 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
394 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
395 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
396 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
397 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
398 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
399 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
400 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
402 /* Generic coprocessor instructions */
403 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
404 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
405 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
406 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
407 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
408 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
409 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
411 /* V6 coprocessor instructions */
412 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
413 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
415 /* V5 coprocessor instructions */
416 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
417 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
418 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
419 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
420 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
422 {0, 0, 0, 0}
425 /* Neon opcode table: This does not encode the top byte -- that is
426 checked by the print_insn_neon routine, as it depends on whether we are
427 doing thumb32 or arm32 disassembly. */
429 /* print_insn_neon recognizes the following format control codes:
431 %% %
433 %A print v{st,ld}[1234] operands
434 %B print v{st,ld}[1234] any one operands
435 %C print v{st,ld}[1234] single->all operands
436 %D print scalar
437 %E print vmov, vmvn, vorr, vbic encoded constant
438 %F print vtbl,vtbx register list
440 %<bitfield>r print as an ARM register
441 %<bitfield>d print the bitfield in decimal
442 %<bitfield>e print the 2^N - bitfield in decimal
443 %<bitfield>D print as a NEON D register
444 %<bitfield>Q print as a NEON Q register
445 %<bitfield>R print as a NEON D or Q register
446 %<bitfield>Sn print byte scaled width limited by n
447 %<bitfield>Tn print short scaled width limited by n
448 %<bitfield>Un print long scaled width limited by n
450 %<bitfield>'c print specified char iff bitfield is all ones
451 %<bitfield>`c print specified char iff bitfield is all zeroes
452 %<bitfield>?ab... select from array of values in big endian order */
454 static const struct opcode32 neon_opcodes[] =
456 /* Extract */
457 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
458 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
460 /* Move data element to all lanes */
461 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup.32\t%12-15,22R, %0-3,5D[%19d]"},
462 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup.16\t%12-15,22R, %0-3,5D[%18-19d]"},
463 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup.8\t%12-15,22R, %0-3,5D[%17-19d]"},
465 /* Table lookup */
466 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl.8\t%12-15,22D, %F, %0-3,5D"},
467 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx.8\t%12-15,22D, %F, %0-3,5D"},
469 /* Two registers, miscellaneous */
470 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl.%24?us8\t%12-15,22Q, %0-3,5D"},
471 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl.%24?us16\t%12-15,22Q, %0-3,5D"},
472 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl.%24?us32\t%12-15,22Q, %0-3,5D"},
473 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt.8\t%12-15,22R, %0-3,5R"},
474 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn\t%12-15,22R, %0-3,5R"},
475 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp\t%12-15,22R, %0-3,5R"},
476 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn.i%18-19S2\t%12-15,22D, %0-3,5Q"},
477 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun.s%18-19T2\t%12-15,22D, %0-3,5Q"},
478 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn.s%18-19T2\t%12-15,22D, %0-3,5Q"},
479 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn.u%18-19T2\t%12-15,22D, %0-3,5Q"},
480 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
481 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
482 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
483 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64.%18-19S2\t%12-15,22R, %0-3,5R"},
484 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32.%18-19S2\t%12-15,22R, %0-3,5R"},
485 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16.%18-19S2\t%12-15,22R, %0-3,5R"},
486 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls.s%18-19S2\t%12-15,22R, %0-3,5R"},
487 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz.i%18-19S2\t%12-15,22R, %0-3,5R"},
488 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs.s%18-19S2\t%12-15,22R, %0-3,5R"},
489 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg.s%18-19S2\t%12-15,22R, %0-3,5R"},
490 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn.%18-19S2\t%12-15,22R, %0-3,5R"},
491 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp.%18-19S2\t%12-15,22R, %0-3,5R"},
492 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip.%18-19S2\t%12-15,22R, %0-3,5R"},
493 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
494 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
495 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
496 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
497 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
498 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
499 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
500 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
501 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
502 {FPU_NEON_EXT_V1, 0xf3b30600, 0xffb30e10, "vcvt.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
504 /* Three registers of the same length */
505 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand\t%12-15,22R, %16-19,7R, %0-3,5R"},
506 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic\t%12-15,22R, %16-19,7R, %0-3,5R"},
507 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr\t%12-15,22R, %16-19,7R, %0-3,5R"},
508 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn\t%12-15,22R, %16-19,7R, %0-3,5R"},
509 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor\t%12-15,22R, %16-19,7R, %0-3,5R"},
510 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl\t%12-15,22R, %16-19,7R, %0-3,5R"},
511 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit\t%12-15,22R, %16-19,7R, %0-3,5R"},
512 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif\t%12-15,22R, %16-19,7R, %0-3,5R"},
513 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
514 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
515 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
516 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
517 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
518 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
519 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
520 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
521 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
522 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
523 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
524 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
525 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
526 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
527 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
528 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
529 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
530 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
531 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
532 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
533 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
534 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
535 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
536 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
537 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
538 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
539 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
540 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
541 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
542 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
543 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
544 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
545 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
546 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
547 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
548 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
549 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
550 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
551 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
552 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
553 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
554 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
555 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
556 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
557 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
559 /* One register and an immediate value */
560 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov.i8\t%12-15,22R, %E"},
561 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov.i64\t%12-15,22R, %E"},
562 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov.f32\t%12-15,22R, %E"},
563 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov.i16\t%12-15,22R, %E"},
564 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn.i16\t%12-15,22R, %E"},
565 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr.i16\t%12-15,22R, %E"},
566 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic.i16\t%12-15,22R, %E"},
567 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov.i32\t%12-15,22R, %E"},
568 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn.i32\t%12-15,22R, %E"},
569 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr.i32\t%12-15,22R, %E"},
570 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic.i32\t%12-15,22R, %E"},
571 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov.i32\t%12-15,22R, %E"},
572 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn.i32\t%12-15,22R, %E"},
574 /* Two registers and a shift amount */
575 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
576 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
577 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
578 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
579 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
580 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
581 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
582 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
583 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
584 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
585 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri.8\t%12-15,22R, %0-3,5R, #%16-18e"},
586 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli.8\t%12-15,22R, %0-3,5R, #%16-18d"},
587 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
588 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
589 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
590 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
591 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
592 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
593 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
594 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
595 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
596 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
597 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
598 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
599 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
600 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
601 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri.16\t%12-15,22R, %0-3,5R, #%16-19e"},
602 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli.16\t%12-15,22R, %0-3,5R, #%16-19d"},
603 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
604 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
605 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
606 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
607 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
608 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
609 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
610 {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
611 {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
612 {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
613 {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
614 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
615 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri.32\t%12-15,22R, %0-3,5R, #%16-20e"},
616 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli.32\t%12-15,22R, %0-3,5R, #%16-20d"},
617 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
618 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
619 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
620 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
621 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
622 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
623 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
624 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri.64\t%12-15,22R, %0-3,5R, #%16-21e"},
625 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli.64\t%12-15,22R, %0-3,5R, #%16-21d"},
626 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
627 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
628 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
629 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
630 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
631 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
632 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
634 /* Three registers of different lengths */
635 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
636 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
637 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
638 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
639 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
640 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
641 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
642 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
643 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
644 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
645 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
646 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
647 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
648 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
649 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
650 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
651 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
653 /* Two registers and a scalar */
654 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
655 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
656 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
657 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
658 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
659 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
660 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
661 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
662 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
663 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
664 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
665 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
666 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
667 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
668 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
669 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
670 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
671 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
672 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
673 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
674 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
675 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
677 /* Element and structure load/store */
678 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4.32\t%C"},
679 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1.%6-7S2\t%C"},
680 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2.%6-7S2\t%C"},
681 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3.%6-7S2\t%C"},
682 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4.%6-7S2\t%C"},
683 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"},
684 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2.%6-7S2\t%A"},
685 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3.%6-7S2\t%A"},
686 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3.%6-7S2\t%A"},
687 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"},
688 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"},
689 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2.%6-7S2\t%A"},
690 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2.%6-7S2\t%A"},
691 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1.%6-7S3\t%A"},
692 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4.%6-7S2\t%A"},
693 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1.%10-11S2\t%B"},
694 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2.%10-11S2\t%B"},
695 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3.%10-11S2\t%B"},
696 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4.%10-11S2\t%B"},
698 {0,0 ,0, 0}
701 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
702 ordered: they must be searched linearly from the top to obtain a correct
703 match. */
705 /* print_insn_arm recognizes the following format control codes:
707 %% %
709 %a print address for ldr/str instruction
710 %s print address for ldr/str halfword/signextend instruction
711 %b print branch destination
712 %c print condition code (always bits 28-31)
713 %m print register mask for ldm/stm instruction
714 %o print operand2 (immediate or register + shift)
715 %p print 'p' iff bits 12-15 are 15
716 %t print 't' iff bit 21 set and bit 24 clear
717 %B print arm BLX(1) destination
718 %C print the PSR sub type.
719 %U print barrier type.
720 %P print address for pli instruction.
722 %<bitfield>r print as an ARM register
723 %<bitfield>d print the bitfield in decimal
724 %<bitfield>W print the bitfield plus one in decimal
725 %<bitfield>x print the bitfield in hex
726 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
728 %<bitfield>'c print specified char iff bitfield is all ones
729 %<bitfield>`c print specified char iff bitfield is all zeroes
730 %<bitfield>?ab... select from array of values in big endian order
732 %e print arm SMI operand (bits 0..7,8..19).
733 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
734 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
736 static const struct opcode32 arm_opcodes[] =
738 /* ARM instructions. */
739 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
740 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
741 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
742 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
743 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
744 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
745 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
747 /* V7 instructions. */
748 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
749 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
750 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
751 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
752 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
754 /* ARM V6T2 instructions. */
755 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
756 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
757 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
758 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
759 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
760 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
761 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
762 {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
763 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
765 /* ARM V6Z instructions. */
766 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
768 /* ARM V6K instructions. */
769 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
770 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
771 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
772 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
773 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
774 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
775 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
777 /* ARM V6K NOP hints. */
778 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
779 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
780 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
781 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
782 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
784 /* ARM V6 instructions. */
785 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
786 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
787 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
788 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
789 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
790 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
791 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
792 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
793 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
794 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
795 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
796 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
797 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
798 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
799 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
800 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
801 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
802 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
803 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
804 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
805 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
806 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
807 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
808 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
809 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
810 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
811 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
812 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
813 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
814 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
815 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
816 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
817 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
818 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
819 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
820 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
821 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
822 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
823 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
824 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
825 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
826 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
827 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
828 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
829 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
830 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
831 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
832 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
833 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
834 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
835 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
836 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
837 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
838 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
839 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
840 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
841 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
842 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
843 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
844 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
845 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
846 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
847 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
848 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
849 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
850 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
851 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
852 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
853 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
854 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
855 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
856 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
857 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
858 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
859 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
860 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
861 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
862 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
863 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
864 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
865 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
866 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
867 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
869 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
870 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
871 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
872 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
873 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
874 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
875 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
877 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
878 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
879 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
881 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
882 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
883 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
885 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
886 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
887 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
888 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
889 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
890 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
891 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
892 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
893 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
894 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
895 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
896 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
897 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
898 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
899 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
900 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
901 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
902 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
903 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
904 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
905 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
906 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
908 /* V5J instruction. */
909 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
911 /* V5 Instructions. */
912 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
913 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
914 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
915 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
917 /* V5E "El Segundo" Instructions. */
918 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
919 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
920 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
921 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
922 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
923 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
924 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
926 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
927 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
929 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
930 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
931 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
932 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
934 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
935 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
936 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
937 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
939 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
940 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
942 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
943 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
944 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
945 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
947 /* ARM Instructions. */
948 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
949 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
950 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
951 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
952 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
953 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
954 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
955 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
956 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
957 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
958 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
959 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
960 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
961 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
962 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
963 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
964 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
965 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
966 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
967 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
968 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
969 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
970 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
971 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
972 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
973 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
974 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
975 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
976 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
978 /* The rest. */
979 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
980 {0, 0x00000000, 0x00000000, 0}
983 /* print_insn_thumb16 recognizes the following format control codes:
985 %S print Thumb register (bits 3..5 as high number if bit 6 set)
986 %D print Thumb register (bits 0..2 as high number if bit 7 set)
987 %<bitfield>I print bitfield as a signed decimal
988 (top bit of range being the sign bit)
989 %N print Thumb register mask (with LR)
990 %O print Thumb register mask (with PC)
991 %M print Thumb register mask
992 %b print CZB's 6-bit unsigned branch destination
993 %s print Thumb right-shift immediate (6..10; 0 == 32).
994 %<bitfield>r print bitfield as an ARM register
995 %<bitfield>d print bitfield as a decimal
996 %<bitfield>H print (bitfield * 2) as a decimal
997 %<bitfield>W print (bitfield * 4) as a decimal
998 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
999 %<bitfield>B print Thumb branch destination (signed displacement)
1000 %<bitfield>c print bitfield as a condition code
1001 %<bitnum>'c print specified char iff bit is one
1002 %<bitnum>?ab print a if bit is one else print b. */
1004 static const struct opcode16 thumb_opcodes[] =
1006 /* Thumb instructions. */
1008 /* ARM V6K no-argument instructions. */
1009 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
1010 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
1011 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
1012 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
1013 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
1014 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
1016 /* ARM V6T2 instructions. */
1017 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"},
1018 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"},
1019 {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"},
1020 {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"},
1021 {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"},
1022 {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"},
1023 {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"},
1024 {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"},
1025 {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"},
1027 /* ARM V6. */
1028 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
1029 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
1030 {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
1031 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
1032 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
1033 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
1034 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
1035 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
1036 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
1037 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
1038 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
1040 /* ARM V5 ISA extends Thumb. */
1041 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
1042 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1043 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
1044 /* ARM V4T ISA (Thumb v1). */
1045 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
1046 /* Format 4. */
1047 {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"},
1048 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"},
1049 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"},
1050 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"},
1051 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"},
1052 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"},
1053 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
1054 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
1055 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
1056 {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
1057 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
1058 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
1059 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
1060 {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"},
1061 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"},
1062 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"},
1063 /* format 13 */
1064 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
1065 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
1066 /* format 5 */
1067 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
1068 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
1069 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
1070 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
1071 /* format 14 */
1072 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
1073 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
1074 /* format 2 */
1075 {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
1076 {ARM_EXT_V4T, 0x1A00, 0xFE00, "subs\t%0-2r, %3-5r, %6-8r"},
1077 {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
1078 {ARM_EXT_V4T, 0x1E00, 0xFE00, "subs\t%0-2r, %3-5r, #%6-8d"},
1079 /* format 8 */
1080 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
1081 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
1082 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
1083 /* format 7 */
1084 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
1085 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
1086 /* format 1 */
1087 {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"},
1088 {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"},
1089 {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"},
1090 /* format 3 */
1091 {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
1092 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
1093 {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
1094 {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
1095 /* format 6 */
1096 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1097 /* format 9 */
1098 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
1099 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
1100 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
1101 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
1102 /* format 10 */
1103 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
1104 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
1105 /* format 11 */
1106 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
1107 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
1108 /* format 12 */
1109 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
1110 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
1111 /* format 15 */
1112 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
1113 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
1114 /* format 17 */
1115 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc\t%0-7d"},
1116 /* format 16 */
1117 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"},
1118 /* format 18 */
1119 {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"},
1121 /* The E800 .. FFFF range is unconditionally redirected to the
1122 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1123 are processed via that table. Thus, we can never encounter a
1124 bare "second half of BL/BLX(1)" instruction here. */
1125 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
1126 {0, 0, 0, 0}
1129 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1130 We adopt the convention that hw1 is the high 16 bits of .value and
1131 .mask, hw2 the low 16 bits.
1133 print_insn_thumb32 recognizes the following format control codes:
1135 %% %
1137 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1138 %M print a modified 12-bit immediate (same location)
1139 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1140 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1141 %S print a possibly-shifted Rm
1143 %a print the address of a plain load/store
1144 %w print the width and signedness of a core load/store
1145 %m print register mask for ldm/stm
1147 %E print the lsb and width fields of a bfc/bfi instruction
1148 %F print the lsb and width fields of a sbfx/ubfx instruction
1149 %b print a conditional branch offset
1150 %B print an unconditional branch offset
1151 %s print the shift field of an SSAT instruction
1152 %R print the rotation field of an SXT instruction
1153 %U print barrier type.
1154 %P print address for pli instruction.
1156 %<bitfield>d print bitfield in decimal
1157 %<bitfield>W print bitfield*4 in decimal
1158 %<bitfield>r print bitfield as an ARM register
1159 %<bitfield>c print bitfield as a condition code
1161 %<bitfield>'c print specified char iff bitfield is all ones
1162 %<bitfield>`c print specified char iff bitfield is all zeroes
1163 %<bitfield>?ab... select from array of values in big endian order
1165 With one exception at the bottom (done because BL and BLX(1) need
1166 to come dead last), this table was machine-sorted first in
1167 decreasing order of number of bits set in the mask, then in
1168 increasing numeric order of mask, then in increasing numeric order
1169 of opcode. This order is not the clearest for a human reader, but
1170 is guaranteed never to catch a special-case bit pattern with a more
1171 general mask, which is important, because this instruction encoding
1172 makes heavy use of special-case bit patterns. */
1173 static const struct opcode32 thumb32_opcodes[] =
1175 /* V7 instructions. */
1176 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"},
1177 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"},
1178 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"},
1179 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"},
1180 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"},
1181 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"},
1182 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"},
1184 /* Instructions defined in the basic V6T2 set. */
1185 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
1186 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
1187 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
1188 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
1189 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
1190 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
1192 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
1193 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
1194 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
1195 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
1196 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
1197 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
1198 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"},
1199 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
1200 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
1201 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
1202 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
1203 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
1204 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
1205 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"},
1206 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
1207 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
1208 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
1209 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
1210 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"},
1211 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"},
1212 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"},
1213 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
1214 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
1215 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
1216 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
1217 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
1218 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
1219 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
1220 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"},
1221 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"},
1222 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"},
1223 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"},
1224 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"},
1225 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"},
1226 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"},
1227 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"},
1228 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"},
1229 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"},
1230 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"},
1231 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"},
1232 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"},
1233 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"},
1234 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"},
1235 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"},
1236 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"},
1237 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"},
1238 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"},
1239 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"},
1240 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"},
1241 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"},
1242 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"},
1243 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"},
1244 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"},
1245 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"},
1246 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"},
1247 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"},
1248 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"},
1249 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"},
1250 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"},
1251 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"},
1252 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"},
1253 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"},
1254 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"},
1255 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"},
1256 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"},
1257 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"},
1258 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"},
1259 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"},
1260 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"},
1261 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"},
1262 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"},
1263 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"},
1264 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"},
1265 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"},
1266 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"},
1267 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"},
1268 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"},
1269 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"},
1270 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
1271 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
1272 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
1273 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
1274 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
1275 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
1276 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
1277 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
1278 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
1279 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
1280 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"},
1281 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"},
1282 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"},
1283 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"},
1284 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
1285 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
1286 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
1287 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
1288 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
1289 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
1290 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
1291 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
1292 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
1293 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
1294 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
1295 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1296 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"},
1297 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"},
1298 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"},
1299 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"},
1300 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"},
1301 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
1302 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
1303 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
1304 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
1305 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc\t%K"},
1306 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
1307 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
1308 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
1309 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
1310 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
1311 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
1312 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
1313 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
1314 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1315 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1316 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
1317 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
1318 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
1319 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
1320 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
1321 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
1322 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
1323 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"},
1324 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"},
1325 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"},
1326 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"},
1327 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"},
1328 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"},
1329 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"},
1330 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"},
1331 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"},
1332 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"},
1333 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"},
1334 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"},
1335 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"},
1336 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
1337 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
1338 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
1339 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
1340 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
1341 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1342 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"},
1343 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"},
1344 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"},
1345 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
1346 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
1347 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
1348 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
1349 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
1350 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
1351 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
1352 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
1353 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
1354 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
1355 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
1356 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
1357 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
1358 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1359 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1360 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
1361 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"},
1363 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1364 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1365 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1366 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
1367 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
1369 /* These have been 32-bit since the invention of Thumb. */
1370 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx\t%B"},
1371 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl\t%B"},
1373 /* Fallback. */
1374 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1375 {0, 0, 0, 0}
1378 static const char *const arm_conditional[] =
1379 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1380 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1382 static const char *const arm_fp_const[] =
1383 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1385 static const char *const arm_shift[] =
1386 {"lsl", "lsr", "asr", "ror"};
1388 typedef struct
1390 const char *name;
1391 const char *description;
1392 const char *reg_names[16];
1394 arm_regname;
1396 static const arm_regname regnames[] =
1398 { "raw" , "Select raw register names",
1399 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1400 { "gcc", "Select register names used by GCC",
1401 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1402 { "std", "Select register names used in ARM's ISA documentation",
1403 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1404 { "apcs", "Select register names used in the APCS",
1405 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1406 { "atpcs", "Select register names used in the ATPCS",
1407 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1408 { "special-atpcs", "Select special register names used in the ATPCS",
1409 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1412 static const char *const iwmmxt_wwnames[] =
1413 {"b", "h", "w", "d"};
1415 static const char *const iwmmxt_wwssnames[] =
1416 {"b", "bus", "b", "bss",
1417 "h", "hus", "h", "hss",
1418 "w", "wus", "w", "wss",
1419 "d", "dus", "d", "dss"
1422 static const char *const iwmmxt_regnames[] =
1423 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1424 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1427 static const char *const iwmmxt_cregnames[] =
1428 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1429 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1432 /* Default to GCC register name set. */
1433 static unsigned int regname_selected = 1;
1435 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1436 #define arm_regnames regnames[regname_selected].reg_names
1438 static bfd_boolean force_thumb = FALSE;
1441 /* Functions. */
1443 get_arm_regname_num_options (void)
1445 return NUM_ARM_REGNAMES;
1449 set_arm_regname_option (int option)
1451 int old = regname_selected;
1452 regname_selected = option;
1453 return old;
1457 get_arm_regnames (int option, const char **setname, const char **setdescription,
1458 const char *const **register_names)
1460 *setname = regnames[option].name;
1461 *setdescription = regnames[option].description;
1462 *register_names = regnames[option].reg_names;
1463 return 16;
1466 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1467 Returns pointer to following character of the format string and
1468 fills in *VALUEP and *WIDTHP with the extracted value and number of
1469 bits extracted. WIDTHP can be NULL. */
1471 static const char *
1472 arm_decode_bitfield (const char *ptr, unsigned long insn,
1473 unsigned long *valuep, int *widthp)
1475 unsigned long value = 0;
1476 int width = 0;
1480 int start, end;
1481 int bits;
1483 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1484 start = start * 10 + *ptr - '0';
1485 if (*ptr == '-')
1486 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1487 end = end * 10 + *ptr - '0';
1488 else
1489 end = start;
1490 bits = end - start;
1491 if (bits < 0)
1492 abort ();
1493 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1494 width += bits + 1;
1496 while (*ptr++ == ',');
1497 *valuep = value;
1498 if (widthp)
1499 *widthp = width;
1500 return ptr - 1;
1503 static void
1504 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1506 func (stream, "%s", arm_regnames[given & 0xf]);
1508 if ((given & 0xff0) != 0)
1510 if ((given & 0x10) == 0)
1512 int amount = (given & 0xf80) >> 7;
1513 int shift = (given & 0x60) >> 5;
1515 if (amount == 0)
1517 if (shift == 3)
1519 func (stream, ", rrx");
1520 return;
1523 amount = 32;
1526 func (stream, ", %s #%d", arm_shift[shift], amount);
1528 else
1529 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1530 arm_regnames[(given & 0xf00) >> 8]);
1534 /* Print one coprocessor instruction on INFO->STREAM.
1535 Return TRUE if the instuction matched, FALSE if this is not a
1536 recognised coprocessor instruction. */
1538 static bfd_boolean
1539 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1540 bfd_boolean thumb)
1542 const struct opcode32 *insn;
1543 void *stream = info->stream;
1544 fprintf_ftype func = info->fprintf_func;
1545 unsigned long mask;
1546 unsigned long value;
1548 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1550 if (insn->value == FIRST_IWMMXT_INSN
1551 && info->mach != bfd_mach_arm_XScale
1552 && info->mach != bfd_mach_arm_iWMMXt)
1553 insn = insn + IWMMXT_INSN_COUNT;
1555 mask = insn->mask;
1556 value = insn->value;
1557 if (thumb)
1559 /* The high 4 bits are 0xe for Arm conditional instructions, and
1560 0xe for arm unconditional instructions. The rest of the
1561 encoding is the same. */
1562 mask |= 0xf0000000;
1563 value |= 0xe0000000;
1565 else
1567 /* Only match unconditional instuctions against unconditional
1568 patterns. */
1569 if ((given & 0xf0000000) == 0xf0000000)
1570 mask |= 0xf0000000;
1572 if ((given & mask) == value)
1574 const char *c;
1576 for (c = insn->assembler; *c; c++)
1578 if (*c == '%')
1580 switch (*++c)
1582 case '%':
1583 func (stream, "%%");
1584 break;
1586 case 'A':
1587 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1589 if ((given & (1 << 24)) != 0)
1591 int offset = given & 0xff;
1593 if (offset)
1594 func (stream, ", #%s%d]%s",
1595 ((given & 0x00800000) == 0 ? "-" : ""),
1596 offset * 4,
1597 ((given & 0x00200000) != 0 ? "!" : ""));
1598 else
1599 func (stream, "]");
1601 else
1603 int offset = given & 0xff;
1605 func (stream, "]");
1607 if (given & (1 << 21))
1609 if (offset)
1610 func (stream, ", #%s%d",
1611 ((given & 0x00800000) == 0 ? "-" : ""),
1612 offset * 4);
1614 else
1615 func (stream, ", {%d}", offset);
1617 break;
1619 case 'B':
1621 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1622 int offset = (given >> 1) & 0x3f;
1624 if (offset == 1)
1625 func (stream, "{d%d}", regno);
1626 else if (regno + offset > 32)
1627 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1628 else
1629 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1631 break;
1633 case 'C':
1635 int rn = (given >> 16) & 0xf;
1636 int offset = (given & 0xff) * 4;
1637 int add = (given >> 23) & 1;
1639 func (stream, "[%s", arm_regnames[rn]);
1641 if (offset)
1643 if (!add)
1644 offset = -offset;
1645 func (stream, ", #%d", offset);
1647 func (stream, "]");
1648 if (rn == 15)
1650 func (stream, "\t; ");
1651 /* FIXME: Unsure if info->bytes_per_chunk is the
1652 right thing to use here. */
1653 info->print_address_func (offset + pc
1654 + info->bytes_per_chunk * 2, info);
1657 break;
1659 case 'c':
1660 func (stream, "%s",
1661 arm_conditional [(given >> 28) & 0xf]);
1662 break;
1664 case 'I':
1665 /* Print a Cirrus/DSP shift immediate. */
1666 /* Immediates are 7bit signed ints with bits 0..3 in
1667 bits 0..3 of opcode and bits 4..6 in bits 5..7
1668 of opcode. */
1670 int imm;
1672 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1674 /* Is ``imm'' a negative number? */
1675 if (imm & 0x40)
1676 imm |= (-1 << 7);
1678 func (stream, "%d", imm);
1681 break;
1683 case 'F':
1684 switch (given & 0x00408000)
1686 case 0:
1687 func (stream, "4");
1688 break;
1689 case 0x8000:
1690 func (stream, "1");
1691 break;
1692 case 0x00400000:
1693 func (stream, "2");
1694 break;
1695 default:
1696 func (stream, "3");
1698 break;
1700 case 'P':
1701 switch (given & 0x00080080)
1703 case 0:
1704 func (stream, "s");
1705 break;
1706 case 0x80:
1707 func (stream, "d");
1708 break;
1709 case 0x00080000:
1710 func (stream, "e");
1711 break;
1712 default:
1713 func (stream, _("<illegal precision>"));
1714 break;
1716 break;
1717 case 'Q':
1718 switch (given & 0x00408000)
1720 case 0:
1721 func (stream, "s");
1722 break;
1723 case 0x8000:
1724 func (stream, "d");
1725 break;
1726 case 0x00400000:
1727 func (stream, "e");
1728 break;
1729 default:
1730 func (stream, "p");
1731 break;
1733 break;
1734 case 'R':
1735 switch (given & 0x60)
1737 case 0:
1738 break;
1739 case 0x20:
1740 func (stream, "p");
1741 break;
1742 case 0x40:
1743 func (stream, "m");
1744 break;
1745 default:
1746 func (stream, "z");
1747 break;
1749 break;
1751 case '0': case '1': case '2': case '3': case '4':
1752 case '5': case '6': case '7': case '8': case '9':
1754 int width;
1755 unsigned long value;
1757 c = arm_decode_bitfield (c, given, &value, &width);
1759 switch (*c)
1761 case 'r':
1762 func (stream, "%s", arm_regnames[value]);
1763 break;
1764 case 'D':
1765 func (stream, "d%ld", value);
1766 break;
1767 case 'Q':
1768 if (value & 1)
1769 func (stream, "<illegal reg q%ld.5>", value >> 1);
1770 else
1771 func (stream, "q%ld", value >> 1);
1772 break;
1773 case 'd':
1774 func (stream, "%ld", value);
1775 break;
1776 case 'k':
1778 int from = (given & (1 << 7)) ? 32 : 16;
1779 func (stream, "%ld", from - value);
1781 break;
1783 case 'f':
1784 if (value > 7)
1785 func (stream, "#%s", arm_fp_const[value & 7]);
1786 else
1787 func (stream, "f%ld", value);
1788 break;
1790 case 'w':
1791 if (width == 2)
1792 func (stream, "%s", iwmmxt_wwnames[value]);
1793 else
1794 func (stream, "%s", iwmmxt_wwssnames[value]);
1795 break;
1797 case 'g':
1798 func (stream, "%s", iwmmxt_regnames[value]);
1799 break;
1800 case 'G':
1801 func (stream, "%s", iwmmxt_cregnames[value]);
1802 break;
1803 case '`':
1804 c++;
1805 if (value == 0)
1806 func (stream, "%c", *c);
1807 break;
1808 case '\'':
1809 c++;
1810 if (value == ((1ul << width) - 1))
1811 func (stream, "%c", *c);
1812 break;
1813 case '?':
1814 func (stream, "%c", c[(1 << width) - (int)value]);
1815 c += 1 << width;
1816 break;
1817 default:
1818 abort ();
1820 break;
1822 case 'y':
1823 case 'z':
1825 int single = *c++ == 'y';
1826 int regno;
1828 switch (*c)
1830 case '4': /* Sm pair */
1831 func (stream, "{");
1832 /* Fall through. */
1833 case '0': /* Sm, Dm */
1834 regno = given & 0x0000000f;
1835 if (single)
1837 regno <<= 1;
1838 regno += (given >> 5) & 1;
1840 else
1841 regno += ((given >> 5) & 1) << 4;
1842 break;
1844 case '1': /* Sd, Dd */
1845 regno = (given >> 12) & 0x0000000f;
1846 if (single)
1848 regno <<= 1;
1849 regno += (given >> 22) & 1;
1851 else
1852 regno += ((given >> 22) & 1) << 4;
1853 break;
1855 case '2': /* Sn, Dn */
1856 regno = (given >> 16) & 0x0000000f;
1857 if (single)
1859 regno <<= 1;
1860 regno += (given >> 7) & 1;
1862 else
1863 regno += ((given >> 7) & 1) << 4;
1864 break;
1866 case '3': /* List */
1867 func (stream, "{");
1868 regno = (given >> 12) & 0x0000000f;
1869 if (single)
1871 regno <<= 1;
1872 regno += (given >> 22) & 1;
1874 else
1875 regno += ((given >> 22) & 1) << 4;
1876 break;
1878 default:
1879 abort ();
1882 func (stream, "%c%d", single ? 's' : 'd', regno);
1884 if (*c == '3')
1886 int count = given & 0xff;
1888 if (single == 0)
1889 count >>= 1;
1891 if (--count)
1893 func (stream, "-%c%d",
1894 single ? 's' : 'd',
1895 regno + count);
1898 func (stream, "}");
1900 else if (*c == '4')
1901 func (stream, ", %c%d}", single ? 's' : 'd',
1902 regno + 1);
1904 break;
1906 case 'L':
1907 switch (given & 0x00400100)
1909 case 0x00000000: func (stream, "b"); break;
1910 case 0x00400000: func (stream, "h"); break;
1911 case 0x00000100: func (stream, "w"); break;
1912 case 0x00400100: func (stream, "d"); break;
1913 default:
1914 break;
1916 break;
1918 case 'Z':
1920 int value;
1921 /* given (20, 23) | given (0, 3) */
1922 value = ((given >> 16) & 0xf0) | (given & 0xf);
1923 func (stream, "%d", value);
1925 break;
1927 case 'l':
1928 /* This is like the 'A' operator, except that if
1929 the width field "M" is zero, then the offset is
1930 *not* multiplied by four. */
1932 int offset = given & 0xff;
1933 int multiplier = (given & 0x00000100) ? 4 : 1;
1935 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1937 if (offset)
1939 if ((given & 0x01000000) != 0)
1940 func (stream, ", #%s%d]%s",
1941 ((given & 0x00800000) == 0 ? "-" : ""),
1942 offset * multiplier,
1943 ((given & 0x00200000) != 0 ? "!" : ""));
1944 else
1945 func (stream, "], #%s%d",
1946 ((given & 0x00800000) == 0 ? "-" : ""),
1947 offset * multiplier);
1949 else
1950 func (stream, "]");
1952 break;
1954 default:
1955 abort ();
1959 else
1960 func (stream, "%c", *c);
1962 return TRUE;
1965 return FALSE;
1968 static void
1969 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
1971 void *stream = info->stream;
1972 fprintf_ftype func = info->fprintf_func;
1974 if (((given & 0x000f0000) == 0x000f0000)
1975 && ((given & 0x02000000) == 0))
1977 int offset = given & 0xfff;
1979 func (stream, "[pc");
1981 if (given & 0x01000000)
1983 if ((given & 0x00800000) == 0)
1984 offset = - offset;
1986 /* Pre-indexed. */
1987 func (stream, ", #%d]", offset);
1989 offset += pc + 8;
1991 /* Cope with the possibility of write-back
1992 being used. Probably a very dangerous thing
1993 for the programmer to do, but who are we to
1994 argue ? */
1995 if (given & 0x00200000)
1996 func (stream, "!");
1998 else
2000 /* Post indexed. */
2001 func (stream, "], #%d", offset);
2003 /* ie ignore the offset. */
2004 offset = pc + 8;
2007 func (stream, "\t; ");
2008 info->print_address_func (offset, info);
2010 else
2012 func (stream, "[%s",
2013 arm_regnames[(given >> 16) & 0xf]);
2014 if ((given & 0x01000000) != 0)
2016 if ((given & 0x02000000) == 0)
2018 int offset = given & 0xfff;
2019 if (offset)
2020 func (stream, ", #%s%d",
2021 (((given & 0x00800000) == 0)
2022 ? "-" : ""), offset);
2024 else
2026 func (stream, ", %s",
2027 (((given & 0x00800000) == 0)
2028 ? "-" : ""));
2029 arm_decode_shift (given, func, stream);
2032 func (stream, "]%s",
2033 ((given & 0x00200000) != 0) ? "!" : "");
2035 else
2037 if ((given & 0x02000000) == 0)
2039 int offset = given & 0xfff;
2040 if (offset)
2041 func (stream, "], #%s%d",
2042 (((given & 0x00800000) == 0)
2043 ? "-" : ""), offset);
2044 else
2045 func (stream, "]");
2047 else
2049 func (stream, "], %s",
2050 (((given & 0x00800000) == 0)
2051 ? "-" : ""));
2052 arm_decode_shift (given, func, stream);
2058 /* Print one neon instruction on INFO->STREAM.
2059 Return TRUE if the instuction matched, FALSE if this is not a
2060 recognised neon instruction. */
2062 static bfd_boolean
2063 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2065 const struct opcode32 *insn;
2066 void *stream = info->stream;
2067 fprintf_ftype func = info->fprintf_func;
2069 if (thumb)
2071 if ((given & 0xef000000) == 0xef000000)
2073 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2074 unsigned long bit28 = given & (1 << 28);
2076 given &= 0x00ffffff;
2077 if (bit28)
2078 given |= 0xf3000000;
2079 else
2080 given |= 0xf2000000;
2082 else if ((given & 0xff000000) == 0xf9000000)
2083 given ^= 0xf9000000 ^ 0xf4000000;
2084 else
2085 return FALSE;
2088 for (insn = neon_opcodes; insn->assembler; insn++)
2090 if ((given & insn->mask) == insn->value)
2092 const char *c;
2094 for (c = insn->assembler; *c; c++)
2096 if (*c == '%')
2098 switch (*++c)
2100 case '%':
2101 func (stream, "%%");
2102 break;
2104 case 'A':
2106 static const unsigned char enc[16] =
2108 0x4, 0x14, /* st4 0,1 */
2109 0x4, /* st1 2 */
2110 0x4, /* st2 3 */
2111 0x3, /* st3 4 */
2112 0x13, /* st3 5 */
2113 0x3, /* st1 6 */
2114 0x1, /* st1 7 */
2115 0x2, /* st2 8 */
2116 0x12, /* st2 9 */
2117 0x2, /* st1 10 */
2118 0, 0, 0, 0, 0
2120 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2121 int rn = ((given >> 16) & 0xf);
2122 int rm = ((given >> 0) & 0xf);
2123 int align = ((given >> 4) & 0x3);
2124 int type = ((given >> 8) & 0xf);
2125 int n = enc[type] & 0xf;
2126 int stride = (enc[type] >> 4) + 1;
2127 int ix;
2129 func (stream, "{");
2130 if (stride > 1)
2131 for (ix = 0; ix != n; ix++)
2132 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2133 else if (n == 1)
2134 func (stream, "d%d", rd);
2135 else
2136 func (stream, "d%d-d%d", rd, rd + n - 1);
2137 func (stream, "}, [%s", arm_regnames[rn]);
2138 if (align)
2139 func (stream, ", :%d", 32 << align);
2140 func (stream, "]");
2141 if (rm == 0xd)
2142 func (stream, "!");
2143 else if (rm != 0xf)
2144 func (stream, ", %s", arm_regnames[rm]);
2146 break;
2148 case 'B':
2150 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2151 int rn = ((given >> 16) & 0xf);
2152 int rm = ((given >> 0) & 0xf);
2153 int idx_align = ((given >> 4) & 0xf);
2154 int align = 0;
2155 int size = ((given >> 10) & 0x3);
2156 int idx = idx_align >> (size + 1);
2157 int length = ((given >> 8) & 3) + 1;
2158 int stride = 1;
2159 int i;
2161 if (length > 1 && size > 0)
2162 stride = (idx_align & (1 << size)) ? 2 : 1;
2164 switch (length)
2166 case 1:
2168 int amask = (1 << size) - 1;
2169 if ((idx_align & (1 << size)) != 0)
2170 return FALSE;
2171 if (size > 0)
2173 if ((idx_align & amask) == amask)
2174 align = 8 << size;
2175 else if ((idx_align & amask) != 0)
2176 return FALSE;
2179 break;
2181 case 2:
2182 if (size == 2 && (idx_align & 2) != 0)
2183 return FALSE;
2184 align = (idx_align & 1) ? 16 << size : 0;
2185 break;
2187 case 3:
2188 if ((size == 2 && (idx_align & 3) != 0)
2189 || (idx_align & 1) != 0)
2190 return FALSE;
2191 break;
2193 case 4:
2194 if (size == 2)
2196 if ((idx_align & 3) == 3)
2197 return FALSE;
2198 align = (idx_align & 3) * 64;
2200 else
2201 align = (idx_align & 1) ? 32 << size : 0;
2202 break;
2204 default:
2205 abort ();
2208 func (stream, "{");
2209 for (i = 0; i < length; i++)
2210 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2211 rd + i * stride, idx);
2212 func (stream, "}, [%s", arm_regnames[rn]);
2213 if (align)
2214 func (stream, ", :%d", align);
2215 func (stream, "]");
2216 if (rm == 0xd)
2217 func (stream, "!");
2218 else if (rm != 0xf)
2219 func (stream, ", %s", arm_regnames[rm]);
2221 break;
2223 case 'C':
2225 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2226 int rn = ((given >> 16) & 0xf);
2227 int rm = ((given >> 0) & 0xf);
2228 int align = ((given >> 4) & 0x1);
2229 int size = ((given >> 6) & 0x3);
2230 int type = ((given >> 8) & 0x3);
2231 int n = type + 1;
2232 int stride = ((given >> 5) & 0x1);
2233 int ix;
2235 if (stride && (n == 1))
2236 n++;
2237 else
2238 stride++;
2240 func (stream, "{");
2241 if (stride > 1)
2242 for (ix = 0; ix != n; ix++)
2243 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2244 else if (n == 1)
2245 func (stream, "d%d[]", rd);
2246 else
2247 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2248 func (stream, "}, [%s", arm_regnames[rn]);
2249 if (align)
2251 int align = (8 * (type + 1)) << size;
2252 if (type == 3)
2253 align = (size > 1) ? align >> 1 : align;
2254 if (type == 2 || (type == 0 && !size))
2255 func (stream, ", :<bad align %d>", align);
2256 else
2257 func (stream, ", :%d", align);
2259 func (stream, "]");
2260 if (rm == 0xd)
2261 func (stream, "!");
2262 else if (rm != 0xf)
2263 func (stream, ", %s", arm_regnames[rm]);
2265 break;
2267 case 'D':
2269 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2270 int size = (given >> 20) & 3;
2271 int reg = raw_reg & ((4 << size) - 1);
2272 int ix = raw_reg >> size >> 2;
2274 func (stream, "d%d[%d]", reg, ix);
2276 break;
2278 case 'E':
2279 /* Neon encoded constant for mov, mvn, vorr, vbic */
2281 int bits = 0;
2282 int cmode = (given >> 8) & 0xf;
2283 int op = (given >> 5) & 0x1;
2284 unsigned long value = 0, hival = 0;
2285 unsigned shift;
2286 int size = 0;
2287 int isfloat = 0;
2289 bits |= ((given >> 24) & 1) << 7;
2290 bits |= ((given >> 16) & 7) << 4;
2291 bits |= ((given >> 0) & 15) << 0;
2293 if (cmode < 8)
2295 shift = (cmode >> 1) & 3;
2296 value = (unsigned long)bits << (8 * shift);
2297 size = 32;
2299 else if (cmode < 12)
2301 shift = (cmode >> 1) & 1;
2302 value = (unsigned long)bits << (8 * shift);
2303 size = 16;
2305 else if (cmode < 14)
2307 shift = (cmode & 1) + 1;
2308 value = (unsigned long)bits << (8 * shift);
2309 value |= (1ul << (8 * shift)) - 1;
2310 size = 32;
2312 else if (cmode == 14)
2314 if (op)
2316 /* bit replication into bytes */
2317 int ix;
2318 unsigned long mask;
2320 value = 0;
2321 hival = 0;
2322 for (ix = 7; ix >= 0; ix--)
2324 mask = ((bits >> ix) & 1) ? 0xff : 0;
2325 if (ix <= 3)
2326 value = (value << 8) | mask;
2327 else
2328 hival = (hival << 8) | mask;
2330 size = 64;
2332 else
2334 /* byte replication */
2335 value = (unsigned long)bits;
2336 size = 8;
2339 else if (!op)
2341 /* floating point encoding */
2342 int tmp;
2344 value = (unsigned long)(bits & 0x7f) << 19;
2345 value |= (unsigned long)(bits & 0x80) << 24;
2346 tmp = bits & 0x40 ? 0x3c : 0x40;
2347 value |= (unsigned long)tmp << 24;
2348 size = 32;
2349 isfloat = 1;
2351 else
2353 func (stream, "<illegal constant %.8x:%x:%x>",
2354 bits, cmode, op);
2355 size = 32;
2356 break;
2358 switch (size)
2360 case 8:
2361 func (stream, "#%ld\t; 0x%.2lx", value, value);
2362 break;
2364 case 16:
2365 func (stream, "#%ld\t; 0x%.4lx", value, value);
2366 break;
2368 case 32:
2369 if (isfloat)
2371 unsigned char valbytes[4];
2372 double fvalue;
2374 /* Do this a byte at a time so we don't have to
2375 worry about the host's endianness. */
2376 valbytes[0] = value & 0xff;
2377 valbytes[1] = (value >> 8) & 0xff;
2378 valbytes[2] = (value >> 16) & 0xff;
2379 valbytes[3] = (value >> 24) & 0xff;
2381 floatformat_to_double
2382 (&floatformat_ieee_single_little, valbytes,
2383 &fvalue);
2385 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2386 value);
2388 else
2389 func (stream, "#%ld\t; 0x%.8lx", value, value);
2390 break;
2392 case 64:
2393 func (stream, "#0x%.8lx%.8lx", hival, value);
2394 break;
2396 default:
2397 abort ();
2400 break;
2402 case 'F':
2404 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2405 int num = (given >> 8) & 0x3;
2407 if (!num)
2408 func (stream, "{d%d}", regno);
2409 else if (num + regno >= 32)
2410 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2411 else
2412 func (stream, "{d%d-d%d}", regno, regno + num);
2414 break;
2417 case '0': case '1': case '2': case '3': case '4':
2418 case '5': case '6': case '7': case '8': case '9':
2420 int width;
2421 unsigned long value;
2423 c = arm_decode_bitfield (c, given, &value, &width);
2425 switch (*c)
2427 case 'r':
2428 func (stream, "%s", arm_regnames[value]);
2429 break;
2430 case 'd':
2431 func (stream, "%ld", value);
2432 break;
2433 case 'e':
2434 func (stream, "%ld", (1ul << width) - value);
2435 break;
2437 case 'S':
2438 case 'T':
2439 case 'U':
2440 /* various width encodings */
2442 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2443 int limit;
2444 unsigned low, high;
2446 c++;
2447 if (*c >= '0' && *c <= '9')
2448 limit = *c - '0';
2449 else if (*c >= 'a' && *c <= 'f')
2450 limit = *c - 'a' + 10;
2451 else
2452 abort ();
2453 low = limit >> 2;
2454 high = limit & 3;
2456 if (value < low || value > high)
2457 func (stream, "<illegal width %d>", base << value);
2458 else
2459 func (stream, "%d", base << value);
2461 break;
2462 case 'R':
2463 if (given & (1 << 6))
2464 goto Q;
2465 /* FALLTHROUGH */
2466 case 'D':
2467 func (stream, "d%ld", value);
2468 break;
2469 case 'Q':
2471 if (value & 1)
2472 func (stream, "<illegal reg q%ld.5>", value >> 1);
2473 else
2474 func (stream, "q%ld", value >> 1);
2475 break;
2477 case '`':
2478 c++;
2479 if (value == 0)
2480 func (stream, "%c", *c);
2481 break;
2482 case '\'':
2483 c++;
2484 if (value == ((1ul << width) - 1))
2485 func (stream, "%c", *c);
2486 break;
2487 case '?':
2488 func (stream, "%c", c[(1 << width) - (int)value]);
2489 c += 1 << width;
2490 break;
2491 default:
2492 abort ();
2494 break;
2496 default:
2497 abort ();
2501 else
2502 func (stream, "%c", *c);
2504 return TRUE;
2507 return FALSE;
2510 /* Print one ARM instruction from PC on INFO->STREAM. */
2512 static void
2513 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2515 const struct opcode32 *insn;
2516 void *stream = info->stream;
2517 fprintf_ftype func = info->fprintf_func;
2519 if (print_insn_coprocessor (pc, info, given, FALSE))
2520 return;
2522 if (print_insn_neon (info, given, FALSE))
2523 return;
2525 for (insn = arm_opcodes; insn->assembler; insn++)
2527 if (insn->value == FIRST_IWMMXT_INSN
2528 && info->mach != bfd_mach_arm_XScale
2529 && info->mach != bfd_mach_arm_iWMMXt)
2530 insn = insn + IWMMXT_INSN_COUNT;
2532 if ((given & insn->mask) == insn->value
2533 /* Special case: an instruction with all bits set in the condition field
2534 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2535 or by the catchall at the end of the table. */
2536 && ((given & 0xF0000000) != 0xF0000000
2537 || (insn->mask & 0xF0000000) == 0xF0000000
2538 || (insn->mask == 0 && insn->value == 0)))
2540 const char *c;
2542 for (c = insn->assembler; *c; c++)
2544 if (*c == '%')
2546 switch (*++c)
2548 case '%':
2549 func (stream, "%%");
2550 break;
2552 case 'a':
2553 print_arm_address (pc, info, given);
2554 break;
2556 case 'P':
2557 /* Set P address bit and use normal address
2558 printing routine. */
2559 print_arm_address (pc, info, given | (1 << 24));
2560 break;
2562 case 's':
2563 if ((given & 0x004f0000) == 0x004f0000)
2565 /* PC relative with immediate offset. */
2566 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2568 if ((given & 0x00800000) == 0)
2569 offset = -offset;
2571 func (stream, "[pc, #%d]\t; ", offset);
2572 info->print_address_func (offset + pc + 8, info);
2574 else
2576 func (stream, "[%s",
2577 arm_regnames[(given >> 16) & 0xf]);
2578 if ((given & 0x01000000) != 0)
2580 /* Pre-indexed. */
2581 if ((given & 0x00400000) == 0x00400000)
2583 /* Immediate. */
2584 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2585 if (offset)
2586 func (stream, ", #%s%d",
2587 (((given & 0x00800000) == 0)
2588 ? "-" : ""), offset);
2590 else
2592 /* Register. */
2593 func (stream, ", %s%s",
2594 (((given & 0x00800000) == 0)
2595 ? "-" : ""),
2596 arm_regnames[given & 0xf]);
2599 func (stream, "]%s",
2600 ((given & 0x00200000) != 0) ? "!" : "");
2602 else
2604 /* Post-indexed. */
2605 if ((given & 0x00400000) == 0x00400000)
2607 /* Immediate. */
2608 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2609 if (offset)
2610 func (stream, "], #%s%d",
2611 (((given & 0x00800000) == 0)
2612 ? "-" : ""), offset);
2613 else
2614 func (stream, "]");
2616 else
2618 /* Register. */
2619 func (stream, "], %s%s",
2620 (((given & 0x00800000) == 0)
2621 ? "-" : ""),
2622 arm_regnames[given & 0xf]);
2626 break;
2628 case 'b':
2630 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2631 info->print_address_func (disp*4 + pc + 8, info);
2633 break;
2635 case 'c':
2636 func (stream, "%s",
2637 arm_conditional [(given >> 28) & 0xf]);
2638 break;
2640 case 'm':
2642 int started = 0;
2643 int reg;
2645 func (stream, "{");
2646 for (reg = 0; reg < 16; reg++)
2647 if ((given & (1 << reg)) != 0)
2649 if (started)
2650 func (stream, ", ");
2651 started = 1;
2652 func (stream, "%s", arm_regnames[reg]);
2654 func (stream, "}");
2656 break;
2658 case 'o':
2659 if ((given & 0x02000000) != 0)
2661 int rotate = (given & 0xf00) >> 7;
2662 int immed = (given & 0xff);
2663 immed = (((immed << (32 - rotate))
2664 | (immed >> rotate)) & 0xffffffff);
2665 func (stream, "#%d\t; 0x%x", immed, immed);
2667 else
2668 arm_decode_shift (given, func, stream);
2669 break;
2671 case 'p':
2672 if ((given & 0x0000f000) == 0x0000f000)
2673 func (stream, "p");
2674 break;
2676 case 't':
2677 if ((given & 0x01200000) == 0x00200000)
2678 func (stream, "t");
2679 break;
2681 case 'A':
2682 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2684 if ((given & (1 << 24)) != 0)
2686 int offset = given & 0xff;
2688 if (offset)
2689 func (stream, ", #%s%d]%s",
2690 ((given & 0x00800000) == 0 ? "-" : ""),
2691 offset * 4,
2692 ((given & 0x00200000) != 0 ? "!" : ""));
2693 else
2694 func (stream, "]");
2696 else
2698 int offset = given & 0xff;
2700 func (stream, "]");
2702 if (given & (1 << 21))
2704 if (offset)
2705 func (stream, ", #%s%d",
2706 ((given & 0x00800000) == 0 ? "-" : ""),
2707 offset * 4);
2709 else
2710 func (stream, ", {%d}", offset);
2712 break;
2714 case 'B':
2715 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2717 bfd_vma address;
2718 bfd_vma offset = 0;
2720 if (given & 0x00800000)
2721 /* Is signed, hi bits should be ones. */
2722 offset = (-1) ^ 0x00ffffff;
2724 /* Offset is (SignExtend(offset field)<<2). */
2725 offset += given & 0x00ffffff;
2726 offset <<= 2;
2727 address = offset + pc + 8;
2729 if (given & 0x01000000)
2730 /* H bit allows addressing to 2-byte boundaries. */
2731 address += 2;
2733 info->print_address_func (address, info);
2735 break;
2737 case 'C':
2738 func (stream, "_");
2739 if (given & 0x80000)
2740 func (stream, "f");
2741 if (given & 0x40000)
2742 func (stream, "s");
2743 if (given & 0x20000)
2744 func (stream, "x");
2745 if (given & 0x10000)
2746 func (stream, "c");
2747 break;
2749 case 'U':
2750 switch (given & 0xf)
2752 case 0xf: func(stream, "sy"); break;
2753 case 0x7: func(stream, "un"); break;
2754 case 0xe: func(stream, "st"); break;
2755 case 0x6: func(stream, "unst"); break;
2756 default:
2757 func(stream, "#%d", (int)given & 0xf);
2758 break;
2760 break;
2762 case '0': case '1': case '2': case '3': case '4':
2763 case '5': case '6': case '7': case '8': case '9':
2765 int width;
2766 unsigned long value;
2768 c = arm_decode_bitfield (c, given, &value, &width);
2770 switch (*c)
2772 case 'r':
2773 func (stream, "%s", arm_regnames[value]);
2774 break;
2775 case 'd':
2776 func (stream, "%ld", value);
2777 break;
2778 case 'b':
2779 func (stream, "%ld", value * 8);
2780 break;
2781 case 'W':
2782 func (stream, "%ld", value + 1);
2783 break;
2784 case 'x':
2785 func (stream, "0x%08lx", value);
2787 /* Some SWI instructions have special
2788 meanings. */
2789 if ((given & 0x0fffffff) == 0x0FF00000)
2790 func (stream, "\t; IMB");
2791 else if ((given & 0x0fffffff) == 0x0FF00001)
2792 func (stream, "\t; IMBRange");
2793 break;
2794 case 'X':
2795 func (stream, "%01lx", value & 0xf);
2796 break;
2797 case '`':
2798 c++;
2799 if (value == 0)
2800 func (stream, "%c", *c);
2801 break;
2802 case '\'':
2803 c++;
2804 if (value == ((1ul << width) - 1))
2805 func (stream, "%c", *c);
2806 break;
2807 case '?':
2808 func (stream, "%c", c[(1 << width) - (int)value]);
2809 c += 1 << width;
2810 break;
2811 default:
2812 abort ();
2814 break;
2816 case 'e':
2818 int imm;
2820 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2821 func (stream, "%d", imm);
2823 break;
2825 case 'E':
2826 /* LSB and WIDTH fields of BFI or BFC. The machine-
2827 language instruction encodes LSB and MSB. */
2829 long msb = (given & 0x001f0000) >> 16;
2830 long lsb = (given & 0x00000f80) >> 7;
2832 long width = msb - lsb + 1;
2833 if (width > 0)
2834 func (stream, "#%lu, #%lu", lsb, width);
2835 else
2836 func (stream, "(invalid: %lu:%lu)", lsb, msb);
2838 break;
2840 case 'V':
2841 /* 16-bit unsigned immediate from a MOVT or MOVW
2842 instruction, encoded in bits 0:11 and 15:19. */
2844 long hi = (given & 0x000f0000) >> 4;
2845 long lo = (given & 0x00000fff);
2846 long imm16 = hi | lo;
2847 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2849 break;
2851 default:
2852 abort ();
2856 else
2857 func (stream, "%c", *c);
2859 return;
2862 abort ();
2865 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2867 static void
2868 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2870 const struct opcode16 *insn;
2871 void *stream = info->stream;
2872 fprintf_ftype func = info->fprintf_func;
2874 for (insn = thumb_opcodes; insn->assembler; insn++)
2875 if ((given & insn->mask) == insn->value)
2877 const char *c = insn->assembler;
2878 for (; *c; c++)
2880 int domaskpc = 0;
2881 int domasklr = 0;
2883 if (*c != '%')
2885 func (stream, "%c", *c);
2886 continue;
2889 switch (*++c)
2891 case '%':
2892 func (stream, "%%");
2893 break;
2895 case 'S':
2897 long reg;
2899 reg = (given >> 3) & 0x7;
2900 if (given & (1 << 6))
2901 reg += 8;
2903 func (stream, "%s", arm_regnames[reg]);
2905 break;
2907 case 'D':
2909 long reg;
2911 reg = given & 0x7;
2912 if (given & (1 << 7))
2913 reg += 8;
2915 func (stream, "%s", arm_regnames[reg]);
2917 break;
2919 case 'N':
2920 if (given & (1 << 8))
2921 domasklr = 1;
2922 /* Fall through. */
2923 case 'O':
2924 if (*c == 'O' && (given & (1 << 8)))
2925 domaskpc = 1;
2926 /* Fall through. */
2927 case 'M':
2929 int started = 0;
2930 int reg;
2932 func (stream, "{");
2934 /* It would be nice if we could spot
2935 ranges, and generate the rS-rE format: */
2936 for (reg = 0; (reg < 8); reg++)
2937 if ((given & (1 << reg)) != 0)
2939 if (started)
2940 func (stream, ", ");
2941 started = 1;
2942 func (stream, "%s", arm_regnames[reg]);
2945 if (domasklr)
2947 if (started)
2948 func (stream, ", ");
2949 started = 1;
2950 func (stream, arm_regnames[14] /* "lr" */);
2953 if (domaskpc)
2955 if (started)
2956 func (stream, ", ");
2957 func (stream, arm_regnames[15] /* "pc" */);
2960 func (stream, "}");
2962 break;
2964 case 'b':
2965 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
2967 bfd_vma address = (pc + 4
2968 + ((given & 0x00f8) >> 2)
2969 + ((given & 0x0200) >> 3));
2970 info->print_address_func (address, info);
2972 break;
2974 case 's':
2975 /* Right shift immediate -- bits 6..10; 1-31 print
2976 as themselves, 0 prints as 32. */
2978 long imm = (given & 0x07c0) >> 6;
2979 if (imm == 0)
2980 imm = 32;
2981 func (stream, "#%ld", imm);
2983 break;
2985 case '0': case '1': case '2': case '3': case '4':
2986 case '5': case '6': case '7': case '8': case '9':
2988 int bitstart = *c++ - '0';
2989 int bitend = 0;
2991 while (*c >= '0' && *c <= '9')
2992 bitstart = (bitstart * 10) + *c++ - '0';
2994 switch (*c)
2996 case '-':
2998 long reg;
3000 c++;
3001 while (*c >= '0' && *c <= '9')
3002 bitend = (bitend * 10) + *c++ - '0';
3003 if (!bitend)
3004 abort ();
3005 reg = given >> bitstart;
3006 reg &= (2 << (bitend - bitstart)) - 1;
3007 switch (*c)
3009 case 'r':
3010 func (stream, "%s", arm_regnames[reg]);
3011 break;
3013 case 'd':
3014 func (stream, "%ld", reg);
3015 break;
3017 case 'H':
3018 func (stream, "%ld", reg << 1);
3019 break;
3021 case 'W':
3022 func (stream, "%ld", reg << 2);
3023 break;
3025 case 'a':
3026 /* PC-relative address -- the bottom two
3027 bits of the address are dropped
3028 before the calculation. */
3029 info->print_address_func
3030 (((pc + 4) & ~3) + (reg << 2), info);
3031 break;
3033 case 'x':
3034 func (stream, "0x%04lx", reg);
3035 break;
3037 case 'B':
3038 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3039 info->print_address_func (reg * 2 + pc + 4, info);
3040 break;
3042 case 'c':
3044 /* Must print 0xE as 'al' to distinguish
3045 unconditional B from conditional BAL. */
3046 if (reg == 0xE)
3047 func (stream, "al");
3048 else
3049 func (stream, "%s", arm_conditional [reg]);
3051 break;
3053 default:
3054 abort ();
3057 break;
3059 case '\'':
3060 c++;
3061 if ((given & (1 << bitstart)) != 0)
3062 func (stream, "%c", *c);
3063 break;
3065 case '?':
3066 ++c;
3067 if ((given & (1 << bitstart)) != 0)
3068 func (stream, "%c", *c++);
3069 else
3070 func (stream, "%c", *++c);
3071 break;
3073 default:
3074 abort ();
3077 break;
3079 default:
3080 abort ();
3083 return;
3086 /* No match. */
3087 abort ();
3090 /* Return the name of an V7M special register. */
3091 static const char *
3092 psr_name (int regno)
3094 switch (regno)
3096 case 0: return "APSR";
3097 case 1: return "IAPSR";
3098 case 2: return "EAPSR";
3099 case 3: return "PSR";
3100 case 5: return "IPSR";
3101 case 6: return "EPSR";
3102 case 7: return "IEPSR";
3103 case 8: return "MSP";
3104 case 9: return "PSP";
3105 case 16: return "PRIMASK";
3106 case 17: return "BASEPRI";
3107 case 18: return "BASEPRI_MASK";
3108 case 19: return "FAULTMASK";
3109 case 20: return "CONTROL";
3110 default: return "<unknown>";
3114 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3116 static void
3117 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3119 const struct opcode32 *insn;
3120 void *stream = info->stream;
3121 fprintf_ftype func = info->fprintf_func;
3123 if (print_insn_coprocessor (pc, info, given, TRUE))
3124 return;
3126 if (print_insn_neon (info, given, TRUE))
3127 return;
3129 for (insn = thumb32_opcodes; insn->assembler; insn++)
3130 if ((given & insn->mask) == insn->value)
3132 const char *c = insn->assembler;
3133 for (; *c; c++)
3135 if (*c != '%')
3137 func (stream, "%c", *c);
3138 continue;
3141 switch (*++c)
3143 case '%':
3144 func (stream, "%%");
3145 break;
3147 case 'I':
3149 unsigned int imm12 = 0;
3150 imm12 |= (given & 0x000000ffu);
3151 imm12 |= (given & 0x00007000u) >> 4;
3152 imm12 |= (given & 0x04000000u) >> 15;
3153 func (stream, "#%u\t; 0x%x", imm12, imm12);
3155 break;
3157 case 'M':
3159 unsigned int bits = 0, imm, imm8, mod;
3160 bits |= (given & 0x000000ffu);
3161 bits |= (given & 0x00007000u) >> 4;
3162 bits |= (given & 0x04000000u) >> 15;
3163 imm8 = (bits & 0x0ff);
3164 mod = (bits & 0xf00) >> 8;
3165 switch (mod)
3167 case 0: imm = imm8; break;
3168 case 1: imm = ((imm8<<16) | imm8); break;
3169 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3170 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3171 default:
3172 mod = (bits & 0xf80) >> 7;
3173 imm8 = (bits & 0x07f) | 0x80;
3174 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3176 func (stream, "#%u\t; 0x%x", imm, imm);
3178 break;
3180 case 'J':
3182 unsigned int imm = 0;
3183 imm |= (given & 0x000000ffu);
3184 imm |= (given & 0x00007000u) >> 4;
3185 imm |= (given & 0x04000000u) >> 15;
3186 imm |= (given & 0x000f0000u) >> 4;
3187 func (stream, "#%u\t; 0x%x", imm, imm);
3189 break;
3191 case 'K':
3193 unsigned int imm = 0;
3194 imm |= (given & 0x000f0000u) >> 16;
3195 imm |= (given & 0x00000ff0u) >> 0;
3196 imm |= (given & 0x0000000fu) << 12;
3197 func (stream, "#%u\t; 0x%x", imm, imm);
3199 break;
3201 case 'S':
3203 unsigned int reg = (given & 0x0000000fu);
3204 unsigned int stp = (given & 0x00000030u) >> 4;
3205 unsigned int imm = 0;
3206 imm |= (given & 0x000000c0u) >> 6;
3207 imm |= (given & 0x00007000u) >> 10;
3209 func (stream, "%s", arm_regnames[reg]);
3210 switch (stp)
3212 case 0:
3213 if (imm > 0)
3214 func (stream, ", lsl #%u", imm);
3215 break;
3217 case 1:
3218 if (imm == 0)
3219 imm = 32;
3220 func (stream, ", lsr #%u", imm);
3221 break;
3223 case 2:
3224 if (imm == 0)
3225 imm = 32;
3226 func (stream, ", asr #%u", imm);
3227 break;
3229 case 3:
3230 if (imm == 0)
3231 func (stream, ", rrx");
3232 else
3233 func (stream, ", ror #%u", imm);
3236 break;
3238 case 'a':
3240 unsigned int Rn = (given & 0x000f0000) >> 16;
3241 unsigned int U = (given & 0x00800000) >> 23;
3242 unsigned int op = (given & 0x00000f00) >> 8;
3243 unsigned int i12 = (given & 0x00000fff);
3244 unsigned int i8 = (given & 0x000000ff);
3245 bfd_boolean writeback = FALSE, postind = FALSE;
3246 int offset = 0;
3248 func (stream, "[%s", arm_regnames[Rn]);
3249 if (U) /* 12-bit positive immediate offset */
3250 offset = i12;
3251 else if (Rn == 15) /* 12-bit negative immediate offset */
3252 offset = -(int)i12;
3253 else if (op == 0x0) /* shifted register offset */
3255 unsigned int Rm = (i8 & 0x0f);
3256 unsigned int sh = (i8 & 0x30) >> 4;
3257 func (stream, ", %s", arm_regnames[Rm]);
3258 if (sh)
3259 func (stream, ", lsl #%u", sh);
3260 func (stream, "]");
3261 break;
3263 else switch (op)
3265 case 0xE: /* 8-bit positive immediate offset */
3266 offset = i8;
3267 break;
3269 case 0xC: /* 8-bit negative immediate offset */
3270 offset = -i8;
3271 break;
3273 case 0xF: /* 8-bit + preindex with wb */
3274 offset = i8;
3275 writeback = TRUE;
3276 break;
3278 case 0xD: /* 8-bit - preindex with wb */
3279 offset = -i8;
3280 writeback = TRUE;
3281 break;
3283 case 0xB: /* 8-bit + postindex */
3284 offset = i8;
3285 postind = TRUE;
3286 break;
3288 case 0x9: /* 8-bit - postindex */
3289 offset = -i8;
3290 postind = TRUE;
3291 break;
3293 default:
3294 func (stream, ", <undefined>]");
3295 goto skip;
3298 if (postind)
3299 func (stream, "], #%d", offset);
3300 else
3302 if (offset)
3303 func (stream, ", #%d", offset);
3304 func (stream, writeback ? "]!" : "]");
3307 if (Rn == 15)
3309 func (stream, "\t; ");
3310 info->print_address_func (((pc + 4) & ~3) + offset, info);
3313 skip:
3314 break;
3316 case 'A':
3318 unsigned int P = (given & 0x01000000) >> 24;
3319 unsigned int U = (given & 0x00800000) >> 23;
3320 unsigned int W = (given & 0x00400000) >> 21;
3321 unsigned int Rn = (given & 0x000f0000) >> 16;
3322 unsigned int off = (given & 0x000000ff);
3324 func (stream, "[%s", arm_regnames[Rn]);
3325 if (P)
3327 if (off || !U)
3328 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3329 func (stream, "]");
3330 if (W)
3331 func (stream, "!");
3333 else
3335 func (stream, "], ");
3336 if (W)
3337 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3338 else
3339 func (stream, "{%u}", off);
3342 break;
3344 case 'w':
3346 unsigned int Sbit = (given & 0x01000000) >> 24;
3347 unsigned int type = (given & 0x00600000) >> 21;
3348 switch (type)
3350 case 0: func (stream, Sbit ? "sb" : "b"); break;
3351 case 1: func (stream, Sbit ? "sh" : "h"); break;
3352 case 2:
3353 if (Sbit)
3354 func (stream, "??");
3355 break;
3356 case 3:
3357 func (stream, "??");
3358 break;
3361 break;
3363 case 'm':
3365 int started = 0;
3366 int reg;
3368 func (stream, "{");
3369 for (reg = 0; reg < 16; reg++)
3370 if ((given & (1 << reg)) != 0)
3372 if (started)
3373 func (stream, ", ");
3374 started = 1;
3375 func (stream, "%s", arm_regnames[reg]);
3377 func (stream, "}");
3379 break;
3381 case 'E':
3383 unsigned int msb = (given & 0x0000001f);
3384 unsigned int lsb = 0;
3385 lsb |= (given & 0x000000c0u) >> 6;
3386 lsb |= (given & 0x00007000u) >> 10;
3387 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3389 break;
3391 case 'F':
3393 unsigned int width = (given & 0x0000001f) + 1;
3394 unsigned int lsb = 0;
3395 lsb |= (given & 0x000000c0u) >> 6;
3396 lsb |= (given & 0x00007000u) >> 10;
3397 func (stream, "#%u, #%u", lsb, width);
3399 break;
3401 case 'b':
3403 unsigned int S = (given & 0x04000000u) >> 26;
3404 unsigned int J1 = (given & 0x00002000u) >> 13;
3405 unsigned int J2 = (given & 0x00000800u) >> 11;
3406 int offset = 0;
3408 offset |= !S << 20;
3409 offset |= J2 << 19;
3410 offset |= J1 << 18;
3411 offset |= (given & 0x003f0000) >> 4;
3412 offset |= (given & 0x000007ff) << 1;
3413 offset -= (1 << 20);
3415 info->print_address_func (pc + 4 + offset, info);
3417 break;
3419 case 'B':
3421 unsigned int S = (given & 0x04000000u) >> 26;
3422 unsigned int I1 = (given & 0x00002000u) >> 13;
3423 unsigned int I2 = (given & 0x00000800u) >> 11;
3424 int offset = 0;
3426 offset |= !S << 24;
3427 offset |= !(I1 ^ S) << 23;
3428 offset |= !(I2 ^ S) << 22;
3429 offset |= (given & 0x03ff0000u) >> 4;
3430 offset |= (given & 0x000007ffu) << 1;
3431 offset -= (1 << 24);
3432 offset += pc + 4;
3434 /* BLX target addresses are always word aligned. */
3435 if ((given & 0x00001000u) == 0)
3436 offset &= ~2u;
3438 info->print_address_func (offset, info);
3440 break;
3442 case 's':
3444 unsigned int shift = 0;
3445 shift |= (given & 0x000000c0u) >> 6;
3446 shift |= (given & 0x00007000u) >> 10;
3447 if (given & 0x00200000u)
3448 func (stream, ", asr #%u", shift);
3449 else if (shift)
3450 func (stream, ", lsl #%u", shift);
3451 /* else print nothing - lsl #0 */
3453 break;
3455 case 'R':
3457 unsigned int rot = (given & 0x00000030) >> 4;
3458 if (rot)
3459 func (stream, ", ror #%u", rot * 8);
3461 break;
3463 case 'U':
3464 switch (given & 0xf)
3466 case 0xf: func(stream, "sy"); break;
3467 case 0x7: func(stream, "un"); break;
3468 case 0xe: func(stream, "st"); break;
3469 case 0x6: func(stream, "unst"); break;
3470 default:
3471 func(stream, "#%d", (int)given & 0xf);
3472 break;
3474 break;
3476 case 'C':
3477 if ((given & 0xff) == 0)
3479 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3480 if (given & 0x800)
3481 func (stream, "f");
3482 if (given & 0x400)
3483 func (stream, "s");
3484 if (given & 0x200)
3485 func (stream, "x");
3486 if (given & 0x100)
3487 func (stream, "c");
3489 else
3491 func (stream, psr_name (given & 0xff));
3493 break;
3495 case 'D':
3496 if ((given & 0xff) == 0)
3497 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3498 else
3499 func (stream, psr_name (given & 0xff));
3500 break;
3502 case '0': case '1': case '2': case '3': case '4':
3503 case '5': case '6': case '7': case '8': case '9':
3505 int width;
3506 unsigned long val;
3508 c = arm_decode_bitfield (c, given, &val, &width);
3510 switch (*c)
3512 case 'd': func (stream, "%lu", val); break;
3513 case 'W': func (stream, "%lu", val * 4); break;
3514 case 'r': func (stream, "%s", arm_regnames[val]); break;
3516 case 'c':
3517 if (val == 0xE)
3518 func (stream, "al");
3519 else
3520 func (stream, "%s", arm_conditional[val]);
3521 break;
3523 case '\'':
3524 c++;
3525 if (val == ((1ul << width) - 1))
3526 func (stream, "%c", *c);
3527 break;
3529 case '`':
3530 c++;
3531 if (val == 0)
3532 func (stream, "%c", *c);
3533 break;
3535 case '?':
3536 func (stream, "%c", c[(1 << width) - (int)val]);
3537 c += 1 << width;
3538 break;
3540 default:
3541 abort ();
3544 break;
3546 default:
3547 abort ();
3550 return;
3553 /* No match. */
3554 abort ();
3557 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3558 being displayed in symbol relative addresses. */
3560 bfd_boolean
3561 arm_symbol_is_valid (asymbol * sym,
3562 struct disassemble_info * info ATTRIBUTE_UNUSED)
3564 const char * name;
3566 if (sym == NULL)
3567 return FALSE;
3569 name = bfd_asymbol_name (sym);
3571 return (name && *name != '$');
3574 /* Parse an individual disassembler option. */
3576 void
3577 parse_arm_disassembler_option (char *option)
3579 if (option == NULL)
3580 return;
3582 if (strneq (option, "reg-names-", 10))
3584 int i;
3586 option += 10;
3588 for (i = NUM_ARM_REGNAMES; i--;)
3589 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3591 regname_selected = i;
3592 break;
3595 if (i < 0)
3596 /* XXX - should break 'option' at following delimiter. */
3597 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3599 else if (strneq (option, "force-thumb", 11))
3600 force_thumb = 1;
3601 else if (strneq (option, "no-force-thumb", 14))
3602 force_thumb = 0;
3603 else
3604 /* XXX - should break 'option' at following delimiter. */
3605 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3607 return;
3610 /* Parse the string of disassembler options, spliting it at whitespaces
3611 or commas. (Whitespace separators supported for backwards compatibility). */
3613 static void
3614 parse_disassembler_options (char *options)
3616 if (options == NULL)
3617 return;
3619 while (*options)
3621 parse_arm_disassembler_option (options);
3623 /* Skip forward to next seperator. */
3624 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3625 ++ options;
3626 /* Skip forward past seperators. */
3627 while (ISSPACE (*options) || (*options == ','))
3628 ++ options;
3632 /* NOTE: There are no checks in these routines that
3633 the relevant number of data bytes exist. */
3635 static int
3636 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3638 unsigned char b[4];
3639 long given;
3640 int status;
3641 int is_thumb;
3642 int size;
3643 void (*printer) (bfd_vma, struct disassemble_info *, long);
3645 if (info->disassembler_options)
3647 parse_disassembler_options (info->disassembler_options);
3649 /* To avoid repeated parsing of these options, we remove them here. */
3650 info->disassembler_options = NULL;
3653 is_thumb = force_thumb;
3655 if (!is_thumb && info->symbols != NULL)
3657 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3659 coff_symbol_type * cs;
3661 cs = coffsymbol (*info->symbols);
3662 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
3663 || cs->native->u.syment.n_sclass == C_THUMBSTAT
3664 || cs->native->u.syment.n_sclass == C_THUMBLABEL
3665 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
3666 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
3668 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
3670 elf_symbol_type * es;
3671 unsigned int type;
3673 es = *(elf_symbol_type **)(info->symbols);
3674 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3676 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
3680 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
3681 info->bytes_per_line = 4;
3683 if (!is_thumb)
3685 /* In ARM mode endianness is a straightforward issue: the instruction
3686 is four bytes long and is either ordered 0123 or 3210. */
3687 printer = print_insn_arm;
3688 info->bytes_per_chunk = 4;
3689 size = 4;
3691 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
3692 if (little)
3693 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
3694 else
3695 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
3697 else
3699 /* In Thumb mode we have the additional wrinkle of two
3700 instruction lengths. Fortunately, the bits that determine
3701 the length of the current instruction are always to be found
3702 in the first two bytes. */
3703 printer = print_insn_thumb16;
3704 info->bytes_per_chunk = 2;
3705 size = 2;
3707 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
3708 if (little)
3709 given = (b[0]) | (b[1] << 8);
3710 else
3711 given = (b[1]) | (b[0] << 8);
3713 if (!status)
3715 /* These bit patterns signal a four-byte Thumb
3716 instruction. */
3717 if ((given & 0xF800) == 0xF800
3718 || (given & 0xF800) == 0xF000
3719 || (given & 0xF800) == 0xE800)
3721 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
3722 if (little)
3723 given = (b[0]) | (b[1] << 8) | (given << 16);
3724 else
3725 given = (b[1]) | (b[0] << 8) | (given << 16);
3727 printer = print_insn_thumb32;
3728 size = 4;
3733 if (status)
3735 info->memory_error_func (status, pc, info);
3736 return -1;
3738 if (info->flags & INSN_HAS_RELOC)
3739 /* If the instruction has a reloc associated with it, then
3740 the offset field in the instruction will actually be the
3741 addend for the reloc. (We are using REL type relocs).
3742 In such cases, we can ignore the pc when computing
3743 addresses, since the addend is not currently pc-relative. */
3744 pc = 0;
3746 printer (pc, info, given);
3747 return size;
3751 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3753 return print_insn (pc, info, FALSE);
3757 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3759 return print_insn (pc, info, TRUE);
3762 void
3763 print_arm_disassembler_options (FILE *stream)
3765 int i;
3767 fprintf (stream, _("\n\
3768 The following ARM specific disassembler options are supported for use with\n\
3769 the -M switch:\n"));
3771 for (i = NUM_ARM_REGNAMES; i--;)
3772 fprintf (stream, " reg-names-%s %*c%s\n",
3773 regnames[i].name,
3774 (int)(14 - strlen (regnames[i].name)), ' ',
3775 regnames[i].description);
3777 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
3778 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");