* README: Make version-agnostic.
[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",
9d82ec38
MGD
2723 (long) (((value & 0x80000000L) != 0)
2724 ? value | ~0xffffffffL : value),
c1e26897 2725 value);
16980d0b
JB
2726 break;
2727
2728 case 64:
2729 func (stream, "#0x%.8lx%.8lx", hival, value);
2730 break;
2731
2732 default:
2733 abort ();
2734 }
2735 }
2736 break;
2737
2738 case 'F':
2739 {
2740 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2741 int num = (given >> 8) & 0x3;
2742
2743 if (!num)
2744 func (stream, "{d%d}", regno);
2745 else if (num + regno >= 32)
2746 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2747 else
2748 func (stream, "{d%d-d%d}", regno, regno + num);
2749 }
2750 break;
2751
2752
2753 case '0': case '1': case '2': case '3': case '4':
2754 case '5': case '6': case '7': case '8': case '9':
2755 {
2756 int width;
2757 unsigned long value;
2758
2759 c = arm_decode_bitfield (c, given, &value, &width);
2760
2761 switch (*c)
2762 {
2763 case 'r':
2764 func (stream, "%s", arm_regnames[value]);
2765 break;
2766 case 'd':
2767 func (stream, "%ld", value);
05413229 2768 value_in_comment = value;
16980d0b
JB
2769 break;
2770 case 'e':
2771 func (stream, "%ld", (1ul << width) - value);
2772 break;
2773
2774 case 'S':
2775 case 'T':
2776 case 'U':
05413229 2777 /* Various width encodings. */
16980d0b
JB
2778 {
2779 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2780 int limit;
2781 unsigned low, high;
2782
2783 c++;
2784 if (*c >= '0' && *c <= '9')
2785 limit = *c - '0';
2786 else if (*c >= 'a' && *c <= 'f')
2787 limit = *c - 'a' + 10;
2788 else
2789 abort ();
2790 low = limit >> 2;
2791 high = limit & 3;
2792
2793 if (value < low || value > high)
2794 func (stream, "<illegal width %d>", base << value);
2795 else
2796 func (stream, "%d", base << value);
2797 }
2798 break;
2799 case 'R':
2800 if (given & (1 << 6))
2801 goto Q;
2802 /* FALLTHROUGH */
2803 case 'D':
2804 func (stream, "d%ld", value);
2805 break;
2806 case 'Q':
2807 Q:
2808 if (value & 1)
2809 func (stream, "<illegal reg q%ld.5>", value >> 1);
2810 else
2811 func (stream, "q%ld", value >> 1);
2812 break;
2813
2814 case '`':
2815 c++;
2816 if (value == 0)
2817 func (stream, "%c", *c);
2818 break;
2819 case '\'':
2820 c++;
2821 if (value == ((1ul << width) - 1))
2822 func (stream, "%c", *c);
2823 break;
2824 case '?':
fe56b6ce 2825 func (stream, "%c", c[(1 << width) - (int) value]);
16980d0b
JB
2826 c += 1 << width;
2827 break;
2828 default:
2829 abort ();
2830 }
2831 break;
2832
2833 default:
2834 abort ();
2835 }
2836 }
2837 }
2838 else
2839 func (stream, "%c", *c);
2840 }
05413229
NC
2841
2842 if (value_in_comment > 32 || value_in_comment < -16)
2843 func (stream, "\t; 0x%lx", value_in_comment);
2844
16980d0b
JB
2845 return TRUE;
2846 }
2847 }
2848 return FALSE;
2849}
2850
4a5329c6
ZW
2851/* Print one ARM instruction from PC on INFO->STREAM. */
2852
2853static void
2854print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
252b5132 2855{
6b5d3a4d 2856 const struct opcode32 *insn;
6a51a8a8 2857 void *stream = info->stream;
6b5d3a4d 2858 fprintf_ftype func = info->fprintf_func;
b0e28b39 2859 struct arm_private_data *private_data = info->private_data;
252b5132 2860
16980d0b
JB
2861 if (print_insn_coprocessor (pc, info, given, FALSE))
2862 return;
2863
2864 if (print_insn_neon (info, given, FALSE))
8f06b2d8
PB
2865 return;
2866
252b5132
RH
2867 for (insn = arm_opcodes; insn->assembler; insn++)
2868 {
0313a2b8
NC
2869 if ((given & insn->mask) != insn->value)
2870 continue;
2871
b0e28b39 2872 if ((insn->arch & private_data->features.core) == 0)
0313a2b8
NC
2873 continue;
2874
2875 /* Special case: an instruction with all bits set in the condition field
2876 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2877 or by the catchall at the end of the table. */
2878 if ((given & 0xF0000000) != 0xF0000000
2879 || (insn->mask & 0xF0000000) == 0xF0000000
2880 || (insn->mask == 0 && insn->value == 0))
252b5132 2881 {
ff4a8d2b
NC
2882 unsigned long u_reg = 16;
2883 unsigned long U_reg = 16;
ab8e2090 2884 bfd_boolean is_unpredictable = FALSE;
05413229 2885 signed long value_in_comment = 0;
6b5d3a4d 2886 const char *c;
b34976b6 2887
252b5132
RH
2888 for (c = insn->assembler; *c; c++)
2889 {
2890 if (*c == '%')
2891 {
c1e26897
NC
2892 bfd_boolean allow_unpredictable = FALSE;
2893
252b5132
RH
2894 switch (*++c)
2895 {
2896 case '%':
2897 func (stream, "%%");
2898 break;
2899
2900 case 'a':
05413229 2901 value_in_comment = print_arm_address (pc, info, given);
62b3e311 2902 break;
252b5132 2903
62b3e311
PB
2904 case 'P':
2905 /* Set P address bit and use normal address
2906 printing routine. */
c1e26897 2907 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
252b5132
RH
2908 break;
2909
c1e26897
NC
2910 case 'S':
2911 allow_unpredictable = TRUE;
252b5132
RH
2912 case 's':
2913 if ((given & 0x004f0000) == 0x004f0000)
2914 {
58efb6c0 2915 /* PC relative with immediate offset. */
252b5132 2916 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
b34976b6 2917
c1e26897
NC
2918 if (NEGATIVE_BIT_SET)
2919 offset = - offset;
b34976b6 2920
aefd8a40
NC
2921 if (PRE_BIT_SET)
2922 {
945ee430
NC
2923 if (offset)
2924 func (stream, "[pc, #%d]\t; ", offset);
2925 else
2926 func (stream, "[pc]\t; ");
aefd8a40
NC
2927 info->print_address_func (offset + pc + 8, info);
2928 }
2929 else
2930 {
2931 func (stream, "[pc], #%d", offset);
ff4a8d2b
NC
2932 if (! allow_unpredictable)
2933 is_unpredictable = TRUE;
aefd8a40 2934 }
252b5132
RH
2935 }
2936 else
2937 {
fe56b6ce
NC
2938 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2939
c1e26897
NC
2940 if (NEGATIVE_BIT_SET)
2941 offset = - offset;
fe56b6ce 2942
b34976b6 2943 func (stream, "[%s",
252b5132 2944 arm_regnames[(given >> 16) & 0xf]);
fe56b6ce 2945
c1e26897 2946 if (PRE_BIT_SET)
252b5132 2947 {
c1e26897 2948 if (IMMEDIATE_BIT_SET)
252b5132 2949 {
945ee430
NC
2950 if (WRITEBACK_BIT_SET)
2951 /* Immediate Pre-indexed. */
2952 /* PR 10924: Offset must be printed, even if it is zero. */
2953 func (stream, ", #%d", offset);
2954 else if (offset)
2955 /* Immediate Offset: printing zero offset is optional. */
2956 func (stream, ", #%d", offset);
2957
fe56b6ce 2958 value_in_comment = offset;
252b5132 2959 }
945ee430 2960 else
ff4a8d2b
NC
2961 {
2962 /* Register Offset or Register Pre-Indexed. */
2963 func (stream, ", %s%s",
2964 NEGATIVE_BIT_SET ? "-" : "",
2965 arm_regnames[given & 0xf]);
2966
2967 /* Writing back to the register that is the source/
2968 destination of the load/store is unpredictable. */
2969 if (! allow_unpredictable
2970 && WRITEBACK_BIT_SET
2971 && ((given & 0xf) == ((given >> 12) & 0xf)))
2972 is_unpredictable = TRUE;
2973 }
252b5132 2974
b34976b6 2975 func (stream, "]%s",
c1e26897 2976 WRITEBACK_BIT_SET ? "!" : "");
252b5132 2977 }
945ee430 2978 else
252b5132 2979 {
c1e26897 2980 if (IMMEDIATE_BIT_SET)
252b5132 2981 {
945ee430 2982 /* Immediate Post-indexed. */
aefd8a40
NC
2983 /* PR 10924: Offset must be printed, even if it is zero. */
2984 func (stream, "], #%d", offset);
fe56b6ce 2985 value_in_comment = offset;
252b5132 2986 }
945ee430 2987 else
ff4a8d2b
NC
2988 {
2989 /* Register Post-indexed. */
2990 func (stream, "], %s%s",
2991 NEGATIVE_BIT_SET ? "-" : "",
2992 arm_regnames[given & 0xf]);
2993
2994 /* Writing back to the register that is the source/
2995 destination of the load/store is unpredictable. */
2996 if (! allow_unpredictable
2997 && (given & 0xf) == ((given >> 12) & 0xf))
2998 is_unpredictable = TRUE;
2999 }
c1e26897 3000
07a28fab
NC
3001 if (! allow_unpredictable)
3002 {
3003 /* Writeback is automatically implied by post- addressing.
3004 Setting the W bit is unnecessary and ARM specify it as
3005 being unpredictable. */
3006 if (WRITEBACK_BIT_SET
3007 /* Specifying the PC register as the post-indexed
3008 registers is also unpredictable. */
ab8e2090
NC
3009 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3010 is_unpredictable = TRUE;
07a28fab 3011 }
252b5132
RH
3012 }
3013 }
3014 break;
b34976b6 3015
252b5132 3016 case 'b':
6b5d3a4d
ZW
3017 {
3018 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
05413229 3019 info->print_address_func (disp * 4 + pc + 8, info);
6b5d3a4d 3020 }
252b5132
RH
3021 break;
3022
3023 case 'c':
c22aaad1
PB
3024 if (((given >> 28) & 0xf) != 0xe)
3025 func (stream, "%s",
3026 arm_conditional [(given >> 28) & 0xf]);
252b5132
RH
3027 break;
3028
3029 case 'm':
3030 {
3031 int started = 0;
3032 int reg;
3033
3034 func (stream, "{");
3035 for (reg = 0; reg < 16; reg++)
3036 if ((given & (1 << reg)) != 0)
3037 {
3038 if (started)
3039 func (stream, ", ");
3040 started = 1;
3041 func (stream, "%s", arm_regnames[reg]);
3042 }
3043 func (stream, "}");
ab8e2090
NC
3044 if (! started)
3045 is_unpredictable = TRUE;
252b5132
RH
3046 }
3047 break;
3048
37b37b2d 3049 case 'q':
78c66db8 3050 arm_decode_shift (given, func, stream, FALSE);
37b37b2d
RE
3051 break;
3052
252b5132
RH
3053 case 'o':
3054 if ((given & 0x02000000) != 0)
3055 {
3056 int rotate = (given & 0xf00) >> 7;
3057 int immed = (given & 0xff);
fe56b6ce 3058
9f20bbfd
NC
3059 immed = (((immed << (32 - rotate))
3060 | (immed >> rotate)) & 0xffffffff);
fe56b6ce
NC
3061 func (stream, "#%d", immed);
3062 value_in_comment = immed;
252b5132
RH
3063 }
3064 else
78c66db8 3065 arm_decode_shift (given, func, stream, TRUE);
252b5132
RH
3066 break;
3067
3068 case 'p':
3069 if ((given & 0x0000f000) == 0x0000f000)
aefd8a40
NC
3070 {
3071 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3072 mechanism for setting PSR flag bits. They are
3073 obsolete in V6 onwards. */
b0e28b39 3074 if ((private_data->features.core & ARM_EXT_V6) == 0)
aefd8a40
NC
3075 func (stream, "p");
3076 }
252b5132
RH
3077 break;
3078
3079 case 't':
3080 if ((given & 0x01200000) == 0x00200000)
3081 func (stream, "t");
3082 break;
3083
252b5132 3084 case 'A':
05413229
NC
3085 {
3086 int offset = given & 0xff;
f02232aa 3087
05413229 3088 value_in_comment = offset * 4;
c1e26897 3089 if (NEGATIVE_BIT_SET)
05413229 3090 value_in_comment = - value_in_comment;
f02232aa 3091
05413229 3092 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
f02232aa 3093
c1e26897 3094 if (PRE_BIT_SET)
05413229
NC
3095 {
3096 if (offset)
fe56b6ce
NC
3097 func (stream, ", #%d]%s",
3098 value_in_comment,
c1e26897 3099 WRITEBACK_BIT_SET ? "!" : "");
05413229
NC
3100 else
3101 func (stream, "]");
3102 }
3103 else
3104 {
3105 func (stream, "]");
f02232aa 3106
c1e26897 3107 if (WRITEBACK_BIT_SET)
05413229
NC
3108 {
3109 if (offset)
fe56b6ce 3110 func (stream, ", #%d", value_in_comment);
05413229
NC
3111 }
3112 else
fe56b6ce
NC
3113 {
3114 func (stream, ", {%d}", offset);
3115 value_in_comment = offset;
3116 }
05413229
NC
3117 }
3118 }
252b5132
RH
3119 break;
3120
077b8428
NC
3121 case 'B':
3122 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3123 {
3124 bfd_vma address;
3125 bfd_vma offset = 0;
b34976b6 3126
c1e26897 3127 if (! NEGATIVE_BIT_SET)
077b8428
NC
3128 /* Is signed, hi bits should be ones. */
3129 offset = (-1) ^ 0x00ffffff;
3130
3131 /* Offset is (SignExtend(offset field)<<2). */
3132 offset += given & 0x00ffffff;
3133 offset <<= 2;
3134 address = offset + pc + 8;
b34976b6 3135
8f06b2d8
PB
3136 if (given & 0x01000000)
3137 /* H bit allows addressing to 2-byte boundaries. */
3138 address += 2;
b1ee46c5 3139
8f06b2d8 3140 info->print_address_func (address, info);
b1ee46c5 3141 }
b1ee46c5
AH
3142 break;
3143
252b5132 3144 case 'C':
6eeeb4b4
AO
3145 func (stream, "_");
3146 if (given & 0x80000)
3147 func (stream, "f");
3148 if (given & 0x40000)
3149 func (stream, "s");
3150 if (given & 0x20000)
3151 func (stream, "x");
3152 if (given & 0x10000)
3153 func (stream, "c");
252b5132
RH
3154 break;
3155
62b3e311
PB
3156 case 'U':
3157 switch (given & 0xf)
3158 {
fe56b6ce
NC
3159 case 0xf: func (stream, "sy"); break;
3160 case 0x7: func (stream, "un"); break;
3161 case 0xe: func (stream, "st"); break;
3162 case 0x6: func (stream, "unst"); break;
62b3e311 3163 default:
fe56b6ce 3164 func (stream, "#%d", (int) given & 0xf);
62b3e311
PB
3165 break;
3166 }
3167 break;
3168
b34976b6 3169 case '0': case '1': case '2': case '3': case '4':
252b5132
RH
3170 case '5': case '6': case '7': case '8': case '9':
3171 {
16980d0b
JB
3172 int width;
3173 unsigned long value;
252b5132 3174
16980d0b
JB
3175 c = arm_decode_bitfield (c, given, &value, &width);
3176
252b5132
RH
3177 switch (*c)
3178 {
ab8e2090
NC
3179 case 'R':
3180 if (value == 15)
3181 is_unpredictable = TRUE;
3182 /* Fall through. */
16980d0b 3183 case 'r':
ff4a8d2b
NC
3184 if (c[1] == 'u')
3185 {
3186 /* Eat the 'u' character. */
3187 ++ c;
3188
3189 if (u_reg == value)
3190 is_unpredictable = TRUE;
3191 u_reg = value;
3192 }
3193 if (c[1] == 'U')
3194 {
3195 /* Eat the 'U' character. */
3196 ++ c;
3197
3198 if (U_reg == value)
3199 is_unpredictable = TRUE;
3200 U_reg = value;
3201 }
16980d0b
JB
3202 func (stream, "%s", arm_regnames[value]);
3203 break;
3204 case 'd':
3205 func (stream, "%ld", value);
05413229 3206 value_in_comment = value;
16980d0b
JB
3207 break;
3208 case 'b':
3209 func (stream, "%ld", value * 8);
05413229 3210 value_in_comment = value * 8;
16980d0b
JB
3211 break;
3212 case 'W':
3213 func (stream, "%ld", value + 1);
05413229 3214 value_in_comment = value + 1;
16980d0b
JB
3215 break;
3216 case 'x':
3217 func (stream, "0x%08lx", value);
3218
3219 /* Some SWI instructions have special
3220 meanings. */
3221 if ((given & 0x0fffffff) == 0x0FF00000)
3222 func (stream, "\t; IMB");
3223 else if ((given & 0x0fffffff) == 0x0FF00001)
3224 func (stream, "\t; IMBRange");
3225 break;
3226 case 'X':
3227 func (stream, "%01lx", value & 0xf);
05413229 3228 value_in_comment = value;
252b5132
RH
3229 break;
3230 case '`':
3231 c++;
16980d0b 3232 if (value == 0)
252b5132
RH
3233 func (stream, "%c", *c);
3234 break;
3235 case '\'':
3236 c++;
16980d0b 3237 if (value == ((1ul << width) - 1))
252b5132
RH
3238 func (stream, "%c", *c);
3239 break;
3240 case '?':
fe56b6ce 3241 func (stream, "%c", c[(1 << width) - (int) value]);
16980d0b 3242 c += 1 << width;
252b5132
RH
3243 break;
3244 default:
3245 abort ();
3246 }
3247 break;
3248
0dd132b6
NC
3249 case 'e':
3250 {
3251 int imm;
3252
3253 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3254 func (stream, "%d", imm);
fe56b6ce 3255 value_in_comment = imm;
0dd132b6
NC
3256 }
3257 break;
3258
0a003adc
ZW
3259 case 'E':
3260 /* LSB and WIDTH fields of BFI or BFC. The machine-
3261 language instruction encodes LSB and MSB. */
3262 {
3263 long msb = (given & 0x001f0000) >> 16;
3264 long lsb = (given & 0x00000f80) >> 7;
91d6fa6a 3265 long w = msb - lsb + 1;
fe56b6ce 3266
91d6fa6a
NC
3267 if (w > 0)
3268 func (stream, "#%lu, #%lu", lsb, w);
0a003adc
ZW
3269 else
3270 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3271 }
3272 break;
3273
3274 case 'V':
3275 /* 16-bit unsigned immediate from a MOVT or MOVW
3276 instruction, encoded in bits 0:11 and 15:19. */
3277 {
3278 long hi = (given & 0x000f0000) >> 4;
3279 long lo = (given & 0x00000fff);
3280 long imm16 = hi | lo;
fe56b6ce
NC
3281
3282 func (stream, "#%lu", imm16);
3283 value_in_comment = imm16;
0a003adc
ZW
3284 }
3285 break;
3286
252b5132
RH
3287 default:
3288 abort ();
3289 }
3290 }
3291 }
3292 else
3293 func (stream, "%c", *c);
3294 }
05413229
NC
3295
3296 if (value_in_comment > 32 || value_in_comment < -16)
d1aaab3c 3297 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
ab8e2090
NC
3298
3299 if (is_unpredictable)
3300 func (stream, UNPREDICTABLE_INSTRUCTION);
ff4a8d2b 3301
4a5329c6 3302 return;
252b5132
RH
3303 }
3304 }
3305 abort ();
3306}
3307
4a5329c6 3308/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
baf0cc5e 3309
4a5329c6
ZW
3310static void
3311print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
252b5132 3312{
6b5d3a4d 3313 const struct opcode16 *insn;
6a51a8a8
AM
3314 void *stream = info->stream;
3315 fprintf_ftype func = info->fprintf_func;
252b5132
RH
3316
3317 for (insn = thumb_opcodes; insn->assembler; insn++)
c19d1205
ZW
3318 if ((given & insn->mask) == insn->value)
3319 {
05413229 3320 signed long value_in_comment = 0;
6b5d3a4d 3321 const char *c = insn->assembler;
05413229 3322
c19d1205
ZW
3323 for (; *c; c++)
3324 {
3325 int domaskpc = 0;
3326 int domasklr = 0;
3327
3328 if (*c != '%')
3329 {
3330 func (stream, "%c", *c);
3331 continue;
3332 }
252b5132 3333
c19d1205
ZW
3334 switch (*++c)
3335 {
3336 case '%':
3337 func (stream, "%%");
3338 break;
b34976b6 3339
c22aaad1
PB
3340 case 'c':
3341 if (ifthen_state)
3342 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3343 break;
3344
3345 case 'C':
3346 if (ifthen_state)
3347 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3348 else
3349 func (stream, "s");
3350 break;
3351
3352 case 'I':
3353 {
3354 unsigned int tmp;
3355
3356 ifthen_next_state = given & 0xff;
3357 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3358 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3359 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3360 }
3361 break;
3362
3363 case 'x':
3364 if (ifthen_next_state)
3365 func (stream, "\t; unpredictable branch in IT block\n");
3366 break;
3367
3368 case 'X':
3369 if (ifthen_state)
3370 func (stream, "\t; unpredictable <IT:%s>",
3371 arm_conditional[IFTHEN_COND]);
3372 break;
3373
c19d1205
ZW
3374 case 'S':
3375 {
3376 long reg;
3377
3378 reg = (given >> 3) & 0x7;
3379 if (given & (1 << 6))
3380 reg += 8;
4f3c3dbb 3381
c19d1205
ZW
3382 func (stream, "%s", arm_regnames[reg]);
3383 }
3384 break;
baf0cc5e 3385
c19d1205 3386 case 'D':
4f3c3dbb 3387 {
c19d1205
ZW
3388 long reg;
3389
3390 reg = given & 0x7;
3391 if (given & (1 << 7))
3392 reg += 8;
3393
3394 func (stream, "%s", arm_regnames[reg]);
4f3c3dbb 3395 }
c19d1205
ZW
3396 break;
3397
3398 case 'N':
3399 if (given & (1 << 8))
3400 domasklr = 1;
3401 /* Fall through. */
3402 case 'O':
3403 if (*c == 'O' && (given & (1 << 8)))
3404 domaskpc = 1;
3405 /* Fall through. */
3406 case 'M':
3407 {
3408 int started = 0;
3409 int reg;
3410
3411 func (stream, "{");
3412
3413 /* It would be nice if we could spot
3414 ranges, and generate the rS-rE format: */
3415 for (reg = 0; (reg < 8); reg++)
3416 if ((given & (1 << reg)) != 0)
3417 {
3418 if (started)
3419 func (stream, ", ");
3420 started = 1;
3421 func (stream, "%s", arm_regnames[reg]);
3422 }
3423
3424 if (domasklr)
3425 {
3426 if (started)
3427 func (stream, ", ");
3428 started = 1;
3429 func (stream, arm_regnames[14] /* "lr" */);
3430 }
3431
3432 if (domaskpc)
3433 {
3434 if (started)
3435 func (stream, ", ");
3436 func (stream, arm_regnames[15] /* "pc" */);
3437 }
3438
3439 func (stream, "}");
3440 }
3441 break;
3442
4547cb56
NC
3443 case 'W':
3444 /* Print writeback indicator for a LDMIA. We are doing a
3445 writeback if the base register is not in the register
3446 mask. */
3447 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3448 func (stream, "!");
3449 break;
3450
c19d1205
ZW
3451 case 'b':
3452 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3453 {
3454 bfd_vma address = (pc + 4
3455 + ((given & 0x00f8) >> 2)
3456 + ((given & 0x0200) >> 3));
3457 info->print_address_func (address, info);
3458 }
3459 break;
3460
3461 case 's':
3462 /* Right shift immediate -- bits 6..10; 1-31 print
3463 as themselves, 0 prints as 32. */
3464 {
3465 long imm = (given & 0x07c0) >> 6;
3466 if (imm == 0)
3467 imm = 32;
0fd3a477 3468 func (stream, "#%ld", imm);
c19d1205
ZW
3469 }
3470 break;
3471
3472 case '0': case '1': case '2': case '3': case '4':
3473 case '5': case '6': case '7': case '8': case '9':
3474 {
3475 int bitstart = *c++ - '0';
3476 int bitend = 0;
3477
3478 while (*c >= '0' && *c <= '9')
3479 bitstart = (bitstart * 10) + *c++ - '0';
3480
3481 switch (*c)
3482 {
3483 case '-':
3484 {
3485 long reg;
3486
3487 c++;
3488 while (*c >= '0' && *c <= '9')
3489 bitend = (bitend * 10) + *c++ - '0';
3490 if (!bitend)
3491 abort ();
3492 reg = given >> bitstart;
3493 reg &= (2 << (bitend - bitstart)) - 1;
ff4a8d2b 3494
c19d1205
ZW
3495 switch (*c)
3496 {
3497 case 'r':
3498 func (stream, "%s", arm_regnames[reg]);
3499 break;
3500
3501 case 'd':
0fd3a477 3502 func (stream, "%ld", reg);
05413229 3503 value_in_comment = reg;
c19d1205
ZW
3504 break;
3505
3506 case 'H':
0fd3a477 3507 func (stream, "%ld", reg << 1);
05413229 3508 value_in_comment = reg << 1;
c19d1205
ZW
3509 break;
3510
3511 case 'W':
0fd3a477 3512 func (stream, "%ld", reg << 2);
05413229 3513 value_in_comment = reg << 2;
c19d1205
ZW
3514 break;
3515
3516 case 'a':
3517 /* PC-relative address -- the bottom two
3518 bits of the address are dropped
3519 before the calculation. */
3520 info->print_address_func
3521 (((pc + 4) & ~3) + (reg << 2), info);
05413229 3522 value_in_comment = 0;
c19d1205
ZW
3523 break;
3524
3525 case 'x':
0fd3a477 3526 func (stream, "0x%04lx", reg);
c19d1205
ZW
3527 break;
3528
c19d1205
ZW
3529 case 'B':
3530 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
6b5d3a4d 3531 info->print_address_func (reg * 2 + pc + 4, info);
05413229 3532 value_in_comment = 0;
c19d1205
ZW
3533 break;
3534
3535 case 'c':
c22aaad1 3536 func (stream, "%s", arm_conditional [reg]);
c19d1205
ZW
3537 break;
3538
3539 default:
3540 abort ();
3541 }
3542 }
3543 break;
3544
3545 case '\'':
3546 c++;
3547 if ((given & (1 << bitstart)) != 0)
3548 func (stream, "%c", *c);
3549 break;
3550
3551 case '?':
3552 ++c;
3553 if ((given & (1 << bitstart)) != 0)
3554 func (stream, "%c", *c++);
3555 else
3556 func (stream, "%c", *++c);
3557 break;
3558
3559 default:
3560 abort ();
3561 }
3562 }
3563 break;
3564
3565 default:
3566 abort ();
3567 }
3568 }
05413229
NC
3569
3570 if (value_in_comment > 32 || value_in_comment < -16)
3571 func (stream, "\t; 0x%lx", value_in_comment);
4a5329c6 3572 return;
c19d1205
ZW
3573 }
3574
3575 /* No match. */
3576 abort ();
3577}
3578
62b3e311 3579/* Return the name of an V7M special register. */
fe56b6ce 3580
62b3e311
PB
3581static const char *
3582psr_name (int regno)
3583{
3584 switch (regno)
3585 {
3586 case 0: return "APSR";
3587 case 1: return "IAPSR";
3588 case 2: return "EAPSR";
3589 case 3: return "PSR";
3590 case 5: return "IPSR";
3591 case 6: return "EPSR";
3592 case 7: return "IEPSR";
3593 case 8: return "MSP";
3594 case 9: return "PSP";
3595 case 16: return "PRIMASK";
3596 case 17: return "BASEPRI";
3597 case 18: return "BASEPRI_MASK";
3598 case 19: return "FAULTMASK";
3599 case 20: return "CONTROL";
3600 default: return "<unknown>";
3601 }
3602}
3603
4a5329c6
ZW
3604/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3605
3606static void
3607print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
c19d1205 3608{
6b5d3a4d 3609 const struct opcode32 *insn;
c19d1205
ZW
3610 void *stream = info->stream;
3611 fprintf_ftype func = info->fprintf_func;
3612
16980d0b
JB
3613 if (print_insn_coprocessor (pc, info, given, TRUE))
3614 return;
3615
3616 if (print_insn_neon (info, given, TRUE))
8f06b2d8
PB
3617 return;
3618
c19d1205
ZW
3619 for (insn = thumb32_opcodes; insn->assembler; insn++)
3620 if ((given & insn->mask) == insn->value)
3621 {
ff4a8d2b 3622 bfd_boolean is_unpredictable = FALSE;
05413229 3623 signed long value_in_comment = 0;
6b5d3a4d 3624 const char *c = insn->assembler;
05413229 3625
c19d1205
ZW
3626 for (; *c; c++)
3627 {
3628 if (*c != '%')
3629 {
3630 func (stream, "%c", *c);
3631 continue;
3632 }
3633
3634 switch (*++c)
3635 {
3636 case '%':
3637 func (stream, "%%");
3638 break;
3639
c22aaad1
PB
3640 case 'c':
3641 if (ifthen_state)
3642 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3643 break;
3644
3645 case 'x':
3646 if (ifthen_next_state)
3647 func (stream, "\t; unpredictable branch in IT block\n");
3648 break;
3649
3650 case 'X':
3651 if (ifthen_state)
3652 func (stream, "\t; unpredictable <IT:%s>",
3653 arm_conditional[IFTHEN_COND]);
3654 break;
3655
c19d1205
ZW
3656 case 'I':
3657 {
3658 unsigned int imm12 = 0;
fe56b6ce 3659
c19d1205
ZW
3660 imm12 |= (given & 0x000000ffu);
3661 imm12 |= (given & 0x00007000u) >> 4;
92e90b6e 3662 imm12 |= (given & 0x04000000u) >> 15;
fe56b6ce
NC
3663 func (stream, "#%u", imm12);
3664 value_in_comment = imm12;
c19d1205
ZW
3665 }
3666 break;
3667
3668 case 'M':
3669 {
3670 unsigned int bits = 0, imm, imm8, mod;
fe56b6ce 3671
c19d1205
ZW
3672 bits |= (given & 0x000000ffu);
3673 bits |= (given & 0x00007000u) >> 4;
3674 bits |= (given & 0x04000000u) >> 15;
3675 imm8 = (bits & 0x0ff);
3676 mod = (bits & 0xf00) >> 8;
3677 switch (mod)
3678 {
3679 case 0: imm = imm8; break;
c1e26897
NC
3680 case 1: imm = ((imm8 << 16) | imm8); break;
3681 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3682 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
c19d1205
ZW
3683 default:
3684 mod = (bits & 0xf80) >> 7;
3685 imm8 = (bits & 0x07f) | 0x80;
3686 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3687 }
fe56b6ce
NC
3688 func (stream, "#%u", imm);
3689 value_in_comment = imm;
c19d1205
ZW
3690 }
3691 break;
3692
3693 case 'J':
3694 {
3695 unsigned int imm = 0;
fe56b6ce 3696
c19d1205
ZW
3697 imm |= (given & 0x000000ffu);
3698 imm |= (given & 0x00007000u) >> 4;
3699 imm |= (given & 0x04000000u) >> 15;
3700 imm |= (given & 0x000f0000u) >> 4;
fe56b6ce
NC
3701 func (stream, "#%u", imm);
3702 value_in_comment = imm;
c19d1205
ZW
3703 }
3704 break;
3705
3706 case 'K':
3707 {
3708 unsigned int imm = 0;
fe56b6ce 3709
c19d1205
ZW
3710 imm |= (given & 0x000f0000u) >> 16;
3711 imm |= (given & 0x00000ff0u) >> 0;
3712 imm |= (given & 0x0000000fu) << 12;
fe56b6ce
NC
3713 func (stream, "#%u", imm);
3714 value_in_comment = imm;
c19d1205
ZW
3715 }
3716 break;
3717
3718 case 'S':
3719 {
3720 unsigned int reg = (given & 0x0000000fu);
3721 unsigned int stp = (given & 0x00000030u) >> 4;
3722 unsigned int imm = 0;
3723 imm |= (given & 0x000000c0u) >> 6;
3724 imm |= (given & 0x00007000u) >> 10;
3725
3726 func (stream, "%s", arm_regnames[reg]);
3727 switch (stp)
3728 {
3729 case 0:
3730 if (imm > 0)
3731 func (stream, ", lsl #%u", imm);
3732 break;
3733
3734 case 1:
3735 if (imm == 0)
3736 imm = 32;
3737 func (stream, ", lsr #%u", imm);
3738 break;
3739
3740 case 2:
3741 if (imm == 0)
3742 imm = 32;
3743 func (stream, ", asr #%u", imm);
3744 break;
3745
3746 case 3:
3747 if (imm == 0)
3748 func (stream, ", rrx");
3749 else
3750 func (stream, ", ror #%u", imm);
3751 }
3752 }
3753 break;
3754
3755 case 'a':
3756 {
3757 unsigned int Rn = (given & 0x000f0000) >> 16;
c1e26897 3758 unsigned int U = ! NEGATIVE_BIT_SET;
c19d1205
ZW
3759 unsigned int op = (given & 0x00000f00) >> 8;
3760 unsigned int i12 = (given & 0x00000fff);
3761 unsigned int i8 = (given & 0x000000ff);
3762 bfd_boolean writeback = FALSE, postind = FALSE;
3763 int offset = 0;
3764
3765 func (stream, "[%s", arm_regnames[Rn]);
05413229
NC
3766 if (U) /* 12-bit positive immediate offset. */
3767 {
3768 offset = i12;
3769 if (Rn != 15)
3770 value_in_comment = offset;
3771 }
3772 else if (Rn == 15) /* 12-bit negative immediate offset. */
3773 offset = - (int) i12;
3774 else if (op == 0x0) /* Shifted register offset. */
c19d1205
ZW
3775 {
3776 unsigned int Rm = (i8 & 0x0f);
3777 unsigned int sh = (i8 & 0x30) >> 4;
05413229 3778
c19d1205
ZW
3779 func (stream, ", %s", arm_regnames[Rm]);
3780 if (sh)
3781 func (stream, ", lsl #%u", sh);
3782 func (stream, "]");
3783 break;
3784 }
3785 else switch (op)
3786 {
05413229 3787 case 0xE: /* 8-bit positive immediate offset. */
c19d1205
ZW
3788 offset = i8;
3789 break;
3790
05413229 3791 case 0xC: /* 8-bit negative immediate offset. */
c19d1205
ZW
3792 offset = -i8;
3793 break;
3794
05413229 3795 case 0xF: /* 8-bit + preindex with wb. */
c19d1205
ZW
3796 offset = i8;
3797 writeback = TRUE;
3798 break;
3799
05413229 3800 case 0xD: /* 8-bit - preindex with wb. */
c19d1205
ZW
3801 offset = -i8;
3802 writeback = TRUE;
3803 break;
3804
05413229 3805 case 0xB: /* 8-bit + postindex. */
c19d1205
ZW
3806 offset = i8;
3807 postind = TRUE;
3808 break;
3809
05413229 3810 case 0x9: /* 8-bit - postindex. */
c19d1205
ZW
3811 offset = -i8;
3812 postind = TRUE;
3813 break;
3814
3815 default:
3816 func (stream, ", <undefined>]");
3817 goto skip;
3818 }
3819
3820 if (postind)
3821 func (stream, "], #%d", offset);
3822 else
3823 {
3824 if (offset)
3825 func (stream, ", #%d", offset);
3826 func (stream, writeback ? "]!" : "]");
3827 }
3828
3829 if (Rn == 15)
3830 {
3831 func (stream, "\t; ");
3832 info->print_address_func (((pc + 4) & ~3) + offset, info);
3833 }
3834 }
3835 skip:
3836 break;
3837
3838 case 'A':
3839 {
c1e26897
NC
3840 unsigned int U = ! NEGATIVE_BIT_SET;
3841 unsigned int W = WRITEBACK_BIT_SET;
c19d1205
ZW
3842 unsigned int Rn = (given & 0x000f0000) >> 16;
3843 unsigned int off = (given & 0x000000ff);
3844
3845 func (stream, "[%s", arm_regnames[Rn]);
c1e26897
NC
3846
3847 if (PRE_BIT_SET)
c19d1205
ZW
3848 {
3849 if (off || !U)
05413229
NC
3850 {
3851 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3852 value_in_comment = off * 4 * U ? 1 : -1;
3853 }
c19d1205
ZW
3854 func (stream, "]");
3855 if (W)
3856 func (stream, "!");
3857 }
3858 else
3859 {
3860 func (stream, "], ");
3861 if (W)
05413229
NC
3862 {
3863 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3864 value_in_comment = off * 4 * U ? 1 : -1;
3865 }
c19d1205 3866 else
fe56b6ce
NC
3867 {
3868 func (stream, "{%u}", off);
3869 value_in_comment = off;
3870 }
c19d1205
ZW
3871 }
3872 }
3873 break;
3874
3875 case 'w':
3876 {
3877 unsigned int Sbit = (given & 0x01000000) >> 24;
3878 unsigned int type = (given & 0x00600000) >> 21;
05413229 3879
c19d1205
ZW
3880 switch (type)
3881 {
3882 case 0: func (stream, Sbit ? "sb" : "b"); break;
3883 case 1: func (stream, Sbit ? "sh" : "h"); break;
3884 case 2:
3885 if (Sbit)
3886 func (stream, "??");
3887 break;
3888 case 3:
3889 func (stream, "??");
3890 break;
3891 }
3892 }
3893 break;
3894
3895 case 'm':
3896 {
3897 int started = 0;
3898 int reg;
3899
3900 func (stream, "{");
3901 for (reg = 0; reg < 16; reg++)
3902 if ((given & (1 << reg)) != 0)
3903 {
3904 if (started)
3905 func (stream, ", ");
3906 started = 1;
3907 func (stream, "%s", arm_regnames[reg]);
3908 }
3909 func (stream, "}");
3910 }
3911 break;
3912
3913 case 'E':
3914 {
3915 unsigned int msb = (given & 0x0000001f);
3916 unsigned int lsb = 0;
fe56b6ce 3917
c19d1205
ZW
3918 lsb |= (given & 0x000000c0u) >> 6;
3919 lsb |= (given & 0x00007000u) >> 10;
3920 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3921 }
3922 break;
3923
3924 case 'F':
3925 {
3926 unsigned int width = (given & 0x0000001f) + 1;
3927 unsigned int lsb = 0;
fe56b6ce 3928
c19d1205
ZW
3929 lsb |= (given & 0x000000c0u) >> 6;
3930 lsb |= (given & 0x00007000u) >> 10;
3931 func (stream, "#%u, #%u", lsb, width);
3932 }
3933 break;
3934
3935 case 'b':
3936 {
3937 unsigned int S = (given & 0x04000000u) >> 26;
3938 unsigned int J1 = (given & 0x00002000u) >> 13;
3939 unsigned int J2 = (given & 0x00000800u) >> 11;
3940 int offset = 0;
3941
3942 offset |= !S << 20;
3943 offset |= J2 << 19;
3944 offset |= J1 << 18;
3945 offset |= (given & 0x003f0000) >> 4;
3946 offset |= (given & 0x000007ff) << 1;
3947 offset -= (1 << 20);
3948
3949 info->print_address_func (pc + 4 + offset, info);
3950 }
3951 break;
3952
3953 case 'B':
3954 {
3955 unsigned int S = (given & 0x04000000u) >> 26;
3956 unsigned int I1 = (given & 0x00002000u) >> 13;
3957 unsigned int I2 = (given & 0x00000800u) >> 11;
3958 int offset = 0;
3959
3960 offset |= !S << 24;
3961 offset |= !(I1 ^ S) << 23;
3962 offset |= !(I2 ^ S) << 22;
3963 offset |= (given & 0x03ff0000u) >> 4;
3964 offset |= (given & 0x000007ffu) << 1;
3965 offset -= (1 << 24);
36b0c57d 3966 offset += pc + 4;
c19d1205 3967
36b0c57d
PB
3968 /* BLX target addresses are always word aligned. */
3969 if ((given & 0x00001000u) == 0)
3970 offset &= ~2u;
3971
3972 info->print_address_func (offset, info);
c19d1205
ZW
3973 }
3974 break;
3975
3976 case 's':
3977 {
3978 unsigned int shift = 0;
fe56b6ce 3979
c19d1205
ZW
3980 shift |= (given & 0x000000c0u) >> 6;
3981 shift |= (given & 0x00007000u) >> 10;
c1e26897 3982 if (WRITEBACK_BIT_SET)
c19d1205
ZW
3983 func (stream, ", asr #%u", shift);
3984 else if (shift)
3985 func (stream, ", lsl #%u", shift);
3986 /* else print nothing - lsl #0 */
3987 }
3988 break;
3989
3990 case 'R':
3991 {
3992 unsigned int rot = (given & 0x00000030) >> 4;
fe56b6ce 3993
c19d1205
ZW
3994 if (rot)
3995 func (stream, ", ror #%u", rot * 8);
3996 }
3997 break;
3998
62b3e311
PB
3999 case 'U':
4000 switch (given & 0xf)
4001 {
fe56b6ce
NC
4002 case 0xf: func (stream, "sy"); break;
4003 case 0x7: func (stream, "un"); break;
4004 case 0xe: func (stream, "st"); break;
4005 case 0x6: func (stream, "unst"); break;
62b3e311 4006 default:
fe56b6ce 4007 func (stream, "#%d", (int) given & 0xf);
62b3e311
PB
4008 break;
4009 }
4010 break;
4011
4012 case 'C':
4013 if ((given & 0xff) == 0)
4014 {
4015 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4016 if (given & 0x800)
4017 func (stream, "f");
4018 if (given & 0x400)
4019 func (stream, "s");
4020 if (given & 0x200)
4021 func (stream, "x");
4022 if (given & 0x100)
4023 func (stream, "c");
4024 }
4025 else
4026 {
4027 func (stream, psr_name (given & 0xff));
4028 }
4029 break;
4030
4031 case 'D':
4032 if ((given & 0xff) == 0)
4033 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
4034 else
4035 func (stream, psr_name (given & 0xff));
4036 break;
4037
c19d1205
ZW
4038 case '0': case '1': case '2': case '3': case '4':
4039 case '5': case '6': case '7': case '8': case '9':
4040 {
16980d0b
JB
4041 int width;
4042 unsigned long val;
c19d1205 4043
16980d0b
JB
4044 c = arm_decode_bitfield (c, given, &val, &width);
4045
c19d1205
ZW
4046 switch (*c)
4047 {
05413229
NC
4048 case 'd':
4049 func (stream, "%lu", val);
4050 value_in_comment = val;
4051 break;
ff4a8d2b 4052
05413229
NC
4053 case 'W':
4054 func (stream, "%lu", val * 4);
4055 value_in_comment = val * 4;
4056 break;
ff4a8d2b
NC
4057
4058 case 'R':
4059 if (val == 15)
4060 is_unpredictable = TRUE;
4061 /* Fall through. */
4062 case 'r':
4063 func (stream, "%s", arm_regnames[val]);
4064 break;
c19d1205
ZW
4065
4066 case 'c':
c22aaad1 4067 func (stream, "%s", arm_conditional[val]);
c19d1205
ZW
4068 break;
4069
4070 case '\'':
c19d1205 4071 c++;
16980d0b
JB
4072 if (val == ((1ul << width) - 1))
4073 func (stream, "%c", *c);
c19d1205
ZW
4074 break;
4075
4076 case '`':
c19d1205 4077 c++;
16980d0b
JB
4078 if (val == 0)
4079 func (stream, "%c", *c);
c19d1205
ZW
4080 break;
4081
4082 case '?':
fe56b6ce 4083 func (stream, "%c", c[(1 << width) - (int) val]);
16980d0b 4084 c += 1 << width;
c19d1205 4085 break;
0bb027fd
RR
4086
4087 case 'x':
4088 func (stream, "0x%lx", val & 0xffffffffUL);
4089 break;
c19d1205
ZW
4090
4091 default:
4092 abort ();
4093 }
4094 }
4095 break;
4096
4097 default:
4098 abort ();
4099 }
4100 }
05413229
NC
4101
4102 if (value_in_comment > 32 || value_in_comment < -16)
4103 func (stream, "\t; 0x%lx", value_in_comment);
ff4a8d2b
NC
4104
4105 if (is_unpredictable)
4106 func (stream, UNPREDICTABLE_INSTRUCTION);
4107
4a5329c6 4108 return;
c19d1205 4109 }
252b5132 4110
58efb6c0 4111 /* No match. */
252b5132
RH
4112 abort ();
4113}
4114
e821645d
DJ
4115/* Print data bytes on INFO->STREAM. */
4116
4117static void
fe56b6ce
NC
4118print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4119 struct disassemble_info *info,
e821645d
DJ
4120 long given)
4121{
4122 switch (info->bytes_per_chunk)
4123 {
4124 case 1:
4125 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4126 break;
4127 case 2:
4128 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4129 break;
4130 case 4:
4131 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4132 break;
4133 default:
4134 abort ();
4135 }
4136}
4137
22a398e1
NC
4138/* Disallow mapping symbols ($a, $b, $d, $t etc) from
4139 being displayed in symbol relative addresses. */
4140
4141bfd_boolean
4142arm_symbol_is_valid (asymbol * sym,
4143 struct disassemble_info * info ATTRIBUTE_UNUSED)
4144{
4145 const char * name;
4146
4147 if (sym == NULL)
4148 return FALSE;
4149
4150 name = bfd_asymbol_name (sym);
4151
4152 return (name && *name != '$');
4153}
4154
58efb6c0 4155/* Parse an individual disassembler option. */
baf0cc5e 4156
a3d9c82d 4157void
4a5329c6 4158parse_arm_disassembler_option (char *option)
dd92f639 4159{
01c7f630 4160 if (option == NULL)
dd92f639 4161 return;
b34976b6 4162
0112cd26 4163 if (CONST_STRNEQ (option, "reg-names-"))
dd92f639 4164 {
58efb6c0 4165 int i;
b34976b6 4166
01c7f630 4167 option += 10;
58efb6c0
NC
4168
4169 for (i = NUM_ARM_REGNAMES; i--;)
31e0f3cd 4170 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
58efb6c0
NC
4171 {
4172 regname_selected = i;
4173 break;
4174 }
b34976b6 4175
58efb6c0 4176 if (i < 0)
31e0f3cd 4177 /* XXX - should break 'option' at following delimiter. */
58efb6c0 4178 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
dd92f639 4179 }
0112cd26 4180 else if (CONST_STRNEQ (option, "force-thumb"))
01c7f630 4181 force_thumb = 1;
0112cd26 4182 else if (CONST_STRNEQ (option, "no-force-thumb"))
01c7f630 4183 force_thumb = 0;
dd92f639 4184 else
31e0f3cd 4185 /* XXX - should break 'option' at following delimiter. */
58efb6c0 4186 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
b34976b6 4187
dd92f639
NC
4188 return;
4189}
4190
31e0f3cd
NC
4191/* Parse the string of disassembler options, spliting it at whitespaces
4192 or commas. (Whitespace separators supported for backwards compatibility). */
baf0cc5e 4193
01c7f630 4194static void
4a5329c6 4195parse_disassembler_options (char *options)
01c7f630 4196{
01c7f630
NC
4197 if (options == NULL)
4198 return;
4199
31e0f3cd 4200 while (*options)
01c7f630 4201 {
31e0f3cd
NC
4202 parse_arm_disassembler_option (options);
4203
4204 /* Skip forward to next seperator. */
4205 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4206 ++ options;
4207 /* Skip forward past seperators. */
4208 while (ISSPACE (*options) || (*options == ','))
4209 ++ options;
01c7f630 4210 }
01c7f630
NC
4211}
4212
c22aaad1
PB
4213/* Search back through the insn stream to determine if this instruction is
4214 conditionally executed. */
fe56b6ce 4215
c22aaad1 4216static void
fe56b6ce
NC
4217find_ifthen_state (bfd_vma pc,
4218 struct disassemble_info *info,
c22aaad1
PB
4219 bfd_boolean little)
4220{
4221 unsigned char b[2];
4222 unsigned int insn;
4223 int status;
4224 /* COUNT is twice the number of instructions seen. It will be odd if we
4225 just crossed an instruction boundary. */
4226 int count;
4227 int it_count;
4228 unsigned int seen_it;
4229 bfd_vma addr;
4230
4231 ifthen_address = pc;
4232 ifthen_state = 0;
4233
4234 addr = pc;
4235 count = 1;
4236 it_count = 0;
4237 seen_it = 0;
4238 /* Scan backwards looking for IT instructions, keeping track of where
4239 instruction boundaries are. We don't know if something is actually an
4240 IT instruction until we find a definite instruction boundary. */
4241 for (;;)
4242 {
fe56b6ce 4243 if (addr == 0 || info->symbol_at_address_func (addr, info))
c22aaad1
PB
4244 {
4245 /* A symbol must be on an instruction boundary, and will not
4246 be within an IT block. */
4247 if (seen_it && (count & 1))
4248 break;
4249
4250 return;
4251 }
4252 addr -= 2;
fe56b6ce 4253 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
c22aaad1
PB
4254 if (status)
4255 return;
4256
4257 if (little)
4258 insn = (b[0]) | (b[1] << 8);
4259 else
4260 insn = (b[1]) | (b[0] << 8);
4261 if (seen_it)
4262 {
4263 if ((insn & 0xf800) < 0xe800)
4264 {
4265 /* Addr + 2 is an instruction boundary. See if this matches
4266 the expected boundary based on the position of the last
4267 IT candidate. */
4268 if (count & 1)
4269 break;
4270 seen_it = 0;
4271 }
4272 }
4273 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4274 {
4275 /* This could be an IT instruction. */
4276 seen_it = insn;
4277 it_count = count >> 1;
4278 }
4279 if ((insn & 0xf800) >= 0xe800)
4280 count++;
4281 else
4282 count = (count + 2) | 1;
4283 /* IT blocks contain at most 4 instructions. */
4284 if (count >= 8 && !seen_it)
4285 return;
4286 }
4287 /* We found an IT instruction. */
4288 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4289 if ((ifthen_state & 0xf) == 0)
4290 ifthen_state = 0;
4291}
4292
b0e28b39
DJ
4293/* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4294 mapping symbol. */
4295
4296static int
4297is_mapping_symbol (struct disassemble_info *info, int n,
4298 enum map_type *map_type)
4299{
4300 const char *name;
4301
4302 name = bfd_asymbol_name (info->symtab[n]);
4303 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4304 && (name[2] == 0 || name[2] == '.'))
4305 {
4306 *map_type = ((name[1] == 'a') ? MAP_ARM
4307 : (name[1] == 't') ? MAP_THUMB
4308 : MAP_DATA);
4309 return TRUE;
4310 }
4311
4312 return FALSE;
4313}
4314
4315/* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4316 Returns nonzero if *MAP_TYPE was set. */
4317
4318static int
4319get_map_sym_type (struct disassemble_info *info,
4320 int n,
4321 enum map_type *map_type)
4322{
4323 /* If the symbol is in a different section, ignore it. */
4324 if (info->section != NULL && info->section != info->symtab[n]->section)
4325 return FALSE;
4326
4327 return is_mapping_symbol (info, n, map_type);
4328}
4329
4330/* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
e821645d 4331 Returns nonzero if *MAP_TYPE was set. */
2087ad84
PB
4332
4333static int
fe56b6ce
NC
4334get_sym_code_type (struct disassemble_info *info,
4335 int n,
e821645d 4336 enum map_type *map_type)
2087ad84
PB
4337{
4338 elf_symbol_type *es;
4339 unsigned int type;
b0e28b39
DJ
4340
4341 /* If the symbol is in a different section, ignore it. */
4342 if (info->section != NULL && info->section != info->symtab[n]->section)
4343 return FALSE;
2087ad84 4344
e821645d 4345 es = *(elf_symbol_type **)(info->symtab + n);
2087ad84
PB
4346 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4347
4348 /* If the symbol has function type then use that. */
4349 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4350 {
e821645d 4351 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
2087ad84
PB
4352 return TRUE;
4353 }
4354
2087ad84
PB
4355 return FALSE;
4356}
4357
0313a2b8
NC
4358/* Given a bfd_mach_arm_XXX value, this function fills in the fields
4359 of the supplied arm_feature_set structure with bitmasks indicating
4360 the support base architectures and coprocessor extensions.
4361
4362 FIXME: This could more efficiently implemented as a constant array,
4363 although it would also be less robust. */
4364
4365static void
4366select_arm_features (unsigned long mach,
4367 arm_feature_set * features)
4368{
4369#undef ARM_FEATURE
4370#define ARM_FEATURE(ARCH,CEXT) \
4371 features->core = (ARCH); \
4372 features->coproc = (CEXT) | FPU_FPA; \
4373 return
4374
4375 switch (mach)
4376 {
4377 case bfd_mach_arm_2: ARM_ARCH_V2;
4378 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4379 case bfd_mach_arm_3: ARM_ARCH_V3;
4380 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4381 case bfd_mach_arm_4: ARM_ARCH_V4;
4382 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4383 case bfd_mach_arm_5: ARM_ARCH_V5;
4384 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4385 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4386 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4387 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4388 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4389 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4390 /* If the machine type is unknown allow all
4391 architecture types and all extensions. */
4392 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4393 default:
4394 abort ();
4395 }
4396}
4397
4398
58efb6c0
NC
4399/* NOTE: There are no checks in these routines that
4400 the relevant number of data bytes exist. */
baf0cc5e 4401
58efb6c0 4402static int
4a5329c6 4403print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
252b5132 4404{
c19d1205
ZW
4405 unsigned char b[4];
4406 long given;
4407 int status;
e821645d 4408 int is_thumb = FALSE;
b0e28b39 4409 int is_data = FALSE;
bd2e2557 4410 int little_code;
e821645d 4411 unsigned int size = 4;
4a5329c6 4412 void (*printer) (bfd_vma, struct disassemble_info *, long);
e821645d 4413 bfd_boolean found = FALSE;
b0e28b39 4414 struct arm_private_data *private_data;
58efb6c0 4415
dd92f639
NC
4416 if (info->disassembler_options)
4417 {
4418 parse_disassembler_options (info->disassembler_options);
b34976b6 4419
58efb6c0 4420 /* To avoid repeated parsing of these options, we remove them here. */
dd92f639
NC
4421 info->disassembler_options = NULL;
4422 }
b34976b6 4423
0313a2b8
NC
4424 /* PR 10288: Control which instructions will be disassembled. */
4425 if (info->private_data == NULL)
4426 {
b0e28b39 4427 static struct arm_private_data private;
0313a2b8
NC
4428
4429 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4430 /* If the user did not use the -m command line switch then default to
4431 disassembling all types of ARM instruction.
4432
4433 The info->mach value has to be ignored as this will be based on
4434 the default archictecture for the target and/or hints in the notes
4435 section, but it will never be greater than the current largest arm
4436 machine value (iWMMXt2), which is only equivalent to the V5TE
4437 architecture. ARM architectures have advanced beyond the machine
4438 value encoding, and these newer architectures would be ignored if
4439 the machine value was used.
4440
4441 Ie the -m switch is used to restrict which instructions will be
4442 disassembled. If it is necessary to use the -m switch to tell
4443 objdump that an ARM binary is being disassembled, eg because the
4444 input is a raw binary file, but it is also desired to disassemble
4445 all ARM instructions then use "-marm". This will select the
4446 "unknown" arm architecture which is compatible with any ARM
4447 instruction. */
4448 info->mach = bfd_mach_arm_unknown;
4449
4450 /* Compute the architecture bitmask from the machine number.
4451 Note: This assumes that the machine number will not change
4452 during disassembly.... */
b0e28b39 4453 select_arm_features (info->mach, & private.features);
0313a2b8 4454
b0e28b39
DJ
4455 private.has_mapping_symbols = -1;
4456
4457 info->private_data = & private;
0313a2b8 4458 }
b0e28b39
DJ
4459
4460 private_data = info->private_data;
4461
bd2e2557
SS
4462 /* Decide if our code is going to be little-endian, despite what the
4463 function argument might say. */
4464 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4465
b0e28b39
DJ
4466 /* For ELF, consult the symbol table to determine what kind of code
4467 or data we have. */
8977d4b2 4468 if (info->symtab_size != 0
e821645d
DJ
4469 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4470 {
4471 bfd_vma addr;
b0e28b39 4472 int n, start;
e821645d 4473 int last_sym = -1;
b0e28b39 4474 enum map_type type = MAP_ARM;
e821645d 4475
e821645d
DJ
4476 /* Start scanning at the start of the function, or wherever
4477 we finished last time. */
b0e28b39
DJ
4478 start = info->symtab_pos + 1;
4479 if (start < last_mapping_sym)
4480 start = last_mapping_sym;
4481 found = FALSE;
e821645d 4482
b0e28b39
DJ
4483 /* First, look for mapping symbols. */
4484 if (private_data->has_mapping_symbols != 0)
e821645d 4485 {
b0e28b39
DJ
4486 /* Scan up to the location being disassembled. */
4487 for (n = start; n < info->symtab_size; n++)
4488 {
4489 addr = bfd_asymbol_value (info->symtab[n]);
4490 if (addr > pc)
4491 break;
4492 if (get_map_sym_type (info, n, &type))
4493 {
4494 last_sym = n;
4495 found = TRUE;
4496 }
4497 }
4498
4499 if (!found)
4500 {
4501 /* No mapping symbol found at this address. Look backwards
4502 for a preceeding one. */
4503 for (n = start - 1; n >= 0; n--)
4504 {
4505 if (get_map_sym_type (info, n, &type))
4506 {
4507 last_sym = n;
4508 found = TRUE;
4509 break;
4510 }
4511 }
4512 }
4513
4514 if (found)
4515 private_data->has_mapping_symbols = 1;
4516
4517 /* No mapping symbols were found. A leading $d may be
4518 omitted for sections which start with data; but for
4519 compatibility with legacy and stripped binaries, only
4520 assume the leading $d if there is at least one mapping
4521 symbol in the file. */
4522 if (!found && private_data->has_mapping_symbols == -1)
e821645d 4523 {
b0e28b39
DJ
4524 /* Look for mapping symbols, in any section. */
4525 for (n = 0; n < info->symtab_size; n++)
4526 if (is_mapping_symbol (info, n, &type))
4527 {
4528 private_data->has_mapping_symbols = 1;
4529 break;
4530 }
4531 if (private_data->has_mapping_symbols == -1)
4532 private_data->has_mapping_symbols = 0;
4533 }
4534
4535 if (!found && private_data->has_mapping_symbols == 1)
4536 {
4537 type = MAP_DATA;
e821645d
DJ
4538 found = TRUE;
4539 }
4540 }
4541
b0e28b39
DJ
4542 /* Next search for function symbols to separate ARM from Thumb
4543 in binaries without mapping symbols. */
e821645d
DJ
4544 if (!found)
4545 {
b0e28b39
DJ
4546 /* Scan up to the location being disassembled. */
4547 for (n = start; n < info->symtab_size; n++)
e821645d 4548 {
b0e28b39
DJ
4549 addr = bfd_asymbol_value (info->symtab[n]);
4550 if (addr > pc)
4551 break;
4552 if (get_sym_code_type (info, n, &type))
e821645d
DJ
4553 {
4554 last_sym = n;
4555 found = TRUE;
b0e28b39
DJ
4556 }
4557 }
4558
4559 if (!found)
4560 {
4561 /* No mapping symbol found at this address. Look backwards
4562 for a preceeding one. */
4563 for (n = start - 1; n >= 0; n--)
4564 {
4565 if (get_sym_code_type (info, n, &type))
4566 {
4567 last_sym = n;
4568 found = TRUE;
4569 break;
4570 }
e821645d
DJ
4571 }
4572 }
4573 }
4574
4575 last_mapping_sym = last_sym;
4576 last_type = type;
4577 is_thumb = (last_type == MAP_THUMB);
4578 is_data = (last_type == MAP_DATA);
b34976b6 4579
e821645d
DJ
4580 /* Look a little bit ahead to see if we should print out
4581 two or four bytes of data. If there's a symbol,
4582 mapping or otherwise, after two bytes then don't
4583 print more. */
4584 if (is_data)
4585 {
4586 size = 4 - (pc & 3);
4587 for (n = last_sym + 1; n < info->symtab_size; n++)
4588 {
4589 addr = bfd_asymbol_value (info->symtab[n]);
e3e535bc
NC
4590 if (addr > pc
4591 && (info->section == NULL
4592 || info->section == info->symtab[n]->section))
e821645d
DJ
4593 {
4594 if (addr - pc < size)
4595 size = addr - pc;
4596 break;
4597 }
4598 }
4599 /* If the next symbol is after three bytes, we need to
4600 print only part of the data, so that we can use either
4601 .byte or .short. */
4602 if (size == 3)
4603 size = (pc & 1) ? 1 : 2;
4604 }
4605 }
4606
4607 if (info->symbols != NULL)
252b5132 4608 {
5876e06d
NC
4609 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4610 {
2f0ca46a 4611 coff_symbol_type * cs;
b34976b6 4612
5876e06d
NC
4613 cs = coffsymbol (*info->symbols);
4614 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4615 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4616 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4617 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4618 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4619 }
e821645d
DJ
4620 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4621 && !found)
5876e06d 4622 {
2087ad84
PB
4623 /* If no mapping symbol has been found then fall back to the type
4624 of the function symbol. */
e821645d
DJ
4625 elf_symbol_type * es;
4626 unsigned int type;
2087ad84 4627
e821645d
DJ
4628 es = *(elf_symbol_type **)(info->symbols);
4629 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2087ad84 4630
e821645d 4631 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
5876e06d
NC
4632 }
4633 }
b34976b6 4634
e821645d
DJ
4635 if (force_thumb)
4636 is_thumb = TRUE;
4637
b8f9ee44
CL
4638 if (is_data)
4639 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4640 else
4641 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4642
c19d1205 4643 info->bytes_per_line = 4;
252b5132 4644
1316c8b3
NC
4645 /* PR 10263: Disassemble data if requested to do so by the user. */
4646 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
e821645d
DJ
4647 {
4648 int i;
4649
1316c8b3 4650 /* Size was already set above. */
e821645d
DJ
4651 info->bytes_per_chunk = size;
4652 printer = print_insn_data;
4653
fe56b6ce 4654 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
e821645d
DJ
4655 given = 0;
4656 if (little)
4657 for (i = size - 1; i >= 0; i--)
4658 given = b[i] | (given << 8);
4659 else
4660 for (i = 0; i < (int) size; i++)
4661 given = b[i] | (given << 8);
4662 }
4663 else if (!is_thumb)
252b5132 4664 {
c19d1205
ZW
4665 /* In ARM mode endianness is a straightforward issue: the instruction
4666 is four bytes long and is either ordered 0123 or 3210. */
4667 printer = print_insn_arm;
4668 info->bytes_per_chunk = 4;
4a5329c6 4669 size = 4;
c19d1205 4670
0313a2b8 4671 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
bd2e2557 4672 if (little_code)
c19d1205
ZW
4673 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4674 else
4675 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
252b5132 4676 }
58efb6c0 4677 else
252b5132 4678 {
c19d1205
ZW
4679 /* In Thumb mode we have the additional wrinkle of two
4680 instruction lengths. Fortunately, the bits that determine
4681 the length of the current instruction are always to be found
4682 in the first two bytes. */
4a5329c6 4683 printer = print_insn_thumb16;
c19d1205 4684 info->bytes_per_chunk = 2;
4a5329c6
ZW
4685 size = 2;
4686
fe56b6ce 4687 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
bd2e2557 4688 if (little_code)
9a2ff3f5
AM
4689 given = (b[0]) | (b[1] << 8);
4690 else
4691 given = (b[1]) | (b[0] << 8);
4692
c19d1205 4693 if (!status)
252b5132 4694 {
c19d1205
ZW
4695 /* These bit patterns signal a four-byte Thumb
4696 instruction. */
4697 if ((given & 0xF800) == 0xF800
4698 || (given & 0xF800) == 0xF000
4699 || (given & 0xF800) == 0xE800)
252b5132 4700 {
0313a2b8 4701 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
bd2e2557 4702 if (little_code)
c19d1205 4703 given = (b[0]) | (b[1] << 8) | (given << 16);
b7693d02 4704 else
c19d1205
ZW
4705 given = (b[1]) | (b[0] << 8) | (given << 16);
4706
4707 printer = print_insn_thumb32;
4a5329c6 4708 size = 4;
252b5132 4709 }
252b5132 4710 }
c22aaad1
PB
4711
4712 if (ifthen_address != pc)
0313a2b8 4713 find_ifthen_state (pc, info, little_code);
c22aaad1
PB
4714
4715 if (ifthen_state)
4716 {
4717 if ((ifthen_state & 0xf) == 0x8)
4718 ifthen_next_state = 0;
4719 else
4720 ifthen_next_state = (ifthen_state & 0xe0)
4721 | ((ifthen_state & 0xf) << 1);
4722 }
252b5132 4723 }
b34976b6 4724
c19d1205
ZW
4725 if (status)
4726 {
4727 info->memory_error_func (status, pc, info);
4728 return -1;
4729 }
6a56ec7e
NC
4730 if (info->flags & INSN_HAS_RELOC)
4731 /* If the instruction has a reloc associated with it, then
4732 the offset field in the instruction will actually be the
4733 addend for the reloc. (We are using REL type relocs).
4734 In such cases, we can ignore the pc when computing
4735 addresses, since the addend is not currently pc-relative. */
4736 pc = 0;
b34976b6 4737
4a5329c6 4738 printer (pc, info, given);
c22aaad1
PB
4739
4740 if (is_thumb)
4741 {
4742 ifthen_state = ifthen_next_state;
4743 ifthen_address += size;
4744 }
4a5329c6 4745 return size;
252b5132
RH
4746}
4747
4748int
4a5329c6 4749print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
252b5132 4750{
bd2e2557
SS
4751 /* Detect BE8-ness and record it in the disassembler info. */
4752 if (info->flavour == bfd_target_elf_flavour
4753 && info->section != NULL
4754 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4755 info->endian_code = BFD_ENDIAN_LITTLE;
4756
b34976b6 4757 return print_insn (pc, info, FALSE);
58efb6c0 4758}
01c7f630 4759
58efb6c0 4760int
4a5329c6 4761print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
58efb6c0 4762{
b34976b6 4763 return print_insn (pc, info, TRUE);
58efb6c0 4764}
252b5132 4765
58efb6c0 4766void
4a5329c6 4767print_arm_disassembler_options (FILE *stream)
58efb6c0
NC
4768{
4769 int i;
252b5132 4770
58efb6c0
NC
4771 fprintf (stream, _("\n\
4772The following ARM specific disassembler options are supported for use with\n\
4773the -M switch:\n"));
b34976b6 4774
58efb6c0
NC
4775 for (i = NUM_ARM_REGNAMES; i--;)
4776 fprintf (stream, " reg-names-%s %*c%s\n",
4777 regnames[i].name,
d5b2f4d6 4778 (int)(14 - strlen (regnames[i].name)), ' ',
58efb6c0
NC
4779 regnames[i].description);
4780
4781 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4782 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
252b5132 4783}
This page took 0.832268 seconds and 4 git commands to generate.