Must use VOID expression in VOID context.
[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
ZW
3934 break;
3935
3936 default:
3937 abort ();
3938 }
3939 }
3940 break;
3941
3942 default:
3943 abort ();
3944 }
3945 }
05413229
NC
3946
3947 if (value_in_comment > 32 || value_in_comment < -16)
3948 func (stream, "\t; 0x%lx", value_in_comment);
4a5329c6 3949 return;
c19d1205 3950 }
252b5132 3951
58efb6c0 3952 /* No match. */
252b5132
RH
3953 abort ();
3954}
3955
e821645d
DJ
3956/* Print data bytes on INFO->STREAM. */
3957
3958static void
fe56b6ce
NC
3959print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3960 struct disassemble_info *info,
e821645d
DJ
3961 long given)
3962{
3963 switch (info->bytes_per_chunk)
3964 {
3965 case 1:
3966 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3967 break;
3968 case 2:
3969 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3970 break;
3971 case 4:
3972 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3973 break;
3974 default:
3975 abort ();
3976 }
3977}
3978
22a398e1
NC
3979/* Disallow mapping symbols ($a, $b, $d, $t etc) from
3980 being displayed in symbol relative addresses. */
3981
3982bfd_boolean
3983arm_symbol_is_valid (asymbol * sym,
3984 struct disassemble_info * info ATTRIBUTE_UNUSED)
3985{
3986 const char * name;
3987
3988 if (sym == NULL)
3989 return FALSE;
3990
3991 name = bfd_asymbol_name (sym);
3992
3993 return (name && *name != '$');
3994}
3995
58efb6c0 3996/* Parse an individual disassembler option. */
baf0cc5e 3997
a3d9c82d 3998void
4a5329c6 3999parse_arm_disassembler_option (char *option)
dd92f639 4000{
01c7f630 4001 if (option == NULL)
dd92f639 4002 return;
b34976b6 4003
0112cd26 4004 if (CONST_STRNEQ (option, "reg-names-"))
dd92f639 4005 {
58efb6c0 4006 int i;
b34976b6 4007
01c7f630 4008 option += 10;
58efb6c0
NC
4009
4010 for (i = NUM_ARM_REGNAMES; i--;)
31e0f3cd 4011 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
58efb6c0
NC
4012 {
4013 regname_selected = i;
4014 break;
4015 }
b34976b6 4016
58efb6c0 4017 if (i < 0)
31e0f3cd 4018 /* XXX - should break 'option' at following delimiter. */
58efb6c0 4019 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
dd92f639 4020 }
0112cd26 4021 else if (CONST_STRNEQ (option, "force-thumb"))
01c7f630 4022 force_thumb = 1;
0112cd26 4023 else if (CONST_STRNEQ (option, "no-force-thumb"))
01c7f630 4024 force_thumb = 0;
dd92f639 4025 else
31e0f3cd 4026 /* XXX - should break 'option' at following delimiter. */
58efb6c0 4027 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
b34976b6 4028
dd92f639
NC
4029 return;
4030}
4031
31e0f3cd
NC
4032/* Parse the string of disassembler options, spliting it at whitespaces
4033 or commas. (Whitespace separators supported for backwards compatibility). */
baf0cc5e 4034
01c7f630 4035static void
4a5329c6 4036parse_disassembler_options (char *options)
01c7f630 4037{
01c7f630
NC
4038 if (options == NULL)
4039 return;
4040
31e0f3cd 4041 while (*options)
01c7f630 4042 {
31e0f3cd
NC
4043 parse_arm_disassembler_option (options);
4044
4045 /* Skip forward to next seperator. */
4046 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4047 ++ options;
4048 /* Skip forward past seperators. */
4049 while (ISSPACE (*options) || (*options == ','))
4050 ++ options;
01c7f630 4051 }
01c7f630
NC
4052}
4053
c22aaad1
PB
4054/* Search back through the insn stream to determine if this instruction is
4055 conditionally executed. */
fe56b6ce 4056
c22aaad1 4057static void
fe56b6ce
NC
4058find_ifthen_state (bfd_vma pc,
4059 struct disassemble_info *info,
c22aaad1
PB
4060 bfd_boolean little)
4061{
4062 unsigned char b[2];
4063 unsigned int insn;
4064 int status;
4065 /* COUNT is twice the number of instructions seen. It will be odd if we
4066 just crossed an instruction boundary. */
4067 int count;
4068 int it_count;
4069 unsigned int seen_it;
4070 bfd_vma addr;
4071
4072 ifthen_address = pc;
4073 ifthen_state = 0;
4074
4075 addr = pc;
4076 count = 1;
4077 it_count = 0;
4078 seen_it = 0;
4079 /* Scan backwards looking for IT instructions, keeping track of where
4080 instruction boundaries are. We don't know if something is actually an
4081 IT instruction until we find a definite instruction boundary. */
4082 for (;;)
4083 {
fe56b6ce 4084 if (addr == 0 || info->symbol_at_address_func (addr, info))
c22aaad1
PB
4085 {
4086 /* A symbol must be on an instruction boundary, and will not
4087 be within an IT block. */
4088 if (seen_it && (count & 1))
4089 break;
4090
4091 return;
4092 }
4093 addr -= 2;
fe56b6ce 4094 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
c22aaad1
PB
4095 if (status)
4096 return;
4097
4098 if (little)
4099 insn = (b[0]) | (b[1] << 8);
4100 else
4101 insn = (b[1]) | (b[0] << 8);
4102 if (seen_it)
4103 {
4104 if ((insn & 0xf800) < 0xe800)
4105 {
4106 /* Addr + 2 is an instruction boundary. See if this matches
4107 the expected boundary based on the position of the last
4108 IT candidate. */
4109 if (count & 1)
4110 break;
4111 seen_it = 0;
4112 }
4113 }
4114 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4115 {
4116 /* This could be an IT instruction. */
4117 seen_it = insn;
4118 it_count = count >> 1;
4119 }
4120 if ((insn & 0xf800) >= 0xe800)
4121 count++;
4122 else
4123 count = (count + 2) | 1;
4124 /* IT blocks contain at most 4 instructions. */
4125 if (count >= 8 && !seen_it)
4126 return;
4127 }
4128 /* We found an IT instruction. */
4129 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4130 if ((ifthen_state & 0xf) == 0)
4131 ifthen_state = 0;
4132}
4133
2087ad84 4134/* Try to infer the code type (Arm or Thumb) from a symbol.
e821645d 4135 Returns nonzero if *MAP_TYPE was set. */
2087ad84
PB
4136
4137static int
fe56b6ce
NC
4138get_sym_code_type (struct disassemble_info *info,
4139 int n,
e821645d 4140 enum map_type *map_type)
2087ad84
PB
4141{
4142 elf_symbol_type *es;
4143 unsigned int type;
4144 const char *name;
4145
e821645d 4146 es = *(elf_symbol_type **)(info->symtab + n);
2087ad84
PB
4147 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4148
4149 /* If the symbol has function type then use that. */
4150 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4151 {
e821645d 4152 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
2087ad84
PB
4153 return TRUE;
4154 }
4155
4156 /* Check for mapping symbols. */
fe56b6ce 4157 name = bfd_asymbol_name (info->symtab[n]);
e821645d 4158 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
2087ad84
PB
4159 && (name[2] == 0 || name[2] == '.'))
4160 {
e821645d
DJ
4161 *map_type = ((name[1] == 'a') ? MAP_ARM
4162 : (name[1] == 't') ? MAP_THUMB
4163 : MAP_DATA);
2087ad84
PB
4164 return TRUE;
4165 }
4166
4167 return FALSE;
4168}
4169
0313a2b8
NC
4170/* Given a bfd_mach_arm_XXX value, this function fills in the fields
4171 of the supplied arm_feature_set structure with bitmasks indicating
4172 the support base architectures and coprocessor extensions.
4173
4174 FIXME: This could more efficiently implemented as a constant array,
4175 although it would also be less robust. */
4176
4177static void
4178select_arm_features (unsigned long mach,
4179 arm_feature_set * features)
4180{
4181#undef ARM_FEATURE
4182#define ARM_FEATURE(ARCH,CEXT) \
4183 features->core = (ARCH); \
4184 features->coproc = (CEXT) | FPU_FPA; \
4185 return
4186
4187 switch (mach)
4188 {
4189 case bfd_mach_arm_2: ARM_ARCH_V2;
4190 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4191 case bfd_mach_arm_3: ARM_ARCH_V3;
4192 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4193 case bfd_mach_arm_4: ARM_ARCH_V4;
4194 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4195 case bfd_mach_arm_5: ARM_ARCH_V5;
4196 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4197 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4198 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4199 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4200 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4201 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4202 /* If the machine type is unknown allow all
4203 architecture types and all extensions. */
4204 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4205 default:
4206 abort ();
4207 }
4208}
4209
4210
58efb6c0
NC
4211/* NOTE: There are no checks in these routines that
4212 the relevant number of data bytes exist. */
baf0cc5e 4213
58efb6c0 4214static int
4a5329c6 4215print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
252b5132 4216{
c19d1205
ZW
4217 unsigned char b[4];
4218 long given;
4219 int status;
e821645d
DJ
4220 int is_thumb = FALSE;
4221 int is_data = FALSE;
bd2e2557 4222 int little_code;
e821645d 4223 unsigned int size = 4;
4a5329c6 4224 void (*printer) (bfd_vma, struct disassemble_info *, long);
e821645d 4225 bfd_boolean found = FALSE;
58efb6c0 4226
dd92f639
NC
4227 if (info->disassembler_options)
4228 {
4229 parse_disassembler_options (info->disassembler_options);
b34976b6 4230
58efb6c0 4231 /* To avoid repeated parsing of these options, we remove them here. */
dd92f639
NC
4232 info->disassembler_options = NULL;
4233 }
b34976b6 4234
0313a2b8
NC
4235 /* PR 10288: Control which instructions will be disassembled. */
4236 if (info->private_data == NULL)
4237 {
4238 static arm_feature_set features;
4239
4240 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4241 /* If the user did not use the -m command line switch then default to
4242 disassembling all types of ARM instruction.
4243
4244 The info->mach value has to be ignored as this will be based on
4245 the default archictecture for the target and/or hints in the notes
4246 section, but it will never be greater than the current largest arm
4247 machine value (iWMMXt2), which is only equivalent to the V5TE
4248 architecture. ARM architectures have advanced beyond the machine
4249 value encoding, and these newer architectures would be ignored if
4250 the machine value was used.
4251
4252 Ie the -m switch is used to restrict which instructions will be
4253 disassembled. If it is necessary to use the -m switch to tell
4254 objdump that an ARM binary is being disassembled, eg because the
4255 input is a raw binary file, but it is also desired to disassemble
4256 all ARM instructions then use "-marm". This will select the
4257 "unknown" arm architecture which is compatible with any ARM
4258 instruction. */
4259 info->mach = bfd_mach_arm_unknown;
4260
4261 /* Compute the architecture bitmask from the machine number.
4262 Note: This assumes that the machine number will not change
4263 during disassembly.... */
4264 select_arm_features (info->mach, & features);
4265
4266 info->private_data = & features;
4267 }
4268
bd2e2557
SS
4269 /* Decide if our code is going to be little-endian, despite what the
4270 function argument might say. */
4271 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4272
e821645d
DJ
4273 /* First check the full symtab for a mapping symbol, even if there
4274 are no usable non-mapping symbols for this address. */
8977d4b2 4275 if (info->symtab_size != 0
e821645d
DJ
4276 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4277 {
4278 bfd_vma addr;
4279 int n;
4280 int last_sym = -1;
fbb92301 4281 enum map_type type = MAP_ARM;
e821645d
DJ
4282
4283 if (pc <= last_mapping_addr)
4284 last_mapping_sym = -1;
4285 is_thumb = (last_type == MAP_THUMB);
4286 found = FALSE;
4287 /* Start scanning at the start of the function, or wherever
4288 we finished last time. */
4289 n = info->symtab_pos + 1;
4290 if (n < last_mapping_sym)
4291 n = last_mapping_sym;
4292
4293 /* Scan up to the location being disassembled. */
4294 for (; n < info->symtab_size; n++)
4295 {
4296 addr = bfd_asymbol_value (info->symtab[n]);
4297 if (addr > pc)
4298 break;
86ad2a13
RE
4299 if ((info->section == NULL
4300 || info->section == info->symtab[n]->section)
4301 && get_sym_code_type (info, n, &type))
e821645d
DJ
4302 {
4303 last_sym = n;
4304 found = TRUE;
4305 }
4306 }
4307
4308 if (!found)
4309 {
4310 n = info->symtab_pos;
4311 if (n < last_mapping_sym - 1)
4312 n = last_mapping_sym - 1;
4313
4314 /* No mapping symbol found at this address. Look backwards
4315 for a preceeding one. */
4316 for (; n >= 0; n--)
4317 {
d460e92e
JM
4318 if ((info->section == NULL
4319 || info->section == info->symtab[n]->section)
4320 && get_sym_code_type (info, n, &type))
e821645d
DJ
4321 {
4322 last_sym = n;
4323 found = TRUE;
4324 break;
4325 }
4326 }
4327 }
4328
4329 last_mapping_sym = last_sym;
4330 last_type = type;
4331 is_thumb = (last_type == MAP_THUMB);
4332 is_data = (last_type == MAP_DATA);
b34976b6 4333
e821645d
DJ
4334 /* Look a little bit ahead to see if we should print out
4335 two or four bytes of data. If there's a symbol,
4336 mapping or otherwise, after two bytes then don't
4337 print more. */
4338 if (is_data)
4339 {
4340 size = 4 - (pc & 3);
4341 for (n = last_sym + 1; n < info->symtab_size; n++)
4342 {
4343 addr = bfd_asymbol_value (info->symtab[n]);
4344 if (addr > pc)
4345 {
4346 if (addr - pc < size)
4347 size = addr - pc;
4348 break;
4349 }
4350 }
4351 /* If the next symbol is after three bytes, we need to
4352 print only part of the data, so that we can use either
4353 .byte or .short. */
4354 if (size == 3)
4355 size = (pc & 1) ? 1 : 2;
4356 }
4357 }
4358
4359 if (info->symbols != NULL)
252b5132 4360 {
5876e06d
NC
4361 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4362 {
2f0ca46a 4363 coff_symbol_type * cs;
b34976b6 4364
5876e06d
NC
4365 cs = coffsymbol (*info->symbols);
4366 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4367 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4368 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4369 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4370 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4371 }
e821645d
DJ
4372 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4373 && !found)
5876e06d 4374 {
2087ad84
PB
4375 /* If no mapping symbol has been found then fall back to the type
4376 of the function symbol. */
e821645d
DJ
4377 elf_symbol_type * es;
4378 unsigned int type;
2087ad84 4379
e821645d
DJ
4380 es = *(elf_symbol_type **)(info->symbols);
4381 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2087ad84 4382
e821645d 4383 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
5876e06d
NC
4384 }
4385 }
b34976b6 4386
e821645d
DJ
4387 if (force_thumb)
4388 is_thumb = TRUE;
4389
b8f9ee44
CL
4390 if (is_data)
4391 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4392 else
4393 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4394
c19d1205 4395 info->bytes_per_line = 4;
252b5132 4396
1316c8b3
NC
4397 /* PR 10263: Disassemble data if requested to do so by the user. */
4398 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
e821645d
DJ
4399 {
4400 int i;
4401
1316c8b3 4402 /* Size was already set above. */
e821645d
DJ
4403 info->bytes_per_chunk = size;
4404 printer = print_insn_data;
4405
fe56b6ce 4406 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
e821645d
DJ
4407 given = 0;
4408 if (little)
4409 for (i = size - 1; i >= 0; i--)
4410 given = b[i] | (given << 8);
4411 else
4412 for (i = 0; i < (int) size; i++)
4413 given = b[i] | (given << 8);
4414 }
4415 else if (!is_thumb)
252b5132 4416 {
c19d1205
ZW
4417 /* In ARM mode endianness is a straightforward issue: the instruction
4418 is four bytes long and is either ordered 0123 or 3210. */
4419 printer = print_insn_arm;
4420 info->bytes_per_chunk = 4;
4a5329c6 4421 size = 4;
c19d1205 4422
0313a2b8 4423 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
bd2e2557 4424 if (little_code)
c19d1205
ZW
4425 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4426 else
4427 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
252b5132 4428 }
58efb6c0 4429 else
252b5132 4430 {
c19d1205
ZW
4431 /* In Thumb mode we have the additional wrinkle of two
4432 instruction lengths. Fortunately, the bits that determine
4433 the length of the current instruction are always to be found
4434 in the first two bytes. */
4a5329c6 4435 printer = print_insn_thumb16;
c19d1205 4436 info->bytes_per_chunk = 2;
4a5329c6
ZW
4437 size = 2;
4438
fe56b6ce 4439 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
bd2e2557 4440 if (little_code)
9a2ff3f5
AM
4441 given = (b[0]) | (b[1] << 8);
4442 else
4443 given = (b[1]) | (b[0] << 8);
4444
c19d1205 4445 if (!status)
252b5132 4446 {
c19d1205
ZW
4447 /* These bit patterns signal a four-byte Thumb
4448 instruction. */
4449 if ((given & 0xF800) == 0xF800
4450 || (given & 0xF800) == 0xF000
4451 || (given & 0xF800) == 0xE800)
252b5132 4452 {
0313a2b8 4453 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
bd2e2557 4454 if (little_code)
c19d1205 4455 given = (b[0]) | (b[1] << 8) | (given << 16);
b7693d02 4456 else
c19d1205
ZW
4457 given = (b[1]) | (b[0] << 8) | (given << 16);
4458
4459 printer = print_insn_thumb32;
4a5329c6 4460 size = 4;
252b5132 4461 }
252b5132 4462 }
c22aaad1
PB
4463
4464 if (ifthen_address != pc)
0313a2b8 4465 find_ifthen_state (pc, info, little_code);
c22aaad1
PB
4466
4467 if (ifthen_state)
4468 {
4469 if ((ifthen_state & 0xf) == 0x8)
4470 ifthen_next_state = 0;
4471 else
4472 ifthen_next_state = (ifthen_state & 0xe0)
4473 | ((ifthen_state & 0xf) << 1);
4474 }
252b5132 4475 }
b34976b6 4476
c19d1205
ZW
4477 if (status)
4478 {
4479 info->memory_error_func (status, pc, info);
4480 return -1;
4481 }
6a56ec7e
NC
4482 if (info->flags & INSN_HAS_RELOC)
4483 /* If the instruction has a reloc associated with it, then
4484 the offset field in the instruction will actually be the
4485 addend for the reloc. (We are using REL type relocs).
4486 In such cases, we can ignore the pc when computing
4487 addresses, since the addend is not currently pc-relative. */
4488 pc = 0;
b34976b6 4489
4a5329c6 4490 printer (pc, info, given);
c22aaad1
PB
4491
4492 if (is_thumb)
4493 {
4494 ifthen_state = ifthen_next_state;
4495 ifthen_address += size;
4496 }
4a5329c6 4497 return size;
252b5132
RH
4498}
4499
4500int
4a5329c6 4501print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
252b5132 4502{
bd2e2557
SS
4503 /* Detect BE8-ness and record it in the disassembler info. */
4504 if (info->flavour == bfd_target_elf_flavour
4505 && info->section != NULL
4506 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4507 info->endian_code = BFD_ENDIAN_LITTLE;
4508
b34976b6 4509 return print_insn (pc, info, FALSE);
58efb6c0 4510}
01c7f630 4511
58efb6c0 4512int
4a5329c6 4513print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
58efb6c0 4514{
b34976b6 4515 return print_insn (pc, info, TRUE);
58efb6c0 4516}
252b5132 4517
58efb6c0 4518void
4a5329c6 4519print_arm_disassembler_options (FILE *stream)
58efb6c0
NC
4520{
4521 int i;
252b5132 4522
58efb6c0
NC
4523 fprintf (stream, _("\n\
4524The following ARM specific disassembler options are supported for use with\n\
4525the -M switch:\n"));
b34976b6 4526
58efb6c0
NC
4527 for (i = NUM_ARM_REGNAMES; i--;)
4528 fprintf (stream, " reg-names-%s %*c%s\n",
4529 regnames[i].name,
d5b2f4d6 4530 (int)(14 - strlen (regnames[i].name)), ' ',
58efb6c0
NC
4531 regnames[i].description);
4532
4533 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4534 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
252b5132 4535}
This page took 0.792457 seconds and 4 git commands to generate.