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