remove some duplicate #include's.
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
... / ...
CommitLineData
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)
6
7 This file is part of libopcodes.
8
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
13
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
22
23#include "sysdep.h"
24
25#include "dis-asm.h"
26#include "opcode/arm.h"
27#include "opintl.h"
28#include "safe-ctype.h"
29#include "floatformat.h"
30
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"
37
38/* FIXME: Belongs in global header. */
39#ifndef strneq
40#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
41#endif
42
43#ifndef NUM_ELEM
44#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
45#endif
46
47struct opcode32
48{
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. */
52};
53
54struct opcode16
55{
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. */
59};
60
61/* print_insn_coprocessor recognizes the following format control codes:
62
63 %% %
64
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
74
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
87
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
92
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
96
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. */
101
102/* Common coprocessor opcodes shared between Arm and Thumb-2. */
103
104static const struct opcode32 coprocessor_opcodes[] =
105{
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"},
112
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"},
165
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"},
210
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"},
218
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]"},
234
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"},
315
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"},
401
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"},
410
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"},
414
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}"},
421
422 {0, 0, 0, 0}
423};
424
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. */
428
429/* print_insn_neon recognizes the following format control codes:
430
431 %% %
432
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
439
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
449
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 */
453
454static const struct opcode32 neon_opcodes[] =
455{
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"},
459
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]"},
464
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"},
468
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"},
503
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"},
558
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"},
573
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"},
633
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"},
652
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"},
676
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"},
697
698 {0,0 ,0, 0}
699};
700
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. */
704
705/* print_insn_arm recognizes the following format control codes:
706
707 %% %
708
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.
721
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"
727
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
731
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. */
735
736static const struct opcode32 arm_opcodes[] =
737{
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"},
746
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"},
753
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"},
764
765 /* ARM V6Z instructions. */
766 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
767
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]"},
776
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}"},
783
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"},
907
908 /* V5J instruction. */
909 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
910
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"},
916
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"},
925
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"},
928
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"},
933
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"},
938
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"},
941
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"},
946
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"},
977
978 /* The rest. */
979 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
980 {0, 0x00000000, 0x00000000, 0}
981};
982
983/* print_insn_thumb16 recognizes the following format control codes:
984
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. */
1003
1004static const struct opcode16 thumb_opcodes[] =
1005{
1006 /* Thumb instructions. */
1007
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}"},
1015
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"},
1026
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"},
1039
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"},
1120
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}
1127};
1128
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.
1132
1133 print_insn_thumb32 recognizes the following format control codes:
1134
1135 %% %
1136
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
1142
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
1146
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.
1155
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
1160
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
1164
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. */
1173static const struct opcode32 thumb32_opcodes[] =
1174{
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"},
1183
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}"},
1191
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"},
1362
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"},
1368
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"},
1372
1373 /* Fallback. */
1374 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1375 {0, 0, 0, 0}
1376};
1377
1378static const char *const arm_conditional[] =
1379{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1380 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1381
1382static const char *const arm_fp_const[] =
1383{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1384
1385static const char *const arm_shift[] =
1386{"lsl", "lsr", "asr", "ror"};
1387
1388typedef struct
1389{
1390 const char *name;
1391 const char *description;
1392 const char *reg_names[16];
1393}
1394arm_regname;
1395
1396static const arm_regname regnames[] =
1397{
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" }},
1410};
1411
1412static const char *const iwmmxt_wwnames[] =
1413{"b", "h", "w", "d"};
1414
1415static 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"
1420};
1421
1422static const char *const iwmmxt_regnames[] =
1423{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1424 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1425};
1426
1427static const char *const iwmmxt_cregnames[] =
1428{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1429 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1430};
1431
1432/* Default to GCC register name set. */
1433static unsigned int regname_selected = 1;
1434
1435#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1436#define arm_regnames regnames[regname_selected].reg_names
1437
1438static bfd_boolean force_thumb = FALSE;
1439
1440\f
1441/* Functions. */
1442int
1443get_arm_regname_num_options (void)
1444{
1445 return NUM_ARM_REGNAMES;
1446}
1447
1448int
1449set_arm_regname_option (int option)
1450{
1451 int old = regname_selected;
1452 regname_selected = option;
1453 return old;
1454}
1455
1456int
1457get_arm_regnames (int option, const char **setname, const char **setdescription,
1458 const char *const **register_names)
1459{
1460 *setname = regnames[option].name;
1461 *setdescription = regnames[option].description;
1462 *register_names = regnames[option].reg_names;
1463 return 16;
1464}
1465
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. */
1470
1471static const char *
1472arm_decode_bitfield (const char *ptr, unsigned long insn,
1473 unsigned long *valuep, int *widthp)
1474{
1475 unsigned long value = 0;
1476 int width = 0;
1477
1478 do
1479 {
1480 int start, end;
1481 int bits;
1482
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;
1495 }
1496 while (*ptr++ == ',');
1497 *valuep = value;
1498 if (widthp)
1499 *widthp = width;
1500 return ptr - 1;
1501}
1502
1503static void
1504arm_decode_shift (long given, fprintf_ftype func, void *stream)
1505{
1506 func (stream, "%s", arm_regnames[given & 0xf]);
1507
1508 if ((given & 0xff0) != 0)
1509 {
1510 if ((given & 0x10) == 0)
1511 {
1512 int amount = (given & 0xf80) >> 7;
1513 int shift = (given & 0x60) >> 5;
1514
1515 if (amount == 0)
1516 {
1517 if (shift == 3)
1518 {
1519 func (stream, ", rrx");
1520 return;
1521 }
1522
1523 amount = 32;
1524 }
1525
1526 func (stream, ", %s #%d", arm_shift[shift], amount);
1527 }
1528 else
1529 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1530 arm_regnames[(given & 0xf00) >> 8]);
1531 }
1532}
1533
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. */
1537
1538static bfd_boolean
1539print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1540 bfd_boolean thumb)
1541{
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;
1547
1548 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1549 {
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;
1554
1555 mask = insn->mask;
1556 value = insn->value;
1557 if (thumb)
1558 {
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;
1564 }
1565 else
1566 {
1567 /* Only match unconditional instuctions against unconditional
1568 patterns. */
1569 if ((given & 0xf0000000) == 0xf0000000)
1570 mask |= 0xf0000000;
1571 }
1572 if ((given & mask) == value)
1573 {
1574 const char *c;
1575
1576 for (c = insn->assembler; *c; c++)
1577 {
1578 if (*c == '%')
1579 {
1580 switch (*++c)
1581 {
1582 case '%':
1583 func (stream, "%%");
1584 break;
1585
1586 case 'A':
1587 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1588
1589 if ((given & (1 << 24)) != 0)
1590 {
1591 int offset = given & 0xff;
1592
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, "]");
1600 }
1601 else
1602 {
1603 int offset = given & 0xff;
1604
1605 func (stream, "]");
1606
1607 if (given & (1 << 21))
1608 {
1609 if (offset)
1610 func (stream, ", #%s%d",
1611 ((given & 0x00800000) == 0 ? "-" : ""),
1612 offset * 4);
1613 }
1614 else
1615 func (stream, ", {%d}", offset);
1616 }
1617 break;
1618
1619 case 'B':
1620 {
1621 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1622 int offset = (given >> 1) & 0x3f;
1623
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);
1630 }
1631 break;
1632
1633 case 'C':
1634 {
1635 int rn = (given >> 16) & 0xf;
1636 int offset = (given & 0xff) * 4;
1637 int add = (given >> 23) & 1;
1638
1639 func (stream, "[%s", arm_regnames[rn]);
1640
1641 if (offset)
1642 {
1643 if (!add)
1644 offset = -offset;
1645 func (stream, ", #%d", offset);
1646 }
1647 func (stream, "]");
1648 if (rn == 15)
1649 {
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);
1655 }
1656 }
1657 break;
1658
1659 case 'c':
1660 func (stream, "%s",
1661 arm_conditional [(given >> 28) & 0xf]);
1662 break;
1663
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. */
1669 {
1670 int imm;
1671
1672 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1673
1674 /* Is ``imm'' a negative number? */
1675 if (imm & 0x40)
1676 imm |= (-1 << 7);
1677
1678 func (stream, "%d", imm);
1679 }
1680
1681 break;
1682
1683 case 'F':
1684 switch (given & 0x00408000)
1685 {
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");
1697 }
1698 break;
1699
1700 case 'P':
1701 switch (given & 0x00080080)
1702 {
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;
1715 }
1716 break;
1717 case 'Q':
1718 switch (given & 0x00408000)
1719 {
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;
1732 }
1733 break;
1734 case 'R':
1735 switch (given & 0x60)
1736 {
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;
1748 }
1749 break;
1750
1751 case '0': case '1': case '2': case '3': case '4':
1752 case '5': case '6': case '7': case '8': case '9':
1753 {
1754 int width;
1755 unsigned long value;
1756
1757 c = arm_decode_bitfield (c, given, &value, &width);
1758
1759 switch (*c)
1760 {
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':
1777 {
1778 int from = (given & (1 << 7)) ? 32 : 16;
1779 func (stream, "%ld", from - value);
1780 }
1781 break;
1782
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;
1789
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;
1796
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 ();
1819 }
1820 break;
1821
1822 case 'y':
1823 case 'z':
1824 {
1825 int single = *c++ == 'y';
1826 int regno;
1827
1828 switch (*c)
1829 {
1830 case '4': /* Sm pair */
1831 func (stream, "{");
1832 /* Fall through. */
1833 case '0': /* Sm, Dm */
1834 regno = given & 0x0000000f;
1835 if (single)
1836 {
1837 regno <<= 1;
1838 regno += (given >> 5) & 1;
1839 }
1840 else
1841 regno += ((given >> 5) & 1) << 4;
1842 break;
1843
1844 case '1': /* Sd, Dd */
1845 regno = (given >> 12) & 0x0000000f;
1846 if (single)
1847 {
1848 regno <<= 1;
1849 regno += (given >> 22) & 1;
1850 }
1851 else
1852 regno += ((given >> 22) & 1) << 4;
1853 break;
1854
1855 case '2': /* Sn, Dn */
1856 regno = (given >> 16) & 0x0000000f;
1857 if (single)
1858 {
1859 regno <<= 1;
1860 regno += (given >> 7) & 1;
1861 }
1862 else
1863 regno += ((given >> 7) & 1) << 4;
1864 break;
1865
1866 case '3': /* List */
1867 func (stream, "{");
1868 regno = (given >> 12) & 0x0000000f;
1869 if (single)
1870 {
1871 regno <<= 1;
1872 regno += (given >> 22) & 1;
1873 }
1874 else
1875 regno += ((given >> 22) & 1) << 4;
1876 break;
1877
1878 default:
1879 abort ();
1880 }
1881
1882 func (stream, "%c%d", single ? 's' : 'd', regno);
1883
1884 if (*c == '3')
1885 {
1886 int count = given & 0xff;
1887
1888 if (single == 0)
1889 count >>= 1;
1890
1891 if (--count)
1892 {
1893 func (stream, "-%c%d",
1894 single ? 's' : 'd',
1895 regno + count);
1896 }
1897
1898 func (stream, "}");
1899 }
1900 else if (*c == '4')
1901 func (stream, ", %c%d}", single ? 's' : 'd',
1902 regno + 1);
1903 }
1904 break;
1905
1906 case 'L':
1907 switch (given & 0x00400100)
1908 {
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;
1915 }
1916 break;
1917
1918 case 'Z':
1919 {
1920 int value;
1921 /* given (20, 23) | given (0, 3) */
1922 value = ((given >> 16) & 0xf0) | (given & 0xf);
1923 func (stream, "%d", value);
1924 }
1925 break;
1926
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. */
1931 {
1932 int offset = given & 0xff;
1933 int multiplier = (given & 0x00000100) ? 4 : 1;
1934
1935 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1936
1937 if (offset)
1938 {
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);
1948 }
1949 else
1950 func (stream, "]");
1951 }
1952 break;
1953
1954 default:
1955 abort ();
1956 }
1957 }
1958 }
1959 else
1960 func (stream, "%c", *c);
1961 }
1962 return TRUE;
1963 }
1964 }
1965 return FALSE;
1966}
1967
1968static void
1969print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
1970{
1971 void *stream = info->stream;
1972 fprintf_ftype func = info->fprintf_func;
1973
1974 if (((given & 0x000f0000) == 0x000f0000)
1975 && ((given & 0x02000000) == 0))
1976 {
1977 int offset = given & 0xfff;
1978
1979 func (stream, "[pc");
1980
1981 if (given & 0x01000000)
1982 {
1983 if ((given & 0x00800000) == 0)
1984 offset = - offset;
1985
1986 /* Pre-indexed. */
1987 func (stream, ", #%d]", offset);
1988
1989 offset += pc + 8;
1990
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, "!");
1997 }
1998 else
1999 {
2000 /* Post indexed. */
2001 func (stream, "], #%d", offset);
2002
2003 /* ie ignore the offset. */
2004 offset = pc + 8;
2005 }
2006
2007 func (stream, "\t; ");
2008 info->print_address_func (offset, info);
2009 }
2010 else
2011 {
2012 func (stream, "[%s",
2013 arm_regnames[(given >> 16) & 0xf]);
2014 if ((given & 0x01000000) != 0)
2015 {
2016 if ((given & 0x02000000) == 0)
2017 {
2018 int offset = given & 0xfff;
2019 if (offset)
2020 func (stream, ", #%s%d",
2021 (((given & 0x00800000) == 0)
2022 ? "-" : ""), offset);
2023 }
2024 else
2025 {
2026 func (stream, ", %s",
2027 (((given & 0x00800000) == 0)
2028 ? "-" : ""));
2029 arm_decode_shift (given, func, stream);
2030 }
2031
2032 func (stream, "]%s",
2033 ((given & 0x00200000) != 0) ? "!" : "");
2034 }
2035 else
2036 {
2037 if ((given & 0x02000000) == 0)
2038 {
2039 int offset = given & 0xfff;
2040 if (offset)
2041 func (stream, "], #%s%d",
2042 (((given & 0x00800000) == 0)
2043 ? "-" : ""), offset);
2044 else
2045 func (stream, "]");
2046 }
2047 else
2048 {
2049 func (stream, "], %s",
2050 (((given & 0x00800000) == 0)
2051 ? "-" : ""));
2052 arm_decode_shift (given, func, stream);
2053 }
2054 }
2055 }
2056}
2057
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. */
2061
2062static bfd_boolean
2063print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2064{
2065 const struct opcode32 *insn;
2066 void *stream = info->stream;
2067 fprintf_ftype func = info->fprintf_func;
2068
2069 if (thumb)
2070 {
2071 if ((given & 0xef000000) == 0xef000000)
2072 {
2073 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2074 unsigned long bit28 = given & (1 << 28);
2075
2076 given &= 0x00ffffff;
2077 if (bit28)
2078 given |= 0xf3000000;
2079 else
2080 given |= 0xf2000000;
2081 }
2082 else if ((given & 0xff000000) == 0xf9000000)
2083 given ^= 0xf9000000 ^ 0xf4000000;
2084 else
2085 return FALSE;
2086 }
2087
2088 for (insn = neon_opcodes; insn->assembler; insn++)
2089 {
2090 if ((given & insn->mask) == insn->value)
2091 {
2092 const char *c;
2093
2094 for (c = insn->assembler; *c; c++)
2095 {
2096 if (*c == '%')
2097 {
2098 switch (*++c)
2099 {
2100 case '%':
2101 func (stream, "%%");
2102 break;
2103
2104 case 'A':
2105 {
2106 static const unsigned char enc[16] =
2107 {
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
2119 };
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;
2128
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]);
2145 }
2146 break;
2147
2148 case 'B':
2149 {
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;
2160
2161 if (length > 1 && size > 0)
2162 stride = (idx_align & (1 << size)) ? 2 : 1;
2163
2164 switch (length)
2165 {
2166 case 1:
2167 {
2168 int amask = (1 << size) - 1;
2169 if ((idx_align & (1 << size)) != 0)
2170 return FALSE;
2171 if (size > 0)
2172 {
2173 if ((idx_align & amask) == amask)
2174 align = 8 << size;
2175 else if ((idx_align & amask) != 0)
2176 return FALSE;
2177 }
2178 }
2179 break;
2180
2181 case 2:
2182 if (size == 2 && (idx_align & 2) != 0)
2183 return FALSE;
2184 align = (idx_align & 1) ? 16 << size : 0;
2185 break;
2186
2187 case 3:
2188 if ((size == 2 && (idx_align & 3) != 0)
2189 || (idx_align & 1) != 0)
2190 return FALSE;
2191 break;
2192
2193 case 4:
2194 if (size == 2)
2195 {
2196 if ((idx_align & 3) == 3)
2197 return FALSE;
2198 align = (idx_align & 3) * 64;
2199 }
2200 else
2201 align = (idx_align & 1) ? 32 << size : 0;
2202 break;
2203
2204 default:
2205 abort ();
2206 }
2207
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]);
2220 }
2221 break;
2222
2223 case 'C':
2224 {
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;
2234
2235 if (stride && (n == 1))
2236 n++;
2237 else
2238 stride++;
2239
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)
2250 {
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);
2258 }
2259 func (stream, "]");
2260 if (rm == 0xd)
2261 func (stream, "!");
2262 else if (rm != 0xf)
2263 func (stream, ", %s", arm_regnames[rm]);
2264 }
2265 break;
2266
2267 case 'D':
2268 {
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;
2273
2274 func (stream, "d%d[%d]", reg, ix);
2275 }
2276 break;
2277
2278 case 'E':
2279 /* Neon encoded constant for mov, mvn, vorr, vbic */
2280 {
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;
2288
2289 bits |= ((given >> 24) & 1) << 7;
2290 bits |= ((given >> 16) & 7) << 4;
2291 bits |= ((given >> 0) & 15) << 0;
2292
2293 if (cmode < 8)
2294 {
2295 shift = (cmode >> 1) & 3;
2296 value = (unsigned long)bits << (8 * shift);
2297 size = 32;
2298 }
2299 else if (cmode < 12)
2300 {
2301 shift = (cmode >> 1) & 1;
2302 value = (unsigned long)bits << (8 * shift);
2303 size = 16;
2304 }
2305 else if (cmode < 14)
2306 {
2307 shift = (cmode & 1) + 1;
2308 value = (unsigned long)bits << (8 * shift);
2309 value |= (1ul << (8 * shift)) - 1;
2310 size = 32;
2311 }
2312 else if (cmode == 14)
2313 {
2314 if (op)
2315 {
2316 /* bit replication into bytes */
2317 int ix;
2318 unsigned long mask;
2319
2320 value = 0;
2321 hival = 0;
2322 for (ix = 7; ix >= 0; ix--)
2323 {
2324 mask = ((bits >> ix) & 1) ? 0xff : 0;
2325 if (ix <= 3)
2326 value = (value << 8) | mask;
2327 else
2328 hival = (hival << 8) | mask;
2329 }
2330 size = 64;
2331 }
2332 else
2333 {
2334 /* byte replication */
2335 value = (unsigned long)bits;
2336 size = 8;
2337 }
2338 }
2339 else if (!op)
2340 {
2341 /* floating point encoding */
2342 int tmp;
2343
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;
2350 }
2351 else
2352 {
2353 func (stream, "<illegal constant %.8x:%x:%x>",
2354 bits, cmode, op);
2355 size = 32;
2356 break;
2357 }
2358 switch (size)
2359 {
2360 case 8:
2361 func (stream, "#%ld\t; 0x%.2lx", value, value);
2362 break;
2363
2364 case 16:
2365 func (stream, "#%ld\t; 0x%.4lx", value, value);
2366 break;
2367
2368 case 32:
2369 if (isfloat)
2370 {
2371 unsigned char valbytes[4];
2372 double fvalue;
2373
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;
2380
2381 floatformat_to_double
2382 (&floatformat_ieee_single_little, valbytes,
2383 &fvalue);
2384
2385 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2386 value);
2387 }
2388 else
2389 func (stream, "#%ld\t; 0x%.8lx", value, value);
2390 break;
2391
2392 case 64:
2393 func (stream, "#0x%.8lx%.8lx", hival, value);
2394 break;
2395
2396 default:
2397 abort ();
2398 }
2399 }
2400 break;
2401
2402 case 'F':
2403 {
2404 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2405 int num = (given >> 8) & 0x3;
2406
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);
2413 }
2414 break;
2415
2416
2417 case '0': case '1': case '2': case '3': case '4':
2418 case '5': case '6': case '7': case '8': case '9':
2419 {
2420 int width;
2421 unsigned long value;
2422
2423 c = arm_decode_bitfield (c, given, &value, &width);
2424
2425 switch (*c)
2426 {
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;
2436
2437 case 'S':
2438 case 'T':
2439 case 'U':
2440 /* various width encodings */
2441 {
2442 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2443 int limit;
2444 unsigned low, high;
2445
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;
2455
2456 if (value < low || value > high)
2457 func (stream, "<illegal width %d>", base << value);
2458 else
2459 func (stream, "%d", base << value);
2460 }
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':
2470 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;
2476
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 ();
2493 }
2494 break;
2495
2496 default:
2497 abort ();
2498 }
2499 }
2500 }
2501 else
2502 func (stream, "%c", *c);
2503 }
2504 return TRUE;
2505 }
2506 }
2507 return FALSE;
2508}
2509
2510/* Print one ARM instruction from PC on INFO->STREAM. */
2511
2512static void
2513print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2514{
2515 const struct opcode32 *insn;
2516 void *stream = info->stream;
2517 fprintf_ftype func = info->fprintf_func;
2518
2519 if (print_insn_coprocessor (pc, info, given, FALSE))
2520 return;
2521
2522 if (print_insn_neon (info, given, FALSE))
2523 return;
2524
2525 for (insn = arm_opcodes; insn->assembler; insn++)
2526 {
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;
2531
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)))
2539 {
2540 const char *c;
2541
2542 for (c = insn->assembler; *c; c++)
2543 {
2544 if (*c == '%')
2545 {
2546 switch (*++c)
2547 {
2548 case '%':
2549 func (stream, "%%");
2550 break;
2551
2552 case 'a':
2553 print_arm_address (pc, info, given);
2554 break;
2555
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;
2561
2562 case 's':
2563 if ((given & 0x004f0000) == 0x004f0000)
2564 {
2565 /* PC relative with immediate offset. */
2566 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2567
2568 if ((given & 0x00800000) == 0)
2569 offset = -offset;
2570
2571 func (stream, "[pc, #%d]\t; ", offset);
2572 info->print_address_func (offset + pc + 8, info);
2573 }
2574 else
2575 {
2576 func (stream, "[%s",
2577 arm_regnames[(given >> 16) & 0xf]);
2578 if ((given & 0x01000000) != 0)
2579 {
2580 /* Pre-indexed. */
2581 if ((given & 0x00400000) == 0x00400000)
2582 {
2583 /* Immediate. */
2584 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2585 if (offset)
2586 func (stream, ", #%s%d",
2587 (((given & 0x00800000) == 0)
2588 ? "-" : ""), offset);
2589 }
2590 else
2591 {
2592 /* Register. */
2593 func (stream, ", %s%s",
2594 (((given & 0x00800000) == 0)
2595 ? "-" : ""),
2596 arm_regnames[given & 0xf]);
2597 }
2598
2599 func (stream, "]%s",
2600 ((given & 0x00200000) != 0) ? "!" : "");
2601 }
2602 else
2603 {
2604 /* Post-indexed. */
2605 if ((given & 0x00400000) == 0x00400000)
2606 {
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, "]");
2615 }
2616 else
2617 {
2618 /* Register. */
2619 func (stream, "], %s%s",
2620 (((given & 0x00800000) == 0)
2621 ? "-" : ""),
2622 arm_regnames[given & 0xf]);
2623 }
2624 }
2625 }
2626 break;
2627
2628 case 'b':
2629 {
2630 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2631 info->print_address_func (disp*4 + pc + 8, info);
2632 }
2633 break;
2634
2635 case 'c':
2636 func (stream, "%s",
2637 arm_conditional [(given >> 28) & 0xf]);
2638 break;
2639
2640 case 'm':
2641 {
2642 int started = 0;
2643 int reg;
2644
2645 func (stream, "{");
2646 for (reg = 0; reg < 16; reg++)
2647 if ((given & (1 << reg)) != 0)
2648 {
2649 if (started)
2650 func (stream, ", ");
2651 started = 1;
2652 func (stream, "%s", arm_regnames[reg]);
2653 }
2654 func (stream, "}");
2655 }
2656 break;
2657
2658 case 'o':
2659 if ((given & 0x02000000) != 0)
2660 {
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);
2666 }
2667 else
2668 arm_decode_shift (given, func, stream);
2669 break;
2670
2671 case 'p':
2672 if ((given & 0x0000f000) == 0x0000f000)
2673 func (stream, "p");
2674 break;
2675
2676 case 't':
2677 if ((given & 0x01200000) == 0x00200000)
2678 func (stream, "t");
2679 break;
2680
2681 case 'A':
2682 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2683
2684 if ((given & (1 << 24)) != 0)
2685 {
2686 int offset = given & 0xff;
2687
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, "]");
2695 }
2696 else
2697 {
2698 int offset = given & 0xff;
2699
2700 func (stream, "]");
2701
2702 if (given & (1 << 21))
2703 {
2704 if (offset)
2705 func (stream, ", #%s%d",
2706 ((given & 0x00800000) == 0 ? "-" : ""),
2707 offset * 4);
2708 }
2709 else
2710 func (stream, ", {%d}", offset);
2711 }
2712 break;
2713
2714 case 'B':
2715 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2716 {
2717 bfd_vma address;
2718 bfd_vma offset = 0;
2719
2720 if (given & 0x00800000)
2721 /* Is signed, hi bits should be ones. */
2722 offset = (-1) ^ 0x00ffffff;
2723
2724 /* Offset is (SignExtend(offset field)<<2). */
2725 offset += given & 0x00ffffff;
2726 offset <<= 2;
2727 address = offset + pc + 8;
2728
2729 if (given & 0x01000000)
2730 /* H bit allows addressing to 2-byte boundaries. */
2731 address += 2;
2732
2733 info->print_address_func (address, info);
2734 }
2735 break;
2736
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;
2748
2749 case 'U':
2750 switch (given & 0xf)
2751 {
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;
2759 }
2760 break;
2761
2762 case '0': case '1': case '2': case '3': case '4':
2763 case '5': case '6': case '7': case '8': case '9':
2764 {
2765 int width;
2766 unsigned long value;
2767
2768 c = arm_decode_bitfield (c, given, &value, &width);
2769
2770 switch (*c)
2771 {
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);
2786
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 ();
2813 }
2814 break;
2815
2816 case 'e':
2817 {
2818 int imm;
2819
2820 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2821 func (stream, "%d", imm);
2822 }
2823 break;
2824
2825 case 'E':
2826 /* LSB and WIDTH fields of BFI or BFC. The machine-
2827 language instruction encodes LSB and MSB. */
2828 {
2829 long msb = (given & 0x001f0000) >> 16;
2830 long lsb = (given & 0x00000f80) >> 7;
2831
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);
2837 }
2838 break;
2839
2840 case 'V':
2841 /* 16-bit unsigned immediate from a MOVT or MOVW
2842 instruction, encoded in bits 0:11 and 15:19. */
2843 {
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);
2848 }
2849 break;
2850
2851 default:
2852 abort ();
2853 }
2854 }
2855 }
2856 else
2857 func (stream, "%c", *c);
2858 }
2859 return;
2860 }
2861 }
2862 abort ();
2863}
2864
2865/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2866
2867static void
2868print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2869{
2870 const struct opcode16 *insn;
2871 void *stream = info->stream;
2872 fprintf_ftype func = info->fprintf_func;
2873
2874 for (insn = thumb_opcodes; insn->assembler; insn++)
2875 if ((given & insn->mask) == insn->value)
2876 {
2877 const char *c = insn->assembler;
2878 for (; *c; c++)
2879 {
2880 int domaskpc = 0;
2881 int domasklr = 0;
2882
2883 if (*c != '%')
2884 {
2885 func (stream, "%c", *c);
2886 continue;
2887 }
2888
2889 switch (*++c)
2890 {
2891 case '%':
2892 func (stream, "%%");
2893 break;
2894
2895 case 'S':
2896 {
2897 long reg;
2898
2899 reg = (given >> 3) & 0x7;
2900 if (given & (1 << 6))
2901 reg += 8;
2902
2903 func (stream, "%s", arm_regnames[reg]);
2904 }
2905 break;
2906
2907 case 'D':
2908 {
2909 long reg;
2910
2911 reg = given & 0x7;
2912 if (given & (1 << 7))
2913 reg += 8;
2914
2915 func (stream, "%s", arm_regnames[reg]);
2916 }
2917 break;
2918
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':
2928 {
2929 int started = 0;
2930 int reg;
2931
2932 func (stream, "{");
2933
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)
2938 {
2939 if (started)
2940 func (stream, ", ");
2941 started = 1;
2942 func (stream, "%s", arm_regnames[reg]);
2943 }
2944
2945 if (domasklr)
2946 {
2947 if (started)
2948 func (stream, ", ");
2949 started = 1;
2950 func (stream, arm_regnames[14] /* "lr" */);
2951 }
2952
2953 if (domaskpc)
2954 {
2955 if (started)
2956 func (stream, ", ");
2957 func (stream, arm_regnames[15] /* "pc" */);
2958 }
2959
2960 func (stream, "}");
2961 }
2962 break;
2963
2964 case 'b':
2965 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
2966 {
2967 bfd_vma address = (pc + 4
2968 + ((given & 0x00f8) >> 2)
2969 + ((given & 0x0200) >> 3));
2970 info->print_address_func (address, info);
2971 }
2972 break;
2973
2974 case 's':
2975 /* Right shift immediate -- bits 6..10; 1-31 print
2976 as themselves, 0 prints as 32. */
2977 {
2978 long imm = (given & 0x07c0) >> 6;
2979 if (imm == 0)
2980 imm = 32;
2981 func (stream, "#%ld", imm);
2982 }
2983 break;
2984
2985 case '0': case '1': case '2': case '3': case '4':
2986 case '5': case '6': case '7': case '8': case '9':
2987 {
2988 int bitstart = *c++ - '0';
2989 int bitend = 0;
2990
2991 while (*c >= '0' && *c <= '9')
2992 bitstart = (bitstart * 10) + *c++ - '0';
2993
2994 switch (*c)
2995 {
2996 case '-':
2997 {
2998 long reg;
2999
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)
3008 {
3009 case 'r':
3010 func (stream, "%s", arm_regnames[reg]);
3011 break;
3012
3013 case 'd':
3014 func (stream, "%ld", reg);
3015 break;
3016
3017 case 'H':
3018 func (stream, "%ld", reg << 1);
3019 break;
3020
3021 case 'W':
3022 func (stream, "%ld", reg << 2);
3023 break;
3024
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;
3032
3033 case 'x':
3034 func (stream, "0x%04lx", reg);
3035 break;
3036
3037 case 'B':
3038 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3039 info->print_address_func (reg * 2 + pc + 4, info);
3040 break;
3041
3042 case 'c':
3043 {
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]);
3050 }
3051 break;
3052
3053 default:
3054 abort ();
3055 }
3056 }
3057 break;
3058
3059 case '\'':
3060 c++;
3061 if ((given & (1 << bitstart)) != 0)
3062 func (stream, "%c", *c);
3063 break;
3064
3065 case '?':
3066 ++c;
3067 if ((given & (1 << bitstart)) != 0)
3068 func (stream, "%c", *c++);
3069 else
3070 func (stream, "%c", *++c);
3071 break;
3072
3073 default:
3074 abort ();
3075 }
3076 }
3077 break;
3078
3079 default:
3080 abort ();
3081 }
3082 }
3083 return;
3084 }
3085
3086 /* No match. */
3087 abort ();
3088}
3089
3090/* Return the name of an V7M special register. */
3091static const char *
3092psr_name (int regno)
3093{
3094 switch (regno)
3095 {
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>";
3111 }
3112}
3113
3114/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3115
3116static void
3117print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3118{
3119 const struct opcode32 *insn;
3120 void *stream = info->stream;
3121 fprintf_ftype func = info->fprintf_func;
3122
3123 if (print_insn_coprocessor (pc, info, given, TRUE))
3124 return;
3125
3126 if (print_insn_neon (info, given, TRUE))
3127 return;
3128
3129 for (insn = thumb32_opcodes; insn->assembler; insn++)
3130 if ((given & insn->mask) == insn->value)
3131 {
3132 const char *c = insn->assembler;
3133 for (; *c; c++)
3134 {
3135 if (*c != '%')
3136 {
3137 func (stream, "%c", *c);
3138 continue;
3139 }
3140
3141 switch (*++c)
3142 {
3143 case '%':
3144 func (stream, "%%");
3145 break;
3146
3147 case 'I':
3148 {
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);
3154 }
3155 break;
3156
3157 case 'M':
3158 {
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)
3166 {
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);
3175 }
3176 func (stream, "#%u\t; 0x%x", imm, imm);
3177 }
3178 break;
3179
3180 case 'J':
3181 {
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);
3188 }
3189 break;
3190
3191 case 'K':
3192 {
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);
3198 }
3199 break;
3200
3201 case 'S':
3202 {
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;
3208
3209 func (stream, "%s", arm_regnames[reg]);
3210 switch (stp)
3211 {
3212 case 0:
3213 if (imm > 0)
3214 func (stream, ", lsl #%u", imm);
3215 break;
3216
3217 case 1:
3218 if (imm == 0)
3219 imm = 32;
3220 func (stream, ", lsr #%u", imm);
3221 break;
3222
3223 case 2:
3224 if (imm == 0)
3225 imm = 32;
3226 func (stream, ", asr #%u", imm);
3227 break;
3228
3229 case 3:
3230 if (imm == 0)
3231 func (stream, ", rrx");
3232 else
3233 func (stream, ", ror #%u", imm);
3234 }
3235 }
3236 break;
3237
3238 case 'a':
3239 {
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;
3247
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 */
3254 {
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;
3262 }
3263 else switch (op)
3264 {
3265 case 0xE: /* 8-bit positive immediate offset */
3266 offset = i8;
3267 break;
3268
3269 case 0xC: /* 8-bit negative immediate offset */
3270 offset = -i8;
3271 break;
3272
3273 case 0xF: /* 8-bit + preindex with wb */
3274 offset = i8;
3275 writeback = TRUE;
3276 break;
3277
3278 case 0xD: /* 8-bit - preindex with wb */
3279 offset = -i8;
3280 writeback = TRUE;
3281 break;
3282
3283 case 0xB: /* 8-bit + postindex */
3284 offset = i8;
3285 postind = TRUE;
3286 break;
3287
3288 case 0x9: /* 8-bit - postindex */
3289 offset = -i8;
3290 postind = TRUE;
3291 break;
3292
3293 default:
3294 func (stream, ", <undefined>]");
3295 goto skip;
3296 }
3297
3298 if (postind)
3299 func (stream, "], #%d", offset);
3300 else
3301 {
3302 if (offset)
3303 func (stream, ", #%d", offset);
3304 func (stream, writeback ? "]!" : "]");
3305 }
3306
3307 if (Rn == 15)
3308 {
3309 func (stream, "\t; ");
3310 info->print_address_func (((pc + 4) & ~3) + offset, info);
3311 }
3312 }
3313 skip:
3314 break;
3315
3316 case 'A':
3317 {
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);
3323
3324 func (stream, "[%s", arm_regnames[Rn]);
3325 if (P)
3326 {
3327 if (off || !U)
3328 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3329 func (stream, "]");
3330 if (W)
3331 func (stream, "!");
3332 }
3333 else
3334 {
3335 func (stream, "], ");
3336 if (W)
3337 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3338 else
3339 func (stream, "{%u}", off);
3340 }
3341 }
3342 break;
3343
3344 case 'w':
3345 {
3346 unsigned int Sbit = (given & 0x01000000) >> 24;
3347 unsigned int type = (given & 0x00600000) >> 21;
3348 switch (type)
3349 {
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;
3359 }
3360 }
3361 break;
3362
3363 case 'm':
3364 {
3365 int started = 0;
3366 int reg;
3367
3368 func (stream, "{");
3369 for (reg = 0; reg < 16; reg++)
3370 if ((given & (1 << reg)) != 0)
3371 {
3372 if (started)
3373 func (stream, ", ");
3374 started = 1;
3375 func (stream, "%s", arm_regnames[reg]);
3376 }
3377 func (stream, "}");
3378 }
3379 break;
3380
3381 case 'E':
3382 {
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);
3388 }
3389 break;
3390
3391 case 'F':
3392 {
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);
3398 }
3399 break;
3400
3401 case 'b':
3402 {
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;
3407
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);
3414
3415 info->print_address_func (pc + 4 + offset, info);
3416 }
3417 break;
3418
3419 case 'B':
3420 {
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;
3425
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;
3433
3434 /* BLX target addresses are always word aligned. */
3435 if ((given & 0x00001000u) == 0)
3436 offset &= ~2u;
3437
3438 info->print_address_func (offset, info);
3439 }
3440 break;
3441
3442 case 's':
3443 {
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 */
3452 }
3453 break;
3454
3455 case 'R':
3456 {
3457 unsigned int rot = (given & 0x00000030) >> 4;
3458 if (rot)
3459 func (stream, ", ror #%u", rot * 8);
3460 }
3461 break;
3462
3463 case 'U':
3464 switch (given & 0xf)
3465 {
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;
3473 }
3474 break;
3475
3476 case 'C':
3477 if ((given & 0xff) == 0)
3478 {
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");
3488 }
3489 else
3490 {
3491 func (stream, psr_name (given & 0xff));
3492 }
3493 break;
3494
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;
3501
3502 case '0': case '1': case '2': case '3': case '4':
3503 case '5': case '6': case '7': case '8': case '9':
3504 {
3505 int width;
3506 unsigned long val;
3507
3508 c = arm_decode_bitfield (c, given, &val, &width);
3509
3510 switch (*c)
3511 {
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;
3515
3516 case 'c':
3517 if (val == 0xE)
3518 func (stream, "al");
3519 else
3520 func (stream, "%s", arm_conditional[val]);
3521 break;
3522
3523 case '\'':
3524 c++;
3525 if (val == ((1ul << width) - 1))
3526 func (stream, "%c", *c);
3527 break;
3528
3529 case '`':
3530 c++;
3531 if (val == 0)
3532 func (stream, "%c", *c);
3533 break;
3534
3535 case '?':
3536 func (stream, "%c", c[(1 << width) - (int)val]);
3537 c += 1 << width;
3538 break;
3539
3540 default:
3541 abort ();
3542 }
3543 }
3544 break;
3545
3546 default:
3547 abort ();
3548 }
3549 }
3550 return;
3551 }
3552
3553 /* No match. */
3554 abort ();
3555}
3556
3557/* Disallow mapping symbols ($a, $b, $d, $t etc) from
3558 being displayed in symbol relative addresses. */
3559
3560bfd_boolean
3561arm_symbol_is_valid (asymbol * sym,
3562 struct disassemble_info * info ATTRIBUTE_UNUSED)
3563{
3564 const char * name;
3565
3566 if (sym == NULL)
3567 return FALSE;
3568
3569 name = bfd_asymbol_name (sym);
3570
3571 return (name && *name != '$');
3572}
3573
3574/* Parse an individual disassembler option. */
3575
3576void
3577parse_arm_disassembler_option (char *option)
3578{
3579 if (option == NULL)
3580 return;
3581
3582 if (strneq (option, "reg-names-", 10))
3583 {
3584 int i;
3585
3586 option += 10;
3587
3588 for (i = NUM_ARM_REGNAMES; i--;)
3589 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3590 {
3591 regname_selected = i;
3592 break;
3593 }
3594
3595 if (i < 0)
3596 /* XXX - should break 'option' at following delimiter. */
3597 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3598 }
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);
3606
3607 return;
3608}
3609
3610/* Parse the string of disassembler options, spliting it at whitespaces
3611 or commas. (Whitespace separators supported for backwards compatibility). */
3612
3613static void
3614parse_disassembler_options (char *options)
3615{
3616 if (options == NULL)
3617 return;
3618
3619 while (*options)
3620 {
3621 parse_arm_disassembler_option (options);
3622
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;
3629 }
3630}
3631
3632/* NOTE: There are no checks in these routines that
3633 the relevant number of data bytes exist. */
3634
3635static int
3636print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3637{
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);
3644
3645 if (info->disassembler_options)
3646 {
3647 parse_disassembler_options (info->disassembler_options);
3648
3649 /* To avoid repeated parsing of these options, we remove them here. */
3650 info->disassembler_options = NULL;
3651 }
3652
3653 is_thumb = force_thumb;
3654
3655 if (!is_thumb && info->symbols != NULL)
3656 {
3657 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3658 {
3659 coff_symbol_type * cs;
3660
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);
3667 }
3668 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
3669 {
3670 elf_symbol_type * es;
3671 unsigned int type;
3672
3673 es = *(elf_symbol_type **)(info->symbols);
3674 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3675
3676 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
3677 }
3678 }
3679
3680 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
3681 info->bytes_per_line = 4;
3682
3683 if (!is_thumb)
3684 {
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;
3690
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);
3696 }
3697 else
3698 {
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;
3706
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);
3712
3713 if (!status)
3714 {
3715 /* These bit patterns signal a four-byte Thumb
3716 instruction. */
3717 if ((given & 0xF800) == 0xF800
3718 || (given & 0xF800) == 0xF000
3719 || (given & 0xF800) == 0xE800)
3720 {
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);
3726
3727 printer = print_insn_thumb32;
3728 size = 4;
3729 }
3730 }
3731 }
3732
3733 if (status)
3734 {
3735 info->memory_error_func (status, pc, info);
3736 return -1;
3737 }
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;
3745
3746 printer (pc, info, given);
3747 return size;
3748}
3749
3750int
3751print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3752{
3753 return print_insn (pc, info, FALSE);
3754}
3755
3756int
3757print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3758{
3759 return print_insn (pc, info, TRUE);
3760}
3761
3762void
3763print_arm_disassembler_options (FILE *stream)
3764{
3765 int i;
3766
3767 fprintf (stream, _("\n\
3768The following ARM specific disassembler options are supported for use with\n\
3769the -M switch:\n"));
3770
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);
3776
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");
3779}
This page took 0.0555 seconds and 4 git commands to generate.