]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - opcodes/arm-dis.c
2009-07-10 Doug Kwan <dougkwan@google.com>
[thirdparty/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"},
1103f72c 145 {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
2d447fca 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"},
1103f72c 149 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
2d447fca 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"},
78c66db8
NC
1006 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
1007 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
05413229 1008 {ARM_EXT_V1, 0x000000b0, 0x0e1000f0, "strh%c\t%12-15r, %s"},
37b37b2d
RE
1009 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1010 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1011 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1012 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1013 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1014 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1015 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1016 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1017 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
8f06b2d8
PB
1018 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1019 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
37b37b2d
RE
1020 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
1021 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
1022 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
1023 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
1024 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1025 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1026 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1027 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1028 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1029 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1030 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1031 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1032 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1033 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
05413229 1034 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
37b37b2d
RE
1035 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1036 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1037 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1038 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1039 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1040 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1041 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1042 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
8f06b2d8 1043 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
c16d2bf0 1044 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
8f06b2d8
PB
1045
1046 /* The rest. */
05413229 1047 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
8f06b2d8
PB
1048 {0, 0x00000000, 0x00000000, 0}
1049};
1050
1051/* print_insn_thumb16 recognizes the following format control codes:
1052
1053 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1054 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1055 %<bitfield>I print bitfield as a signed decimal
1056 (top bit of range being the sign bit)
1057 %N print Thumb register mask (with LR)
1058 %O print Thumb register mask (with PC)
1059 %M print Thumb register mask
1060 %b print CZB's 6-bit unsigned branch destination
1061 %s print Thumb right-shift immediate (6..10; 0 == 32).
c22aaad1
PB
1062 %c print the condition code
1063 %C print the condition code, or "s" if not conditional
1064 %x print warning if conditional an not at end of IT block"
1065 %X print "\t; unpredictable <IT:code>" if conditional
1066 %I print IT instruction suffix and operands
8f06b2d8
PB
1067 %<bitfield>r print bitfield as an ARM register
1068 %<bitfield>d print bitfield as a decimal
1069 %<bitfield>H print (bitfield * 2) as a decimal
1070 %<bitfield>W print (bitfield * 4) as a decimal
1071 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1072 %<bitfield>B print Thumb branch destination (signed displacement)
1073 %<bitfield>c print bitfield as a condition code
1074 %<bitnum>'c print specified char iff bit is one
1075 %<bitnum>?ab print a if bit is one else print b. */
1076
1077static const struct opcode16 thumb_opcodes[] =
1078{
1079 /* Thumb instructions. */
1080
1081 /* ARM V6K no-argument instructions. */
c22aaad1
PB
1082 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1083 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1084 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1085 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1086 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1087 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
8f06b2d8
PB
1088
1089 /* ARM V6T2 instructions. */
c22aaad1
PB
1090 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1091 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1092 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
8f06b2d8
PB
1093
1094 /* ARM V6. */
c22aaad1
PB
1095 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1096 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1097 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1098 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1099 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1100 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1101 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1102 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1103 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1104 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1105 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
8f06b2d8
PB
1106
1107 /* ARM V5 ISA extends Thumb. */
c22aaad1 1108 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
8f06b2d8 1109 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
c22aaad1 1110 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
8f06b2d8 1111 /* ARM V4T ISA (Thumb v1). */
fe56b6ce 1112 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
8f06b2d8 1113 /* Format 4. */
c22aaad1
PB
1114 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1115 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1116 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1117 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1118 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1119 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1120 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1121 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1122 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1123 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1124 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1125 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1126 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1127 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1128 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1129 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
8f06b2d8 1130 /* format 13 */
c22aaad1
PB
1131 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1132 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
8f06b2d8 1133 /* format 5 */
c22aaad1
PB
1134 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1135 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1136 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1137 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
8f06b2d8 1138 /* format 14 */
c22aaad1
PB
1139 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1140 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
8f06b2d8 1141 /* format 2 */
c22aaad1
PB
1142 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1143 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1144 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1145 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
8f06b2d8 1146 /* format 8 */
c22aaad1
PB
1147 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1148 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1149 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
8f06b2d8 1150 /* format 7 */
c22aaad1
PB
1151 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1152 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
8f06b2d8 1153 /* format 1 */
c22aaad1
PB
1154 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1155 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1156 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
8f06b2d8 1157 /* format 3 */
c22aaad1
PB
1158 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1159 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1160 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1161 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
8f06b2d8 1162 /* format 6 */
fe56b6ce 1163 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
8f06b2d8 1164 /* format 9 */
c22aaad1
PB
1165 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1166 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1167 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1168 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
8f06b2d8 1169 /* format 10 */
c22aaad1
PB
1170 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1171 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
8f06b2d8 1172 /* format 11 */
c22aaad1
PB
1173 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1174 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
8f06b2d8 1175 /* format 12 */
fe56b6ce 1176 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
c22aaad1 1177 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
8f06b2d8 1178 /* format 15 */
c22aaad1
PB
1179 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1180 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
8f06b2d8 1181 /* format 17 */
c22aaad1 1182 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
8f06b2d8 1183 /* format 16 */
05413229 1184 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
c22aaad1 1185 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
8f06b2d8 1186 /* format 18 */
c22aaad1 1187 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
8f06b2d8
PB
1188
1189 /* The E800 .. FFFF range is unconditionally redirected to the
1190 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1191 are processed via that table. Thus, we can never encounter a
1192 bare "second half of BL/BLX(1)" instruction here. */
05413229 1193 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
8f06b2d8
PB
1194 {0, 0, 0, 0}
1195};
1196
1197/* Thumb32 opcodes use the same table structure as the ARM opcodes.
1198 We adopt the convention that hw1 is the high 16 bits of .value and
1199 .mask, hw2 the low 16 bits.
1200
1201 print_insn_thumb32 recognizes the following format control codes:
1202
1203 %% %
1204
1205 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1206 %M print a modified 12-bit immediate (same location)
1207 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1208 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1209 %S print a possibly-shifted Rm
1210
1211 %a print the address of a plain load/store
1212 %w print the width and signedness of a core load/store
1213 %m print register mask for ldm/stm
1214
1215 %E print the lsb and width fields of a bfc/bfi instruction
1216 %F print the lsb and width fields of a sbfx/ubfx instruction
1217 %b print a conditional branch offset
1218 %B print an unconditional branch offset
1219 %s print the shift field of an SSAT instruction
1220 %R print the rotation field of an SXT instruction
62b3e311
PB
1221 %U print barrier type.
1222 %P print address for pli instruction.
c22aaad1
PB
1223 %c print the condition code
1224 %x print warning if conditional an not at end of IT block"
1225 %X print "\t; unpredictable <IT:code>" if conditional
8f06b2d8
PB
1226
1227 %<bitfield>d print bitfield in decimal
1228 %<bitfield>W print bitfield*4 in decimal
1229 %<bitfield>r print bitfield as an ARM register
1230 %<bitfield>c print bitfield as a condition code
1231
16980d0b
JB
1232 %<bitfield>'c print specified char iff bitfield is all ones
1233 %<bitfield>`c print specified char iff bitfield is all zeroes
1234 %<bitfield>?ab... select from array of values in big endian order
8f06b2d8
PB
1235
1236 With one exception at the bottom (done because BL and BLX(1) need
1237 to come dead last), this table was machine-sorted first in
1238 decreasing order of number of bits set in the mask, then in
1239 increasing numeric order of mask, then in increasing numeric order
1240 of opcode. This order is not the clearest for a human reader, but
1241 is guaranteed never to catch a special-case bit pattern with a more
1242 general mask, which is important, because this instruction encoding
1243 makes heavy use of special-case bit patterns. */
1244static const struct opcode32 thumb32_opcodes[] =
1245{
62b3e311 1246 /* V7 instructions. */
c22aaad1
PB
1247 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1248 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1249 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1250 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1251 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1252 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1253 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
62b3e311 1254
8f06b2d8 1255 /* Instructions defined in the basic V6T2 set. */
c22aaad1
PB
1256 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1257 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1258 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1259 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
fe2ceba1 1260 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
c22aaad1
PB
1261 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1262
1263 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1264 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1265 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1266 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1267 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1268 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1269 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1270 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1271 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1272 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1273 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1274 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1275 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1276 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1277 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1278 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
b6702015
PB
1279 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1280 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
c22aaad1
PB
1281 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1282 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1283 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1284 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1285 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1286 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1287 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1288 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1289 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1290 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1291 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1292 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1293 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1294 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
087b80de
JM
1295 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1296 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1297 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1298 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
c22aaad1
PB
1299 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1300 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1301 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1302 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1303 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1304 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1305 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1306 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1307 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1308 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1309 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1310 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1311 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1312 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1313 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1314 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1315 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1316 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1317 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1318 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1319 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1320 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1321 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1322 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1323 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1324 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1325 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1326 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1327 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1328 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1329 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1330 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1331 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1332 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1333 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1334 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1335 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1336 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1337 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1338 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1339 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1340 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1341 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1342 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1343 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1344 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1345 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1346 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1347 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1348 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1349 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1350 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1351 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1352 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1353 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1354 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1355 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1356 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1357 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1358 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1359 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1360 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1361 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1362 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1363 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1364 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1365 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1366 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1367 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1368 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1369 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1370 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1371 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1372 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1373 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1374 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1375 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1376 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1377 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1378 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1379 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1380 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1381 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1382 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1383 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1384 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1385 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1387 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1388 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1389 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1390 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1391 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1392 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1393 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1395 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1396 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1397 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1398 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1399 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1400 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1401 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1402 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1403 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1404 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1405 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1406 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1407 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1408 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1409 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1410 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1411 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1412 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1413 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1414 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1415 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1416 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1417 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1418 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1419 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1420 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1421 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1422 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1423 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1424 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1425 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1426 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1427 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1428 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
79d49516
PB
1429 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1430 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1431 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1432 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
c22aaad1
PB
1433 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1434 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
c19d1205
ZW
1435
1436 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1437 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1438 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
c22aaad1
PB
1439 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1440 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
c19d1205 1441
8f06b2d8 1442 /* These have been 32-bit since the invention of Thumb. */
c22aaad1
PB
1443 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1444 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
8f06b2d8
PB
1445
1446 /* Fallback. */
05413229 1447 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
8f06b2d8
PB
1448 {0, 0, 0, 0}
1449};
1450
1451static const char *const arm_conditional[] =
1452{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
c22aaad1 1453 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
8f06b2d8
PB
1454
1455static const char *const arm_fp_const[] =
1456{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1457
1458static const char *const arm_shift[] =
1459{"lsl", "lsr", "asr", "ror"};
1460
1461typedef struct
1462{
1463 const char *name;
1464 const char *description;
1465 const char *reg_names[16];
1466}
1467arm_regname;
1468
1469static const arm_regname regnames[] =
1470{
1471 { "raw" , "Select raw register names",
1472 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1473 { "gcc", "Select register names used by GCC",
1474 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1475 { "std", "Select register names used in ARM's ISA documentation",
1476 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1477 { "apcs", "Select register names used in the APCS",
1478 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1479 { "atpcs", "Select register names used in the ATPCS",
1480 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1481 { "special-atpcs", "Select special register names used in the ATPCS",
1482 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1483};
1484
1485static const char *const iwmmxt_wwnames[] =
1486{"b", "h", "w", "d"};
1487
1488static const char *const iwmmxt_wwssnames[] =
2d447fca
JM
1489{"b", "bus", "bc", "bss",
1490 "h", "hus", "hc", "hss",
1491 "w", "wus", "wc", "wss",
1492 "d", "dus", "dc", "dss"
8f06b2d8
PB
1493};
1494
1495static const char *const iwmmxt_regnames[] =
1496{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1497 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1498};
1499
1500static const char *const iwmmxt_cregnames[] =
1501{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1502 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1503};
1504
1505/* Default to GCC register name set. */
1506static unsigned int regname_selected = 1;
1507
1508#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1509#define arm_regnames regnames[regname_selected].reg_names
1510
1511static bfd_boolean force_thumb = FALSE;
1512
c22aaad1
PB
1513/* Current IT instruction state. This contains the same state as the IT
1514 bits in the CPSR. */
1515static unsigned int ifthen_state;
1516/* IT state for the next instruction. */
1517static unsigned int ifthen_next_state;
1518/* The address of the insn for which the IT state is valid. */
1519static bfd_vma ifthen_address;
1520#define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1521
e821645d 1522/* Cached mapping symbol state. */
fe56b6ce
NC
1523enum map_type
1524{
e821645d
DJ
1525 MAP_ARM,
1526 MAP_THUMB,
1527 MAP_DATA
1528};
1529
1530enum map_type last_type;
2087ad84
PB
1531int last_mapping_sym = -1;
1532bfd_vma last_mapping_addr = 0;
1533
8f06b2d8
PB
1534\f
1535/* Functions. */
1536int
1537get_arm_regname_num_options (void)
1538{
1539 return NUM_ARM_REGNAMES;
1540}
1541
1542int
1543set_arm_regname_option (int option)
1544{
1545 int old = regname_selected;
1546 regname_selected = option;
1547 return old;
1548}
1549
1550int
fe56b6ce
NC
1551get_arm_regnames (int option,
1552 const char **setname,
1553 const char **setdescription,
8f06b2d8
PB
1554 const char *const **register_names)
1555{
1556 *setname = regnames[option].name;
1557 *setdescription = regnames[option].description;
1558 *register_names = regnames[option].reg_names;
1559 return 16;
1560}
1561
16980d0b
JB
1562/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1563 Returns pointer to following character of the format string and
1564 fills in *VALUEP and *WIDTHP with the extracted value and number of
fe56b6ce 1565 bits extracted. WIDTHP can be NULL. */
16980d0b
JB
1566
1567static const char *
fe56b6ce
NC
1568arm_decode_bitfield (const char *ptr,
1569 unsigned long insn,
1570 unsigned long *valuep,
1571 int *widthp)
16980d0b
JB
1572{
1573 unsigned long value = 0;
1574 int width = 0;
1575
1576 do
1577 {
1578 int start, end;
1579 int bits;
1580
1581 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1582 start = start * 10 + *ptr - '0';
1583 if (*ptr == '-')
1584 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1585 end = end * 10 + *ptr - '0';
1586 else
1587 end = start;
1588 bits = end - start;
1589 if (bits < 0)
1590 abort ();
1591 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1592 width += bits + 1;
1593 }
1594 while (*ptr++ == ',');
1595 *valuep = value;
1596 if (widthp)
1597 *widthp = width;
1598 return ptr - 1;
1599}
1600
8f06b2d8 1601static void
37b37b2d 1602arm_decode_shift (long given, fprintf_ftype func, void *stream,
78c66db8 1603 bfd_boolean print_shift)
8f06b2d8
PB
1604{
1605 func (stream, "%s", arm_regnames[given & 0xf]);
1606
1607 if ((given & 0xff0) != 0)
1608 {
1609 if ((given & 0x10) == 0)
1610 {
1611 int amount = (given & 0xf80) >> 7;
1612 int shift = (given & 0x60) >> 5;
1613
1614 if (amount == 0)
1615 {
1616 if (shift == 3)
1617 {
1618 func (stream, ", rrx");
1619 return;
1620 }
1621
1622 amount = 32;
1623 }
1624
37b37b2d
RE
1625 if (print_shift)
1626 func (stream, ", %s #%d", arm_shift[shift], amount);
1627 else
1628 func (stream, ", #%d", amount);
8f06b2d8 1629 }
37b37b2d 1630 else if (print_shift)
8f06b2d8
PB
1631 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1632 arm_regnames[(given & 0xf00) >> 8]);
37b37b2d
RE
1633 else
1634 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
8f06b2d8
PB
1635 }
1636}
1637
1638/* Print one coprocessor instruction on INFO->STREAM.
1639 Return TRUE if the instuction matched, FALSE if this is not a
1640 recognised coprocessor instruction. */
1641
1642static bfd_boolean
fe56b6ce
NC
1643print_insn_coprocessor (bfd_vma pc,
1644 struct disassemble_info *info,
1645 long given,
8f06b2d8
PB
1646 bfd_boolean thumb)
1647{
1648 const struct opcode32 *insn;
1649 void *stream = info->stream;
1650 fprintf_ftype func = info->fprintf_func;
1651 unsigned long mask;
1652 unsigned long value;
05413229 1653 unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
c22aaad1 1654 int cond;
8f06b2d8
PB
1655
1656 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1657 {
05413229 1658 signed long value_in_comment = 0;
0313a2b8
NC
1659 const char *c;
1660
05413229
NC
1661 if (insn->arch == 0)
1662 switch (insn->value)
1663 {
1664 case SENTINEL_IWMMXT_START:
1665 if (info->mach != bfd_mach_arm_XScale
1666 && info->mach != bfd_mach_arm_iWMMXt
1667 && info->mach != bfd_mach_arm_iWMMXt2)
1668 do
1669 insn++;
1670 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1671 continue;
1672
1673 case SENTINEL_IWMMXT_END:
1674 continue;
1675
1676 case SENTINEL_GENERIC_START:
1677 allowed_arches = ((arm_feature_set *) info->private_data)->core;
1678 continue;
1679
1680 default:
1681 abort ();
1682 }
8f06b2d8
PB
1683
1684 mask = insn->mask;
1685 value = insn->value;
1686 if (thumb)
1687 {
1688 /* The high 4 bits are 0xe for Arm conditional instructions, and
1689 0xe for arm unconditional instructions. The rest of the
1690 encoding is the same. */
1691 mask |= 0xf0000000;
1692 value |= 0xe0000000;
c22aaad1
PB
1693 if (ifthen_state)
1694 cond = IFTHEN_COND;
1695 else
1696 cond = 16;
8f06b2d8
PB
1697 }
1698 else
1699 {
1700 /* Only match unconditional instuctions against unconditional
1701 patterns. */
1702 if ((given & 0xf0000000) == 0xf0000000)
c22aaad1
PB
1703 {
1704 mask |= 0xf0000000;
1705 cond = 16;
1706 }
1707 else
1708 {
1709 cond = (given >> 28) & 0xf;
1710 if (cond == 0xe)
1711 cond = 16;
1712 }
8f06b2d8 1713 }
0313a2b8
NC
1714
1715 if ((given & mask) != value)
1716 continue;
8f06b2d8 1717
05413229 1718 if ((insn->arch & allowed_arches) == 0)
0313a2b8
NC
1719 continue;
1720
1721 for (c = insn->assembler; *c; c++)
1722 {
1723 if (*c == '%')
8f06b2d8 1724 {
0313a2b8 1725 switch (*++c)
8f06b2d8 1726 {
0313a2b8
NC
1727 case '%':
1728 func (stream, "%%");
1729 break;
1730
1731 case 'A':
05413229
NC
1732 {
1733 int offset = given & 0xff;
0313a2b8 1734
05413229 1735 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
8f06b2d8 1736
05413229
NC
1737 value_in_comment = offset * 4;
1738 if ((given & 0x00800000) == 0)
1739 value_in_comment = - value_in_comment;
1740
1741 if ((given & (1 << 24)) != 0)
1742 {
1743 if (offset)
fe56b6ce
NC
1744 func (stream, ", #%d]%s",
1745 value_in_comment,
05413229
NC
1746 ((given & 0x00200000) != 0 ? "!" : ""));
1747 else
1748 func (stream, "]");
1749 }
1750 else
1751 {
0313a2b8 1752 func (stream, "]");
8f06b2d8 1753
05413229
NC
1754 if (given & (1 << 21))
1755 {
1756 if (offset)
fe56b6ce 1757 func (stream, ", #%d", value_in_comment);
05413229
NC
1758 }
1759 else
fe56b6ce
NC
1760 {
1761 func (stream, ", {%d}", offset);
1762 value_in_comment = offset;
1763 }
05413229
NC
1764 }
1765 }
0313a2b8 1766 break;
8f06b2d8 1767
0313a2b8
NC
1768 case 'B':
1769 {
1770 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1771 int offset = (given >> 1) & 0x3f;
1772
1773 if (offset == 1)
1774 func (stream, "{d%d}", regno);
1775 else if (regno + offset > 32)
1776 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1777 else
1778 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1779 }
1780 break;
8f06b2d8 1781
0313a2b8
NC
1782 case 'C':
1783 {
1784 int rn = (given >> 16) & 0xf;
1785 int offset = (given & 0xff) * 4;
1786 int add = (given >> 23) & 1;
8f06b2d8 1787
0313a2b8
NC
1788 func (stream, "[%s", arm_regnames[rn]);
1789
1790 if (offset)
16980d0b 1791 {
0313a2b8
NC
1792 if (!add)
1793 offset = -offset;
1794 func (stream, ", #%d", offset);
fe56b6ce
NC
1795 if (rn != 15)
1796 value_in_comment = offset;
16980d0b 1797 }
0313a2b8
NC
1798 func (stream, "]");
1799 if (rn == 15)
16980d0b 1800 {
0313a2b8
NC
1801 func (stream, "\t; ");
1802 /* FIXME: Unsure if info->bytes_per_chunk is the
1803 right thing to use here. */
1804 info->print_address_func (offset + pc
1805 + info->bytes_per_chunk * 2, info);
16980d0b 1806 }
0313a2b8
NC
1807 }
1808 break;
c22aaad1 1809
0313a2b8
NC
1810 case 'c':
1811 func (stream, "%s", arm_conditional[cond]);
1812 break;
8f06b2d8 1813
0313a2b8
NC
1814 case 'I':
1815 /* Print a Cirrus/DSP shift immediate. */
1816 /* Immediates are 7bit signed ints with bits 0..3 in
1817 bits 0..3 of opcode and bits 4..6 in bits 5..7
1818 of opcode. */
1819 {
1820 int imm;
8f06b2d8 1821
0313a2b8 1822 imm = (given & 0xf) | ((given & 0xe0) >> 1);
8f06b2d8 1823
0313a2b8
NC
1824 /* Is ``imm'' a negative number? */
1825 if (imm & 0x40)
1826 imm |= (-1 << 7);
8f06b2d8 1827
0313a2b8
NC
1828 func (stream, "%d", imm);
1829 }
1830
1831 break;
8f06b2d8 1832
0313a2b8
NC
1833 case 'F':
1834 switch (given & 0x00408000)
1835 {
1836 case 0:
1837 func (stream, "4");
1838 break;
1839 case 0x8000:
1840 func (stream, "1");
1841 break;
1842 case 0x00400000:
1843 func (stream, "2");
8f06b2d8 1844 break;
0313a2b8
NC
1845 default:
1846 func (stream, "3");
1847 }
1848 break;
8f06b2d8 1849
0313a2b8
NC
1850 case 'P':
1851 switch (given & 0x00080080)
1852 {
1853 case 0:
1854 func (stream, "s");
1855 break;
1856 case 0x80:
1857 func (stream, "d");
1858 break;
1859 case 0x00080000:
1860 func (stream, "e");
1861 break;
1862 default:
1863 func (stream, _("<illegal precision>"));
8f06b2d8 1864 break;
0313a2b8
NC
1865 }
1866 break;
8f06b2d8 1867
0313a2b8
NC
1868 case 'Q':
1869 switch (given & 0x00408000)
1870 {
1871 case 0:
1872 func (stream, "s");
8f06b2d8 1873 break;
0313a2b8
NC
1874 case 0x8000:
1875 func (stream, "d");
8f06b2d8 1876 break;
0313a2b8
NC
1877 case 0x00400000:
1878 func (stream, "e");
1879 break;
1880 default:
1881 func (stream, "p");
8f06b2d8 1882 break;
0313a2b8
NC
1883 }
1884 break;
8f06b2d8 1885
0313a2b8
NC
1886 case 'R':
1887 switch (given & 0x60)
1888 {
1889 case 0:
1890 break;
1891 case 0x20:
1892 func (stream, "p");
1893 break;
1894 case 0x40:
1895 func (stream, "m");
1896 break;
1897 default:
1898 func (stream, "z");
1899 break;
1900 }
1901 break;
16980d0b 1902
0313a2b8
NC
1903 case '0': case '1': case '2': case '3': case '4':
1904 case '5': case '6': case '7': case '8': case '9':
1905 {
1906 int width;
1907 unsigned long value;
8f06b2d8 1908
0313a2b8 1909 c = arm_decode_bitfield (c, given, &value, &width);
8f06b2d8 1910
0313a2b8
NC
1911 switch (*c)
1912 {
1913 case 'r':
1914 func (stream, "%s", arm_regnames[value]);
1915 break;
1916 case 'D':
1917 func (stream, "d%ld", value);
1918 break;
1919 case 'Q':
1920 if (value & 1)
1921 func (stream, "<illegal reg q%ld.5>", value >> 1);
1922 else
1923 func (stream, "q%ld", value >> 1);
1924 break;
1925 case 'd':
1926 func (stream, "%ld", value);
05413229 1927 value_in_comment = value;
0313a2b8
NC
1928 break;
1929 case 'k':
1930 {
1931 int from = (given & (1 << 7)) ? 32 : 16;
1932 func (stream, "%ld", from - value);
1933 }
1934 break;
8f06b2d8 1935
0313a2b8
NC
1936 case 'f':
1937 if (value > 7)
1938 func (stream, "#%s", arm_fp_const[value & 7]);
1939 else
1940 func (stream, "f%ld", value);
1941 break;
4146fd53 1942
0313a2b8
NC
1943 case 'w':
1944 if (width == 2)
1945 func (stream, "%s", iwmmxt_wwnames[value]);
1946 else
1947 func (stream, "%s", iwmmxt_wwssnames[value]);
1948 break;
4146fd53 1949
0313a2b8
NC
1950 case 'g':
1951 func (stream, "%s", iwmmxt_regnames[value]);
1952 break;
1953 case 'G':
1954 func (stream, "%s", iwmmxt_cregnames[value]);
16980d0b 1955 break;
8f06b2d8 1956
0313a2b8
NC
1957 case 'x':
1958 func (stream, "0x%lx", value);
1959 break;
8f06b2d8 1960
0313a2b8
NC
1961 case '`':
1962 c++;
1963 if (value == 0)
1964 func (stream, "%c", *c);
1965 break;
1966 case '\'':
1967 c++;
1968 if (value == ((1ul << width) - 1))
1969 func (stream, "%c", *c);
1970 break;
1971 case '?':
fe56b6ce 1972 func (stream, "%c", c[(1 << width) - (int) value]);
0313a2b8
NC
1973 c += 1 << width;
1974 break;
1975 default:
1976 abort ();
1977 }
1978 break;
8f06b2d8 1979
0313a2b8
NC
1980 case 'y':
1981 case 'z':
1982 {
1983 int single = *c++ == 'y';
1984 int regno;
1985
1986 switch (*c)
1987 {
1988 case '4': /* Sm pair */
1989 case '0': /* Sm, Dm */
1990 regno = given & 0x0000000f;
1991 if (single)
1992 {
1993 regno <<= 1;
1994 regno += (given >> 5) & 1;
16980d0b 1995 }
0313a2b8
NC
1996 else
1997 regno += ((given >> 5) & 1) << 4;
1998 break;
8f06b2d8 1999
0313a2b8
NC
2000 case '1': /* Sd, Dd */
2001 regno = (given >> 12) & 0x0000000f;
2002 if (single)
2003 {
2004 regno <<= 1;
2005 regno += (given >> 22) & 1;
2006 }
2007 else
2008 regno += ((given >> 22) & 1) << 4;
2009 break;
8f06b2d8 2010
0313a2b8
NC
2011 case '2': /* Sn, Dn */
2012 regno = (given >> 16) & 0x0000000f;
2013 if (single)
8f06b2d8 2014 {
0313a2b8
NC
2015 regno <<= 1;
2016 regno += (given >> 7) & 1;
8f06b2d8 2017 }
0313a2b8
NC
2018 else
2019 regno += ((given >> 7) & 1) << 4;
2020 break;
7df76b80 2021
0313a2b8
NC
2022 case '3': /* List */
2023 func (stream, "{");
2024 regno = (given >> 12) & 0x0000000f;
2025 if (single)
2026 {
2027 regno <<= 1;
2028 regno += (given >> 22) & 1;
2029 }
2030 else
2031 regno += ((given >> 22) & 1) << 4;
2032 break;
a7f8487e 2033
0313a2b8
NC
2034 default:
2035 abort ();
8f06b2d8 2036 }
a7f8487e 2037
0313a2b8
NC
2038 func (stream, "%c%d", single ? 's' : 'd', regno);
2039
2040 if (*c == '3')
8f06b2d8 2041 {
0313a2b8 2042 int count = given & 0xff;
a7f8487e 2043
0313a2b8
NC
2044 if (single == 0)
2045 count >>= 1;
b34976b6 2046
0313a2b8 2047 if (--count)
8f06b2d8 2048 {
0313a2b8
NC
2049 func (stream, "-%c%d",
2050 single ? 's' : 'd',
2051 regno + count);
8f06b2d8 2052 }
0313a2b8
NC
2053
2054 func (stream, "}");
8f06b2d8 2055 }
0313a2b8
NC
2056 else if (*c == '4')
2057 func (stream, ", %c%d", single ? 's' : 'd',
2058 regno + 1);
2059 }
2060 break;
2061
2062 case 'L':
2063 switch (given & 0x00400100)
2064 {
2065 case 0x00000000: func (stream, "b"); break;
2066 case 0x00400000: func (stream, "h"); break;
2067 case 0x00000100: func (stream, "w"); break;
2068 case 0x00400100: func (stream, "d"); break;
2069 default:
8f06b2d8 2070 break;
0313a2b8
NC
2071 }
2072 break;
b34976b6 2073
0313a2b8
NC
2074 case 'Z':
2075 {
2076 int value;
2077 /* given (20, 23) | given (0, 3) */
2078 value = ((given >> 16) & 0xf0) | (given & 0xf);
2079 func (stream, "%d", value);
2080 }
2081 break;
2d447fca 2082
0313a2b8
NC
2083 case 'l':
2084 /* This is like the 'A' operator, except that if
2085 the width field "M" is zero, then the offset is
2086 *not* multiplied by four. */
2087 {
2088 int offset = given & 0xff;
2089 int multiplier = (given & 0x00000100) ? 4 : 1;
2090
2091 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2092
05413229
NC
2093 if (multiplier > 1)
2094 {
2095 value_in_comment = offset * multiplier;
2096 if ((given & 0x00800000) == 0)
2097 value_in_comment = - value_in_comment;
2098 }
2099
0313a2b8
NC
2100 if (offset)
2101 {
2102 if ((given & 0x01000000) != 0)
2103 func (stream, ", #%s%d]%s",
2104 ((given & 0x00800000) == 0 ? "-" : ""),
2105 offset * multiplier,
2106 ((given & 0x00200000) != 0 ? "!" : ""));
2107 else
2108 func (stream, "], #%s%d",
2109 ((given & 0x00800000) == 0 ? "-" : ""),
2110 offset * multiplier);
2d447fca 2111 }
0313a2b8
NC
2112 else
2113 func (stream, "]");
2114 }
2115 break;
2116
2117 case 'r':
2118 {
2119 int imm4 = (given >> 4) & 0xf;
2120 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2121 int ubit = (given >> 23) & 1;
2122 const char *rm = arm_regnames [given & 0xf];
2123 const char *rn = arm_regnames [(given >> 16) & 0xf];
2d447fca 2124
0313a2b8 2125 switch (puw_bits)
2d447fca 2126 {
0313a2b8
NC
2127 case 1:
2128 case 3:
2129 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2130 if (imm4)
2131 func (stream, ", lsl #%d", imm4);
2132 break;
2133
2134 case 4:
2135 case 5:
2136 case 6:
2137 case 7:
2138 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2139 if (imm4 > 0)
2140 func (stream, ", lsl #%d", imm4);
2141 func (stream, "]");
2142 if (puw_bits == 5 || puw_bits == 7)
2143 func (stream, "!");
2144 break;
2145
2146 default:
2147 func (stream, "INVALID");
2d447fca 2148 }
0313a2b8
NC
2149 }
2150 break;
2d447fca 2151
0313a2b8
NC
2152 case 'i':
2153 {
2154 long imm5;
2155 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2156 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
8f06b2d8 2157 }
0313a2b8
NC
2158 break;
2159
2160 default:
2161 abort ();
2162 }
252b5132 2163 }
252b5132 2164 }
0313a2b8
NC
2165 else
2166 func (stream, "%c", *c);
252b5132 2167 }
05413229
NC
2168
2169 if (value_in_comment > 32 || value_in_comment < -16)
2170 func (stream, "\t; 0x%lx", value_in_comment);
2171
0313a2b8 2172 return TRUE;
252b5132 2173 }
8f06b2d8 2174 return FALSE;
252b5132
RH
2175}
2176
05413229
NC
2177/* Decodes and prints ARM addressing modes. Returns the offset
2178 used in the address, if any, if it is worthwhile printing the
2179 offset as a hexadecimal value in a comment at the end of the
2180 line of disassembly. */
2181
2182static signed long
62b3e311
PB
2183print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2184{
2185 void *stream = info->stream;
2186 fprintf_ftype func = info->fprintf_func;
05413229 2187 int offset = 0;
62b3e311
PB
2188
2189 if (((given & 0x000f0000) == 0x000f0000)
2190 && ((given & 0x02000000) == 0))
2191 {
05413229 2192 offset = given & 0xfff;
62b3e311
PB
2193
2194 func (stream, "[pc");
2195
2196 if (given & 0x01000000)
2197 {
2198 if ((given & 0x00800000) == 0)
2199 offset = - offset;
2200
2201 /* Pre-indexed. */
2202 func (stream, ", #%d]", offset);
2203
2204 offset += pc + 8;
2205
2206 /* Cope with the possibility of write-back
2207 being used. Probably a very dangerous thing
2208 for the programmer to do, but who are we to
2209 argue ? */
2210 if (given & 0x00200000)
2211 func (stream, "!");
2212 }
2213 else
2214 {
2215 /* Post indexed. */
2216 func (stream, "], #%d", offset);
2217
2218 /* ie ignore the offset. */
2219 offset = pc + 8;
2220 }
2221
2222 func (stream, "\t; ");
2223 info->print_address_func (offset, info);
05413229 2224 offset = 0;
62b3e311
PB
2225 }
2226 else
2227 {
2228 func (stream, "[%s",
2229 arm_regnames[(given >> 16) & 0xf]);
2230 if ((given & 0x01000000) != 0)
2231 {
2232 if ((given & 0x02000000) == 0)
2233 {
05413229 2234 offset = given & 0xfff;
62b3e311
PB
2235 if (offset)
2236 func (stream, ", #%s%d",
2237 (((given & 0x00800000) == 0)
2238 ? "-" : ""), offset);
2239 }
2240 else
2241 {
2242 func (stream, ", %s",
2243 (((given & 0x00800000) == 0)
2244 ? "-" : ""));
78c66db8 2245 arm_decode_shift (given, func, stream, TRUE);
62b3e311
PB
2246 }
2247
2248 func (stream, "]%s",
2249 ((given & 0x00200000) != 0) ? "!" : "");
2250 }
2251 else
2252 {
2253 if ((given & 0x02000000) == 0)
2254 {
05413229 2255 offset = given & 0xfff;
62b3e311
PB
2256 if (offset)
2257 func (stream, "], #%s%d",
2258 (((given & 0x00800000) == 0)
2259 ? "-" : ""), offset);
2260 else
2261 func (stream, "]");
2262 }
2263 else
2264 {
2265 func (stream, "], %s",
2266 (((given & 0x00800000) == 0)
2267 ? "-" : ""));
78c66db8 2268 arm_decode_shift (given, func, stream, TRUE);
62b3e311
PB
2269 }
2270 }
2271 }
05413229
NC
2272
2273 return (signed long) offset;
62b3e311
PB
2274}
2275
16980d0b
JB
2276/* Print one neon instruction on INFO->STREAM.
2277 Return TRUE if the instuction matched, FALSE if this is not a
2278 recognised neon instruction. */
2279
2280static bfd_boolean
2281print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2282{
2283 const struct opcode32 *insn;
2284 void *stream = info->stream;
2285 fprintf_ftype func = info->fprintf_func;
2286
2287 if (thumb)
2288 {
2289 if ((given & 0xef000000) == 0xef000000)
2290 {
0313a2b8 2291 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
16980d0b
JB
2292 unsigned long bit28 = given & (1 << 28);
2293
2294 given &= 0x00ffffff;
2295 if (bit28)
2296 given |= 0xf3000000;
2297 else
2298 given |= 0xf2000000;
2299 }
2300 else if ((given & 0xff000000) == 0xf9000000)
2301 given ^= 0xf9000000 ^ 0xf4000000;
2302 else
2303 return FALSE;
2304 }
2305
2306 for (insn = neon_opcodes; insn->assembler; insn++)
2307 {
2308 if ((given & insn->mask) == insn->value)
2309 {
05413229 2310 signed long value_in_comment = 0;
16980d0b
JB
2311 const char *c;
2312
2313 for (c = insn->assembler; *c; c++)
2314 {
2315 if (*c == '%')
2316 {
2317 switch (*++c)
2318 {
2319 case '%':
2320 func (stream, "%%");
2321 break;
2322
c22aaad1
PB
2323 case 'c':
2324 if (thumb && ifthen_state)
2325 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2326 break;
2327
16980d0b
JB
2328 case 'A':
2329 {
2330 static const unsigned char enc[16] =
2331 {
2332 0x4, 0x14, /* st4 0,1 */
2333 0x4, /* st1 2 */
2334 0x4, /* st2 3 */
2335 0x3, /* st3 4 */
2336 0x13, /* st3 5 */
2337 0x3, /* st1 6 */
2338 0x1, /* st1 7 */
2339 0x2, /* st2 8 */
2340 0x12, /* st2 9 */
2341 0x2, /* st1 10 */
2342 0, 0, 0, 0, 0
2343 };
2344 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2345 int rn = ((given >> 16) & 0xf);
2346 int rm = ((given >> 0) & 0xf);
2347 int align = ((given >> 4) & 0x3);
2348 int type = ((given >> 8) & 0xf);
2349 int n = enc[type] & 0xf;
2350 int stride = (enc[type] >> 4) + 1;
2351 int ix;
2352
2353 func (stream, "{");
2354 if (stride > 1)
2355 for (ix = 0; ix != n; ix++)
2356 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2357 else if (n == 1)
2358 func (stream, "d%d", rd);
2359 else
2360 func (stream, "d%d-d%d", rd, rd + n - 1);
2361 func (stream, "}, [%s", arm_regnames[rn]);
2362 if (align)
2363 func (stream, ", :%d", 32 << align);
2364 func (stream, "]");
2365 if (rm == 0xd)
2366 func (stream, "!");
2367 else if (rm != 0xf)
2368 func (stream, ", %s", arm_regnames[rm]);
2369 }
2370 break;
2371
2372 case 'B':
2373 {
2374 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2375 int rn = ((given >> 16) & 0xf);
2376 int rm = ((given >> 0) & 0xf);
2377 int idx_align = ((given >> 4) & 0xf);
2378 int align = 0;
2379 int size = ((given >> 10) & 0x3);
2380 int idx = idx_align >> (size + 1);
2381 int length = ((given >> 8) & 3) + 1;
2382 int stride = 1;
2383 int i;
2384
2385 if (length > 1 && size > 0)
2386 stride = (idx_align & (1 << size)) ? 2 : 1;
2387
2388 switch (length)
2389 {
2390 case 1:
2391 {
2392 int amask = (1 << size) - 1;
2393 if ((idx_align & (1 << size)) != 0)
2394 return FALSE;
2395 if (size > 0)
2396 {
2397 if ((idx_align & amask) == amask)
2398 align = 8 << size;
2399 else if ((idx_align & amask) != 0)
2400 return FALSE;
2401 }
2402 }
2403 break;
2404
2405 case 2:
2406 if (size == 2 && (idx_align & 2) != 0)
2407 return FALSE;
2408 align = (idx_align & 1) ? 16 << size : 0;
2409 break;
2410
2411 case 3:
2412 if ((size == 2 && (idx_align & 3) != 0)
2413 || (idx_align & 1) != 0)
2414 return FALSE;
2415 break;
2416
2417 case 4:
2418 if (size == 2)
2419 {
2420 if ((idx_align & 3) == 3)
2421 return FALSE;
2422 align = (idx_align & 3) * 64;
2423 }
2424 else
2425 align = (idx_align & 1) ? 32 << size : 0;
2426 break;
2427
2428 default:
2429 abort ();
2430 }
2431
2432 func (stream, "{");
2433 for (i = 0; i < length; i++)
2434 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2435 rd + i * stride, idx);
2436 func (stream, "}, [%s", arm_regnames[rn]);
2437 if (align)
2438 func (stream, ", :%d", align);
2439 func (stream, "]");
2440 if (rm == 0xd)
2441 func (stream, "!");
2442 else if (rm != 0xf)
2443 func (stream, ", %s", arm_regnames[rm]);
2444 }
2445 break;
2446
2447 case 'C':
2448 {
2449 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2450 int rn = ((given >> 16) & 0xf);
2451 int rm = ((given >> 0) & 0xf);
2452 int align = ((given >> 4) & 0x1);
2453 int size = ((given >> 6) & 0x3);
2454 int type = ((given >> 8) & 0x3);
2455 int n = type + 1;
2456 int stride = ((given >> 5) & 0x1);
2457 int ix;
2458
2459 if (stride && (n == 1))
2460 n++;
2461 else
2462 stride++;
2463
2464 func (stream, "{");
2465 if (stride > 1)
2466 for (ix = 0; ix != n; ix++)
2467 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2468 else if (n == 1)
2469 func (stream, "d%d[]", rd);
2470 else
2471 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2472 func (stream, "}, [%s", arm_regnames[rn]);
2473 if (align)
2474 {
2475 int align = (8 * (type + 1)) << size;
2476 if (type == 3)
2477 align = (size > 1) ? align >> 1 : align;
2478 if (type == 2 || (type == 0 && !size))
2479 func (stream, ", :<bad align %d>", align);
2480 else
2481 func (stream, ", :%d", align);
2482 }
2483 func (stream, "]");
2484 if (rm == 0xd)
2485 func (stream, "!");
2486 else if (rm != 0xf)
2487 func (stream, ", %s", arm_regnames[rm]);
2488 }
2489 break;
2490
2491 case 'D':
2492 {
2493 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2494 int size = (given >> 20) & 3;
2495 int reg = raw_reg & ((4 << size) - 1);
2496 int ix = raw_reg >> size >> 2;
2497
2498 func (stream, "d%d[%d]", reg, ix);
2499 }
2500 break;
2501
2502 case 'E':
fe56b6ce 2503 /* Neon encoded constant for mov, mvn, vorr, vbic. */
16980d0b
JB
2504 {
2505 int bits = 0;
2506 int cmode = (given >> 8) & 0xf;
2507 int op = (given >> 5) & 0x1;
2508 unsigned long value = 0, hival = 0;
2509 unsigned shift;
2510 int size = 0;
0dbde4cf 2511 int isfloat = 0;
16980d0b
JB
2512
2513 bits |= ((given >> 24) & 1) << 7;
2514 bits |= ((given >> 16) & 7) << 4;
2515 bits |= ((given >> 0) & 15) << 0;
2516
2517 if (cmode < 8)
2518 {
2519 shift = (cmode >> 1) & 3;
fe56b6ce 2520 value = (unsigned long) bits << (8 * shift);
16980d0b
JB
2521 size = 32;
2522 }
2523 else if (cmode < 12)
2524 {
2525 shift = (cmode >> 1) & 1;
fe56b6ce 2526 value = (unsigned long) bits << (8 * shift);
16980d0b
JB
2527 size = 16;
2528 }
2529 else if (cmode < 14)
2530 {
2531 shift = (cmode & 1) + 1;
fe56b6ce 2532 value = (unsigned long) bits << (8 * shift);
16980d0b
JB
2533 value |= (1ul << (8 * shift)) - 1;
2534 size = 32;
2535 }
2536 else if (cmode == 14)
2537 {
2538 if (op)
2539 {
fe56b6ce 2540 /* Bit replication into bytes. */
16980d0b
JB
2541 int ix;
2542 unsigned long mask;
2543
2544 value = 0;
2545 hival = 0;
2546 for (ix = 7; ix >= 0; ix--)
2547 {
2548 mask = ((bits >> ix) & 1) ? 0xff : 0;
2549 if (ix <= 3)
2550 value = (value << 8) | mask;
2551 else
2552 hival = (hival << 8) | mask;
2553 }
2554 size = 64;
2555 }
2556 else
2557 {
fe56b6ce
NC
2558 /* Byte replication. */
2559 value = (unsigned long) bits;
16980d0b
JB
2560 size = 8;
2561 }
2562 }
2563 else if (!op)
2564 {
fe56b6ce 2565 /* Floating point encoding. */
16980d0b
JB
2566 int tmp;
2567
fe56b6ce
NC
2568 value = (unsigned long) (bits & 0x7f) << 19;
2569 value |= (unsigned long) (bits & 0x80) << 24;
16980d0b 2570 tmp = bits & 0x40 ? 0x3c : 0x40;
fe56b6ce 2571 value |= (unsigned long) tmp << 24;
16980d0b 2572 size = 32;
0dbde4cf 2573 isfloat = 1;
16980d0b
JB
2574 }
2575 else
2576 {
2577 func (stream, "<illegal constant %.8x:%x:%x>",
2578 bits, cmode, op);
2579 size = 32;
2580 break;
2581 }
2582 switch (size)
2583 {
2584 case 8:
2585 func (stream, "#%ld\t; 0x%.2lx", value, value);
2586 break;
2587
2588 case 16:
2589 func (stream, "#%ld\t; 0x%.4lx", value, value);
2590 break;
2591
2592 case 32:
0dbde4cf
JB
2593 if (isfloat)
2594 {
2595 unsigned char valbytes[4];
2596 double fvalue;
2597
2598 /* Do this a byte at a time so we don't have to
2599 worry about the host's endianness. */
2600 valbytes[0] = value & 0xff;
2601 valbytes[1] = (value >> 8) & 0xff;
2602 valbytes[2] = (value >> 16) & 0xff;
2603 valbytes[3] = (value >> 24) & 0xff;
2604
2605 floatformat_to_double
2606 (&floatformat_ieee_single_little, valbytes,
2607 &fvalue);
2608
2609 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2610 value);
2611 }
2612 else
4e9d3b81
JB
2613 func (stream, "#%ld\t; 0x%.8lx",
2614 (long) ((value & 0x80000000)
2615 ? value | ~0xffffffffl : value), value);
16980d0b
JB
2616 break;
2617
2618 case 64:
2619 func (stream, "#0x%.8lx%.8lx", hival, value);
2620 break;
2621
2622 default:
2623 abort ();
2624 }
2625 }
2626 break;
2627
2628 case 'F':
2629 {
2630 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2631 int num = (given >> 8) & 0x3;
2632
2633 if (!num)
2634 func (stream, "{d%d}", regno);
2635 else if (num + regno >= 32)
2636 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2637 else
2638 func (stream, "{d%d-d%d}", regno, regno + num);
2639 }
2640 break;
2641
2642
2643 case '0': case '1': case '2': case '3': case '4':
2644 case '5': case '6': case '7': case '8': case '9':
2645 {
2646 int width;
2647 unsigned long value;
2648
2649 c = arm_decode_bitfield (c, given, &value, &width);
2650
2651 switch (*c)
2652 {
2653 case 'r':
2654 func (stream, "%s", arm_regnames[value]);
2655 break;
2656 case 'd':
2657 func (stream, "%ld", value);
05413229 2658 value_in_comment = value;
16980d0b
JB
2659 break;
2660 case 'e':
2661 func (stream, "%ld", (1ul << width) - value);
2662 break;
2663
2664 case 'S':
2665 case 'T':
2666 case 'U':
05413229 2667 /* Various width encodings. */
16980d0b
JB
2668 {
2669 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2670 int limit;
2671 unsigned low, high;
2672
2673 c++;
2674 if (*c >= '0' && *c <= '9')
2675 limit = *c - '0';
2676 else if (*c >= 'a' && *c <= 'f')
2677 limit = *c - 'a' + 10;
2678 else
2679 abort ();
2680 low = limit >> 2;
2681 high = limit & 3;
2682
2683 if (value < low || value > high)
2684 func (stream, "<illegal width %d>", base << value);
2685 else
2686 func (stream, "%d", base << value);
2687 }
2688 break;
2689 case 'R':
2690 if (given & (1 << 6))
2691 goto Q;
2692 /* FALLTHROUGH */
2693 case 'D':
2694 func (stream, "d%ld", value);
2695 break;
2696 case 'Q':
2697 Q:
2698 if (value & 1)
2699 func (stream, "<illegal reg q%ld.5>", value >> 1);
2700 else
2701 func (stream, "q%ld", value >> 1);
2702 break;
2703
2704 case '`':
2705 c++;
2706 if (value == 0)
2707 func (stream, "%c", *c);
2708 break;
2709 case '\'':
2710 c++;
2711 if (value == ((1ul << width) - 1))
2712 func (stream, "%c", *c);
2713 break;
2714 case '?':
fe56b6ce 2715 func (stream, "%c", c[(1 << width) - (int) value]);
16980d0b
JB
2716 c += 1 << width;
2717 break;
2718 default:
2719 abort ();
2720 }
2721 break;
2722
2723 default:
2724 abort ();
2725 }
2726 }
2727 }
2728 else
2729 func (stream, "%c", *c);
2730 }
05413229
NC
2731
2732 if (value_in_comment > 32 || value_in_comment < -16)
2733 func (stream, "\t; 0x%lx", value_in_comment);
2734
16980d0b
JB
2735 return TRUE;
2736 }
2737 }
2738 return FALSE;
2739}
2740
4a5329c6
ZW
2741/* Print one ARM instruction from PC on INFO->STREAM. */
2742
2743static void
2744print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
252b5132 2745{
6b5d3a4d 2746 const struct opcode32 *insn;
6a51a8a8 2747 void *stream = info->stream;
6b5d3a4d 2748 fprintf_ftype func = info->fprintf_func;
252b5132 2749
16980d0b
JB
2750 if (print_insn_coprocessor (pc, info, given, FALSE))
2751 return;
2752
2753 if (print_insn_neon (info, given, FALSE))
8f06b2d8
PB
2754 return;
2755
252b5132
RH
2756 for (insn = arm_opcodes; insn->assembler; insn++)
2757 {
0313a2b8
NC
2758 if ((given & insn->mask) != insn->value)
2759 continue;
2760
2761 if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
2762 continue;
2763
2764 /* Special case: an instruction with all bits set in the condition field
2765 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2766 or by the catchall at the end of the table. */
2767 if ((given & 0xF0000000) != 0xF0000000
2768 || (insn->mask & 0xF0000000) == 0xF0000000
2769 || (insn->mask == 0 && insn->value == 0))
252b5132 2770 {
05413229 2771 signed long value_in_comment = 0;
6b5d3a4d 2772 const char *c;
b34976b6 2773
252b5132
RH
2774 for (c = insn->assembler; *c; c++)
2775 {
2776 if (*c == '%')
2777 {
2778 switch (*++c)
2779 {
2780 case '%':
2781 func (stream, "%%");
2782 break;
2783
2784 case 'a':
05413229 2785 value_in_comment = print_arm_address (pc, info, given);
62b3e311 2786 break;
252b5132 2787
62b3e311
PB
2788 case 'P':
2789 /* Set P address bit and use normal address
2790 printing routine. */
05413229 2791 value_in_comment = print_arm_address (pc, info, given | (1 << 24));
252b5132
RH
2792 break;
2793
2794 case 's':
2795 if ((given & 0x004f0000) == 0x004f0000)
2796 {
58efb6c0 2797 /* PC relative with immediate offset. */
252b5132 2798 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
b34976b6 2799
252b5132
RH
2800 if ((given & 0x00800000) == 0)
2801 offset = -offset;
b34976b6 2802
40536497 2803 func (stream, "[pc, #%d]\t; ", offset);
6b5d3a4d 2804 info->print_address_func (offset + pc + 8, info);
252b5132
RH
2805 }
2806 else
2807 {
fe56b6ce
NC
2808 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2809
2810 if ((given & 0x00800000) == 0)
2811 offset = -offset;
2812
b34976b6 2813 func (stream, "[%s",
252b5132 2814 arm_regnames[(given >> 16) & 0xf]);
fe56b6ce 2815
252b5132
RH
2816 if ((given & 0x01000000) != 0)
2817 {
58efb6c0 2818 /* Pre-indexed. */
252b5132
RH
2819 if ((given & 0x00400000) == 0x00400000)
2820 {
58efb6c0 2821 /* Immediate. */
252b5132 2822 if (offset)
fe56b6ce
NC
2823 func (stream, ", #%d", offset);
2824 value_in_comment = offset;
252b5132
RH
2825 }
2826 else
2827 {
58efb6c0 2828 /* Register. */
fe56b6ce 2829 func (stream, ", %s%s", offset < 0 ? "-" : "",
252b5132
RH
2830 arm_regnames[given & 0xf]);
2831 }
2832
b34976b6 2833 func (stream, "]%s",
252b5132
RH
2834 ((given & 0x00200000) != 0) ? "!" : "");
2835 }
2836 else
2837 {
58efb6c0 2838 /* Post-indexed. */
252b5132
RH
2839 if ((given & 0x00400000) == 0x00400000)
2840 {
58efb6c0 2841 /* Immediate. */
252b5132 2842 if (offset)
fe56b6ce 2843 func (stream, "], #%d", offset);
b34976b6 2844 else
252b5132 2845 func (stream, "]");
fe56b6ce
NC
2846
2847 value_in_comment = offset;
252b5132
RH
2848 }
2849 else
2850 {
58efb6c0 2851 /* Register. */
fe56b6ce 2852 func (stream, "], %s%s", offset < 0 ? "-" : "",
252b5132
RH
2853 arm_regnames[given & 0xf]);
2854 }
2855 }
2856 }
2857 break;
b34976b6 2858
252b5132 2859 case 'b':
6b5d3a4d
ZW
2860 {
2861 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
05413229 2862 info->print_address_func (disp * 4 + pc + 8, info);
6b5d3a4d 2863 }
252b5132
RH
2864 break;
2865
2866 case 'c':
c22aaad1
PB
2867 if (((given >> 28) & 0xf) != 0xe)
2868 func (stream, "%s",
2869 arm_conditional [(given >> 28) & 0xf]);
252b5132
RH
2870 break;
2871
2872 case 'm':
2873 {
2874 int started = 0;
2875 int reg;
2876
2877 func (stream, "{");
2878 for (reg = 0; reg < 16; reg++)
2879 if ((given & (1 << reg)) != 0)
2880 {
2881 if (started)
2882 func (stream, ", ");
2883 started = 1;
2884 func (stream, "%s", arm_regnames[reg]);
2885 }
2886 func (stream, "}");
2887 }
2888 break;
2889
37b37b2d 2890 case 'q':
78c66db8 2891 arm_decode_shift (given, func, stream, FALSE);
37b37b2d
RE
2892 break;
2893
252b5132
RH
2894 case 'o':
2895 if ((given & 0x02000000) != 0)
2896 {
2897 int rotate = (given & 0xf00) >> 7;
2898 int immed = (given & 0xff);
fe56b6ce 2899
9f20bbfd
NC
2900 immed = (((immed << (32 - rotate))
2901 | (immed >> rotate)) & 0xffffffff);
fe56b6ce
NC
2902 func (stream, "#%d", immed);
2903 value_in_comment = immed;
252b5132
RH
2904 }
2905 else
78c66db8 2906 arm_decode_shift (given, func, stream, TRUE);
252b5132
RH
2907 break;
2908
2909 case 'p':
2910 if ((given & 0x0000f000) == 0x0000f000)
2911 func (stream, "p");
2912 break;
2913
2914 case 't':
2915 if ((given & 0x01200000) == 0x00200000)
2916 func (stream, "t");
2917 break;
2918
252b5132 2919 case 'A':
05413229
NC
2920 {
2921 int offset = given & 0xff;
f02232aa 2922
05413229
NC
2923 value_in_comment = offset * 4;
2924 if ((given & 0x00800000) == 0)
2925 value_in_comment = - value_in_comment;
f02232aa 2926
05413229 2927 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
f02232aa 2928
05413229
NC
2929 if ((given & (1 << 24)) != 0)
2930 {
2931 if (offset)
fe56b6ce
NC
2932 func (stream, ", #%d]%s",
2933 value_in_comment,
05413229
NC
2934 ((given & 0x00200000) != 0 ? "!" : ""));
2935 else
2936 func (stream, "]");
2937 }
2938 else
2939 {
2940 func (stream, "]");
f02232aa 2941
05413229
NC
2942 if (given & (1 << 21))
2943 {
2944 if (offset)
fe56b6ce 2945 func (stream, ", #%d", value_in_comment);
05413229
NC
2946 }
2947 else
fe56b6ce
NC
2948 {
2949 func (stream, ", {%d}", offset);
2950 value_in_comment = offset;
2951 }
05413229
NC
2952 }
2953 }
252b5132
RH
2954 break;
2955
077b8428
NC
2956 case 'B':
2957 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2958 {
2959 bfd_vma address;
2960 bfd_vma offset = 0;
b34976b6 2961
077b8428
NC
2962 if (given & 0x00800000)
2963 /* Is signed, hi bits should be ones. */
2964 offset = (-1) ^ 0x00ffffff;
2965
2966 /* Offset is (SignExtend(offset field)<<2). */
2967 offset += given & 0x00ffffff;
2968 offset <<= 2;
2969 address = offset + pc + 8;
b34976b6 2970
8f06b2d8
PB
2971 if (given & 0x01000000)
2972 /* H bit allows addressing to 2-byte boundaries. */
2973 address += 2;
b1ee46c5 2974
8f06b2d8 2975 info->print_address_func (address, info);
b1ee46c5 2976 }
b1ee46c5
AH
2977 break;
2978
252b5132 2979 case 'C':
6eeeb4b4
AO
2980 func (stream, "_");
2981 if (given & 0x80000)
2982 func (stream, "f");
2983 if (given & 0x40000)
2984 func (stream, "s");
2985 if (given & 0x20000)
2986 func (stream, "x");
2987 if (given & 0x10000)
2988 func (stream, "c");
252b5132
RH
2989 break;
2990
62b3e311
PB
2991 case 'U':
2992 switch (given & 0xf)
2993 {
fe56b6ce
NC
2994 case 0xf: func (stream, "sy"); break;
2995 case 0x7: func (stream, "un"); break;
2996 case 0xe: func (stream, "st"); break;
2997 case 0x6: func (stream, "unst"); break;
62b3e311 2998 default:
fe56b6ce 2999 func (stream, "#%d", (int) given & 0xf);
62b3e311
PB
3000 break;
3001 }
3002 break;
3003
b34976b6 3004 case '0': case '1': case '2': case '3': case '4':
252b5132
RH
3005 case '5': case '6': case '7': case '8': case '9':
3006 {
16980d0b
JB
3007 int width;
3008 unsigned long value;
252b5132 3009
16980d0b
JB
3010 c = arm_decode_bitfield (c, given, &value, &width);
3011
252b5132
RH
3012 switch (*c)
3013 {
16980d0b
JB
3014 case 'r':
3015 func (stream, "%s", arm_regnames[value]);
3016 break;
3017 case 'd':
3018 func (stream, "%ld", value);
05413229 3019 value_in_comment = value;
16980d0b
JB
3020 break;
3021 case 'b':
3022 func (stream, "%ld", value * 8);
05413229 3023 value_in_comment = value * 8;
16980d0b
JB
3024 break;
3025 case 'W':
3026 func (stream, "%ld", value + 1);
05413229 3027 value_in_comment = value + 1;
16980d0b
JB
3028 break;
3029 case 'x':
3030 func (stream, "0x%08lx", value);
3031
3032 /* Some SWI instructions have special
3033 meanings. */
3034 if ((given & 0x0fffffff) == 0x0FF00000)
3035 func (stream, "\t; IMB");
3036 else if ((given & 0x0fffffff) == 0x0FF00001)
3037 func (stream, "\t; IMBRange");
3038 break;
3039 case 'X':
3040 func (stream, "%01lx", value & 0xf);
05413229 3041 value_in_comment = value;
252b5132
RH
3042 break;
3043 case '`':
3044 c++;
16980d0b 3045 if (value == 0)
252b5132
RH
3046 func (stream, "%c", *c);
3047 break;
3048 case '\'':
3049 c++;
16980d0b 3050 if (value == ((1ul << width) - 1))
252b5132
RH
3051 func (stream, "%c", *c);
3052 break;
3053 case '?':
fe56b6ce 3054 func (stream, "%c", c[(1 << width) - (int) value]);
16980d0b 3055 c += 1 << width;
252b5132
RH
3056 break;
3057 default:
3058 abort ();
3059 }
3060 break;
3061
0dd132b6
NC
3062 case 'e':
3063 {
3064 int imm;
3065
3066 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3067 func (stream, "%d", imm);
fe56b6ce 3068 value_in_comment = imm;
0dd132b6
NC
3069 }
3070 break;
3071
0a003adc
ZW
3072 case 'E':
3073 /* LSB and WIDTH fields of BFI or BFC. The machine-
3074 language instruction encodes LSB and MSB. */
3075 {
3076 long msb = (given & 0x001f0000) >> 16;
3077 long lsb = (given & 0x00000f80) >> 7;
0a003adc 3078 long width = msb - lsb + 1;
fe56b6ce 3079
0a003adc
ZW
3080 if (width > 0)
3081 func (stream, "#%lu, #%lu", lsb, width);
3082 else
3083 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3084 }
3085 break;
3086
3087 case 'V':
3088 /* 16-bit unsigned immediate from a MOVT or MOVW
3089 instruction, encoded in bits 0:11 and 15:19. */
3090 {
3091 long hi = (given & 0x000f0000) >> 4;
3092 long lo = (given & 0x00000fff);
3093 long imm16 = hi | lo;
fe56b6ce
NC
3094
3095 func (stream, "#%lu", imm16);
3096 value_in_comment = imm16;
0a003adc
ZW
3097 }
3098 break;
3099
252b5132
RH
3100 default:
3101 abort ();
3102 }
3103 }
3104 }
3105 else
3106 func (stream, "%c", *c);
3107 }
05413229
NC
3108
3109 if (value_in_comment > 32 || value_in_comment < -16)
3110 func (stream, "\t; 0x%lx", value_in_comment);
4a5329c6 3111 return;
252b5132
RH
3112 }
3113 }
3114 abort ();
3115}
3116
4a5329c6 3117/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
baf0cc5e 3118
4a5329c6
ZW
3119static void
3120print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
252b5132 3121{
6b5d3a4d 3122 const struct opcode16 *insn;
6a51a8a8
AM
3123 void *stream = info->stream;
3124 fprintf_ftype func = info->fprintf_func;
252b5132
RH
3125
3126 for (insn = thumb_opcodes; insn->assembler; insn++)
c19d1205
ZW
3127 if ((given & insn->mask) == insn->value)
3128 {
05413229 3129 signed long value_in_comment = 0;
6b5d3a4d 3130 const char *c = insn->assembler;
05413229 3131
c19d1205
ZW
3132 for (; *c; c++)
3133 {
3134 int domaskpc = 0;
3135 int domasklr = 0;
3136
3137 if (*c != '%')
3138 {
3139 func (stream, "%c", *c);
3140 continue;
3141 }
252b5132 3142
c19d1205
ZW
3143 switch (*++c)
3144 {
3145 case '%':
3146 func (stream, "%%");
3147 break;
b34976b6 3148
c22aaad1
PB
3149 case 'c':
3150 if (ifthen_state)
3151 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3152 break;
3153
3154 case 'C':
3155 if (ifthen_state)
3156 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3157 else
3158 func (stream, "s");
3159 break;
3160
3161 case 'I':
3162 {
3163 unsigned int tmp;
3164
3165 ifthen_next_state = given & 0xff;
3166 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3167 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3168 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3169 }
3170 break;
3171
3172 case 'x':
3173 if (ifthen_next_state)
3174 func (stream, "\t; unpredictable branch in IT block\n");
3175 break;
3176
3177 case 'X':
3178 if (ifthen_state)
3179 func (stream, "\t; unpredictable <IT:%s>",
3180 arm_conditional[IFTHEN_COND]);
3181 break;
3182
c19d1205
ZW
3183 case 'S':
3184 {
3185 long reg;
3186
3187 reg = (given >> 3) & 0x7;
3188 if (given & (1 << 6))
3189 reg += 8;
4f3c3dbb 3190
c19d1205
ZW
3191 func (stream, "%s", arm_regnames[reg]);
3192 }
3193 break;
baf0cc5e 3194
c19d1205 3195 case 'D':
4f3c3dbb 3196 {
c19d1205
ZW
3197 long reg;
3198
3199 reg = given & 0x7;
3200 if (given & (1 << 7))
3201 reg += 8;
3202
3203 func (stream, "%s", arm_regnames[reg]);
4f3c3dbb 3204 }
c19d1205
ZW
3205 break;
3206
3207 case 'N':
3208 if (given & (1 << 8))
3209 domasklr = 1;
3210 /* Fall through. */
3211 case 'O':
3212 if (*c == 'O' && (given & (1 << 8)))
3213 domaskpc = 1;
3214 /* Fall through. */
3215 case 'M':
3216 {
3217 int started = 0;
3218 int reg;
3219
3220 func (stream, "{");
3221
3222 /* It would be nice if we could spot
3223 ranges, and generate the rS-rE format: */
3224 for (reg = 0; (reg < 8); reg++)
3225 if ((given & (1 << reg)) != 0)
3226 {
3227 if (started)
3228 func (stream, ", ");
3229 started = 1;
3230 func (stream, "%s", arm_regnames[reg]);
3231 }
3232
3233 if (domasklr)
3234 {
3235 if (started)
3236 func (stream, ", ");
3237 started = 1;
3238 func (stream, arm_regnames[14] /* "lr" */);
3239 }
3240
3241 if (domaskpc)
3242 {
3243 if (started)
3244 func (stream, ", ");
3245 func (stream, arm_regnames[15] /* "pc" */);
3246 }
3247
3248 func (stream, "}");
3249 }
3250 break;
3251
3252 case 'b':
3253 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3254 {
3255 bfd_vma address = (pc + 4
3256 + ((given & 0x00f8) >> 2)
3257 + ((given & 0x0200) >> 3));
3258 info->print_address_func (address, info);
3259 }
3260 break;
3261
3262 case 's':
3263 /* Right shift immediate -- bits 6..10; 1-31 print
3264 as themselves, 0 prints as 32. */
3265 {
3266 long imm = (given & 0x07c0) >> 6;
3267 if (imm == 0)
3268 imm = 32;
0fd3a477 3269 func (stream, "#%ld", imm);
c19d1205
ZW
3270 }
3271 break;
3272
3273 case '0': case '1': case '2': case '3': case '4':
3274 case '5': case '6': case '7': case '8': case '9':
3275 {
3276 int bitstart = *c++ - '0';
3277 int bitend = 0;
3278
3279 while (*c >= '0' && *c <= '9')
3280 bitstart = (bitstart * 10) + *c++ - '0';
3281
3282 switch (*c)
3283 {
3284 case '-':
3285 {
3286 long reg;
3287
3288 c++;
3289 while (*c >= '0' && *c <= '9')
3290 bitend = (bitend * 10) + *c++ - '0';
3291 if (!bitend)
3292 abort ();
3293 reg = given >> bitstart;
3294 reg &= (2 << (bitend - bitstart)) - 1;
3295 switch (*c)
3296 {
3297 case 'r':
3298 func (stream, "%s", arm_regnames[reg]);
3299 break;
3300
3301 case 'd':
0fd3a477 3302 func (stream, "%ld", reg);
05413229 3303 value_in_comment = reg;
c19d1205
ZW
3304 break;
3305
3306 case 'H':
0fd3a477 3307 func (stream, "%ld", reg << 1);
05413229 3308 value_in_comment = reg << 1;
c19d1205
ZW
3309 break;
3310
3311 case 'W':
0fd3a477 3312 func (stream, "%ld", reg << 2);
05413229 3313 value_in_comment = reg << 2;
c19d1205
ZW
3314 break;
3315
3316 case 'a':
3317 /* PC-relative address -- the bottom two
3318 bits of the address are dropped
3319 before the calculation. */
3320 info->print_address_func
3321 (((pc + 4) & ~3) + (reg << 2), info);
05413229 3322 value_in_comment = 0;
c19d1205
ZW
3323 break;
3324
3325 case 'x':
0fd3a477 3326 func (stream, "0x%04lx", reg);
c19d1205
ZW
3327 break;
3328
c19d1205
ZW
3329 case 'B':
3330 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
6b5d3a4d 3331 info->print_address_func (reg * 2 + pc + 4, info);
05413229 3332 value_in_comment = 0;
c19d1205
ZW
3333 break;
3334
3335 case 'c':
c22aaad1 3336 func (stream, "%s", arm_conditional [reg]);
c19d1205
ZW
3337 break;
3338
3339 default:
3340 abort ();
3341 }
3342 }
3343 break;
3344
3345 case '\'':
3346 c++;
3347 if ((given & (1 << bitstart)) != 0)
3348 func (stream, "%c", *c);
3349 break;
3350
3351 case '?':
3352 ++c;
3353 if ((given & (1 << bitstart)) != 0)
3354 func (stream, "%c", *c++);
3355 else
3356 func (stream, "%c", *++c);
3357 break;
3358
3359 default:
3360 abort ();
3361 }
3362 }
3363 break;
3364
3365 default:
3366 abort ();
3367 }
3368 }
05413229
NC
3369
3370 if (value_in_comment > 32 || value_in_comment < -16)
3371 func (stream, "\t; 0x%lx", value_in_comment);
4a5329c6 3372 return;
c19d1205
ZW
3373 }
3374
3375 /* No match. */
3376 abort ();
3377}
3378
62b3e311 3379/* Return the name of an V7M special register. */
fe56b6ce 3380
62b3e311
PB
3381static const char *
3382psr_name (int regno)
3383{
3384 switch (regno)
3385 {
3386 case 0: return "APSR";
3387 case 1: return "IAPSR";
3388 case 2: return "EAPSR";
3389 case 3: return "PSR";
3390 case 5: return "IPSR";
3391 case 6: return "EPSR";
3392 case 7: return "IEPSR";
3393 case 8: return "MSP";
3394 case 9: return "PSP";
3395 case 16: return "PRIMASK";
3396 case 17: return "BASEPRI";
3397 case 18: return "BASEPRI_MASK";
3398 case 19: return "FAULTMASK";
3399 case 20: return "CONTROL";
3400 default: return "<unknown>";
3401 }
3402}
3403
4a5329c6
ZW
3404/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3405
3406static void
3407print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
c19d1205 3408{
6b5d3a4d 3409 const struct opcode32 *insn;
c19d1205
ZW
3410 void *stream = info->stream;
3411 fprintf_ftype func = info->fprintf_func;
3412
16980d0b
JB
3413 if (print_insn_coprocessor (pc, info, given, TRUE))
3414 return;
3415
3416 if (print_insn_neon (info, given, TRUE))
8f06b2d8
PB
3417 return;
3418
c19d1205
ZW
3419 for (insn = thumb32_opcodes; insn->assembler; insn++)
3420 if ((given & insn->mask) == insn->value)
3421 {
05413229 3422 signed long value_in_comment = 0;
6b5d3a4d 3423 const char *c = insn->assembler;
05413229 3424
c19d1205
ZW
3425 for (; *c; c++)
3426 {
3427 if (*c != '%')
3428 {
3429 func (stream, "%c", *c);
3430 continue;
3431 }
3432
3433 switch (*++c)
3434 {
3435 case '%':
3436 func (stream, "%%");
3437 break;
3438
c22aaad1
PB
3439 case 'c':
3440 if (ifthen_state)
3441 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3442 break;
3443
3444 case 'x':
3445 if (ifthen_next_state)
3446 func (stream, "\t; unpredictable branch in IT block\n");
3447 break;
3448
3449 case 'X':
3450 if (ifthen_state)
3451 func (stream, "\t; unpredictable <IT:%s>",
3452 arm_conditional[IFTHEN_COND]);
3453 break;
3454
c19d1205
ZW
3455 case 'I':
3456 {
3457 unsigned int imm12 = 0;
fe56b6ce 3458
c19d1205
ZW
3459 imm12 |= (given & 0x000000ffu);
3460 imm12 |= (given & 0x00007000u) >> 4;
92e90b6e 3461 imm12 |= (given & 0x04000000u) >> 15;
fe56b6ce
NC
3462 func (stream, "#%u", imm12);
3463 value_in_comment = imm12;
c19d1205
ZW
3464 }
3465 break;
3466
3467 case 'M':
3468 {
3469 unsigned int bits = 0, imm, imm8, mod;
fe56b6ce 3470
c19d1205
ZW
3471 bits |= (given & 0x000000ffu);
3472 bits |= (given & 0x00007000u) >> 4;
3473 bits |= (given & 0x04000000u) >> 15;
3474 imm8 = (bits & 0x0ff);
3475 mod = (bits & 0xf00) >> 8;
3476 switch (mod)
3477 {
3478 case 0: imm = imm8; break;
3479 case 1: imm = ((imm8<<16) | imm8); break;
3480 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3481 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3482 default:
3483 mod = (bits & 0xf80) >> 7;
3484 imm8 = (bits & 0x07f) | 0x80;
3485 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3486 }
fe56b6ce
NC
3487 func (stream, "#%u", imm);
3488 value_in_comment = imm;
c19d1205
ZW
3489 }
3490 break;
3491
3492 case 'J':
3493 {
3494 unsigned int imm = 0;
fe56b6ce 3495
c19d1205
ZW
3496 imm |= (given & 0x000000ffu);
3497 imm |= (given & 0x00007000u) >> 4;
3498 imm |= (given & 0x04000000u) >> 15;
3499 imm |= (given & 0x000f0000u) >> 4;
fe56b6ce
NC
3500 func (stream, "#%u", imm);
3501 value_in_comment = imm;
c19d1205
ZW
3502 }
3503 break;
3504
3505 case 'K':
3506 {
3507 unsigned int imm = 0;
fe56b6ce 3508
c19d1205
ZW
3509 imm |= (given & 0x000f0000u) >> 16;
3510 imm |= (given & 0x00000ff0u) >> 0;
3511 imm |= (given & 0x0000000fu) << 12;
fe56b6ce
NC
3512 func (stream, "#%u", imm);
3513 value_in_comment = imm;
c19d1205
ZW
3514 }
3515 break;
3516
3517 case 'S':
3518 {
3519 unsigned int reg = (given & 0x0000000fu);
3520 unsigned int stp = (given & 0x00000030u) >> 4;
3521 unsigned int imm = 0;
3522 imm |= (given & 0x000000c0u) >> 6;
3523 imm |= (given & 0x00007000u) >> 10;
3524
3525 func (stream, "%s", arm_regnames[reg]);
3526 switch (stp)
3527 {
3528 case 0:
3529 if (imm > 0)
3530 func (stream, ", lsl #%u", imm);
3531 break;
3532
3533 case 1:
3534 if (imm == 0)
3535 imm = 32;
3536 func (stream, ", lsr #%u", imm);
3537 break;
3538
3539 case 2:
3540 if (imm == 0)
3541 imm = 32;
3542 func (stream, ", asr #%u", imm);
3543 break;
3544
3545 case 3:
3546 if (imm == 0)
3547 func (stream, ", rrx");
3548 else
3549 func (stream, ", ror #%u", imm);
3550 }
3551 }
3552 break;
3553
3554 case 'a':
3555 {
3556 unsigned int Rn = (given & 0x000f0000) >> 16;
3557 unsigned int U = (given & 0x00800000) >> 23;
3558 unsigned int op = (given & 0x00000f00) >> 8;
3559 unsigned int i12 = (given & 0x00000fff);
3560 unsigned int i8 = (given & 0x000000ff);
3561 bfd_boolean writeback = FALSE, postind = FALSE;
3562 int offset = 0;
3563
3564 func (stream, "[%s", arm_regnames[Rn]);
05413229
NC
3565 if (U) /* 12-bit positive immediate offset. */
3566 {
3567 offset = i12;
3568 if (Rn != 15)
3569 value_in_comment = offset;
3570 }
3571 else if (Rn == 15) /* 12-bit negative immediate offset. */
3572 offset = - (int) i12;
3573 else if (op == 0x0) /* Shifted register offset. */
c19d1205
ZW
3574 {
3575 unsigned int Rm = (i8 & 0x0f);
3576 unsigned int sh = (i8 & 0x30) >> 4;
05413229 3577
c19d1205
ZW
3578 func (stream, ", %s", arm_regnames[Rm]);
3579 if (sh)
3580 func (stream, ", lsl #%u", sh);
3581 func (stream, "]");
3582 break;
3583 }
3584 else switch (op)
3585 {
05413229 3586 case 0xE: /* 8-bit positive immediate offset. */
c19d1205
ZW
3587 offset = i8;
3588 break;
3589
05413229 3590 case 0xC: /* 8-bit negative immediate offset. */
c19d1205
ZW
3591 offset = -i8;
3592 break;
3593
05413229 3594 case 0xF: /* 8-bit + preindex with wb. */
c19d1205
ZW
3595 offset = i8;
3596 writeback = TRUE;
3597 break;
3598
05413229 3599 case 0xD: /* 8-bit - preindex with wb. */
c19d1205
ZW
3600 offset = -i8;
3601 writeback = TRUE;
3602 break;
3603
05413229 3604 case 0xB: /* 8-bit + postindex. */
c19d1205
ZW
3605 offset = i8;
3606 postind = TRUE;
3607 break;
3608
05413229 3609 case 0x9: /* 8-bit - postindex. */
c19d1205
ZW
3610 offset = -i8;
3611 postind = TRUE;
3612 break;
3613
3614 default:
3615 func (stream, ", <undefined>]");
3616 goto skip;
3617 }
3618
3619 if (postind)
3620 func (stream, "], #%d", offset);
3621 else
3622 {
3623 if (offset)
3624 func (stream, ", #%d", offset);
3625 func (stream, writeback ? "]!" : "]");
3626 }
3627
3628 if (Rn == 15)
3629 {
3630 func (stream, "\t; ");
3631 info->print_address_func (((pc + 4) & ~3) + offset, info);
3632 }
3633 }
3634 skip:
3635 break;
3636
3637 case 'A':
3638 {
3639 unsigned int P = (given & 0x01000000) >> 24;
3640 unsigned int U = (given & 0x00800000) >> 23;
3641 unsigned int W = (given & 0x00400000) >> 21;
3642 unsigned int Rn = (given & 0x000f0000) >> 16;
3643 unsigned int off = (given & 0x000000ff);
3644
3645 func (stream, "[%s", arm_regnames[Rn]);
3646 if (P)
3647 {
3648 if (off || !U)
05413229
NC
3649 {
3650 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3651 value_in_comment = off * 4 * U ? 1 : -1;
3652 }
c19d1205
ZW
3653 func (stream, "]");
3654 if (W)
3655 func (stream, "!");
3656 }
3657 else
3658 {
3659 func (stream, "], ");
3660 if (W)
05413229
NC
3661 {
3662 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3663 value_in_comment = off * 4 * U ? 1 : -1;
3664 }
c19d1205 3665 else
fe56b6ce
NC
3666 {
3667 func (stream, "{%u}", off);
3668 value_in_comment = off;
3669 }
c19d1205
ZW
3670 }
3671 }
3672 break;
3673
3674 case 'w':
3675 {
3676 unsigned int Sbit = (given & 0x01000000) >> 24;
3677 unsigned int type = (given & 0x00600000) >> 21;
05413229 3678
c19d1205
ZW
3679 switch (type)
3680 {
3681 case 0: func (stream, Sbit ? "sb" : "b"); break;
3682 case 1: func (stream, Sbit ? "sh" : "h"); break;
3683 case 2:
3684 if (Sbit)
3685 func (stream, "??");
3686 break;
3687 case 3:
3688 func (stream, "??");
3689 break;
3690 }
3691 }
3692 break;
3693
3694 case 'm':
3695 {
3696 int started = 0;
3697 int reg;
3698
3699 func (stream, "{");
3700 for (reg = 0; reg < 16; reg++)
3701 if ((given & (1 << reg)) != 0)
3702 {
3703 if (started)
3704 func (stream, ", ");
3705 started = 1;
3706 func (stream, "%s", arm_regnames[reg]);
3707 }
3708 func (stream, "}");
3709 }
3710 break;
3711
3712 case 'E':
3713 {
3714 unsigned int msb = (given & 0x0000001f);
3715 unsigned int lsb = 0;
fe56b6ce 3716
c19d1205
ZW
3717 lsb |= (given & 0x000000c0u) >> 6;
3718 lsb |= (given & 0x00007000u) >> 10;
3719 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3720 }
3721 break;
3722
3723 case 'F':
3724 {
3725 unsigned int width = (given & 0x0000001f) + 1;
3726 unsigned int lsb = 0;
fe56b6ce 3727
c19d1205
ZW
3728 lsb |= (given & 0x000000c0u) >> 6;
3729 lsb |= (given & 0x00007000u) >> 10;
3730 func (stream, "#%u, #%u", lsb, width);
3731 }
3732 break;
3733
3734 case 'b':
3735 {
3736 unsigned int S = (given & 0x04000000u) >> 26;
3737 unsigned int J1 = (given & 0x00002000u) >> 13;
3738 unsigned int J2 = (given & 0x00000800u) >> 11;
3739 int offset = 0;
3740
3741 offset |= !S << 20;
3742 offset |= J2 << 19;
3743 offset |= J1 << 18;
3744 offset |= (given & 0x003f0000) >> 4;
3745 offset |= (given & 0x000007ff) << 1;
3746 offset -= (1 << 20);
3747
3748 info->print_address_func (pc + 4 + offset, info);
3749 }
3750 break;
3751
3752 case 'B':
3753 {
3754 unsigned int S = (given & 0x04000000u) >> 26;
3755 unsigned int I1 = (given & 0x00002000u) >> 13;
3756 unsigned int I2 = (given & 0x00000800u) >> 11;
3757 int offset = 0;
3758
3759 offset |= !S << 24;
3760 offset |= !(I1 ^ S) << 23;
3761 offset |= !(I2 ^ S) << 22;
3762 offset |= (given & 0x03ff0000u) >> 4;
3763 offset |= (given & 0x000007ffu) << 1;
3764 offset -= (1 << 24);
36b0c57d 3765 offset += pc + 4;
c19d1205 3766
36b0c57d
PB
3767 /* BLX target addresses are always word aligned. */
3768 if ((given & 0x00001000u) == 0)
3769 offset &= ~2u;
3770
3771 info->print_address_func (offset, info);
c19d1205
ZW
3772 }
3773 break;
3774
3775 case 's':
3776 {
3777 unsigned int shift = 0;
fe56b6ce 3778
c19d1205
ZW
3779 shift |= (given & 0x000000c0u) >> 6;
3780 shift |= (given & 0x00007000u) >> 10;
3781 if (given & 0x00200000u)
3782 func (stream, ", asr #%u", shift);
3783 else if (shift)
3784 func (stream, ", lsl #%u", shift);
3785 /* else print nothing - lsl #0 */
3786 }
3787 break;
3788
3789 case 'R':
3790 {
3791 unsigned int rot = (given & 0x00000030) >> 4;
fe56b6ce 3792
c19d1205
ZW
3793 if (rot)
3794 func (stream, ", ror #%u", rot * 8);
3795 }
3796 break;
3797
62b3e311
PB
3798 case 'U':
3799 switch (given & 0xf)
3800 {
fe56b6ce
NC
3801 case 0xf: func (stream, "sy"); break;
3802 case 0x7: func (stream, "un"); break;
3803 case 0xe: func (stream, "st"); break;
3804 case 0x6: func (stream, "unst"); break;
62b3e311 3805 default:
fe56b6ce 3806 func (stream, "#%d", (int) given & 0xf);
62b3e311
PB
3807 break;
3808 }
3809 break;
3810
3811 case 'C':
3812 if ((given & 0xff) == 0)
3813 {
3814 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3815 if (given & 0x800)
3816 func (stream, "f");
3817 if (given & 0x400)
3818 func (stream, "s");
3819 if (given & 0x200)
3820 func (stream, "x");
3821 if (given & 0x100)
3822 func (stream, "c");
3823 }
3824 else
3825 {
3826 func (stream, psr_name (given & 0xff));
3827 }
3828 break;
3829
3830 case 'D':
3831 if ((given & 0xff) == 0)
3832 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3833 else
3834 func (stream, psr_name (given & 0xff));
3835 break;
3836
c19d1205
ZW
3837 case '0': case '1': case '2': case '3': case '4':
3838 case '5': case '6': case '7': case '8': case '9':
3839 {
16980d0b
JB
3840 int width;
3841 unsigned long val;
c19d1205 3842
16980d0b
JB
3843 c = arm_decode_bitfield (c, given, &val, &width);
3844
c19d1205
ZW
3845 switch (*c)
3846 {
05413229
NC
3847 case 'd':
3848 func (stream, "%lu", val);
3849 value_in_comment = val;
3850 break;
3851 case 'W':
3852 func (stream, "%lu", val * 4);
3853 value_in_comment = val * 4;
3854 break;
c19d1205
ZW
3855 case 'r': func (stream, "%s", arm_regnames[val]); break;
3856
3857 case 'c':
c22aaad1 3858 func (stream, "%s", arm_conditional[val]);
c19d1205
ZW
3859 break;
3860
3861 case '\'':
c19d1205 3862 c++;
16980d0b
JB
3863 if (val == ((1ul << width) - 1))
3864 func (stream, "%c", *c);
c19d1205
ZW
3865 break;
3866
3867 case '`':
c19d1205 3868 c++;
16980d0b
JB
3869 if (val == 0)
3870 func (stream, "%c", *c);
c19d1205
ZW
3871 break;
3872
3873 case '?':
fe56b6ce 3874 func (stream, "%c", c[(1 << width) - (int) val]);
16980d0b 3875 c += 1 << width;
c19d1205
ZW
3876 break;
3877
3878 default:
3879 abort ();
3880 }
3881 }
3882 break;
3883
3884 default:
3885 abort ();
3886 }
3887 }
05413229
NC
3888
3889 if (value_in_comment > 32 || value_in_comment < -16)
3890 func (stream, "\t; 0x%lx", value_in_comment);
4a5329c6 3891 return;
c19d1205 3892 }
252b5132 3893
58efb6c0 3894 /* No match. */
252b5132
RH
3895 abort ();
3896}
3897
e821645d
DJ
3898/* Print data bytes on INFO->STREAM. */
3899
3900static void
fe56b6ce
NC
3901print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3902 struct disassemble_info *info,
e821645d
DJ
3903 long given)
3904{
3905 switch (info->bytes_per_chunk)
3906 {
3907 case 1:
3908 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3909 break;
3910 case 2:
3911 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3912 break;
3913 case 4:
3914 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3915 break;
3916 default:
3917 abort ();
3918 }
3919}
3920
22a398e1
NC
3921/* Disallow mapping symbols ($a, $b, $d, $t etc) from
3922 being displayed in symbol relative addresses. */
3923
3924bfd_boolean
3925arm_symbol_is_valid (asymbol * sym,
3926 struct disassemble_info * info ATTRIBUTE_UNUSED)
3927{
3928 const char * name;
3929
3930 if (sym == NULL)
3931 return FALSE;
3932
3933 name = bfd_asymbol_name (sym);
3934
3935 return (name && *name != '$');
3936}
3937
58efb6c0 3938/* Parse an individual disassembler option. */
baf0cc5e 3939
a3d9c82d 3940void
4a5329c6 3941parse_arm_disassembler_option (char *option)
dd92f639 3942{
01c7f630 3943 if (option == NULL)
dd92f639 3944 return;
b34976b6 3945
0112cd26 3946 if (CONST_STRNEQ (option, "reg-names-"))
dd92f639 3947 {
58efb6c0 3948 int i;
b34976b6 3949
01c7f630 3950 option += 10;
58efb6c0
NC
3951
3952 for (i = NUM_ARM_REGNAMES; i--;)
31e0f3cd 3953 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
58efb6c0
NC
3954 {
3955 regname_selected = i;
3956 break;
3957 }
b34976b6 3958
58efb6c0 3959 if (i < 0)
31e0f3cd 3960 /* XXX - should break 'option' at following delimiter. */
58efb6c0 3961 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
dd92f639 3962 }
0112cd26 3963 else if (CONST_STRNEQ (option, "force-thumb"))
01c7f630 3964 force_thumb = 1;
0112cd26 3965 else if (CONST_STRNEQ (option, "no-force-thumb"))
01c7f630 3966 force_thumb = 0;
dd92f639 3967 else
31e0f3cd 3968 /* XXX - should break 'option' at following delimiter. */
58efb6c0 3969 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
b34976b6 3970
dd92f639
NC
3971 return;
3972}
3973
31e0f3cd
NC
3974/* Parse the string of disassembler options, spliting it at whitespaces
3975 or commas. (Whitespace separators supported for backwards compatibility). */
baf0cc5e 3976
01c7f630 3977static void
4a5329c6 3978parse_disassembler_options (char *options)
01c7f630 3979{
01c7f630
NC
3980 if (options == NULL)
3981 return;
3982
31e0f3cd 3983 while (*options)
01c7f630 3984 {
31e0f3cd
NC
3985 parse_arm_disassembler_option (options);
3986
3987 /* Skip forward to next seperator. */
3988 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3989 ++ options;
3990 /* Skip forward past seperators. */
3991 while (ISSPACE (*options) || (*options == ','))
3992 ++ options;
01c7f630 3993 }
01c7f630
NC
3994}
3995
c22aaad1
PB
3996/* Search back through the insn stream to determine if this instruction is
3997 conditionally executed. */
fe56b6ce 3998
c22aaad1 3999static void
fe56b6ce
NC
4000find_ifthen_state (bfd_vma pc,
4001 struct disassemble_info *info,
c22aaad1
PB
4002 bfd_boolean little)
4003{
4004 unsigned char b[2];
4005 unsigned int insn;
4006 int status;
4007 /* COUNT is twice the number of instructions seen. It will be odd if we
4008 just crossed an instruction boundary. */
4009 int count;
4010 int it_count;
4011 unsigned int seen_it;
4012 bfd_vma addr;
4013
4014 ifthen_address = pc;
4015 ifthen_state = 0;
4016
4017 addr = pc;
4018 count = 1;
4019 it_count = 0;
4020 seen_it = 0;
4021 /* Scan backwards looking for IT instructions, keeping track of where
4022 instruction boundaries are. We don't know if something is actually an
4023 IT instruction until we find a definite instruction boundary. */
4024 for (;;)
4025 {
fe56b6ce 4026 if (addr == 0 || info->symbol_at_address_func (addr, info))
c22aaad1
PB
4027 {
4028 /* A symbol must be on an instruction boundary, and will not
4029 be within an IT block. */
4030 if (seen_it && (count & 1))
4031 break;
4032
4033 return;
4034 }
4035 addr -= 2;
fe56b6ce 4036 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
c22aaad1
PB
4037 if (status)
4038 return;
4039
4040 if (little)
4041 insn = (b[0]) | (b[1] << 8);
4042 else
4043 insn = (b[1]) | (b[0] << 8);
4044 if (seen_it)
4045 {
4046 if ((insn & 0xf800) < 0xe800)
4047 {
4048 /* Addr + 2 is an instruction boundary. See if this matches
4049 the expected boundary based on the position of the last
4050 IT candidate. */
4051 if (count & 1)
4052 break;
4053 seen_it = 0;
4054 }
4055 }
4056 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4057 {
4058 /* This could be an IT instruction. */
4059 seen_it = insn;
4060 it_count = count >> 1;
4061 }
4062 if ((insn & 0xf800) >= 0xe800)
4063 count++;
4064 else
4065 count = (count + 2) | 1;
4066 /* IT blocks contain at most 4 instructions. */
4067 if (count >= 8 && !seen_it)
4068 return;
4069 }
4070 /* We found an IT instruction. */
4071 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4072 if ((ifthen_state & 0xf) == 0)
4073 ifthen_state = 0;
4074}
4075
2087ad84 4076/* Try to infer the code type (Arm or Thumb) from a symbol.
e821645d 4077 Returns nonzero if *MAP_TYPE was set. */
2087ad84
PB
4078
4079static int
fe56b6ce
NC
4080get_sym_code_type (struct disassemble_info *info,
4081 int n,
e821645d 4082 enum map_type *map_type)
2087ad84
PB
4083{
4084 elf_symbol_type *es;
4085 unsigned int type;
4086 const char *name;
4087
e821645d 4088 es = *(elf_symbol_type **)(info->symtab + n);
2087ad84
PB
4089 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4090
4091 /* If the symbol has function type then use that. */
4092 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4093 {
e821645d 4094 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
2087ad84
PB
4095 return TRUE;
4096 }
4097
4098 /* Check for mapping symbols. */
fe56b6ce 4099 name = bfd_asymbol_name (info->symtab[n]);
e821645d 4100 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
2087ad84
PB
4101 && (name[2] == 0 || name[2] == '.'))
4102 {
e821645d
DJ
4103 *map_type = ((name[1] == 'a') ? MAP_ARM
4104 : (name[1] == 't') ? MAP_THUMB
4105 : MAP_DATA);
2087ad84
PB
4106 return TRUE;
4107 }
4108
4109 return FALSE;
4110}
4111
0313a2b8
NC
4112/* Given a bfd_mach_arm_XXX value, this function fills in the fields
4113 of the supplied arm_feature_set structure with bitmasks indicating
4114 the support base architectures and coprocessor extensions.
4115
4116 FIXME: This could more efficiently implemented as a constant array,
4117 although it would also be less robust. */
4118
4119static void
4120select_arm_features (unsigned long mach,
4121 arm_feature_set * features)
4122{
4123#undef ARM_FEATURE
4124#define ARM_FEATURE(ARCH,CEXT) \
4125 features->core = (ARCH); \
4126 features->coproc = (CEXT) | FPU_FPA; \
4127 return
4128
4129 switch (mach)
4130 {
4131 case bfd_mach_arm_2: ARM_ARCH_V2;
4132 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4133 case bfd_mach_arm_3: ARM_ARCH_V3;
4134 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4135 case bfd_mach_arm_4: ARM_ARCH_V4;
4136 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4137 case bfd_mach_arm_5: ARM_ARCH_V5;
4138 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4139 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4140 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4141 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4142 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4143 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4144 /* If the machine type is unknown allow all
4145 architecture types and all extensions. */
4146 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4147 default:
4148 abort ();
4149 }
4150}
4151
4152
58efb6c0
NC
4153/* NOTE: There are no checks in these routines that
4154 the relevant number of data bytes exist. */
baf0cc5e 4155
58efb6c0 4156static int
4a5329c6 4157print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
252b5132 4158{
c19d1205
ZW
4159 unsigned char b[4];
4160 long given;
4161 int status;
e821645d
DJ
4162 int is_thumb = FALSE;
4163 int is_data = FALSE;
bd2e2557 4164 int little_code;
e821645d 4165 unsigned int size = 4;
4a5329c6 4166 void (*printer) (bfd_vma, struct disassemble_info *, long);
e821645d 4167 bfd_boolean found = FALSE;
58efb6c0 4168
dd92f639
NC
4169 if (info->disassembler_options)
4170 {
4171 parse_disassembler_options (info->disassembler_options);
b34976b6 4172
58efb6c0 4173 /* To avoid repeated parsing of these options, we remove them here. */
dd92f639
NC
4174 info->disassembler_options = NULL;
4175 }
b34976b6 4176
0313a2b8
NC
4177 /* PR 10288: Control which instructions will be disassembled. */
4178 if (info->private_data == NULL)
4179 {
4180 static arm_feature_set features;
4181
4182 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4183 /* If the user did not use the -m command line switch then default to
4184 disassembling all types of ARM instruction.
4185
4186 The info->mach value has to be ignored as this will be based on
4187 the default archictecture for the target and/or hints in the notes
4188 section, but it will never be greater than the current largest arm
4189 machine value (iWMMXt2), which is only equivalent to the V5TE
4190 architecture. ARM architectures have advanced beyond the machine
4191 value encoding, and these newer architectures would be ignored if
4192 the machine value was used.
4193
4194 Ie the -m switch is used to restrict which instructions will be
4195 disassembled. If it is necessary to use the -m switch to tell
4196 objdump that an ARM binary is being disassembled, eg because the
4197 input is a raw binary file, but it is also desired to disassemble
4198 all ARM instructions then use "-marm". This will select the
4199 "unknown" arm architecture which is compatible with any ARM
4200 instruction. */
4201 info->mach = bfd_mach_arm_unknown;
4202
4203 /* Compute the architecture bitmask from the machine number.
4204 Note: This assumes that the machine number will not change
4205 during disassembly.... */
4206 select_arm_features (info->mach, & features);
4207
4208 info->private_data = & features;
4209 }
4210
bd2e2557
SS
4211 /* Decide if our code is going to be little-endian, despite what the
4212 function argument might say. */
4213 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4214
e821645d
DJ
4215 /* First check the full symtab for a mapping symbol, even if there
4216 are no usable non-mapping symbols for this address. */
4217 if (info->symtab != NULL
2cc7bb5d 4218 && * info->symtab
e821645d
DJ
4219 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4220 {
4221 bfd_vma addr;
4222 int n;
4223 int last_sym = -1;
fbb92301 4224 enum map_type type = MAP_ARM;
e821645d
DJ
4225
4226 if (pc <= last_mapping_addr)
4227 last_mapping_sym = -1;
4228 is_thumb = (last_type == MAP_THUMB);
4229 found = FALSE;
4230 /* Start scanning at the start of the function, or wherever
4231 we finished last time. */
4232 n = info->symtab_pos + 1;
4233 if (n < last_mapping_sym)
4234 n = last_mapping_sym;
4235
4236 /* Scan up to the location being disassembled. */
4237 for (; n < info->symtab_size; n++)
4238 {
4239 addr = bfd_asymbol_value (info->symtab[n]);
4240 if (addr > pc)
4241 break;
86ad2a13
RE
4242 if ((info->section == NULL
4243 || info->section == info->symtab[n]->section)
4244 && get_sym_code_type (info, n, &type))
e821645d
DJ
4245 {
4246 last_sym = n;
4247 found = TRUE;
4248 }
4249 }
4250
4251 if (!found)
4252 {
4253 n = info->symtab_pos;
4254 if (n < last_mapping_sym - 1)
4255 n = last_mapping_sym - 1;
4256
4257 /* No mapping symbol found at this address. Look backwards
4258 for a preceeding one. */
4259 for (; n >= 0; n--)
4260 {
d460e92e
JM
4261 if ((info->section == NULL
4262 || info->section == info->symtab[n]->section)
4263 && get_sym_code_type (info, n, &type))
e821645d
DJ
4264 {
4265 last_sym = n;
4266 found = TRUE;
4267 break;
4268 }
4269 }
4270 }
4271
4272 last_mapping_sym = last_sym;
4273 last_type = type;
4274 is_thumb = (last_type == MAP_THUMB);
4275 is_data = (last_type == MAP_DATA);
b34976b6 4276
e821645d
DJ
4277 /* Look a little bit ahead to see if we should print out
4278 two or four bytes of data. If there's a symbol,
4279 mapping or otherwise, after two bytes then don't
4280 print more. */
4281 if (is_data)
4282 {
4283 size = 4 - (pc & 3);
4284 for (n = last_sym + 1; n < info->symtab_size; n++)
4285 {
4286 addr = bfd_asymbol_value (info->symtab[n]);
4287 if (addr > pc)
4288 {
4289 if (addr - pc < size)
4290 size = addr - pc;
4291 break;
4292 }
4293 }
4294 /* If the next symbol is after three bytes, we need to
4295 print only part of the data, so that we can use either
4296 .byte or .short. */
4297 if (size == 3)
4298 size = (pc & 1) ? 1 : 2;
4299 }
4300 }
4301
4302 if (info->symbols != NULL)
252b5132 4303 {
5876e06d
NC
4304 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4305 {
2f0ca46a 4306 coff_symbol_type * cs;
b34976b6 4307
5876e06d
NC
4308 cs = coffsymbol (*info->symbols);
4309 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4310 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4311 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4312 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4313 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4314 }
e821645d
DJ
4315 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4316 && !found)
5876e06d 4317 {
2087ad84
PB
4318 /* If no mapping symbol has been found then fall back to the type
4319 of the function symbol. */
e821645d
DJ
4320 elf_symbol_type * es;
4321 unsigned int type;
2087ad84 4322
e821645d
DJ
4323 es = *(elf_symbol_type **)(info->symbols);
4324 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2087ad84 4325
e821645d 4326 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
5876e06d
NC
4327 }
4328 }
b34976b6 4329
e821645d
DJ
4330 if (force_thumb)
4331 is_thumb = TRUE;
4332
b8f9ee44
CL
4333 if (is_data)
4334 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4335 else
4336 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4337
c19d1205 4338 info->bytes_per_line = 4;
252b5132 4339
1316c8b3
NC
4340 /* PR 10263: Disassemble data if requested to do so by the user. */
4341 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
e821645d
DJ
4342 {
4343 int i;
4344
1316c8b3 4345 /* Size was already set above. */
e821645d
DJ
4346 info->bytes_per_chunk = size;
4347 printer = print_insn_data;
4348
fe56b6ce 4349 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
e821645d
DJ
4350 given = 0;
4351 if (little)
4352 for (i = size - 1; i >= 0; i--)
4353 given = b[i] | (given << 8);
4354 else
4355 for (i = 0; i < (int) size; i++)
4356 given = b[i] | (given << 8);
4357 }
4358 else if (!is_thumb)
252b5132 4359 {
c19d1205
ZW
4360 /* In ARM mode endianness is a straightforward issue: the instruction
4361 is four bytes long and is either ordered 0123 or 3210. */
4362 printer = print_insn_arm;
4363 info->bytes_per_chunk = 4;
4a5329c6 4364 size = 4;
c19d1205 4365
0313a2b8 4366 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
bd2e2557 4367 if (little_code)
c19d1205
ZW
4368 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4369 else
4370 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
252b5132 4371 }
58efb6c0 4372 else
252b5132 4373 {
c19d1205
ZW
4374 /* In Thumb mode we have the additional wrinkle of two
4375 instruction lengths. Fortunately, the bits that determine
4376 the length of the current instruction are always to be found
4377 in the first two bytes. */
4a5329c6 4378 printer = print_insn_thumb16;
c19d1205 4379 info->bytes_per_chunk = 2;
4a5329c6
ZW
4380 size = 2;
4381
fe56b6ce 4382 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
bd2e2557 4383 if (little_code)
9a2ff3f5
AM
4384 given = (b[0]) | (b[1] << 8);
4385 else
4386 given = (b[1]) | (b[0] << 8);
4387
c19d1205 4388 if (!status)
252b5132 4389 {
c19d1205
ZW
4390 /* These bit patterns signal a four-byte Thumb
4391 instruction. */
4392 if ((given & 0xF800) == 0xF800
4393 || (given & 0xF800) == 0xF000
4394 || (given & 0xF800) == 0xE800)
252b5132 4395 {
0313a2b8 4396 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
bd2e2557 4397 if (little_code)
c19d1205 4398 given = (b[0]) | (b[1] << 8) | (given << 16);
b7693d02 4399 else
c19d1205
ZW
4400 given = (b[1]) | (b[0] << 8) | (given << 16);
4401
4402 printer = print_insn_thumb32;
4a5329c6 4403 size = 4;
252b5132 4404 }
252b5132 4405 }
c22aaad1
PB
4406
4407 if (ifthen_address != pc)
0313a2b8 4408 find_ifthen_state (pc, info, little_code);
c22aaad1
PB
4409
4410 if (ifthen_state)
4411 {
4412 if ((ifthen_state & 0xf) == 0x8)
4413 ifthen_next_state = 0;
4414 else
4415 ifthen_next_state = (ifthen_state & 0xe0)
4416 | ((ifthen_state & 0xf) << 1);
4417 }
252b5132 4418 }
b34976b6 4419
c19d1205
ZW
4420 if (status)
4421 {
4422 info->memory_error_func (status, pc, info);
4423 return -1;
4424 }
6a56ec7e
NC
4425 if (info->flags & INSN_HAS_RELOC)
4426 /* If the instruction has a reloc associated with it, then
4427 the offset field in the instruction will actually be the
4428 addend for the reloc. (We are using REL type relocs).
4429 In such cases, we can ignore the pc when computing
4430 addresses, since the addend is not currently pc-relative. */
4431 pc = 0;
b34976b6 4432
4a5329c6 4433 printer (pc, info, given);
c22aaad1
PB
4434
4435 if (is_thumb)
4436 {
4437 ifthen_state = ifthen_next_state;
4438 ifthen_address += size;
4439 }
4a5329c6 4440 return size;
252b5132
RH
4441}
4442
4443int
4a5329c6 4444print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
252b5132 4445{
bd2e2557
SS
4446 /* Detect BE8-ness and record it in the disassembler info. */
4447 if (info->flavour == bfd_target_elf_flavour
4448 && info->section != NULL
4449 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4450 info->endian_code = BFD_ENDIAN_LITTLE;
4451
b34976b6 4452 return print_insn (pc, info, FALSE);
58efb6c0 4453}
01c7f630 4454
58efb6c0 4455int
4a5329c6 4456print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
58efb6c0 4457{
b34976b6 4458 return print_insn (pc, info, TRUE);
58efb6c0 4459}
252b5132 4460
58efb6c0 4461void
4a5329c6 4462print_arm_disassembler_options (FILE *stream)
58efb6c0
NC
4463{
4464 int i;
252b5132 4465
58efb6c0
NC
4466 fprintf (stream, _("\n\
4467The following ARM specific disassembler options are supported for use with\n\
4468the -M switch:\n"));
b34976b6 4469
58efb6c0
NC
4470 for (i = NUM_ARM_REGNAMES; i--;)
4471 fprintf (stream, " reg-names-%s %*c%s\n",
4472 regnames[i].name,
d5b2f4d6 4473 (int)(14 - strlen (regnames[i].name)), ' ',
58efb6c0
NC
4474 regnames[i].description);
4475
4476 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4477 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
252b5132 4478}