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