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