Updated Indonesian translation.
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
... / ...
CommitLineData
1/* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7 This file is part of libopcodes.
8
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.
13
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.
18
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
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24#include "sysdep.h"
25
26#include "dis-asm.h"
27#include "opcode/arm.h"
28#include "opintl.h"
29#include "safe-ctype.h"
30#include "floatformat.h"
31
32/* FIXME: This shouldn't be done here. */
33#include "coff/internal.h"
34#include "libcoff.h"
35#include "elf-bfd.h"
36#include "elf/internal.h"
37#include "elf/arm.h"
38
39/* FIXME: Belongs in global header. */
40#ifndef strneq
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])
46#endif
47
48struct opcode32
49{
50 unsigned long arch; /* Architecture defining this insn. */
51 unsigned long value; /* If arch == 0 then value is a sentinel. */
52 unsigned long mask; /* Recognise insn if (op & mask) == value. */
53 const char * assembler; /* How to disassemble this insn. */
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};
62
63/* print_insn_coprocessor recognizes the following format control codes:
64
65 %% %
66
67 %c print condition code (always bits 28-31 in ARM mode)
68 %q print shifter argument
69 %u print condition code (unconditional in ARM mode)
70 %A print address for ldc/stc/ldf/stf instruction
71 %B print vstm/vldm register list
72 %C print vstr/vldr address operand
73 %I print cirrus signed shift immediate: bits 0..3|4..6
74 %F print the COUNT field of a LFM/SFM instruction.
75 %P print floating point precision in arithmetic insn
76 %Q print floating point precision in ldf/stf insn
77 %R print floating point rounding mode
78
79 %<bitfield>r print as an ARM register
80 %<bitfield>d print the bitfield in decimal
81 %<bitfield>k print immediate for VFPv3 conversion instruction
82 %<bitfield>x print the bitfield in hex
83 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
84 %<bitfield>f print a floating point constant if >7 else a
85 floating point register
86 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
87 %<bitfield>g print as an iWMMXt 64-bit register
88 %<bitfield>G print as an iWMMXt general purpose or control register
89 %<bitfield>D print as a NEON D register
90 %<bitfield>Q print as a NEON Q register
91
92 %y<code> print a single precision VFP reg.
93 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
94 %z<code> print a double precision VFP reg
95 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
96
97 %<bitfield>'c print specified char iff bitfield is all ones
98 %<bitfield>`c print specified char iff bitfield is all zeroes
99 %<bitfield>?ab... select from array of values in big endian order
100
101 %L print as an iWMMXt N/M width field.
102 %Z print the Immediate of a WSHUFH instruction.
103 %l like 'A' except use byte offsets for 'B' & 'H'
104 versions.
105 %i print 5-bit immediate in bits 8,3..0
106 (print "32" when 0)
107 %r print register offset address for wldt/wstr instruction. */
108
109enum opcode_sentinel_enum
110{
111 SENTINEL_IWMMXT_START = 1,
112 SENTINEL_IWMMXT_END,
113 SENTINEL_GENERIC_START
114} opcode_sentinels;
115
116#define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
117
118/* Common coprocessor opcodes shared between Arm and Thumb-2. */
119
120static const struct opcode32 coprocessor_opcodes[] =
121{
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"},
128
129 /* Intel Wireless MMX technology instructions. */
130 { 0, SENTINEL_IWMMXT_START, 0, "" },
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"},
145 {ARM_CEXT_XSCALE, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
146 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
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"},
149 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
150 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
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"},
155 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
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"},
158 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
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"},
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"},
164 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
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"},
168 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
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"},
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"},
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"},
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"},
184 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
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"},
187 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
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"},
190 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
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"},
193 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
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"},
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"},
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"},
206 { 0, SENTINEL_IWMMXT_END, 0, "" },
207
208 /* Floating point coprocessor (FPA) instructions. */
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"},
250 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A\t; (stc%22'l%c %8-11d, cr%12-15d, %A)"},
251 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A\t; (ldc%22'l%c %8-11d, cr%12-15d, %A)"},
252
253 /* Register load/store. */
254 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
255 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
256 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
257 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
258 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
259 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
260 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
261 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
262 {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
263 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
264 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
265 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
266 {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
267 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
268 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
269 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
270
271 {FPU_VFP_EXT_V1xD, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
272 {FPU_VFP_EXT_V1xD, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
273 {FPU_VFP_EXT_V1xD, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
274 {FPU_VFP_EXT_V1xD, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
275
276 /* Data transfer between ARM and NEON registers. */
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]"},
291 /* Half-precision conversion instructions. */
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"},
294
295 /* Floating point coprocessor (VFP) instructions. */
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"},
333 {FPU_VFP_EXT_V3xD, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
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"},
337 {FPU_VFP_EXT_V3xD, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
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"},
340 {FPU_VFP_EXT_V3xD, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
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"},
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"},
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"},
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"},
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"},
449
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
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"},
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}"},
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"},
469
470 /* V6 coprocessor instructions. */
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"},
473
474 /* V5 coprocessor instructions. */
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}"},
480
481 {0, 0, 0, 0}
482};
483
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
492 %c print condition code
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
512 %<bitfield>?ab... select from array of values in big endian order. */
513
514static const struct opcode32 neon_opcodes[] =
515{
516 /* Extract. */
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"},
519
520 /* Move data element to all lanes. */
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]"},
524
525 /* Table lookup. */
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"},
528
529 /* Half-precision conversions. */
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"},
536
537 /* Two registers, miscellaneous. */
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"},
544 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
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"},
571
572 /* Three registers of the same length. */
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"},
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"},
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"},
626
627 /* One register and an immediate value. */
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"},
641
642 /* Two registers and a shift amount. */
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"},
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"},
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"},
701
702 /* Three registers of different lengths. */
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"},
720
721 /* Two registers and a scalar. */
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"},
744
745 /* Element and structure load/store. */
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"},
765
766 {0,0 ,0, 0}
767};
768
769/* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
770 ordered: they must be searched linearly from the top to obtain a correct
771 match. */
772
773/* print_insn_arm recognizes the following format control codes:
774
775 %% %
776
777 %a print address for ldr/str instruction
778 %s print address for ldr/str halfword/signextend instruction
779 %b print branch destination
780 %c print condition code (always bits 28-31)
781 %m print register mask for ldm/stm instruction
782 %o print operand2 (immediate or register + shift)
783 %p print 'p' iff bits 12-15 are 15
784 %t print 't' iff bit 21 set and bit 24 clear
785 %B print arm BLX(1) destination
786 %C print the PSR sub type.
787 %U print barrier type.
788 %P print address for pli instruction.
789
790 %<bitfield>r print as an ARM register
791 %<bitfield>d print the bitfield in decimal
792 %<bitfield>W print the bitfield plus one in decimal
793 %<bitfield>x print the bitfield in hex
794 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
795
796 %<bitfield>'c print specified char iff bitfield is all ones
797 %<bitfield>`c print specified char iff bitfield is all zeroes
798 %<bitfield>?ab... select from array of values in big endian order
799
800 %e print arm SMI operand (bits 0..7,8..19).
801 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
802 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
803
804static const struct opcode32 arm_opcodes[] =
805{
806 /* ARM instructions. */
807 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
808 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
809 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
810 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
811 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
812 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
813 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
814
815 /* V7 instructions. */
816 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
817 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
818 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
819 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
820 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
821
822 /* ARM V6T2 instructions. */
823 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
824 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
825 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
826 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
827 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
828 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
829 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
830 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
831 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
832
833 /* ARM V6Z instructions. */
834 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
835
836 /* ARM V6K instructions. */
837 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
838 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
839 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
840 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
841 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
842 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
843 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
844
845 /* ARM V6K NOP hints. */
846 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
847 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
848 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
849 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
850 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
851
852 /* ARM V6 instructions. */
853 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
854 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
855 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
856 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
857 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
858 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
859 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
860 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
861 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
862 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
863 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
864 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
865 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
866 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
867 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
869 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
870 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
871 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
872 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
873 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
874 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
875 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
877 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
878 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
879 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
881 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
882 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
883 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
885 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
886 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
887 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
888 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
889 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
890 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
891 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
893 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
894 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
895 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
897 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
898 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
899 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15r, %0-3r"},
900 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15r, %0-3r"},
901 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15r, %0-3r"},
902 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
903 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
904 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
905 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
906 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
907 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
908 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
909 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
910 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
911 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
912 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
913 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
914 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
915 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
916 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
917 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
918 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
919 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
920 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
921 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
922 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
923 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
924 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
925 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
926 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
927 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
928 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
929 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
930 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
931 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
932 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
933 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
934 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
935 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
936 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
937 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
938 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
939 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
940 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
941 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
942 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
943 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
944 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
945 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
946 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
947 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
948 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
949 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
950 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
951 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
952 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
953 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
954 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
955 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
956 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
957 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
958 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
959 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
960 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
961 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
962 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
963 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
964 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
965 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
966 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
967 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
968 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
969 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
970 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
971 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
972 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
973 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
974 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
975
976 /* V5J instruction. */
977 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
978
979 /* V5 Instructions. */
980 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
981 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
982 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
983 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
984
985 /* V5E "El Segundo" Instructions. */
986 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
987 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
988 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
989 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
990 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
991 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
992 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
993
994 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
995 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
996
997 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
998 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
999 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1000 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1001
1002 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1003 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1004 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1005 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1006
1007 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1008 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1009
1010 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1011 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1012 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1013 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1014
1015 /* ARM Instructions. */
1016 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1017 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1018 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1019 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1020 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
1021 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
1022 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
1023 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
1024 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1025 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
1026
1027 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1028 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1029 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
1030
1031 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1032 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1033 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
1034
1035 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1036 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1037 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
1038
1039 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1040 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1041 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1042
1043 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1044 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1045 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
1046
1047 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1048 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1049 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
1050
1051 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1052 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1053 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1054
1055 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1056 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1057 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1058
1059 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1060 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1061
1062 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1063 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1064 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
1065
1066 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1067 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1068 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
1069
1070 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1071 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1072 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
1073
1074 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1075 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1076 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
1077
1078 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1079 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
1081
1082 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1083 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1084 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1085 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1086 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1087 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1088 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1089
1090 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1091 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
1093
1094 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1095 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1096 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
1097
1098 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1099 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1100 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1101 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1102 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1103 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1104 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1105 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1106 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1107 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1108 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1109
1110 /* The rest. */
1111 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1112 {0, 0x00000000, 0x00000000, 0}
1113};
1114
1115/* print_insn_thumb16 recognizes the following format control codes:
1116
1117 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1118 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1119 %<bitfield>I print bitfield as a signed decimal
1120 (top bit of range being the sign bit)
1121 %N print Thumb register mask (with LR)
1122 %O print Thumb register mask (with PC)
1123 %M print Thumb register mask
1124 %b print CZB's 6-bit unsigned branch destination
1125 %s print Thumb right-shift immediate (6..10; 0 == 32).
1126 %c print the condition code
1127 %C print the condition code, or "s" if not conditional
1128 %x print warning if conditional an not at end of IT block"
1129 %X print "\t; unpredictable <IT:code>" if conditional
1130 %I print IT instruction suffix and operands
1131 %<bitfield>r print bitfield as an ARM register
1132 %<bitfield>d print bitfield as a decimal
1133 %<bitfield>H print (bitfield * 2) as a decimal
1134 %<bitfield>W print (bitfield * 4) as a decimal
1135 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1136 %<bitfield>B print Thumb branch destination (signed displacement)
1137 %<bitfield>c print bitfield as a condition code
1138 %<bitnum>'c print specified char iff bit is one
1139 %<bitnum>?ab print a if bit is one else print b. */
1140
1141static const struct opcode16 thumb_opcodes[] =
1142{
1143 /* Thumb instructions. */
1144
1145 /* ARM V6K no-argument instructions. */
1146 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1147 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1148 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1149 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1150 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1151 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1152
1153 /* ARM V6T2 instructions. */
1154 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1155 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1156 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1157
1158 /* ARM V6. */
1159 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1160 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1161 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1162 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1163 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1164 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1165 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1166 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1167 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1168 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1169 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1170
1171 /* ARM V5 ISA extends Thumb. */
1172 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1173 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1174 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1175 /* ARM V4T ISA (Thumb v1). */
1176 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1177 /* Format 4. */
1178 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1179 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1180 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1181 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1182 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1183 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1184 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1185 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1186 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1187 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1188 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1189 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1190 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1191 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1192 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1193 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1194 /* format 13 */
1195 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1196 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1197 /* format 5 */
1198 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1199 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1200 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1201 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1202 /* format 14 */
1203 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1204 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1205 /* format 2 */
1206 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1207 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1208 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1209 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1210 /* format 8 */
1211 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1212 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1213 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1214 /* format 7 */
1215 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1216 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1217 /* format 1 */
1218 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1219 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1220 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1221 /* format 3 */
1222 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1223 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1224 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1225 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1226 /* format 6 */
1227 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1228 /* format 9 */
1229 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1230 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1231 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1232 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1233 /* format 10 */
1234 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1235 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1236 /* format 11 */
1237 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1238 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1239 /* format 12 */
1240 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1241 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1242 /* format 15 */
1243 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1244 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1245 /* format 17 */
1246 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1247 /* format 16 */
1248 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1249 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1250 /* format 18 */
1251 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1252
1253 /* The E800 .. FFFF range is unconditionally redirected to the
1254 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1255 are processed via that table. Thus, we can never encounter a
1256 bare "second half of BL/BLX(1)" instruction here. */
1257 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1258 {0, 0, 0, 0}
1259};
1260
1261/* Thumb32 opcodes use the same table structure as the ARM opcodes.
1262 We adopt the convention that hw1 is the high 16 bits of .value and
1263 .mask, hw2 the low 16 bits.
1264
1265 print_insn_thumb32 recognizes the following format control codes:
1266
1267 %% %
1268
1269 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1270 %M print a modified 12-bit immediate (same location)
1271 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1272 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1273 %S print a possibly-shifted Rm
1274
1275 %a print the address of a plain load/store
1276 %w print the width and signedness of a core load/store
1277 %m print register mask for ldm/stm
1278
1279 %E print the lsb and width fields of a bfc/bfi instruction
1280 %F print the lsb and width fields of a sbfx/ubfx instruction
1281 %b print a conditional branch offset
1282 %B print an unconditional branch offset
1283 %s print the shift field of an SSAT instruction
1284 %R print the rotation field of an SXT instruction
1285 %U print barrier type.
1286 %P print address for pli instruction.
1287 %c print the condition code
1288 %x print warning if conditional an not at end of IT block"
1289 %X print "\t; unpredictable <IT:code>" if conditional
1290
1291 %<bitfield>d print bitfield in decimal
1292 %<bitfield>W print bitfield*4 in decimal
1293 %<bitfield>r print bitfield as an ARM register
1294 %<bitfield>c print bitfield as a condition code
1295
1296 %<bitfield>'c print specified char iff bitfield is all ones
1297 %<bitfield>`c print specified char iff bitfield is all zeroes
1298 %<bitfield>?ab... select from array of values in big endian order
1299
1300 With one exception at the bottom (done because BL and BLX(1) need
1301 to come dead last), this table was machine-sorted first in
1302 decreasing order of number of bits set in the mask, then in
1303 increasing numeric order of mask, then in increasing numeric order
1304 of opcode. This order is not the clearest for a human reader, but
1305 is guaranteed never to catch a special-case bit pattern with a more
1306 general mask, which is important, because this instruction encoding
1307 makes heavy use of special-case bit patterns. */
1308static const struct opcode32 thumb32_opcodes[] =
1309{
1310 /* V7 instructions. */
1311 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1312 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1313 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1314 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1315 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1316 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1317 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1318
1319 /* Instructions defined in the basic V6T2 set. */
1320 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1321 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1322 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1323 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1324 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1325 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1326
1327 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1328 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1329 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1330 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1331 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1332 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1333 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1334 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1335 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1336 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1337 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1338 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1339 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1340 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1341 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1342 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1343 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1344 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1345 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1346 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1347 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1348 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1349 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1350 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1351 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1352 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1353 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1354 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1355 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1356 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1358 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1359 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1360 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1361 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1362 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
1363 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1364 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1365 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1366 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1368 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1369 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1370 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1371 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1372 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1373 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1374 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1375 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1376 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1377 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1378 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1379 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1380 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1381 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1382 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1384 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1385 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1387 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1388 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1389 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1390 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1391 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1397 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1398 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1399 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1400 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1406 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1407 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1408 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1409 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1410 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1413 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1414 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1415 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1416 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1417 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1418 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1420 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1421 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1422 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1423 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1424 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1425 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1426 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1427 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1428 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1429 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1430 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1431 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1432 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1433 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1434 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1440 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1441 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1442 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1443 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1444 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1445 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1446 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1447 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1448 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1449 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1452 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1453 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1454 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1455 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1456 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1457 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1459 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1460 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1461 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1462 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1463 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1464 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1465 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1466 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1467 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1468 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1469 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1470 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1471 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1472 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1473 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1474 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1475 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1476 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1477 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1478 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1479 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1480 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1481 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1482 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1483 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1484 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1485 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1486 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1487 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1488 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1489 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1490 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1491 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1492 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1493 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1494 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1495 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1496 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1497 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1498 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1499
1500 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1501 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1502 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1503 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1504 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1505
1506 /* These have been 32-bit since the invention of Thumb. */
1507 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1508 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1509
1510 /* Fallback. */
1511 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1512 {0, 0, 0, 0}
1513};
1514
1515static const char *const arm_conditional[] =
1516{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1517 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1518
1519static const char *const arm_fp_const[] =
1520{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1521
1522static const char *const arm_shift[] =
1523{"lsl", "lsr", "asr", "ror"};
1524
1525typedef struct
1526{
1527 const char *name;
1528 const char *description;
1529 const char *reg_names[16];
1530}
1531arm_regname;
1532
1533static const arm_regname regnames[] =
1534{
1535 { "raw" , "Select raw register names",
1536 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1537 { "gcc", "Select register names used by GCC",
1538 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1539 { "std", "Select register names used in ARM's ISA documentation",
1540 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1541 { "apcs", "Select register names used in the APCS",
1542 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1543 { "atpcs", "Select register names used in the ATPCS",
1544 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1545 { "special-atpcs", "Select special register names used in the ATPCS",
1546 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1547};
1548
1549static const char *const iwmmxt_wwnames[] =
1550{"b", "h", "w", "d"};
1551
1552static const char *const iwmmxt_wwssnames[] =
1553{"b", "bus", "bc", "bss",
1554 "h", "hus", "hc", "hss",
1555 "w", "wus", "wc", "wss",
1556 "d", "dus", "dc", "dss"
1557};
1558
1559static const char *const iwmmxt_regnames[] =
1560{ "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1561 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1562};
1563
1564static const char *const iwmmxt_cregnames[] =
1565{ "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1566 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1567};
1568
1569/* Default to GCC register name set. */
1570static unsigned int regname_selected = 1;
1571
1572#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1573#define arm_regnames regnames[regname_selected].reg_names
1574
1575static bfd_boolean force_thumb = FALSE;
1576
1577/* Current IT instruction state. This contains the same state as the IT
1578 bits in the CPSR. */
1579static unsigned int ifthen_state;
1580/* IT state for the next instruction. */
1581static unsigned int ifthen_next_state;
1582/* The address of the insn for which the IT state is valid. */
1583static bfd_vma ifthen_address;
1584#define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1585
1586/* Cached mapping symbol state. */
1587enum map_type
1588{
1589 MAP_ARM,
1590 MAP_THUMB,
1591 MAP_DATA
1592};
1593
1594enum map_type last_type;
1595int last_mapping_sym = -1;
1596bfd_vma last_mapping_addr = 0;
1597
1598\f
1599/* Functions. */
1600int
1601get_arm_regname_num_options (void)
1602{
1603 return NUM_ARM_REGNAMES;
1604}
1605
1606int
1607set_arm_regname_option (int option)
1608{
1609 int old = regname_selected;
1610 regname_selected = option;
1611 return old;
1612}
1613
1614int
1615get_arm_regnames (int option,
1616 const char **setname,
1617 const char **setdescription,
1618 const char *const **register_names)
1619{
1620 *setname = regnames[option].name;
1621 *setdescription = regnames[option].description;
1622 *register_names = regnames[option].reg_names;
1623 return 16;
1624}
1625
1626/* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1627 Returns pointer to following character of the format string and
1628 fills in *VALUEP and *WIDTHP with the extracted value and number of
1629 bits extracted. WIDTHP can be NULL. */
1630
1631static const char *
1632arm_decode_bitfield (const char *ptr,
1633 unsigned long insn,
1634 unsigned long *valuep,
1635 int *widthp)
1636{
1637 unsigned long value = 0;
1638 int width = 0;
1639
1640 do
1641 {
1642 int start, end;
1643 int bits;
1644
1645 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1646 start = start * 10 + *ptr - '0';
1647 if (*ptr == '-')
1648 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1649 end = end * 10 + *ptr - '0';
1650 else
1651 end = start;
1652 bits = end - start;
1653 if (bits < 0)
1654 abort ();
1655 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1656 width += bits + 1;
1657 }
1658 while (*ptr++ == ',');
1659 *valuep = value;
1660 if (widthp)
1661 *widthp = width;
1662 return ptr - 1;
1663}
1664
1665static void
1666arm_decode_shift (long given, fprintf_ftype func, void *stream,
1667 bfd_boolean print_shift)
1668{
1669 func (stream, "%s", arm_regnames[given & 0xf]);
1670
1671 if ((given & 0xff0) != 0)
1672 {
1673 if ((given & 0x10) == 0)
1674 {
1675 int amount = (given & 0xf80) >> 7;
1676 int shift = (given & 0x60) >> 5;
1677
1678 if (amount == 0)
1679 {
1680 if (shift == 3)
1681 {
1682 func (stream, ", rrx");
1683 return;
1684 }
1685
1686 amount = 32;
1687 }
1688
1689 if (print_shift)
1690 func (stream, ", %s #%d", arm_shift[shift], amount);
1691 else
1692 func (stream, ", #%d", amount);
1693 }
1694 else if ((given & 0x80) == 0x80)
1695 func (stream, ", <illegal shifter operand>");
1696 else if (print_shift)
1697 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1698 arm_regnames[(given & 0xf00) >> 8]);
1699 else
1700 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1701 }
1702}
1703
1704/* Print one coprocessor instruction on INFO->STREAM.
1705 Return TRUE if the instuction matched, FALSE if this is not a
1706 recognised coprocessor instruction. */
1707
1708static bfd_boolean
1709print_insn_coprocessor (bfd_vma pc,
1710 struct disassemble_info *info,
1711 long given,
1712 bfd_boolean thumb)
1713{
1714 const struct opcode32 *insn;
1715 void *stream = info->stream;
1716 fprintf_ftype func = info->fprintf_func;
1717 unsigned long mask;
1718 unsigned long value;
1719 unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
1720 int cond;
1721
1722 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1723 {
1724 signed long value_in_comment = 0;
1725 const char *c;
1726
1727 if (insn->arch == 0)
1728 switch (insn->value)
1729 {
1730 case SENTINEL_IWMMXT_START:
1731 if (info->mach != bfd_mach_arm_XScale
1732 && info->mach != bfd_mach_arm_iWMMXt
1733 && info->mach != bfd_mach_arm_iWMMXt2)
1734 do
1735 insn++;
1736 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1737 continue;
1738
1739 case SENTINEL_IWMMXT_END:
1740 continue;
1741
1742 case SENTINEL_GENERIC_START:
1743 allowed_arches = ((arm_feature_set *) info->private_data)->core;
1744 continue;
1745
1746 default:
1747 abort ();
1748 }
1749
1750 mask = insn->mask;
1751 value = insn->value;
1752 if (thumb)
1753 {
1754 /* The high 4 bits are 0xe for Arm conditional instructions, and
1755 0xe for arm unconditional instructions. The rest of the
1756 encoding is the same. */
1757 mask |= 0xf0000000;
1758 value |= 0xe0000000;
1759 if (ifthen_state)
1760 cond = IFTHEN_COND;
1761 else
1762 cond = 16;
1763 }
1764 else
1765 {
1766 /* Only match unconditional instuctions against unconditional
1767 patterns. */
1768 if ((given & 0xf0000000) == 0xf0000000)
1769 {
1770 mask |= 0xf0000000;
1771 cond = 16;
1772 }
1773 else
1774 {
1775 cond = (given >> 28) & 0xf;
1776 if (cond == 0xe)
1777 cond = 16;
1778 }
1779 }
1780
1781 if ((given & mask) != value)
1782 continue;
1783
1784 if ((insn->arch & allowed_arches) == 0)
1785 continue;
1786
1787 for (c = insn->assembler; *c; c++)
1788 {
1789 if (*c == '%')
1790 {
1791 switch (*++c)
1792 {
1793 case '%':
1794 func (stream, "%%");
1795 break;
1796
1797 case 'A':
1798 {
1799 int offset = given & 0xff;
1800
1801 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1802
1803 value_in_comment = offset * 4;
1804 if ((given & 0x00800000) == 0)
1805 value_in_comment = - value_in_comment;
1806
1807 if ((given & (1 << 24)) != 0)
1808 {
1809 if (offset)
1810 func (stream, ", #%d]%s",
1811 value_in_comment,
1812 ((given & 0x00200000) != 0 ? "!" : ""));
1813 else
1814 func (stream, "]");
1815 }
1816 else
1817 {
1818 func (stream, "]");
1819
1820 if (given & (1 << 21))
1821 {
1822 if (offset)
1823 func (stream, ", #%d", value_in_comment);
1824 }
1825 else
1826 {
1827 func (stream, ", {%d}", offset);
1828 value_in_comment = offset;
1829 }
1830 }
1831 }
1832 break;
1833
1834 case 'B':
1835 {
1836 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1837 int offset = (given >> 1) & 0x3f;
1838
1839 if (offset == 1)
1840 func (stream, "{d%d}", regno);
1841 else if (regno + offset > 32)
1842 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1843 else
1844 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1845 }
1846 break;
1847
1848 case 'C':
1849 {
1850 int rn = (given >> 16) & 0xf;
1851 int offset = (given & 0xff) * 4;
1852 int add = (given >> 23) & 1;
1853
1854 func (stream, "[%s", arm_regnames[rn]);
1855
1856 if (offset)
1857 {
1858 if (!add)
1859 offset = -offset;
1860 func (stream, ", #%d", offset);
1861 if (rn != 15)
1862 value_in_comment = offset;
1863 }
1864 func (stream, "]");
1865 if (rn == 15)
1866 {
1867 func (stream, "\t; ");
1868 /* FIXME: Unsure if info->bytes_per_chunk is the
1869 right thing to use here. */
1870 info->print_address_func (offset + pc
1871 + info->bytes_per_chunk * 2, info);
1872 }
1873 }
1874 break;
1875
1876 case 'c':
1877 func (stream, "%s", arm_conditional[cond]);
1878 break;
1879
1880 case 'I':
1881 /* Print a Cirrus/DSP shift immediate. */
1882 /* Immediates are 7bit signed ints with bits 0..3 in
1883 bits 0..3 of opcode and bits 4..6 in bits 5..7
1884 of opcode. */
1885 {
1886 int imm;
1887
1888 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1889
1890 /* Is ``imm'' a negative number? */
1891 if (imm & 0x40)
1892 imm |= (-1 << 7);
1893
1894 func (stream, "%d", imm);
1895 }
1896
1897 break;
1898
1899 case 'F':
1900 switch (given & 0x00408000)
1901 {
1902 case 0:
1903 func (stream, "4");
1904 break;
1905 case 0x8000:
1906 func (stream, "1");
1907 break;
1908 case 0x00400000:
1909 func (stream, "2");
1910 break;
1911 default:
1912 func (stream, "3");
1913 }
1914 break;
1915
1916 case 'P':
1917 switch (given & 0x00080080)
1918 {
1919 case 0:
1920 func (stream, "s");
1921 break;
1922 case 0x80:
1923 func (stream, "d");
1924 break;
1925 case 0x00080000:
1926 func (stream, "e");
1927 break;
1928 default:
1929 func (stream, _("<illegal precision>"));
1930 break;
1931 }
1932 break;
1933
1934 case 'Q':
1935 switch (given & 0x00408000)
1936 {
1937 case 0:
1938 func (stream, "s");
1939 break;
1940 case 0x8000:
1941 func (stream, "d");
1942 break;
1943 case 0x00400000:
1944 func (stream, "e");
1945 break;
1946 default:
1947 func (stream, "p");
1948 break;
1949 }
1950 break;
1951
1952 case 'R':
1953 switch (given & 0x60)
1954 {
1955 case 0:
1956 break;
1957 case 0x20:
1958 func (stream, "p");
1959 break;
1960 case 0x40:
1961 func (stream, "m");
1962 break;
1963 default:
1964 func (stream, "z");
1965 break;
1966 }
1967 break;
1968
1969 case '0': case '1': case '2': case '3': case '4':
1970 case '5': case '6': case '7': case '8': case '9':
1971 {
1972 int width;
1973 unsigned long value;
1974
1975 c = arm_decode_bitfield (c, given, &value, &width);
1976
1977 switch (*c)
1978 {
1979 case 'r':
1980 func (stream, "%s", arm_regnames[value]);
1981 break;
1982 case 'D':
1983 func (stream, "d%ld", value);
1984 break;
1985 case 'Q':
1986 if (value & 1)
1987 func (stream, "<illegal reg q%ld.5>", value >> 1);
1988 else
1989 func (stream, "q%ld", value >> 1);
1990 break;
1991 case 'd':
1992 func (stream, "%ld", value);
1993 value_in_comment = value;
1994 break;
1995 case 'k':
1996 {
1997 int from = (given & (1 << 7)) ? 32 : 16;
1998 func (stream, "%ld", from - value);
1999 }
2000 break;
2001
2002 case 'f':
2003 if (value > 7)
2004 func (stream, "#%s", arm_fp_const[value & 7]);
2005 else
2006 func (stream, "f%ld", value);
2007 break;
2008
2009 case 'w':
2010 if (width == 2)
2011 func (stream, "%s", iwmmxt_wwnames[value]);
2012 else
2013 func (stream, "%s", iwmmxt_wwssnames[value]);
2014 break;
2015
2016 case 'g':
2017 func (stream, "%s", iwmmxt_regnames[value]);
2018 break;
2019 case 'G':
2020 func (stream, "%s", iwmmxt_cregnames[value]);
2021 break;
2022
2023 case 'x':
2024 func (stream, "0x%lx", (value & 0xffffffffUL));
2025 break;
2026
2027 case '`':
2028 c++;
2029 if (value == 0)
2030 func (stream, "%c", *c);
2031 break;
2032 case '\'':
2033 c++;
2034 if (value == ((1ul << width) - 1))
2035 func (stream, "%c", *c);
2036 break;
2037 case '?':
2038 func (stream, "%c", c[(1 << width) - (int) value]);
2039 c += 1 << width;
2040 break;
2041 default:
2042 abort ();
2043 }
2044 break;
2045
2046 case 'y':
2047 case 'z':
2048 {
2049 int single = *c++ == 'y';
2050 int regno;
2051
2052 switch (*c)
2053 {
2054 case '4': /* Sm pair */
2055 case '0': /* Sm, Dm */
2056 regno = given & 0x0000000f;
2057 if (single)
2058 {
2059 regno <<= 1;
2060 regno += (given >> 5) & 1;
2061 }
2062 else
2063 regno += ((given >> 5) & 1) << 4;
2064 break;
2065
2066 case '1': /* Sd, Dd */
2067 regno = (given >> 12) & 0x0000000f;
2068 if (single)
2069 {
2070 regno <<= 1;
2071 regno += (given >> 22) & 1;
2072 }
2073 else
2074 regno += ((given >> 22) & 1) << 4;
2075 break;
2076
2077 case '2': /* Sn, Dn */
2078 regno = (given >> 16) & 0x0000000f;
2079 if (single)
2080 {
2081 regno <<= 1;
2082 regno += (given >> 7) & 1;
2083 }
2084 else
2085 regno += ((given >> 7) & 1) << 4;
2086 break;
2087
2088 case '3': /* List */
2089 func (stream, "{");
2090 regno = (given >> 12) & 0x0000000f;
2091 if (single)
2092 {
2093 regno <<= 1;
2094 regno += (given >> 22) & 1;
2095 }
2096 else
2097 regno += ((given >> 22) & 1) << 4;
2098 break;
2099
2100 default:
2101 abort ();
2102 }
2103
2104 func (stream, "%c%d", single ? 's' : 'd', regno);
2105
2106 if (*c == '3')
2107 {
2108 int count = given & 0xff;
2109
2110 if (single == 0)
2111 count >>= 1;
2112
2113 if (--count)
2114 {
2115 func (stream, "-%c%d",
2116 single ? 's' : 'd',
2117 regno + count);
2118 }
2119
2120 func (stream, "}");
2121 }
2122 else if (*c == '4')
2123 func (stream, ", %c%d", single ? 's' : 'd',
2124 regno + 1);
2125 }
2126 break;
2127
2128 case 'L':
2129 switch (given & 0x00400100)
2130 {
2131 case 0x00000000: func (stream, "b"); break;
2132 case 0x00400000: func (stream, "h"); break;
2133 case 0x00000100: func (stream, "w"); break;
2134 case 0x00400100: func (stream, "d"); break;
2135 default:
2136 break;
2137 }
2138 break;
2139
2140 case 'Z':
2141 {
2142 int value;
2143 /* given (20, 23) | given (0, 3) */
2144 value = ((given >> 16) & 0xf0) | (given & 0xf);
2145 func (stream, "%d", value);
2146 }
2147 break;
2148
2149 case 'l':
2150 /* This is like the 'A' operator, except that if
2151 the width field "M" is zero, then the offset is
2152 *not* multiplied by four. */
2153 {
2154 int offset = given & 0xff;
2155 int multiplier = (given & 0x00000100) ? 4 : 1;
2156
2157 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2158
2159 if (multiplier > 1)
2160 {
2161 value_in_comment = offset * multiplier;
2162 if ((given & 0x00800000) == 0)
2163 value_in_comment = - value_in_comment;
2164 }
2165
2166 if (offset)
2167 {
2168 if ((given & 0x01000000) != 0)
2169 func (stream, ", #%s%d]%s",
2170 ((given & 0x00800000) == 0 ? "-" : ""),
2171 offset * multiplier,
2172 ((given & 0x00200000) != 0 ? "!" : ""));
2173 else
2174 func (stream, "], #%s%d",
2175 ((given & 0x00800000) == 0 ? "-" : ""),
2176 offset * multiplier);
2177 }
2178 else
2179 func (stream, "]");
2180 }
2181 break;
2182
2183 case 'r':
2184 {
2185 int imm4 = (given >> 4) & 0xf;
2186 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2187 int ubit = (given >> 23) & 1;
2188 const char *rm = arm_regnames [given & 0xf];
2189 const char *rn = arm_regnames [(given >> 16) & 0xf];
2190
2191 switch (puw_bits)
2192 {
2193 case 1:
2194 case 3:
2195 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2196 if (imm4)
2197 func (stream, ", lsl #%d", imm4);
2198 break;
2199
2200 case 4:
2201 case 5:
2202 case 6:
2203 case 7:
2204 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2205 if (imm4 > 0)
2206 func (stream, ", lsl #%d", imm4);
2207 func (stream, "]");
2208 if (puw_bits == 5 || puw_bits == 7)
2209 func (stream, "!");
2210 break;
2211
2212 default:
2213 func (stream, "INVALID");
2214 }
2215 }
2216 break;
2217
2218 case 'i':
2219 {
2220 long imm5;
2221 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2222 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2223 }
2224 break;
2225
2226 default:
2227 abort ();
2228 }
2229 }
2230 }
2231 else
2232 func (stream, "%c", *c);
2233 }
2234
2235 if (value_in_comment > 32 || value_in_comment < -16)
2236 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2237
2238 return TRUE;
2239 }
2240 return FALSE;
2241}
2242
2243/* Decodes and prints ARM addressing modes. Returns the offset
2244 used in the address, if any, if it is worthwhile printing the
2245 offset as a hexadecimal value in a comment at the end of the
2246 line of disassembly. */
2247
2248static signed long
2249print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2250{
2251 void *stream = info->stream;
2252 fprintf_ftype func = info->fprintf_func;
2253 int offset = 0;
2254
2255 if (((given & 0x000f0000) == 0x000f0000)
2256 && ((given & 0x02000000) == 0))
2257 {
2258 offset = given & 0xfff;
2259
2260 func (stream, "[pc");
2261
2262 if (given & 0x01000000)
2263 {
2264 if ((given & 0x00800000) == 0)
2265 offset = - offset;
2266
2267 /* Pre-indexed. */
2268 func (stream, ", #%d]", offset);
2269
2270 offset += pc + 8;
2271
2272 /* Cope with the possibility of write-back
2273 being used. Probably a very dangerous thing
2274 for the programmer to do, but who are we to
2275 argue ? */
2276 if (given & 0x00200000)
2277 func (stream, "!");
2278 }
2279 else
2280 {
2281 /* Post indexed. */
2282 func (stream, "], #%d", offset);
2283
2284 /* ie ignore the offset. */
2285 offset = pc + 8;
2286 }
2287
2288 func (stream, "\t; ");
2289 info->print_address_func (offset, info);
2290 offset = 0;
2291 }
2292 else
2293 {
2294 func (stream, "[%s",
2295 arm_regnames[(given >> 16) & 0xf]);
2296 if ((given & 0x01000000) != 0)
2297 {
2298 if ((given & 0x02000000) == 0)
2299 {
2300 offset = given & 0xfff;
2301 if (offset)
2302 func (stream, ", #%s%d",
2303 (((given & 0x00800000) == 0)
2304 ? "-" : ""), offset);
2305 }
2306 else
2307 {
2308 func (stream, ", %s",
2309 (((given & 0x00800000) == 0)
2310 ? "-" : ""));
2311 arm_decode_shift (given, func, stream, TRUE);
2312 }
2313
2314 func (stream, "]%s",
2315 ((given & 0x00200000) != 0) ? "!" : "");
2316 }
2317 else
2318 {
2319 if ((given & 0x02000000) == 0)
2320 {
2321 offset = given & 0xfff;
2322 if (offset)
2323 func (stream, "], #%s%d",
2324 (((given & 0x00800000) == 0)
2325 ? "-" : ""), offset);
2326 else
2327 func (stream, "]");
2328 }
2329 else
2330 {
2331 func (stream, "], %s",
2332 (((given & 0x00800000) == 0)
2333 ? "-" : ""));
2334 arm_decode_shift (given, func, stream, TRUE);
2335 }
2336 }
2337 }
2338
2339 return (signed long) offset;
2340}
2341
2342/* Print one neon instruction on INFO->STREAM.
2343 Return TRUE if the instuction matched, FALSE if this is not a
2344 recognised neon instruction. */
2345
2346static bfd_boolean
2347print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2348{
2349 const struct opcode32 *insn;
2350 void *stream = info->stream;
2351 fprintf_ftype func = info->fprintf_func;
2352
2353 if (thumb)
2354 {
2355 if ((given & 0xef000000) == 0xef000000)
2356 {
2357 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2358 unsigned long bit28 = given & (1 << 28);
2359
2360 given &= 0x00ffffff;
2361 if (bit28)
2362 given |= 0xf3000000;
2363 else
2364 given |= 0xf2000000;
2365 }
2366 else if ((given & 0xff000000) == 0xf9000000)
2367 given ^= 0xf9000000 ^ 0xf4000000;
2368 else
2369 return FALSE;
2370 }
2371
2372 for (insn = neon_opcodes; insn->assembler; insn++)
2373 {
2374 if ((given & insn->mask) == insn->value)
2375 {
2376 signed long value_in_comment = 0;
2377 const char *c;
2378
2379 for (c = insn->assembler; *c; c++)
2380 {
2381 if (*c == '%')
2382 {
2383 switch (*++c)
2384 {
2385 case '%':
2386 func (stream, "%%");
2387 break;
2388
2389 case 'c':
2390 if (thumb && ifthen_state)
2391 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2392 break;
2393
2394 case 'A':
2395 {
2396 static const unsigned char enc[16] =
2397 {
2398 0x4, 0x14, /* st4 0,1 */
2399 0x4, /* st1 2 */
2400 0x4, /* st2 3 */
2401 0x3, /* st3 4 */
2402 0x13, /* st3 5 */
2403 0x3, /* st1 6 */
2404 0x1, /* st1 7 */
2405 0x2, /* st2 8 */
2406 0x12, /* st2 9 */
2407 0x2, /* st1 10 */
2408 0, 0, 0, 0, 0
2409 };
2410 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2411 int rn = ((given >> 16) & 0xf);
2412 int rm = ((given >> 0) & 0xf);
2413 int align = ((given >> 4) & 0x3);
2414 int type = ((given >> 8) & 0xf);
2415 int n = enc[type] & 0xf;
2416 int stride = (enc[type] >> 4) + 1;
2417 int ix;
2418
2419 func (stream, "{");
2420 if (stride > 1)
2421 for (ix = 0; ix != n; ix++)
2422 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2423 else if (n == 1)
2424 func (stream, "d%d", rd);
2425 else
2426 func (stream, "d%d-d%d", rd, rd + n - 1);
2427 func (stream, "}, [%s", arm_regnames[rn]);
2428 if (align)
2429 func (stream, ", :%d", 32 << align);
2430 func (stream, "]");
2431 if (rm == 0xd)
2432 func (stream, "!");
2433 else if (rm != 0xf)
2434 func (stream, ", %s", arm_regnames[rm]);
2435 }
2436 break;
2437
2438 case 'B':
2439 {
2440 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2441 int rn = ((given >> 16) & 0xf);
2442 int rm = ((given >> 0) & 0xf);
2443 int idx_align = ((given >> 4) & 0xf);
2444 int align = 0;
2445 int size = ((given >> 10) & 0x3);
2446 int idx = idx_align >> (size + 1);
2447 int length = ((given >> 8) & 3) + 1;
2448 int stride = 1;
2449 int i;
2450
2451 if (length > 1 && size > 0)
2452 stride = (idx_align & (1 << size)) ? 2 : 1;
2453
2454 switch (length)
2455 {
2456 case 1:
2457 {
2458 int amask = (1 << size) - 1;
2459 if ((idx_align & (1 << size)) != 0)
2460 return FALSE;
2461 if (size > 0)
2462 {
2463 if ((idx_align & amask) == amask)
2464 align = 8 << size;
2465 else if ((idx_align & amask) != 0)
2466 return FALSE;
2467 }
2468 }
2469 break;
2470
2471 case 2:
2472 if (size == 2 && (idx_align & 2) != 0)
2473 return FALSE;
2474 align = (idx_align & 1) ? 16 << size : 0;
2475 break;
2476
2477 case 3:
2478 if ((size == 2 && (idx_align & 3) != 0)
2479 || (idx_align & 1) != 0)
2480 return FALSE;
2481 break;
2482
2483 case 4:
2484 if (size == 2)
2485 {
2486 if ((idx_align & 3) == 3)
2487 return FALSE;
2488 align = (idx_align & 3) * 64;
2489 }
2490 else
2491 align = (idx_align & 1) ? 32 << size : 0;
2492 break;
2493
2494 default:
2495 abort ();
2496 }
2497
2498 func (stream, "{");
2499 for (i = 0; i < length; i++)
2500 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2501 rd + i * stride, idx);
2502 func (stream, "}, [%s", arm_regnames[rn]);
2503 if (align)
2504 func (stream, ", :%d", align);
2505 func (stream, "]");
2506 if (rm == 0xd)
2507 func (stream, "!");
2508 else if (rm != 0xf)
2509 func (stream, ", %s", arm_regnames[rm]);
2510 }
2511 break;
2512
2513 case 'C':
2514 {
2515 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2516 int rn = ((given >> 16) & 0xf);
2517 int rm = ((given >> 0) & 0xf);
2518 int align = ((given >> 4) & 0x1);
2519 int size = ((given >> 6) & 0x3);
2520 int type = ((given >> 8) & 0x3);
2521 int n = type + 1;
2522 int stride = ((given >> 5) & 0x1);
2523 int ix;
2524
2525 if (stride && (n == 1))
2526 n++;
2527 else
2528 stride++;
2529
2530 func (stream, "{");
2531 if (stride > 1)
2532 for (ix = 0; ix != n; ix++)
2533 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2534 else if (n == 1)
2535 func (stream, "d%d[]", rd);
2536 else
2537 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2538 func (stream, "}, [%s", arm_regnames[rn]);
2539 if (align)
2540 {
2541 int align = (8 * (type + 1)) << size;
2542 if (type == 3)
2543 align = (size > 1) ? align >> 1 : align;
2544 if (type == 2 || (type == 0 && !size))
2545 func (stream, ", :<bad align %d>", align);
2546 else
2547 func (stream, ", :%d", align);
2548 }
2549 func (stream, "]");
2550 if (rm == 0xd)
2551 func (stream, "!");
2552 else if (rm != 0xf)
2553 func (stream, ", %s", arm_regnames[rm]);
2554 }
2555 break;
2556
2557 case 'D':
2558 {
2559 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2560 int size = (given >> 20) & 3;
2561 int reg = raw_reg & ((4 << size) - 1);
2562 int ix = raw_reg >> size >> 2;
2563
2564 func (stream, "d%d[%d]", reg, ix);
2565 }
2566 break;
2567
2568 case 'E':
2569 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2570 {
2571 int bits = 0;
2572 int cmode = (given >> 8) & 0xf;
2573 int op = (given >> 5) & 0x1;
2574 unsigned long value = 0, hival = 0;
2575 unsigned shift;
2576 int size = 0;
2577 int isfloat = 0;
2578
2579 bits |= ((given >> 24) & 1) << 7;
2580 bits |= ((given >> 16) & 7) << 4;
2581 bits |= ((given >> 0) & 15) << 0;
2582
2583 if (cmode < 8)
2584 {
2585 shift = (cmode >> 1) & 3;
2586 value = (unsigned long) bits << (8 * shift);
2587 size = 32;
2588 }
2589 else if (cmode < 12)
2590 {
2591 shift = (cmode >> 1) & 1;
2592 value = (unsigned long) bits << (8 * shift);
2593 size = 16;
2594 }
2595 else if (cmode < 14)
2596 {
2597 shift = (cmode & 1) + 1;
2598 value = (unsigned long) bits << (8 * shift);
2599 value |= (1ul << (8 * shift)) - 1;
2600 size = 32;
2601 }
2602 else if (cmode == 14)
2603 {
2604 if (op)
2605 {
2606 /* Bit replication into bytes. */
2607 int ix;
2608 unsigned long mask;
2609
2610 value = 0;
2611 hival = 0;
2612 for (ix = 7; ix >= 0; ix--)
2613 {
2614 mask = ((bits >> ix) & 1) ? 0xff : 0;
2615 if (ix <= 3)
2616 value = (value << 8) | mask;
2617 else
2618 hival = (hival << 8) | mask;
2619 }
2620 size = 64;
2621 }
2622 else
2623 {
2624 /* Byte replication. */
2625 value = (unsigned long) bits;
2626 size = 8;
2627 }
2628 }
2629 else if (!op)
2630 {
2631 /* Floating point encoding. */
2632 int tmp;
2633
2634 value = (unsigned long) (bits & 0x7f) << 19;
2635 value |= (unsigned long) (bits & 0x80) << 24;
2636 tmp = bits & 0x40 ? 0x3c : 0x40;
2637 value |= (unsigned long) tmp << 24;
2638 size = 32;
2639 isfloat = 1;
2640 }
2641 else
2642 {
2643 func (stream, "<illegal constant %.8x:%x:%x>",
2644 bits, cmode, op);
2645 size = 32;
2646 break;
2647 }
2648 switch (size)
2649 {
2650 case 8:
2651 func (stream, "#%ld\t; 0x%.2lx", value, value);
2652 break;
2653
2654 case 16:
2655 func (stream, "#%ld\t; 0x%.4lx", value, value);
2656 break;
2657
2658 case 32:
2659 if (isfloat)
2660 {
2661 unsigned char valbytes[4];
2662 double fvalue;
2663
2664 /* Do this a byte at a time so we don't have to
2665 worry about the host's endianness. */
2666 valbytes[0] = value & 0xff;
2667 valbytes[1] = (value >> 8) & 0xff;
2668 valbytes[2] = (value >> 16) & 0xff;
2669 valbytes[3] = (value >> 24) & 0xff;
2670
2671 floatformat_to_double
2672 (&floatformat_ieee_single_little, valbytes,
2673 &fvalue);
2674
2675 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2676 value);
2677 }
2678 else
2679 func (stream, "#%ld\t; 0x%.8lx",
2680 (long) ((value & 0x80000000)
2681 ? value | ~0xffffffffl : value), value);
2682 break;
2683
2684 case 64:
2685 func (stream, "#0x%.8lx%.8lx", hival, value);
2686 break;
2687
2688 default:
2689 abort ();
2690 }
2691 }
2692 break;
2693
2694 case 'F':
2695 {
2696 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2697 int num = (given >> 8) & 0x3;
2698
2699 if (!num)
2700 func (stream, "{d%d}", regno);
2701 else if (num + regno >= 32)
2702 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2703 else
2704 func (stream, "{d%d-d%d}", regno, regno + num);
2705 }
2706 break;
2707
2708
2709 case '0': case '1': case '2': case '3': case '4':
2710 case '5': case '6': case '7': case '8': case '9':
2711 {
2712 int width;
2713 unsigned long value;
2714
2715 c = arm_decode_bitfield (c, given, &value, &width);
2716
2717 switch (*c)
2718 {
2719 case 'r':
2720 func (stream, "%s", arm_regnames[value]);
2721 break;
2722 case 'd':
2723 func (stream, "%ld", value);
2724 value_in_comment = value;
2725 break;
2726 case 'e':
2727 func (stream, "%ld", (1ul << width) - value);
2728 break;
2729
2730 case 'S':
2731 case 'T':
2732 case 'U':
2733 /* Various width encodings. */
2734 {
2735 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2736 int limit;
2737 unsigned low, high;
2738
2739 c++;
2740 if (*c >= '0' && *c <= '9')
2741 limit = *c - '0';
2742 else if (*c >= 'a' && *c <= 'f')
2743 limit = *c - 'a' + 10;
2744 else
2745 abort ();
2746 low = limit >> 2;
2747 high = limit & 3;
2748
2749 if (value < low || value > high)
2750 func (stream, "<illegal width %d>", base << value);
2751 else
2752 func (stream, "%d", base << value);
2753 }
2754 break;
2755 case 'R':
2756 if (given & (1 << 6))
2757 goto Q;
2758 /* FALLTHROUGH */
2759 case 'D':
2760 func (stream, "d%ld", value);
2761 break;
2762 case 'Q':
2763 Q:
2764 if (value & 1)
2765 func (stream, "<illegal reg q%ld.5>", value >> 1);
2766 else
2767 func (stream, "q%ld", value >> 1);
2768 break;
2769
2770 case '`':
2771 c++;
2772 if (value == 0)
2773 func (stream, "%c", *c);
2774 break;
2775 case '\'':
2776 c++;
2777 if (value == ((1ul << width) - 1))
2778 func (stream, "%c", *c);
2779 break;
2780 case '?':
2781 func (stream, "%c", c[(1 << width) - (int) value]);
2782 c += 1 << width;
2783 break;
2784 default:
2785 abort ();
2786 }
2787 break;
2788
2789 default:
2790 abort ();
2791 }
2792 }
2793 }
2794 else
2795 func (stream, "%c", *c);
2796 }
2797
2798 if (value_in_comment > 32 || value_in_comment < -16)
2799 func (stream, "\t; 0x%lx", value_in_comment);
2800
2801 return TRUE;
2802 }
2803 }
2804 return FALSE;
2805}
2806
2807/* Print one ARM instruction from PC on INFO->STREAM. */
2808
2809static void
2810print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2811{
2812 const struct opcode32 *insn;
2813 void *stream = info->stream;
2814 fprintf_ftype func = info->fprintf_func;
2815
2816 if (print_insn_coprocessor (pc, info, given, FALSE))
2817 return;
2818
2819 if (print_insn_neon (info, given, FALSE))
2820 return;
2821
2822 for (insn = arm_opcodes; insn->assembler; insn++)
2823 {
2824 if ((given & insn->mask) != insn->value)
2825 continue;
2826
2827 if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
2828 continue;
2829
2830 /* Special case: an instruction with all bits set in the condition field
2831 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2832 or by the catchall at the end of the table. */
2833 if ((given & 0xF0000000) != 0xF0000000
2834 || (insn->mask & 0xF0000000) == 0xF0000000
2835 || (insn->mask == 0 && insn->value == 0))
2836 {
2837 signed long value_in_comment = 0;
2838 const char *c;
2839
2840 for (c = insn->assembler; *c; c++)
2841 {
2842 if (*c == '%')
2843 {
2844 switch (*++c)
2845 {
2846 case '%':
2847 func (stream, "%%");
2848 break;
2849
2850 case 'a':
2851 value_in_comment = print_arm_address (pc, info, given);
2852 break;
2853
2854 case 'P':
2855 /* Set P address bit and use normal address
2856 printing routine. */
2857 value_in_comment = print_arm_address (pc, info, given | (1 << 24));
2858 break;
2859
2860 case 's':
2861 if ((given & 0x004f0000) == 0x004f0000)
2862 {
2863 /* PC relative with immediate offset. */
2864 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2865
2866 if ((given & 0x00800000) == 0)
2867 offset = -offset;
2868
2869 func (stream, "[pc, #%d]\t; ", offset);
2870 info->print_address_func (offset + pc + 8, info);
2871 }
2872 else
2873 {
2874 bfd_boolean negative = (given & 0x00800000) == 0;
2875 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2876
2877 if (negative)
2878 offset = -offset;
2879
2880 func (stream, "[%s",
2881 arm_regnames[(given >> 16) & 0xf]);
2882
2883 if ((given & 0x01000000) != 0)
2884 {
2885 /* Pre-indexed. */
2886 if ((given & 0x00400000) == 0x00400000)
2887 {
2888 /* Immediate. */
2889 if (offset)
2890 func (stream, ", #%d", offset);
2891 value_in_comment = offset;
2892 }
2893 else
2894 {
2895 /* Register. */
2896 func (stream, ", %s%s", negative ? "-" : "",
2897 arm_regnames[given & 0xf]);
2898 }
2899
2900 func (stream, "]%s",
2901 ((given & 0x00200000) != 0) ? "!" : "");
2902 }
2903 else
2904 {
2905 /* Post-indexed. */
2906 if ((given & 0x00400000) == 0x00400000)
2907 {
2908 /* Immediate. */
2909 if (offset)
2910 func (stream, "], #%d", offset);
2911 else
2912 func (stream, "]");
2913
2914 value_in_comment = offset;
2915 }
2916 else
2917 {
2918 /* Register. */
2919 func (stream, "], %s%s", negative ? "-" : "",
2920 arm_regnames[given & 0xf]);
2921 }
2922 }
2923 }
2924 break;
2925
2926 case 'b':
2927 {
2928 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2929 info->print_address_func (disp * 4 + pc + 8, info);
2930 }
2931 break;
2932
2933 case 'c':
2934 if (((given >> 28) & 0xf) != 0xe)
2935 func (stream, "%s",
2936 arm_conditional [(given >> 28) & 0xf]);
2937 break;
2938
2939 case 'm':
2940 {
2941 int started = 0;
2942 int reg;
2943
2944 func (stream, "{");
2945 for (reg = 0; reg < 16; reg++)
2946 if ((given & (1 << reg)) != 0)
2947 {
2948 if (started)
2949 func (stream, ", ");
2950 started = 1;
2951 func (stream, "%s", arm_regnames[reg]);
2952 }
2953 func (stream, "}");
2954 }
2955 break;
2956
2957 case 'q':
2958 arm_decode_shift (given, func, stream, FALSE);
2959 break;
2960
2961 case 'o':
2962 if ((given & 0x02000000) != 0)
2963 {
2964 int rotate = (given & 0xf00) >> 7;
2965 int immed = (given & 0xff);
2966
2967 immed = (((immed << (32 - rotate))
2968 | (immed >> rotate)) & 0xffffffff);
2969 func (stream, "#%d", immed);
2970 value_in_comment = immed;
2971 }
2972 else
2973 arm_decode_shift (given, func, stream, TRUE);
2974 break;
2975
2976 case 'p':
2977 if ((given & 0x0000f000) == 0x0000f000)
2978 func (stream, "p");
2979 break;
2980
2981 case 't':
2982 if ((given & 0x01200000) == 0x00200000)
2983 func (stream, "t");
2984 break;
2985
2986 case 'A':
2987 {
2988 int offset = given & 0xff;
2989
2990 value_in_comment = offset * 4;
2991 if ((given & 0x00800000) == 0)
2992 value_in_comment = - value_in_comment;
2993
2994 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2995
2996 if ((given & (1 << 24)) != 0)
2997 {
2998 if (offset)
2999 func (stream, ", #%d]%s",
3000 value_in_comment,
3001 ((given & 0x00200000) != 0 ? "!" : ""));
3002 else
3003 func (stream, "]");
3004 }
3005 else
3006 {
3007 func (stream, "]");
3008
3009 if (given & (1 << 21))
3010 {
3011 if (offset)
3012 func (stream, ", #%d", value_in_comment);
3013 }
3014 else
3015 {
3016 func (stream, ", {%d}", offset);
3017 value_in_comment = offset;
3018 }
3019 }
3020 }
3021 break;
3022
3023 case 'B':
3024 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3025 {
3026 bfd_vma address;
3027 bfd_vma offset = 0;
3028
3029 if (given & 0x00800000)
3030 /* Is signed, hi bits should be ones. */
3031 offset = (-1) ^ 0x00ffffff;
3032
3033 /* Offset is (SignExtend(offset field)<<2). */
3034 offset += given & 0x00ffffff;
3035 offset <<= 2;
3036 address = offset + pc + 8;
3037
3038 if (given & 0x01000000)
3039 /* H bit allows addressing to 2-byte boundaries. */
3040 address += 2;
3041
3042 info->print_address_func (address, info);
3043 }
3044 break;
3045
3046 case 'C':
3047 func (stream, "_");
3048 if (given & 0x80000)
3049 func (stream, "f");
3050 if (given & 0x40000)
3051 func (stream, "s");
3052 if (given & 0x20000)
3053 func (stream, "x");
3054 if (given & 0x10000)
3055 func (stream, "c");
3056 break;
3057
3058 case 'U':
3059 switch (given & 0xf)
3060 {
3061 case 0xf: func (stream, "sy"); break;
3062 case 0x7: func (stream, "un"); break;
3063 case 0xe: func (stream, "st"); break;
3064 case 0x6: func (stream, "unst"); break;
3065 default:
3066 func (stream, "#%d", (int) given & 0xf);
3067 break;
3068 }
3069 break;
3070
3071 case '0': case '1': case '2': case '3': case '4':
3072 case '5': case '6': case '7': case '8': case '9':
3073 {
3074 int width;
3075 unsigned long value;
3076
3077 c = arm_decode_bitfield (c, given, &value, &width);
3078
3079 switch (*c)
3080 {
3081 case 'r':
3082 func (stream, "%s", arm_regnames[value]);
3083 break;
3084 case 'd':
3085 func (stream, "%ld", value);
3086 value_in_comment = value;
3087 break;
3088 case 'b':
3089 func (stream, "%ld", value * 8);
3090 value_in_comment = value * 8;
3091 break;
3092 case 'W':
3093 func (stream, "%ld", value + 1);
3094 value_in_comment = value + 1;
3095 break;
3096 case 'x':
3097 func (stream, "0x%08lx", value);
3098
3099 /* Some SWI instructions have special
3100 meanings. */
3101 if ((given & 0x0fffffff) == 0x0FF00000)
3102 func (stream, "\t; IMB");
3103 else if ((given & 0x0fffffff) == 0x0FF00001)
3104 func (stream, "\t; IMBRange");
3105 break;
3106 case 'X':
3107 func (stream, "%01lx", value & 0xf);
3108 value_in_comment = value;
3109 break;
3110 case '`':
3111 c++;
3112 if (value == 0)
3113 func (stream, "%c", *c);
3114 break;
3115 case '\'':
3116 c++;
3117 if (value == ((1ul << width) - 1))
3118 func (stream, "%c", *c);
3119 break;
3120 case '?':
3121 func (stream, "%c", c[(1 << width) - (int) value]);
3122 c += 1 << width;
3123 break;
3124 default:
3125 abort ();
3126 }
3127 break;
3128
3129 case 'e':
3130 {
3131 int imm;
3132
3133 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3134 func (stream, "%d", imm);
3135 value_in_comment = imm;
3136 }
3137 break;
3138
3139 case 'E':
3140 /* LSB and WIDTH fields of BFI or BFC. The machine-
3141 language instruction encodes LSB and MSB. */
3142 {
3143 long msb = (given & 0x001f0000) >> 16;
3144 long lsb = (given & 0x00000f80) >> 7;
3145 long width = msb - lsb + 1;
3146
3147 if (width > 0)
3148 func (stream, "#%lu, #%lu", lsb, width);
3149 else
3150 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3151 }
3152 break;
3153
3154 case 'V':
3155 /* 16-bit unsigned immediate from a MOVT or MOVW
3156 instruction, encoded in bits 0:11 and 15:19. */
3157 {
3158 long hi = (given & 0x000f0000) >> 4;
3159 long lo = (given & 0x00000fff);
3160 long imm16 = hi | lo;
3161
3162 func (stream, "#%lu", imm16);
3163 value_in_comment = imm16;
3164 }
3165 break;
3166
3167 default:
3168 abort ();
3169 }
3170 }
3171 }
3172 else
3173 func (stream, "%c", *c);
3174 }
3175
3176 if (value_in_comment > 32 || value_in_comment < -16)
3177 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3178 return;
3179 }
3180 }
3181 abort ();
3182}
3183
3184/* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3185
3186static void
3187print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3188{
3189 const struct opcode16 *insn;
3190 void *stream = info->stream;
3191 fprintf_ftype func = info->fprintf_func;
3192
3193 for (insn = thumb_opcodes; insn->assembler; insn++)
3194 if ((given & insn->mask) == insn->value)
3195 {
3196 signed long value_in_comment = 0;
3197 const char *c = insn->assembler;
3198
3199 for (; *c; c++)
3200 {
3201 int domaskpc = 0;
3202 int domasklr = 0;
3203
3204 if (*c != '%')
3205 {
3206 func (stream, "%c", *c);
3207 continue;
3208 }
3209
3210 switch (*++c)
3211 {
3212 case '%':
3213 func (stream, "%%");
3214 break;
3215
3216 case 'c':
3217 if (ifthen_state)
3218 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3219 break;
3220
3221 case 'C':
3222 if (ifthen_state)
3223 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3224 else
3225 func (stream, "s");
3226 break;
3227
3228 case 'I':
3229 {
3230 unsigned int tmp;
3231
3232 ifthen_next_state = given & 0xff;
3233 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3234 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3235 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3236 }
3237 break;
3238
3239 case 'x':
3240 if (ifthen_next_state)
3241 func (stream, "\t; unpredictable branch in IT block\n");
3242 break;
3243
3244 case 'X':
3245 if (ifthen_state)
3246 func (stream, "\t; unpredictable <IT:%s>",
3247 arm_conditional[IFTHEN_COND]);
3248 break;
3249
3250 case 'S':
3251 {
3252 long reg;
3253
3254 reg = (given >> 3) & 0x7;
3255 if (given & (1 << 6))
3256 reg += 8;
3257
3258 func (stream, "%s", arm_regnames[reg]);
3259 }
3260 break;
3261
3262 case 'D':
3263 {
3264 long reg;
3265
3266 reg = given & 0x7;
3267 if (given & (1 << 7))
3268 reg += 8;
3269
3270 func (stream, "%s", arm_regnames[reg]);
3271 }
3272 break;
3273
3274 case 'N':
3275 if (given & (1 << 8))
3276 domasklr = 1;
3277 /* Fall through. */
3278 case 'O':
3279 if (*c == 'O' && (given & (1 << 8)))
3280 domaskpc = 1;
3281 /* Fall through. */
3282 case 'M':
3283 {
3284 int started = 0;
3285 int reg;
3286
3287 func (stream, "{");
3288
3289 /* It would be nice if we could spot
3290 ranges, and generate the rS-rE format: */
3291 for (reg = 0; (reg < 8); reg++)
3292 if ((given & (1 << reg)) != 0)
3293 {
3294 if (started)
3295 func (stream, ", ");
3296 started = 1;
3297 func (stream, "%s", arm_regnames[reg]);
3298 }
3299
3300 if (domasklr)
3301 {
3302 if (started)
3303 func (stream, ", ");
3304 started = 1;
3305 func (stream, arm_regnames[14] /* "lr" */);
3306 }
3307
3308 if (domaskpc)
3309 {
3310 if (started)
3311 func (stream, ", ");
3312 func (stream, arm_regnames[15] /* "pc" */);
3313 }
3314
3315 func (stream, "}");
3316 }
3317 break;
3318
3319 case 'b':
3320 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3321 {
3322 bfd_vma address = (pc + 4
3323 + ((given & 0x00f8) >> 2)
3324 + ((given & 0x0200) >> 3));
3325 info->print_address_func (address, info);
3326 }
3327 break;
3328
3329 case 's':
3330 /* Right shift immediate -- bits 6..10; 1-31 print
3331 as themselves, 0 prints as 32. */
3332 {
3333 long imm = (given & 0x07c0) >> 6;
3334 if (imm == 0)
3335 imm = 32;
3336 func (stream, "#%ld", imm);
3337 }
3338 break;
3339
3340 case '0': case '1': case '2': case '3': case '4':
3341 case '5': case '6': case '7': case '8': case '9':
3342 {
3343 int bitstart = *c++ - '0';
3344 int bitend = 0;
3345
3346 while (*c >= '0' && *c <= '9')
3347 bitstart = (bitstart * 10) + *c++ - '0';
3348
3349 switch (*c)
3350 {
3351 case '-':
3352 {
3353 long reg;
3354
3355 c++;
3356 while (*c >= '0' && *c <= '9')
3357 bitend = (bitend * 10) + *c++ - '0';
3358 if (!bitend)
3359 abort ();
3360 reg = given >> bitstart;
3361 reg &= (2 << (bitend - bitstart)) - 1;
3362 switch (*c)
3363 {
3364 case 'r':
3365 func (stream, "%s", arm_regnames[reg]);
3366 break;
3367
3368 case 'd':
3369 func (stream, "%ld", reg);
3370 value_in_comment = reg;
3371 break;
3372
3373 case 'H':
3374 func (stream, "%ld", reg << 1);
3375 value_in_comment = reg << 1;
3376 break;
3377
3378 case 'W':
3379 func (stream, "%ld", reg << 2);
3380 value_in_comment = reg << 2;
3381 break;
3382
3383 case 'a':
3384 /* PC-relative address -- the bottom two
3385 bits of the address are dropped
3386 before the calculation. */
3387 info->print_address_func
3388 (((pc + 4) & ~3) + (reg << 2), info);
3389 value_in_comment = 0;
3390 break;
3391
3392 case 'x':
3393 func (stream, "0x%04lx", reg);
3394 break;
3395
3396 case 'B':
3397 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3398 info->print_address_func (reg * 2 + pc + 4, info);
3399 value_in_comment = 0;
3400 break;
3401
3402 case 'c':
3403 func (stream, "%s", arm_conditional [reg]);
3404 break;
3405
3406 default:
3407 abort ();
3408 }
3409 }
3410 break;
3411
3412 case '\'':
3413 c++;
3414 if ((given & (1 << bitstart)) != 0)
3415 func (stream, "%c", *c);
3416 break;
3417
3418 case '?':
3419 ++c;
3420 if ((given & (1 << bitstart)) != 0)
3421 func (stream, "%c", *c++);
3422 else
3423 func (stream, "%c", *++c);
3424 break;
3425
3426 default:
3427 abort ();
3428 }
3429 }
3430 break;
3431
3432 default:
3433 abort ();
3434 }
3435 }
3436
3437 if (value_in_comment > 32 || value_in_comment < -16)
3438 func (stream, "\t; 0x%lx", value_in_comment);
3439 return;
3440 }
3441
3442 /* No match. */
3443 abort ();
3444}
3445
3446/* Return the name of an V7M special register. */
3447
3448static const char *
3449psr_name (int regno)
3450{
3451 switch (regno)
3452 {
3453 case 0: return "APSR";
3454 case 1: return "IAPSR";
3455 case 2: return "EAPSR";
3456 case 3: return "PSR";
3457 case 5: return "IPSR";
3458 case 6: return "EPSR";
3459 case 7: return "IEPSR";
3460 case 8: return "MSP";
3461 case 9: return "PSP";
3462 case 16: return "PRIMASK";
3463 case 17: return "BASEPRI";
3464 case 18: return "BASEPRI_MASK";
3465 case 19: return "FAULTMASK";
3466 case 20: return "CONTROL";
3467 default: return "<unknown>";
3468 }
3469}
3470
3471/* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3472
3473static void
3474print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3475{
3476 const struct opcode32 *insn;
3477 void *stream = info->stream;
3478 fprintf_ftype func = info->fprintf_func;
3479
3480 if (print_insn_coprocessor (pc, info, given, TRUE))
3481 return;
3482
3483 if (print_insn_neon (info, given, TRUE))
3484 return;
3485
3486 for (insn = thumb32_opcodes; insn->assembler; insn++)
3487 if ((given & insn->mask) == insn->value)
3488 {
3489 signed long value_in_comment = 0;
3490 const char *c = insn->assembler;
3491
3492 for (; *c; c++)
3493 {
3494 if (*c != '%')
3495 {
3496 func (stream, "%c", *c);
3497 continue;
3498 }
3499
3500 switch (*++c)
3501 {
3502 case '%':
3503 func (stream, "%%");
3504 break;
3505
3506 case 'c':
3507 if (ifthen_state)
3508 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3509 break;
3510
3511 case 'x':
3512 if (ifthen_next_state)
3513 func (stream, "\t; unpredictable branch in IT block\n");
3514 break;
3515
3516 case 'X':
3517 if (ifthen_state)
3518 func (stream, "\t; unpredictable <IT:%s>",
3519 arm_conditional[IFTHEN_COND]);
3520 break;
3521
3522 case 'I':
3523 {
3524 unsigned int imm12 = 0;
3525
3526 imm12 |= (given & 0x000000ffu);
3527 imm12 |= (given & 0x00007000u) >> 4;
3528 imm12 |= (given & 0x04000000u) >> 15;
3529 func (stream, "#%u", imm12);
3530 value_in_comment = imm12;
3531 }
3532 break;
3533
3534 case 'M':
3535 {
3536 unsigned int bits = 0, imm, imm8, mod;
3537
3538 bits |= (given & 0x000000ffu);
3539 bits |= (given & 0x00007000u) >> 4;
3540 bits |= (given & 0x04000000u) >> 15;
3541 imm8 = (bits & 0x0ff);
3542 mod = (bits & 0xf00) >> 8;
3543 switch (mod)
3544 {
3545 case 0: imm = imm8; break;
3546 case 1: imm = ((imm8<<16) | imm8); break;
3547 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3548 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3549 default:
3550 mod = (bits & 0xf80) >> 7;
3551 imm8 = (bits & 0x07f) | 0x80;
3552 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3553 }
3554 func (stream, "#%u", imm);
3555 value_in_comment = imm;
3556 }
3557 break;
3558
3559 case 'J':
3560 {
3561 unsigned int imm = 0;
3562
3563 imm |= (given & 0x000000ffu);
3564 imm |= (given & 0x00007000u) >> 4;
3565 imm |= (given & 0x04000000u) >> 15;
3566 imm |= (given & 0x000f0000u) >> 4;
3567 func (stream, "#%u", imm);
3568 value_in_comment = imm;
3569 }
3570 break;
3571
3572 case 'K':
3573 {
3574 unsigned int imm = 0;
3575
3576 imm |= (given & 0x000f0000u) >> 16;
3577 imm |= (given & 0x00000ff0u) >> 0;
3578 imm |= (given & 0x0000000fu) << 12;
3579 func (stream, "#%u", imm);
3580 value_in_comment = imm;
3581 }
3582 break;
3583
3584 case 'S':
3585 {
3586 unsigned int reg = (given & 0x0000000fu);
3587 unsigned int stp = (given & 0x00000030u) >> 4;
3588 unsigned int imm = 0;
3589 imm |= (given & 0x000000c0u) >> 6;
3590 imm |= (given & 0x00007000u) >> 10;
3591
3592 func (stream, "%s", arm_regnames[reg]);
3593 switch (stp)
3594 {
3595 case 0:
3596 if (imm > 0)
3597 func (stream, ", lsl #%u", imm);
3598 break;
3599
3600 case 1:
3601 if (imm == 0)
3602 imm = 32;
3603 func (stream, ", lsr #%u", imm);
3604 break;
3605
3606 case 2:
3607 if (imm == 0)
3608 imm = 32;
3609 func (stream, ", asr #%u", imm);
3610 break;
3611
3612 case 3:
3613 if (imm == 0)
3614 func (stream, ", rrx");
3615 else
3616 func (stream, ", ror #%u", imm);
3617 }
3618 }
3619 break;
3620
3621 case 'a':
3622 {
3623 unsigned int Rn = (given & 0x000f0000) >> 16;
3624 unsigned int U = (given & 0x00800000) >> 23;
3625 unsigned int op = (given & 0x00000f00) >> 8;
3626 unsigned int i12 = (given & 0x00000fff);
3627 unsigned int i8 = (given & 0x000000ff);
3628 bfd_boolean writeback = FALSE, postind = FALSE;
3629 int offset = 0;
3630
3631 func (stream, "[%s", arm_regnames[Rn]);
3632 if (U) /* 12-bit positive immediate offset. */
3633 {
3634 offset = i12;
3635 if (Rn != 15)
3636 value_in_comment = offset;
3637 }
3638 else if (Rn == 15) /* 12-bit negative immediate offset. */
3639 offset = - (int) i12;
3640 else if (op == 0x0) /* Shifted register offset. */
3641 {
3642 unsigned int Rm = (i8 & 0x0f);
3643 unsigned int sh = (i8 & 0x30) >> 4;
3644
3645 func (stream, ", %s", arm_regnames[Rm]);
3646 if (sh)
3647 func (stream, ", lsl #%u", sh);
3648 func (stream, "]");
3649 break;
3650 }
3651 else switch (op)
3652 {
3653 case 0xE: /* 8-bit positive immediate offset. */
3654 offset = i8;
3655 break;
3656
3657 case 0xC: /* 8-bit negative immediate offset. */
3658 offset = -i8;
3659 break;
3660
3661 case 0xF: /* 8-bit + preindex with wb. */
3662 offset = i8;
3663 writeback = TRUE;
3664 break;
3665
3666 case 0xD: /* 8-bit - preindex with wb. */
3667 offset = -i8;
3668 writeback = TRUE;
3669 break;
3670
3671 case 0xB: /* 8-bit + postindex. */
3672 offset = i8;
3673 postind = TRUE;
3674 break;
3675
3676 case 0x9: /* 8-bit - postindex. */
3677 offset = -i8;
3678 postind = TRUE;
3679 break;
3680
3681 default:
3682 func (stream, ", <undefined>]");
3683 goto skip;
3684 }
3685
3686 if (postind)
3687 func (stream, "], #%d", offset);
3688 else
3689 {
3690 if (offset)
3691 func (stream, ", #%d", offset);
3692 func (stream, writeback ? "]!" : "]");
3693 }
3694
3695 if (Rn == 15)
3696 {
3697 func (stream, "\t; ");
3698 info->print_address_func (((pc + 4) & ~3) + offset, info);
3699 }
3700 }
3701 skip:
3702 break;
3703
3704 case 'A':
3705 {
3706 unsigned int P = (given & 0x01000000) >> 24;
3707 unsigned int U = (given & 0x00800000) >> 23;
3708 unsigned int W = (given & 0x00400000) >> 21;
3709 unsigned int Rn = (given & 0x000f0000) >> 16;
3710 unsigned int off = (given & 0x000000ff);
3711
3712 func (stream, "[%s", arm_regnames[Rn]);
3713 if (P)
3714 {
3715 if (off || !U)
3716 {
3717 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3718 value_in_comment = off * 4 * U ? 1 : -1;
3719 }
3720 func (stream, "]");
3721 if (W)
3722 func (stream, "!");
3723 }
3724 else
3725 {
3726 func (stream, "], ");
3727 if (W)
3728 {
3729 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3730 value_in_comment = off * 4 * U ? 1 : -1;
3731 }
3732 else
3733 {
3734 func (stream, "{%u}", off);
3735 value_in_comment = off;
3736 }
3737 }
3738 }
3739 break;
3740
3741 case 'w':
3742 {
3743 unsigned int Sbit = (given & 0x01000000) >> 24;
3744 unsigned int type = (given & 0x00600000) >> 21;
3745
3746 switch (type)
3747 {
3748 case 0: func (stream, Sbit ? "sb" : "b"); break;
3749 case 1: func (stream, Sbit ? "sh" : "h"); break;
3750 case 2:
3751 if (Sbit)
3752 func (stream, "??");
3753 break;
3754 case 3:
3755 func (stream, "??");
3756 break;
3757 }
3758 }
3759 break;
3760
3761 case 'm':
3762 {
3763 int started = 0;
3764 int reg;
3765
3766 func (stream, "{");
3767 for (reg = 0; reg < 16; reg++)
3768 if ((given & (1 << reg)) != 0)
3769 {
3770 if (started)
3771 func (stream, ", ");
3772 started = 1;
3773 func (stream, "%s", arm_regnames[reg]);
3774 }
3775 func (stream, "}");
3776 }
3777 break;
3778
3779 case 'E':
3780 {
3781 unsigned int msb = (given & 0x0000001f);
3782 unsigned int lsb = 0;
3783
3784 lsb |= (given & 0x000000c0u) >> 6;
3785 lsb |= (given & 0x00007000u) >> 10;
3786 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3787 }
3788 break;
3789
3790 case 'F':
3791 {
3792 unsigned int width = (given & 0x0000001f) + 1;
3793 unsigned int lsb = 0;
3794
3795 lsb |= (given & 0x000000c0u) >> 6;
3796 lsb |= (given & 0x00007000u) >> 10;
3797 func (stream, "#%u, #%u", lsb, width);
3798 }
3799 break;
3800
3801 case 'b':
3802 {
3803 unsigned int S = (given & 0x04000000u) >> 26;
3804 unsigned int J1 = (given & 0x00002000u) >> 13;
3805 unsigned int J2 = (given & 0x00000800u) >> 11;
3806 int offset = 0;
3807
3808 offset |= !S << 20;
3809 offset |= J2 << 19;
3810 offset |= J1 << 18;
3811 offset |= (given & 0x003f0000) >> 4;
3812 offset |= (given & 0x000007ff) << 1;
3813 offset -= (1 << 20);
3814
3815 info->print_address_func (pc + 4 + offset, info);
3816 }
3817 break;
3818
3819 case 'B':
3820 {
3821 unsigned int S = (given & 0x04000000u) >> 26;
3822 unsigned int I1 = (given & 0x00002000u) >> 13;
3823 unsigned int I2 = (given & 0x00000800u) >> 11;
3824 int offset = 0;
3825
3826 offset |= !S << 24;
3827 offset |= !(I1 ^ S) << 23;
3828 offset |= !(I2 ^ S) << 22;
3829 offset |= (given & 0x03ff0000u) >> 4;
3830 offset |= (given & 0x000007ffu) << 1;
3831 offset -= (1 << 24);
3832 offset += pc + 4;
3833
3834 /* BLX target addresses are always word aligned. */
3835 if ((given & 0x00001000u) == 0)
3836 offset &= ~2u;
3837
3838 info->print_address_func (offset, info);
3839 }
3840 break;
3841
3842 case 's':
3843 {
3844 unsigned int shift = 0;
3845
3846 shift |= (given & 0x000000c0u) >> 6;
3847 shift |= (given & 0x00007000u) >> 10;
3848 if (given & 0x00200000u)
3849 func (stream, ", asr #%u", shift);
3850 else if (shift)
3851 func (stream, ", lsl #%u", shift);
3852 /* else print nothing - lsl #0 */
3853 }
3854 break;
3855
3856 case 'R':
3857 {
3858 unsigned int rot = (given & 0x00000030) >> 4;
3859
3860 if (rot)
3861 func (stream, ", ror #%u", rot * 8);
3862 }
3863 break;
3864
3865 case 'U':
3866 switch (given & 0xf)
3867 {
3868 case 0xf: func (stream, "sy"); break;
3869 case 0x7: func (stream, "un"); break;
3870 case 0xe: func (stream, "st"); break;
3871 case 0x6: func (stream, "unst"); break;
3872 default:
3873 func (stream, "#%d", (int) given & 0xf);
3874 break;
3875 }
3876 break;
3877
3878 case 'C':
3879 if ((given & 0xff) == 0)
3880 {
3881 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3882 if (given & 0x800)
3883 func (stream, "f");
3884 if (given & 0x400)
3885 func (stream, "s");
3886 if (given & 0x200)
3887 func (stream, "x");
3888 if (given & 0x100)
3889 func (stream, "c");
3890 }
3891 else
3892 {
3893 func (stream, psr_name (given & 0xff));
3894 }
3895 break;
3896
3897 case 'D':
3898 if ((given & 0xff) == 0)
3899 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3900 else
3901 func (stream, psr_name (given & 0xff));
3902 break;
3903
3904 case '0': case '1': case '2': case '3': case '4':
3905 case '5': case '6': case '7': case '8': case '9':
3906 {
3907 int width;
3908 unsigned long val;
3909
3910 c = arm_decode_bitfield (c, given, &val, &width);
3911
3912 switch (*c)
3913 {
3914 case 'd':
3915 func (stream, "%lu", val);
3916 value_in_comment = val;
3917 break;
3918 case 'W':
3919 func (stream, "%lu", val * 4);
3920 value_in_comment = val * 4;
3921 break;
3922 case 'r': func (stream, "%s", arm_regnames[val]); break;
3923
3924 case 'c':
3925 func (stream, "%s", arm_conditional[val]);
3926 break;
3927
3928 case '\'':
3929 c++;
3930 if (val == ((1ul << width) - 1))
3931 func (stream, "%c", *c);
3932 break;
3933
3934 case '`':
3935 c++;
3936 if (val == 0)
3937 func (stream, "%c", *c);
3938 break;
3939
3940 case '?':
3941 func (stream, "%c", c[(1 << width) - (int) val]);
3942 c += 1 << width;
3943 break;
3944
3945 default:
3946 abort ();
3947 }
3948 }
3949 break;
3950
3951 default:
3952 abort ();
3953 }
3954 }
3955
3956 if (value_in_comment > 32 || value_in_comment < -16)
3957 func (stream, "\t; 0x%lx", value_in_comment);
3958 return;
3959 }
3960
3961 /* No match. */
3962 abort ();
3963}
3964
3965/* Print data bytes on INFO->STREAM. */
3966
3967static void
3968print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3969 struct disassemble_info *info,
3970 long given)
3971{
3972 switch (info->bytes_per_chunk)
3973 {
3974 case 1:
3975 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3976 break;
3977 case 2:
3978 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3979 break;
3980 case 4:
3981 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3982 break;
3983 default:
3984 abort ();
3985 }
3986}
3987
3988/* Disallow mapping symbols ($a, $b, $d, $t etc) from
3989 being displayed in symbol relative addresses. */
3990
3991bfd_boolean
3992arm_symbol_is_valid (asymbol * sym,
3993 struct disassemble_info * info ATTRIBUTE_UNUSED)
3994{
3995 const char * name;
3996
3997 if (sym == NULL)
3998 return FALSE;
3999
4000 name = bfd_asymbol_name (sym);
4001
4002 return (name && *name != '$');
4003}
4004
4005/* Parse an individual disassembler option. */
4006
4007void
4008parse_arm_disassembler_option (char *option)
4009{
4010 if (option == NULL)
4011 return;
4012
4013 if (CONST_STRNEQ (option, "reg-names-"))
4014 {
4015 int i;
4016
4017 option += 10;
4018
4019 for (i = NUM_ARM_REGNAMES; i--;)
4020 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4021 {
4022 regname_selected = i;
4023 break;
4024 }
4025
4026 if (i < 0)
4027 /* XXX - should break 'option' at following delimiter. */
4028 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4029 }
4030 else if (CONST_STRNEQ (option, "force-thumb"))
4031 force_thumb = 1;
4032 else if (CONST_STRNEQ (option, "no-force-thumb"))
4033 force_thumb = 0;
4034 else
4035 /* XXX - should break 'option' at following delimiter. */
4036 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4037
4038 return;
4039}
4040
4041/* Parse the string of disassembler options, spliting it at whitespaces
4042 or commas. (Whitespace separators supported for backwards compatibility). */
4043
4044static void
4045parse_disassembler_options (char *options)
4046{
4047 if (options == NULL)
4048 return;
4049
4050 while (*options)
4051 {
4052 parse_arm_disassembler_option (options);
4053
4054 /* Skip forward to next seperator. */
4055 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4056 ++ options;
4057 /* Skip forward past seperators. */
4058 while (ISSPACE (*options) || (*options == ','))
4059 ++ options;
4060 }
4061}
4062
4063/* Search back through the insn stream to determine if this instruction is
4064 conditionally executed. */
4065
4066static void
4067find_ifthen_state (bfd_vma pc,
4068 struct disassemble_info *info,
4069 bfd_boolean little)
4070{
4071 unsigned char b[2];
4072 unsigned int insn;
4073 int status;
4074 /* COUNT is twice the number of instructions seen. It will be odd if we
4075 just crossed an instruction boundary. */
4076 int count;
4077 int it_count;
4078 unsigned int seen_it;
4079 bfd_vma addr;
4080
4081 ifthen_address = pc;
4082 ifthen_state = 0;
4083
4084 addr = pc;
4085 count = 1;
4086 it_count = 0;
4087 seen_it = 0;
4088 /* Scan backwards looking for IT instructions, keeping track of where
4089 instruction boundaries are. We don't know if something is actually an
4090 IT instruction until we find a definite instruction boundary. */
4091 for (;;)
4092 {
4093 if (addr == 0 || info->symbol_at_address_func (addr, info))
4094 {
4095 /* A symbol must be on an instruction boundary, and will not
4096 be within an IT block. */
4097 if (seen_it && (count & 1))
4098 break;
4099
4100 return;
4101 }
4102 addr -= 2;
4103 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4104 if (status)
4105 return;
4106
4107 if (little)
4108 insn = (b[0]) | (b[1] << 8);
4109 else
4110 insn = (b[1]) | (b[0] << 8);
4111 if (seen_it)
4112 {
4113 if ((insn & 0xf800) < 0xe800)
4114 {
4115 /* Addr + 2 is an instruction boundary. See if this matches
4116 the expected boundary based on the position of the last
4117 IT candidate. */
4118 if (count & 1)
4119 break;
4120 seen_it = 0;
4121 }
4122 }
4123 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4124 {
4125 /* This could be an IT instruction. */
4126 seen_it = insn;
4127 it_count = count >> 1;
4128 }
4129 if ((insn & 0xf800) >= 0xe800)
4130 count++;
4131 else
4132 count = (count + 2) | 1;
4133 /* IT blocks contain at most 4 instructions. */
4134 if (count >= 8 && !seen_it)
4135 return;
4136 }
4137 /* We found an IT instruction. */
4138 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4139 if ((ifthen_state & 0xf) == 0)
4140 ifthen_state = 0;
4141}
4142
4143/* Try to infer the code type (Arm or Thumb) from a symbol.
4144 Returns nonzero if *MAP_TYPE was set. */
4145
4146static int
4147get_sym_code_type (struct disassemble_info *info,
4148 int n,
4149 enum map_type *map_type)
4150{
4151 elf_symbol_type *es;
4152 unsigned int type;
4153 const char *name;
4154
4155 es = *(elf_symbol_type **)(info->symtab + n);
4156 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4157
4158 /* If the symbol has function type then use that. */
4159 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4160 {
4161 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4162 return TRUE;
4163 }
4164
4165 /* Check for mapping symbols. */
4166 name = bfd_asymbol_name (info->symtab[n]);
4167 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4168 && (name[2] == 0 || name[2] == '.'))
4169 {
4170 *map_type = ((name[1] == 'a') ? MAP_ARM
4171 : (name[1] == 't') ? MAP_THUMB
4172 : MAP_DATA);
4173 return TRUE;
4174 }
4175
4176 return FALSE;
4177}
4178
4179/* Given a bfd_mach_arm_XXX value, this function fills in the fields
4180 of the supplied arm_feature_set structure with bitmasks indicating
4181 the support base architectures and coprocessor extensions.
4182
4183 FIXME: This could more efficiently implemented as a constant array,
4184 although it would also be less robust. */
4185
4186static void
4187select_arm_features (unsigned long mach,
4188 arm_feature_set * features)
4189{
4190#undef ARM_FEATURE
4191#define ARM_FEATURE(ARCH,CEXT) \
4192 features->core = (ARCH); \
4193 features->coproc = (CEXT) | FPU_FPA; \
4194 return
4195
4196 switch (mach)
4197 {
4198 case bfd_mach_arm_2: ARM_ARCH_V2;
4199 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4200 case bfd_mach_arm_3: ARM_ARCH_V3;
4201 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4202 case bfd_mach_arm_4: ARM_ARCH_V4;
4203 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4204 case bfd_mach_arm_5: ARM_ARCH_V5;
4205 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4206 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4207 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4208 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4209 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4210 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4211 /* If the machine type is unknown allow all
4212 architecture types and all extensions. */
4213 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4214 default:
4215 abort ();
4216 }
4217}
4218
4219
4220/* NOTE: There are no checks in these routines that
4221 the relevant number of data bytes exist. */
4222
4223static int
4224print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4225{
4226 unsigned char b[4];
4227 long given;
4228 int status;
4229 int is_thumb = FALSE;
4230 int is_data = FALSE;
4231 int little_code;
4232 unsigned int size = 4;
4233 void (*printer) (bfd_vma, struct disassemble_info *, long);
4234 bfd_boolean found = FALSE;
4235
4236 if (info->disassembler_options)
4237 {
4238 parse_disassembler_options (info->disassembler_options);
4239
4240 /* To avoid repeated parsing of these options, we remove them here. */
4241 info->disassembler_options = NULL;
4242 }
4243
4244 /* PR 10288: Control which instructions will be disassembled. */
4245 if (info->private_data == NULL)
4246 {
4247 static arm_feature_set features;
4248
4249 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4250 /* If the user did not use the -m command line switch then default to
4251 disassembling all types of ARM instruction.
4252
4253 The info->mach value has to be ignored as this will be based on
4254 the default archictecture for the target and/or hints in the notes
4255 section, but it will never be greater than the current largest arm
4256 machine value (iWMMXt2), which is only equivalent to the V5TE
4257 architecture. ARM architectures have advanced beyond the machine
4258 value encoding, and these newer architectures would be ignored if
4259 the machine value was used.
4260
4261 Ie the -m switch is used to restrict which instructions will be
4262 disassembled. If it is necessary to use the -m switch to tell
4263 objdump that an ARM binary is being disassembled, eg because the
4264 input is a raw binary file, but it is also desired to disassemble
4265 all ARM instructions then use "-marm". This will select the
4266 "unknown" arm architecture which is compatible with any ARM
4267 instruction. */
4268 info->mach = bfd_mach_arm_unknown;
4269
4270 /* Compute the architecture bitmask from the machine number.
4271 Note: This assumes that the machine number will not change
4272 during disassembly.... */
4273 select_arm_features (info->mach, & features);
4274
4275 info->private_data = & features;
4276 }
4277
4278 /* Decide if our code is going to be little-endian, despite what the
4279 function argument might say. */
4280 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4281
4282 /* First check the full symtab for a mapping symbol, even if there
4283 are no usable non-mapping symbols for this address. */
4284 if (info->symtab_size != 0
4285 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4286 {
4287 bfd_vma addr;
4288 int n;
4289 int last_sym = -1;
4290 enum map_type type = MAP_ARM;
4291
4292 if (pc <= last_mapping_addr)
4293 last_mapping_sym = -1;
4294 is_thumb = (last_type == MAP_THUMB);
4295 found = FALSE;
4296 /* Start scanning at the start of the function, or wherever
4297 we finished last time. */
4298 n = info->symtab_pos + 1;
4299 if (n < last_mapping_sym)
4300 n = last_mapping_sym;
4301
4302 /* Scan up to the location being disassembled. */
4303 for (; n < info->symtab_size; n++)
4304 {
4305 addr = bfd_asymbol_value (info->symtab[n]);
4306 if (addr > pc)
4307 break;
4308 if ((info->section == NULL
4309 || info->section == info->symtab[n]->section)
4310 && get_sym_code_type (info, n, &type))
4311 {
4312 last_sym = n;
4313 found = TRUE;
4314 }
4315 }
4316
4317 if (!found)
4318 {
4319 n = info->symtab_pos;
4320 if (n < last_mapping_sym - 1)
4321 n = last_mapping_sym - 1;
4322
4323 /* No mapping symbol found at this address. Look backwards
4324 for a preceeding one. */
4325 for (; n >= 0; n--)
4326 {
4327 if ((info->section == NULL
4328 || info->section == info->symtab[n]->section)
4329 && get_sym_code_type (info, n, &type))
4330 {
4331 last_sym = n;
4332 found = TRUE;
4333 break;
4334 }
4335 }
4336 }
4337
4338 last_mapping_sym = last_sym;
4339 last_type = type;
4340 is_thumb = (last_type == MAP_THUMB);
4341 is_data = (last_type == MAP_DATA);
4342
4343 /* Look a little bit ahead to see if we should print out
4344 two or four bytes of data. If there's a symbol,
4345 mapping or otherwise, after two bytes then don't
4346 print more. */
4347 if (is_data)
4348 {
4349 size = 4 - (pc & 3);
4350 for (n = last_sym + 1; n < info->symtab_size; n++)
4351 {
4352 addr = bfd_asymbol_value (info->symtab[n]);
4353 if (addr > pc)
4354 {
4355 if (addr - pc < size)
4356 size = addr - pc;
4357 break;
4358 }
4359 }
4360 /* If the next symbol is after three bytes, we need to
4361 print only part of the data, so that we can use either
4362 .byte or .short. */
4363 if (size == 3)
4364 size = (pc & 1) ? 1 : 2;
4365 }
4366 }
4367
4368 if (info->symbols != NULL)
4369 {
4370 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4371 {
4372 coff_symbol_type * cs;
4373
4374 cs = coffsymbol (*info->symbols);
4375 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4376 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4377 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4378 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4379 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4380 }
4381 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4382 && !found)
4383 {
4384 /* If no mapping symbol has been found then fall back to the type
4385 of the function symbol. */
4386 elf_symbol_type * es;
4387 unsigned int type;
4388
4389 es = *(elf_symbol_type **)(info->symbols);
4390 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4391
4392 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4393 }
4394 }
4395
4396 if (force_thumb)
4397 is_thumb = TRUE;
4398
4399 if (is_data)
4400 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4401 else
4402 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4403
4404 info->bytes_per_line = 4;
4405
4406 /* PR 10263: Disassemble data if requested to do so by the user. */
4407 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4408 {
4409 int i;
4410
4411 /* Size was already set above. */
4412 info->bytes_per_chunk = size;
4413 printer = print_insn_data;
4414
4415 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4416 given = 0;
4417 if (little)
4418 for (i = size - 1; i >= 0; i--)
4419 given = b[i] | (given << 8);
4420 else
4421 for (i = 0; i < (int) size; i++)
4422 given = b[i] | (given << 8);
4423 }
4424 else if (!is_thumb)
4425 {
4426 /* In ARM mode endianness is a straightforward issue: the instruction
4427 is four bytes long and is either ordered 0123 or 3210. */
4428 printer = print_insn_arm;
4429 info->bytes_per_chunk = 4;
4430 size = 4;
4431
4432 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4433 if (little_code)
4434 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4435 else
4436 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4437 }
4438 else
4439 {
4440 /* In Thumb mode we have the additional wrinkle of two
4441 instruction lengths. Fortunately, the bits that determine
4442 the length of the current instruction are always to be found
4443 in the first two bytes. */
4444 printer = print_insn_thumb16;
4445 info->bytes_per_chunk = 2;
4446 size = 2;
4447
4448 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4449 if (little_code)
4450 given = (b[0]) | (b[1] << 8);
4451 else
4452 given = (b[1]) | (b[0] << 8);
4453
4454 if (!status)
4455 {
4456 /* These bit patterns signal a four-byte Thumb
4457 instruction. */
4458 if ((given & 0xF800) == 0xF800
4459 || (given & 0xF800) == 0xF000
4460 || (given & 0xF800) == 0xE800)
4461 {
4462 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4463 if (little_code)
4464 given = (b[0]) | (b[1] << 8) | (given << 16);
4465 else
4466 given = (b[1]) | (b[0] << 8) | (given << 16);
4467
4468 printer = print_insn_thumb32;
4469 size = 4;
4470 }
4471 }
4472
4473 if (ifthen_address != pc)
4474 find_ifthen_state (pc, info, little_code);
4475
4476 if (ifthen_state)
4477 {
4478 if ((ifthen_state & 0xf) == 0x8)
4479 ifthen_next_state = 0;
4480 else
4481 ifthen_next_state = (ifthen_state & 0xe0)
4482 | ((ifthen_state & 0xf) << 1);
4483 }
4484 }
4485
4486 if (status)
4487 {
4488 info->memory_error_func (status, pc, info);
4489 return -1;
4490 }
4491 if (info->flags & INSN_HAS_RELOC)
4492 /* If the instruction has a reloc associated with it, then
4493 the offset field in the instruction will actually be the
4494 addend for the reloc. (We are using REL type relocs).
4495 In such cases, we can ignore the pc when computing
4496 addresses, since the addend is not currently pc-relative. */
4497 pc = 0;
4498
4499 printer (pc, info, given);
4500
4501 if (is_thumb)
4502 {
4503 ifthen_state = ifthen_next_state;
4504 ifthen_address += size;
4505 }
4506 return size;
4507}
4508
4509int
4510print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4511{
4512 /* Detect BE8-ness and record it in the disassembler info. */
4513 if (info->flavour == bfd_target_elf_flavour
4514 && info->section != NULL
4515 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4516 info->endian_code = BFD_ENDIAN_LITTLE;
4517
4518 return print_insn (pc, info, FALSE);
4519}
4520
4521int
4522print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4523{
4524 return print_insn (pc, info, TRUE);
4525}
4526
4527void
4528print_arm_disassembler_options (FILE *stream)
4529{
4530 int i;
4531
4532 fprintf (stream, _("\n\
4533The following ARM specific disassembler options are supported for use with\n\
4534the -M switch:\n"));
4535
4536 for (i = NUM_ARM_REGNAMES; i--;)
4537 fprintf (stream, " reg-names-%s %*c%s\n",
4538 regnames[i].name,
4539 (int)(14 - strlen (regnames[i].name)), ' ',
4540 regnames[i].description);
4541
4542 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4543 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
4544}
This page took 0.041351 seconds and 4 git commands to generate.