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