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