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