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