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