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