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