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