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