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