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