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