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