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