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