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