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