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