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