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