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