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