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