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