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