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