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