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