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