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