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