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