arm-dis.c revision 1.1 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 (at) pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith (at) 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
1658 /* Functions. */
1660 int
1661 get_arm_regname_num_options (void)
1662 {
1663 return NUM_ARM_REGNAMES;
1664 }
1665
1666 int
1667 set_arm_regname_option (int option)
1668 {
1669 int old = regname_selected;
1670 regname_selected = option;
1671 return old;
1672 }
1673
1674 int
1675 get_arm_regnames (int option,
1676 const char **setname,
1677 const char **setdescription,
1678 const char *const **register_names)
1679 {
1680 *setname = regnames[option].name;
1681 *setdescription = regnames[option].description;
1682 *register_names = regnames[option].reg_names;
1683 return 16;
1684 }
1685
1686 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1687 Returns pointer to following character of the format string and
1688 fills in *VALUEP and *WIDTHP with the extracted value and number of
1689 bits extracted. WIDTHP can be NULL. */
1690
1691 static const char *
1692 arm_decode_bitfield (const char *ptr,
1693 unsigned long insn,
1694 unsigned long *valuep,
1695 int *widthp)
1696 {
1697 unsigned long value = 0;
1698 int width = 0;
1699
1700 do
1701 {
1702 int start, end;
1703 int bits;
1704
1705 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1706 start = start * 10 + *ptr - '0';
1707 if (*ptr == '-')
1708 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1709 end = end * 10 + *ptr - '0';
1710 else
1711 end = start;
1712 bits = end - start;
1713 if (bits < 0)
1714 abort ();
1715 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1716 width += bits + 1;
1717 }
1718 while (*ptr++ == ',');
1719 *valuep = value;
1720 if (widthp)
1721 *widthp = width;
1722 return ptr - 1;
1723 }
1724
1725 static void
1726 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1727 bfd_boolean print_shift)
1728 {
1729 func (stream, "%s", arm_regnames[given & 0xf]);
1730
1731 if ((given & 0xff0) != 0)
1732 {
1733 if ((given & 0x10) == 0)
1734 {
1735 int amount = (given & 0xf80) >> 7;
1736 int shift = (given & 0x60) >> 5;
1737
1738 if (amount == 0)
1739 {
1740 if (shift == 3)
1741 {
1742 func (stream, ", rrx");
1743 return;
1744 }
1745
1746 amount = 32;
1747 }
1748
1749 if (print_shift)
1750 func (stream, ", %s #%d", arm_shift[shift], amount);
1751 else
1752 func (stream, ", #%d", amount);
1753 }
1754 else if ((given & 0x80) == 0x80)
1755 func (stream, "\t; <illegal shifter operand>");
1756 else if (print_shift)
1757 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1758 arm_regnames[(given & 0xf00) >> 8]);
1759 else
1760 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1761 }
1762 }
1763
1764 #define W_BIT 21
1765 #define I_BIT 22
1766 #define U_BIT 23
1767 #define P_BIT 24
1768
1769 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1770 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1771 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1772 #define PRE_BIT_SET (given & (1 << P_BIT))
1773
1774 /* Print one coprocessor instruction on INFO->STREAM.
1775 Return TRUE if the instuction matched, FALSE if this is not a
1776 recognised coprocessor instruction. */
1777
1778 static bfd_boolean
1779 print_insn_coprocessor (bfd_vma pc,
1780 struct disassemble_info *info,
1781 long given,
1782 bfd_boolean thumb)
1783 {
1784 const struct opcode32 *insn;
1785 void *stream = info->stream;
1786 fprintf_ftype func = info->fprintf_func;
1787 unsigned long mask;
1788 unsigned long value = 0;
1789 struct arm_private_data *private_data = info->private_data;
1790 unsigned long allowed_arches = private_data->features.coproc;
1791 int cond;
1792
1793 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1794 {
1795 unsigned long u_reg = 16;
1796 bfd_boolean is_unpredictable = FALSE;
1797 signed long value_in_comment = 0;
1798 const char *c;
1799
1800 if (insn->arch == 0)
1801 switch (insn->value)
1802 {
1803 case SENTINEL_IWMMXT_START:
1804 if (info->mach != bfd_mach_arm_XScale
1805 && info->mach != bfd_mach_arm_iWMMXt
1806 && info->mach != bfd_mach_arm_iWMMXt2)
1807 do
1808 insn++;
1809 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1810 continue;
1811
1812 case SENTINEL_IWMMXT_END:
1813 continue;
1814
1815 case SENTINEL_GENERIC_START:
1816 allowed_arches = private_data->features.core;
1817 continue;
1818
1819 default:
1820 abort ();
1821 }
1822
1823 mask = insn->mask;
1824 value = insn->value;
1825 if (thumb)
1826 {
1827 /* The high 4 bits are 0xe for Arm conditional instructions, and
1828 0xe for arm unconditional instructions. The rest of the
1829 encoding is the same. */
1830 mask |= 0xf0000000;
1831 value |= 0xe0000000;
1832 if (ifthen_state)
1833 cond = IFTHEN_COND;
1834 else
1835 cond = 16;
1836 }
1837 else
1838 {
1839 /* Only match unconditional instuctions against unconditional
1840 patterns. */
1841 if ((given & 0xf0000000) == 0xf0000000)
1842 {
1843 mask |= 0xf0000000;
1844 cond = 16;
1845 }
1846 else
1847 {
1848 cond = (given >> 28) & 0xf;
1849 if (cond == 0xe)
1850 cond = 16;
1851 }
1852 }
1853
1854 if ((given & mask) != value)
1855 continue;
1856
1857 if ((insn->arch & allowed_arches) == 0)
1858 continue;
1859
1860 for (c = insn->assembler; *c; c++)
1861 {
1862 if (*c == '%')
1863 {
1864 switch (*++c)
1865 {
1866 case '%':
1867 func (stream, "%%");
1868 break;
1869
1870 case 'A':
1871 {
1872 int rn = (given >> 16) & 0xf;
1873 int offset = given & 0xff;
1874
1875 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1876
1877 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1878 {
1879 /* Not unindexed. The offset is scaled. */
1880 offset = offset * 4;
1881 if (NEGATIVE_BIT_SET)
1882 offset = - offset;
1883 if (rn != 15)
1884 value_in_comment = offset;
1885 }
1886
1887 if (PRE_BIT_SET)
1888 {
1889 if (offset)
1890 func (stream, ", #%d]%s",
1891 offset,
1892 WRITEBACK_BIT_SET ? "!" : "");
1893 else
1894 func (stream, "]");
1895 }
1896 else
1897 {
1898 func (stream, "]");
1899
1900 if (WRITEBACK_BIT_SET)
1901 {
1902 if (offset)
1903 func (stream, ", #%d", offset);
1904 }
1905 else
1906 {
1907 func (stream, ", {%d}", offset);
1908 value_in_comment = offset;
1909 }
1910 }
1911 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1912 {
1913 func (stream, "\t; ");
1914 /* For unaligned PCs, apply off-by-alignment
1915 correction. */
1916 info->print_address_func (offset + pc
1917 + info->bytes_per_chunk * 2
1918 - (pc & 3),
1919 info);
1920 }
1921 }
1922 break;
1923
1924 case 'B':
1925 {
1926 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1927 int offset = (given >> 1) & 0x3f;
1928
1929 if (offset == 1)
1930 func (stream, "{d%d}", regno);
1931 else if (regno + offset > 32)
1932 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1933 else
1934 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1935 }
1936 break;
1937
1938 case 'c':
1939 func (stream, "%s", arm_conditional[cond]);
1940 break;
1941
1942 case 'I':
1943 /* Print a Cirrus/DSP shift immediate. */
1944 /* Immediates are 7bit signed ints with bits 0..3 in
1945 bits 0..3 of opcode and bits 4..6 in bits 5..7
1946 of opcode. */
1947 {
1948 int imm;
1949
1950 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1951
1952 /* Is ``imm'' a negative number? */
1953 if (imm & 0x40)
1954 imm |= (-1 << 7);
1955
1956 func (stream, "%d", imm);
1957 }
1958
1959 break;
1960
1961 case 'F':
1962 switch (given & 0x00408000)
1963 {
1964 case 0:
1965 func (stream, "4");
1966 break;
1967 case 0x8000:
1968 func (stream, "1");
1969 break;
1970 case 0x00400000:
1971 func (stream, "2");
1972 break;
1973 default:
1974 func (stream, "3");
1975 }
1976 break;
1977
1978 case 'P':
1979 switch (given & 0x00080080)
1980 {
1981 case 0:
1982 func (stream, "s");
1983 break;
1984 case 0x80:
1985 func (stream, "d");
1986 break;
1987 case 0x00080000:
1988 func (stream, "e");
1989 break;
1990 default:
1991 func (stream, _("<illegal precision>"));
1992 break;
1993 }
1994 break;
1995
1996 case 'Q':
1997 switch (given & 0x00408000)
1998 {
1999 case 0:
2000 func (stream, "s");
2001 break;
2002 case 0x8000:
2003 func (stream, "d");
2004 break;
2005 case 0x00400000:
2006 func (stream, "e");
2007 break;
2008 default:
2009 func (stream, "p");
2010 break;
2011 }
2012 break;
2013
2014 case 'R':
2015 switch (given & 0x60)
2016 {
2017 case 0:
2018 break;
2019 case 0x20:
2020 func (stream, "p");
2021 break;
2022 case 0x40:
2023 func (stream, "m");
2024 break;
2025 default:
2026 func (stream, "z");
2027 break;
2028 }
2029 break;
2030
2031 case '0': case '1': case '2': case '3': case '4':
2032 case '5': case '6': case '7': case '8': case '9':
2033 {
2034 int width;
2035
2036 c = arm_decode_bitfield (c, given, &value, &width);
2037
2038 switch (*c)
2039 {
2040 case 'R':
2041 if (value == 15)
2042 is_unpredictable = TRUE;
2043 /* Fall through. */
2044 case 'r':
2045 if (c[1] == 'u')
2046 {
2047 /* Eat the 'u' character. */
2048 ++ c;
2049
2050 if (u_reg == value)
2051 is_unpredictable = TRUE;
2052 u_reg = value;
2053 }
2054 func (stream, "%s", arm_regnames[value]);
2055 break;
2056 case 'D':
2057 func (stream, "d%ld", value);
2058 break;
2059 case 'Q':
2060 if (value & 1)
2061 func (stream, "<illegal reg q%ld.5>", value >> 1);
2062 else
2063 func (stream, "q%ld", value >> 1);
2064 break;
2065 case 'd':
2066 func (stream, "%ld", value);
2067 value_in_comment = value;
2068 break;
2069 case 'k':
2070 {
2071 int from = (given & (1 << 7)) ? 32 : 16;
2072 func (stream, "%ld", from - value);
2073 }
2074 break;
2075
2076 case 'f':
2077 if (value > 7)
2078 func (stream, "#%s", arm_fp_const[value & 7]);
2079 else
2080 func (stream, "f%ld", value);
2081 break;
2082
2083 case 'w':
2084 if (width == 2)
2085 func (stream, "%s", iwmmxt_wwnames[value]);
2086 else
2087 func (stream, "%s", iwmmxt_wwssnames[value]);
2088 break;
2089
2090 case 'g':
2091 func (stream, "%s", iwmmxt_regnames[value]);
2092 break;
2093 case 'G':
2094 func (stream, "%s", iwmmxt_cregnames[value]);
2095 break;
2096
2097 case 'x':
2098 func (stream, "0x%lx", (value & 0xffffffffUL));
2099 break;
2100
2101 case '`':
2102 c++;
2103 if (value == 0)
2104 func (stream, "%c", *c);
2105 break;
2106 case '\'':
2107 c++;
2108 if (value == ((1ul << width) - 1))
2109 func (stream, "%c", *c);
2110 break;
2111 case '?':
2112 func (stream, "%c", c[(1 << width) - (int) value]);
2113 c += 1 << width;
2114 break;
2115 default:
2116 abort ();
2117 }
2118 break;
2119
2120 case 'y':
2121 case 'z':
2122 {
2123 int single = *c++ == 'y';
2124 int regno;
2125
2126 switch (*c)
2127 {
2128 case '4': /* Sm pair */
2129 case '0': /* Sm, Dm */
2130 regno = given & 0x0000000f;
2131 if (single)
2132 {
2133 regno <<= 1;
2134 regno += (given >> 5) & 1;
2135 }
2136 else
2137 regno += ((given >> 5) & 1) << 4;
2138 break;
2139
2140 case '1': /* Sd, Dd */
2141 regno = (given >> 12) & 0x0000000f;
2142 if (single)
2143 {
2144 regno <<= 1;
2145 regno += (given >> 22) & 1;
2146 }
2147 else
2148 regno += ((given >> 22) & 1) << 4;
2149 break;
2150
2151 case '2': /* Sn, Dn */
2152 regno = (given >> 16) & 0x0000000f;
2153 if (single)
2154 {
2155 regno <<= 1;
2156 regno += (given >> 7) & 1;
2157 }
2158 else
2159 regno += ((given >> 7) & 1) << 4;
2160 break;
2161
2162 case '3': /* List */
2163 func (stream, "{");
2164 regno = (given >> 12) & 0x0000000f;
2165 if (single)
2166 {
2167 regno <<= 1;
2168 regno += (given >> 22) & 1;
2169 }
2170 else
2171 regno += ((given >> 22) & 1) << 4;
2172 break;
2173
2174 default:
2175 abort ();
2176 }
2177
2178 func (stream, "%c%d", single ? 's' : 'd', regno);
2179
2180 if (*c == '3')
2181 {
2182 int count = given & 0xff;
2183
2184 if (single == 0)
2185 count >>= 1;
2186
2187 if (--count)
2188 {
2189 func (stream, "-%c%d",
2190 single ? 's' : 'd',
2191 regno + count);
2192 }
2193
2194 func (stream, "}");
2195 }
2196 else if (*c == '4')
2197 func (stream, ", %c%d", single ? 's' : 'd',
2198 regno + 1);
2199 }
2200 break;
2201
2202 case 'L':
2203 switch (given & 0x00400100)
2204 {
2205 case 0x00000000: func (stream, "b"); break;
2206 case 0x00400000: func (stream, "h"); break;
2207 case 0x00000100: func (stream, "w"); break;
2208 case 0x00400100: func (stream, "d"); break;
2209 default:
2210 break;
2211 }
2212 break;
2213
2214 case 'Z':
2215 {
2216 /* given (20, 23) | given (0, 3) */
2217 value = ((given >> 16) & 0xf0) | (given & 0xf);
2218 func (stream, "%d", value);
2219 }
2220 break;
2221
2222 case 'l':
2223 /* This is like the 'A' operator, except that if
2224 the width field "M" is zero, then the offset is
2225 *not* multiplied by four. */
2226 {
2227 int offset = given & 0xff;
2228 int multiplier = (given & 0x00000100) ? 4 : 1;
2229
2230 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2231
2232 if (multiplier > 1)
2233 {
2234 value_in_comment = offset * multiplier;
2235 if (NEGATIVE_BIT_SET)
2236 value_in_comment = - value_in_comment;
2237 }
2238
2239 if (offset)
2240 {
2241 if (PRE_BIT_SET)
2242 func (stream, ", #%s%d]%s",
2243 NEGATIVE_BIT_SET ? "-" : "",
2244 offset * multiplier,
2245 WRITEBACK_BIT_SET ? "!" : "");
2246 else
2247 func (stream, "], #%s%d",
2248 NEGATIVE_BIT_SET ? "-" : "",
2249 offset * multiplier);
2250 }
2251 else
2252 func (stream, "]");
2253 }
2254 break;
2255
2256 case 'r':
2257 {
2258 int imm4 = (given >> 4) & 0xf;
2259 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2260 int ubit = ! NEGATIVE_BIT_SET;
2261 const char *rm = arm_regnames [given & 0xf];
2262 const char *rn = arm_regnames [(given >> 16) & 0xf];
2263
2264 switch (puw_bits)
2265 {
2266 case 1:
2267 case 3:
2268 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2269 if (imm4)
2270 func (stream, ", lsl #%d", imm4);
2271 break;
2272
2273 case 4:
2274 case 5:
2275 case 6:
2276 case 7:
2277 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2278 if (imm4 > 0)
2279 func (stream, ", lsl #%d", imm4);
2280 func (stream, "]");
2281 if (puw_bits == 5 || puw_bits == 7)
2282 func (stream, "!");
2283 break;
2284
2285 default:
2286 func (stream, "INVALID");
2287 }
2288 }
2289 break;
2290
2291 case 'i':
2292 {
2293 long imm5;
2294 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2295 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2296 }
2297 break;
2298
2299 default:
2300 abort ();
2301 }
2302 }
2303 }
2304 else
2305 func (stream, "%c", *c);
2306 }
2307
2308 if (value_in_comment > 32 || value_in_comment < -16)
2309 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2310
2311 if (is_unpredictable)
2312 func (stream, UNPREDICTABLE_INSTRUCTION);
2313
2314 return TRUE;
2315 }
2316 return FALSE;
2317 }
2318
2319 /* Decodes and prints ARM addressing modes. Returns the offset
2320 used in the address, if any, if it is worthwhile printing the
2321 offset as a hexadecimal value in a comment at the end of the
2322 line of disassembly. */
2323
2324 static signed long
2325 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2326 {
2327 void *stream = info->stream;
2328 fprintf_ftype func = info->fprintf_func;
2329 int offset = 0;
2330
2331 if (((given & 0x000f0000) == 0x000f0000)
2332 && ((given & 0x02000000) == 0))
2333 {
2334 offset = given & 0xfff;
2335
2336 func (stream, "[pc");
2337
2338 if (NEGATIVE_BIT_SET)
2339 offset = - offset;
2340
2341 if (PRE_BIT_SET)
2342 {
2343 /* Pre-indexed. */
2344 func (stream, ", #%d]", offset);
2345
2346 offset += pc + 8;
2347
2348 /* Cope with the possibility of write-back
2349 being used. Probably a very dangerous thing
2350 for the programmer to do, but who are we to
2351 argue ? */
2352 if (WRITEBACK_BIT_SET)
2353 func (stream, "!");
2354 }
2355 else /* Post indexed. */
2356 {
2357 func (stream, "], #%d", offset);
2358
2359 /* Ie ignore the offset. */
2360 offset = pc + 8;
2361 }
2362
2363 func (stream, "\t; ");
2364 info->print_address_func (offset, info);
2365 offset = 0;
2366 }
2367 else
2368 {
2369 func (stream, "[%s",
2370 arm_regnames[(given >> 16) & 0xf]);
2371
2372 if (PRE_BIT_SET)
2373 {
2374 if ((given & 0x02000000) == 0)
2375 {
2376 offset = given & 0xfff;
2377 if (offset)
2378 func (stream, ", #%s%d",
2379 NEGATIVE_BIT_SET ? "-" : "", offset);
2380 }
2381 else
2382 {
2383 func (stream, ", %s",
2384 NEGATIVE_BIT_SET ? "-" : "");
2385 arm_decode_shift (given, func, stream, TRUE);
2386 }
2387
2388 func (stream, "]%s",
2389 WRITEBACK_BIT_SET ? "!" : "");
2390 }
2391 else
2392 {
2393 if ((given & 0x02000000) == 0)
2394 {
2395 offset = given & 0xfff;
2396 if (offset)
2397 func (stream, "], #%s%d",
2398 NEGATIVE_BIT_SET ? "-" : "", offset);
2399 else
2400 func (stream, "]");
2401 }
2402 else
2403 {
2404 func (stream, "], %s",
2405 NEGATIVE_BIT_SET ? "-" : "");
2406 arm_decode_shift (given, func, stream, TRUE);
2407 }
2408 }
2409 }
2410
2411 return (signed long) offset;
2412 }
2413
2414 /* Print one neon instruction on INFO->STREAM.
2415 Return TRUE if the instuction matched, FALSE if this is not a
2416 recognised neon instruction. */
2417
2418 static bfd_boolean
2419 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2420 {
2421 const struct opcode32 *insn;
2422 void *stream = info->stream;
2423 fprintf_ftype func = info->fprintf_func;
2424
2425 if (thumb)
2426 {
2427 if ((given & 0xef000000) == 0xef000000)
2428 {
2429 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2430 unsigned long bit28 = given & (1 << 28);
2431
2432 given &= 0x00ffffff;
2433 if (bit28)
2434 given |= 0xf3000000;
2435 else
2436 given |= 0xf2000000;
2437 }
2438 else if ((given & 0xff000000) == 0xf9000000)
2439 given ^= 0xf9000000 ^ 0xf4000000;
2440 else
2441 return FALSE;
2442 }
2443
2444 for (insn = neon_opcodes; insn->assembler; insn++)
2445 {
2446 if ((given & insn->mask) == insn->value)
2447 {
2448 signed long value_in_comment = 0;
2449 const char *c;
2450
2451 for (c = insn->assembler; *c; c++)
2452 {
2453 if (*c == '%')
2454 {
2455 switch (*++c)
2456 {
2457 case '%':
2458 func (stream, "%%");
2459 break;
2460
2461 case 'c':
2462 if (thumb && ifthen_state)
2463 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2464 break;
2465
2466 case 'A':
2467 {
2468 static const unsigned char enc[16] =
2469 {
2470 0x4, 0x14, /* st4 0,1 */
2471 0x4, /* st1 2 */
2472 0x4, /* st2 3 */
2473 0x3, /* st3 4 */
2474 0x13, /* st3 5 */
2475 0x3, /* st1 6 */
2476 0x1, /* st1 7 */
2477 0x2, /* st2 8 */
2478 0x12, /* st2 9 */
2479 0x2, /* st1 10 */
2480 0, 0, 0, 0, 0
2481 };
2482 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2483 int rn = ((given >> 16) & 0xf);
2484 int rm = ((given >> 0) & 0xf);
2485 int align = ((given >> 4) & 0x3);
2486 int type = ((given >> 8) & 0xf);
2487 int n = enc[type] & 0xf;
2488 int stride = (enc[type] >> 4) + 1;
2489 int ix;
2490
2491 func (stream, "{");
2492 if (stride > 1)
2493 for (ix = 0; ix != n; ix++)
2494 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2495 else if (n == 1)
2496 func (stream, "d%d", rd);
2497 else
2498 func (stream, "d%d-d%d", rd, rd + n - 1);
2499 func (stream, "}, [%s", arm_regnames[rn]);
2500 if (align)
2501 func (stream, " :%d", 32 << align);
2502 func (stream, "]");
2503 if (rm == 0xd)
2504 func (stream, "!");
2505 else if (rm != 0xf)
2506 func (stream, ", %s", arm_regnames[rm]);
2507 }
2508 break;
2509
2510 case 'B':
2511 {
2512 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2513 int rn = ((given >> 16) & 0xf);
2514 int rm = ((given >> 0) & 0xf);
2515 int idx_align = ((given >> 4) & 0xf);
2516 int align = 0;
2517 int size = ((given >> 10) & 0x3);
2518 int idx = idx_align >> (size + 1);
2519 int length = ((given >> 8) & 3) + 1;
2520 int stride = 1;
2521 int i;
2522
2523 if (length > 1 && size > 0)
2524 stride = (idx_align & (1 << size)) ? 2 : 1;
2525
2526 switch (length)
2527 {
2528 case 1:
2529 {
2530 int amask = (1 << size) - 1;
2531 if ((idx_align & (1 << size)) != 0)
2532 return FALSE;
2533 if (size > 0)
2534 {
2535 if ((idx_align & amask) == amask)
2536 align = 8 << size;
2537 else if ((idx_align & amask) != 0)
2538 return FALSE;
2539 }
2540 }
2541 break;
2542
2543 case 2:
2544 if (size == 2 && (idx_align & 2) != 0)
2545 return FALSE;
2546 align = (idx_align & 1) ? 16 << size : 0;
2547 break;
2548
2549 case 3:
2550 if ((size == 2 && (idx_align & 3) != 0)
2551 || (idx_align & 1) != 0)
2552 return FALSE;
2553 break;
2554
2555 case 4:
2556 if (size == 2)
2557 {
2558 if ((idx_align & 3) == 3)
2559 return FALSE;
2560 align = (idx_align & 3) * 64;
2561 }
2562 else
2563 align = (idx_align & 1) ? 32 << size : 0;
2564 break;
2565
2566 default:
2567 abort ();
2568 }
2569
2570 func (stream, "{");
2571 for (i = 0; i < length; i++)
2572 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2573 rd + i * stride, idx);
2574 func (stream, "}, [%s", arm_regnames[rn]);
2575 if (align)
2576 func (stream, " :%d", align);
2577 func (stream, "]");
2578 if (rm == 0xd)
2579 func (stream, "!");
2580 else if (rm != 0xf)
2581 func (stream, ", %s", arm_regnames[rm]);
2582 }
2583 break;
2584
2585 case 'C':
2586 {
2587 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2588 int rn = ((given >> 16) & 0xf);
2589 int rm = ((given >> 0) & 0xf);
2590 int align = ((given >> 4) & 0x1);
2591 int size = ((given >> 6) & 0x3);
2592 int type = ((given >> 8) & 0x3);
2593 int n = type + 1;
2594 int stride = ((given >> 5) & 0x1);
2595 int ix;
2596
2597 if (stride && (n == 1))
2598 n++;
2599 else
2600 stride++;
2601
2602 func (stream, "{");
2603 if (stride > 1)
2604 for (ix = 0; ix != n; ix++)
2605 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2606 else if (n == 1)
2607 func (stream, "d%d[]", rd);
2608 else
2609 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2610 func (stream, "}, [%s", arm_regnames[rn]);
2611 if (align)
2612 {
2613 align = (8 * (type + 1)) << size;
2614 if (type == 3)
2615 align = (size > 1) ? align >> 1 : align;
2616 if (type == 2 || (type == 0 && !size))
2617 func (stream, " :<bad align %d>", align);
2618 else
2619 func (stream, " :%d", align);
2620 }
2621 func (stream, "]");
2622 if (rm == 0xd)
2623 func (stream, "!");
2624 else if (rm != 0xf)
2625 func (stream, ", %s", arm_regnames[rm]);
2626 }
2627 break;
2628
2629 case 'D':
2630 {
2631 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2632 int size = (given >> 20) & 3;
2633 int reg = raw_reg & ((4 << size) - 1);
2634 int ix = raw_reg >> size >> 2;
2635
2636 func (stream, "d%d[%d]", reg, ix);
2637 }
2638 break;
2639
2640 case 'E':
2641 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2642 {
2643 int bits = 0;
2644 int cmode = (given >> 8) & 0xf;
2645 int op = (given >> 5) & 0x1;
2646 unsigned long value = 0, hival = 0;
2647 unsigned shift;
2648 int size = 0;
2649 int isfloat = 0;
2650
2651 bits |= ((given >> 24) & 1) << 7;
2652 bits |= ((given >> 16) & 7) << 4;
2653 bits |= ((given >> 0) & 15) << 0;
2654
2655 if (cmode < 8)
2656 {
2657 shift = (cmode >> 1) & 3;
2658 value = (unsigned long) bits << (8 * shift);
2659 size = 32;
2660 }
2661 else if (cmode < 12)
2662 {
2663 shift = (cmode >> 1) & 1;
2664 value = (unsigned long) bits << (8 * shift);
2665 size = 16;
2666 }
2667 else if (cmode < 14)
2668 {
2669 shift = (cmode & 1) + 1;
2670 value = (unsigned long) bits << (8 * shift);
2671 value |= (1ul << (8 * shift)) - 1;
2672 size = 32;
2673 }
2674 else if (cmode == 14)
2675 {
2676 if (op)
2677 {
2678 /* Bit replication into bytes. */
2679 int ix;
2680 unsigned long mask;
2681
2682 value = 0;
2683 hival = 0;
2684 for (ix = 7; ix >= 0; ix--)
2685 {
2686 mask = ((bits >> ix) & 1) ? 0xff : 0;
2687 if (ix <= 3)
2688 value = (value << 8) | mask;
2689 else
2690 hival = (hival << 8) | mask;
2691 }
2692 size = 64;
2693 }
2694 else
2695 {
2696 /* Byte replication. */
2697 value = (unsigned long) bits;
2698 size = 8;
2699 }
2700 }
2701 else if (!op)
2702 {
2703 /* Floating point encoding. */
2704 int tmp;
2705
2706 value = (unsigned long) (bits & 0x7f) << 19;
2707 value |= (unsigned long) (bits & 0x80) << 24;
2708 tmp = bits & 0x40 ? 0x3c : 0x40;
2709 value |= (unsigned long) tmp << 24;
2710 size = 32;
2711 isfloat = 1;
2712 }
2713 else
2714 {
2715 func (stream, "<illegal constant %.8x:%x:%x>",
2716 bits, cmode, op);
2717 size = 32;
2718 break;
2719 }
2720 switch (size)
2721 {
2722 case 8:
2723 func (stream, "#%ld\t; 0x%.2lx", value, value);
2724 break;
2725
2726 case 16:
2727 func (stream, "#%ld\t; 0x%.4lx", value, value);
2728 break;
2729
2730 case 32:
2731 if (isfloat)
2732 {
2733 unsigned char valbytes[4];
2734 double fvalue;
2735
2736 /* Do this a byte at a time so we don't have to
2737 worry about the host's endianness. */
2738 valbytes[0] = value & 0xff;
2739 valbytes[1] = (value >> 8) & 0xff;
2740 valbytes[2] = (value >> 16) & 0xff;
2741 valbytes[3] = (value >> 24) & 0xff;
2742
2743 floatformat_to_double
2744 (& floatformat_ieee_single_little, valbytes,
2745 & fvalue);
2746
2747 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2748 value);
2749 }
2750 else
2751 func (stream, "#%ld\t; 0x%.8lx",
2752 (long) (((value & 0x80000000L) != 0)
2753 ? value | ~0xffffffffL : value),
2754 value);
2755 break;
2756
2757 case 64:
2758 func (stream, "#0x%.8lx%.8lx", hival, value);
2759 break;
2760
2761 default:
2762 abort ();
2763 }
2764 }
2765 break;
2766
2767 case 'F':
2768 {
2769 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2770 int num = (given >> 8) & 0x3;
2771
2772 if (!num)
2773 func (stream, "{d%d}", regno);
2774 else if (num + regno >= 32)
2775 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2776 else
2777 func (stream, "{d%d-d%d}", regno, regno + num);
2778 }
2779 break;
2780
2781
2782 case '0': case '1': case '2': case '3': case '4':
2783 case '5': case '6': case '7': case '8': case '9':
2784 {
2785 int width;
2786 unsigned long value;
2787
2788 c = arm_decode_bitfield (c, given, &value, &width);
2789
2790 switch (*c)
2791 {
2792 case 'r':
2793 func (stream, "%s", arm_regnames[value]);
2794 break;
2795 case 'd':
2796 func (stream, "%ld", value);
2797 value_in_comment = value;
2798 break;
2799 case 'e':
2800 func (stream, "%ld", (1ul << width) - value);
2801 break;
2802
2803 case 'S':
2804 case 'T':
2805 case 'U':
2806 /* Various width encodings. */
2807 {
2808 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2809 int limit;
2810 unsigned low, high;
2811
2812 c++;
2813 if (*c >= '0' && *c <= '9')
2814 limit = *c - '0';
2815 else if (*c >= 'a' && *c <= 'f')
2816 limit = *c - 'a' + 10;
2817 else
2818 abort ();
2819 low = limit >> 2;
2820 high = limit & 3;
2821
2822 if (value < low || value > high)
2823 func (stream, "<illegal width %d>", base << value);
2824 else
2825 func (stream, "%d", base << value);
2826 }
2827 break;
2828 case 'R':
2829 if (given & (1 << 6))
2830 goto Q;
2831 /* FALLTHROUGH */
2832 case 'D':
2833 func (stream, "d%ld", value);
2834 break;
2835 case 'Q':
2836 Q:
2837 if (value & 1)
2838 func (stream, "<illegal reg q%ld.5>", value >> 1);
2839 else
2840 func (stream, "q%ld", value >> 1);
2841 break;
2842
2843 case '`':
2844 c++;
2845 if (value == 0)
2846 func (stream, "%c", *c);
2847 break;
2848 case '\'':
2849 c++;
2850 if (value == ((1ul << width) - 1))
2851 func (stream, "%c", *c);
2852 break;
2853 case '?':
2854 func (stream, "%c", c[(1 << width) - (int) value]);
2855 c += 1 << width;
2856 break;
2857 default:
2858 abort ();
2859 }
2860 break;
2861
2862 default:
2863 abort ();
2864 }
2865 }
2866 }
2867 else
2868 func (stream, "%c", *c);
2869 }
2870
2871 if (value_in_comment > 32 || value_in_comment < -16)
2872 func (stream, "\t; 0x%lx", value_in_comment);
2873
2874 return TRUE;
2875 }
2876 }
2877 return FALSE;
2878 }
2879
2880 /* Return the name of a v7A special register. */
2881
2882 static const char *
2883 banked_regname (unsigned reg)
2884 {
2885 switch (reg)
2886 {
2887 case 15: return "CPSR";
2888 case 32: return "R8_usr";
2889 case 33: return "R9_usr";
2890 case 34: return "R10_usr";
2891 case 35: return "R11_usr";
2892 case 36: return "R12_usr";
2893 case 37: return "SP_usr";
2894 case 38: return "LR_usr";
2895 case 40: return "R8_fiq";
2896 case 41: return "R9_fiq";
2897 case 42: return "R10_fiq";
2898 case 43: return "R11_fiq";
2899 case 44: return "R12_fiq";
2900 case 45: return "SP_fiq";
2901 case 46: return "LR_fiq";
2902 case 48: return "LR_irq";
2903 case 49: return "SP_irq";
2904 case 50: return "LR_svc";
2905 case 51: return "SP_svc";
2906 case 52: return "LR_abt";
2907 case 53: return "SP_abt";
2908 case 54: return "LR_und";
2909 case 55: return "SP_und";
2910 case 60: return "LR_mon";
2911 case 61: return "SP_mon";
2912 case 62: return "ELR_hyp";
2913 case 63: return "SP_hyp";
2914 case 79: return "SPSR";
2915 case 110: return "SPSR_fiq";
2916 case 112: return "SPSR_irq";
2917 case 114: return "SPSR_svc";
2918 case 116: return "SPSR_abt";
2919 case 118: return "SPSR_und";
2920 case 124: return "SPSR_mon";
2921 case 126: return "SPSR_hyp";
2922 default: return NULL;
2923 }
2924 }
2925
2926 /* Print one ARM instruction from PC on INFO->STREAM. */
2927
2928 static void
2929 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2930 {
2931 const struct opcode32 *insn;
2932 void *stream = info->stream;
2933 fprintf_ftype func = info->fprintf_func;
2934 struct arm_private_data *private_data = info->private_data;
2935
2936 if (print_insn_coprocessor (pc, info, given, FALSE))
2937 return;
2938
2939 if (print_insn_neon (info, given, FALSE))
2940 return;
2941
2942 for (insn = arm_opcodes; insn->assembler; insn++)
2943 {
2944 if ((given & insn->mask) != insn->value)
2945 continue;
2946
2947 if ((insn->arch & private_data->features.core) == 0)
2948 continue;
2949
2950 /* Special case: an instruction with all bits set in the condition field
2951 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2952 or by the catchall at the end of the table. */
2953 if ((given & 0xF0000000) != 0xF0000000
2954 || (insn->mask & 0xF0000000) == 0xF0000000
2955 || (insn->mask == 0 && insn->value == 0))
2956 {
2957 unsigned long u_reg = 16;
2958 unsigned long U_reg = 16;
2959 bfd_boolean is_unpredictable = FALSE;
2960 signed long value_in_comment = 0;
2961 const char *c;
2962
2963 for (c = insn->assembler; *c; c++)
2964 {
2965 if (*c == '%')
2966 {
2967 bfd_boolean allow_unpredictable = FALSE;
2968
2969 switch (*++c)
2970 {
2971 case '%':
2972 func (stream, "%%");
2973 break;
2974
2975 case 'a':
2976 value_in_comment = print_arm_address (pc, info, given);
2977 break;
2978
2979 case 'P':
2980 /* Set P address bit and use normal address
2981 printing routine. */
2982 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
2983 break;
2984
2985 case 'S':
2986 allow_unpredictable = TRUE;
2987 case 's':
2988 if ((given & 0x004f0000) == 0x004f0000)
2989 {
2990 /* PC relative with immediate offset. */
2991 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2992
2993 if (NEGATIVE_BIT_SET)
2994 offset = - offset;
2995
2996 if (PRE_BIT_SET)
2997 {
2998 if (offset)
2999 func (stream, "[pc, #%d]\t; ", offset);
3000 else
3001 func (stream, "[pc]\t; ");
3002 info->print_address_func (offset + pc + 8, info);
3003 }
3004 else
3005 {
3006 func (stream, "[pc], #%d", offset);
3007 if (! allow_unpredictable)
3008 is_unpredictable = TRUE;
3009 }
3010 }
3011 else
3012 {
3013 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3014
3015 if (NEGATIVE_BIT_SET)
3016 offset = - offset;
3017
3018 func (stream, "[%s",
3019 arm_regnames[(given >> 16) & 0xf]);
3020
3021 if (PRE_BIT_SET)
3022 {
3023 if (IMMEDIATE_BIT_SET)
3024 {
3025 if (WRITEBACK_BIT_SET)
3026 /* Immediate Pre-indexed. */
3027 /* PR 10924: Offset must be printed, even if it is zero. */
3028 func (stream, ", #%d", offset);
3029 else if (offset)
3030 /* Immediate Offset: printing zero offset is optional. */
3031 func (stream, ", #%d", offset);
3032
3033 value_in_comment = offset;
3034 }
3035 else
3036 {
3037 /* Register Offset or Register Pre-Indexed. */
3038 func (stream, ", %s%s",
3039 NEGATIVE_BIT_SET ? "-" : "",
3040 arm_regnames[given & 0xf]);
3041
3042 /* Writing back to the register that is the source/
3043 destination of the load/store is unpredictable. */
3044 if (! allow_unpredictable
3045 && WRITEBACK_BIT_SET
3046 && ((given & 0xf) == ((given >> 12) & 0xf)))
3047 is_unpredictable = TRUE;
3048 }
3049
3050 func (stream, "]%s",
3051 WRITEBACK_BIT_SET ? "!" : "");
3052 }
3053 else
3054 {
3055 if (IMMEDIATE_BIT_SET)
3056 {
3057 /* Immediate Post-indexed. */
3058 /* PR 10924: Offset must be printed, even if it is zero. */
3059 func (stream, "], #%d", offset);
3060 value_in_comment = offset;
3061 }
3062 else
3063 {
3064 /* Register Post-indexed. */
3065 func (stream, "], %s%s",
3066 NEGATIVE_BIT_SET ? "-" : "",
3067 arm_regnames[given & 0xf]);
3068
3069 /* Writing back to the register that is the source/
3070 destination of the load/store is unpredictable. */
3071 if (! allow_unpredictable
3072 && (given & 0xf) == ((given >> 12) & 0xf))
3073 is_unpredictable = TRUE;
3074 }
3075
3076 if (! allow_unpredictable)
3077 {
3078 /* Writeback is automatically implied by post- addressing.
3079 Setting the W bit is unnecessary and ARM specify it as
3080 being unpredictable. */
3081 if (WRITEBACK_BIT_SET
3082 /* Specifying the PC register as the post-indexed
3083 registers is also unpredictable. */
3084 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3085 is_unpredictable = TRUE;
3086 }
3087 }
3088 }
3089 break;
3090
3091 case 'b':
3092 {
3093 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3094 info->print_address_func (disp * 4 + pc + 8, info);
3095 }
3096 break;
3097
3098 case 'c':
3099 if (((given >> 28) & 0xf) != 0xe)
3100 func (stream, "%s",
3101 arm_conditional [(given >> 28) & 0xf]);
3102 break;
3103
3104 case 'm':
3105 {
3106 int started = 0;
3107 int reg;
3108
3109 func (stream, "{");
3110 for (reg = 0; reg < 16; reg++)
3111 if ((given & (1 << reg)) != 0)
3112 {
3113 if (started)
3114 func (stream, ", ");
3115 started = 1;
3116 func (stream, "%s", arm_regnames[reg]);
3117 }
3118 func (stream, "}");
3119 if (! started)
3120 is_unpredictable = TRUE;
3121 }
3122 break;
3123
3124 case 'q':
3125 arm_decode_shift (given, func, stream, FALSE);
3126 break;
3127
3128 case 'o':
3129 if ((given & 0x02000000) != 0)
3130 {
3131 int rotate = (given & 0xf00) >> 7;
3132 int immed = (given & 0xff);
3133
3134 immed = (((immed << (32 - rotate))
3135 | (immed >> rotate)) & 0xffffffff);
3136 func (stream, "#%d", immed);
3137 value_in_comment = immed;
3138 }
3139 else
3140 arm_decode_shift (given, func, stream, TRUE);
3141 break;
3142
3143 case 'p':
3144 if ((given & 0x0000f000) == 0x0000f000)
3145 {
3146 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3147 mechanism for setting PSR flag bits. They are
3148 obsolete in V6 onwards. */
3149 if ((private_data->features.core & ARM_EXT_V6) == 0)
3150 func (stream, "p");
3151 }
3152 break;
3153
3154 case 't':
3155 if ((given & 0x01200000) == 0x00200000)
3156 func (stream, "t");
3157 break;
3158
3159 case 'A':
3160 {
3161 int offset = given & 0xff;
3162
3163 value_in_comment = offset * 4;
3164 if (NEGATIVE_BIT_SET)
3165 value_in_comment = - value_in_comment;
3166
3167 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3168
3169 if (PRE_BIT_SET)
3170 {
3171 if (offset)
3172 func (stream, ", #%d]%s",
3173 value_in_comment,
3174 WRITEBACK_BIT_SET ? "!" : "");
3175 else
3176 func (stream, "]");
3177 }
3178 else
3179 {
3180 func (stream, "]");
3181
3182 if (WRITEBACK_BIT_SET)
3183 {
3184 if (offset)
3185 func (stream, ", #%d", value_in_comment);
3186 }
3187 else
3188 {
3189 func (stream, ", {%d}", offset);
3190 value_in_comment = offset;
3191 }
3192 }
3193 }
3194 break;
3195
3196 case 'B':
3197 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3198 {
3199 bfd_vma address;
3200 bfd_vma offset = 0;
3201
3202 if (! NEGATIVE_BIT_SET)
3203 /* Is signed, hi bits should be ones. */
3204 offset = (-1) ^ 0x00ffffff;
3205
3206 /* Offset is (SignExtend(offset field)<<2). */
3207 offset += given & 0x00ffffff;
3208 offset <<= 2;
3209 address = offset + pc + 8;
3210
3211 if (given & 0x01000000)
3212 /* H bit allows addressing to 2-byte boundaries. */
3213 address += 2;
3214
3215 info->print_address_func (address, info);
3216 }
3217 break;
3218
3219 case 'C':
3220 if ((given & 0x02000200) == 0x200)
3221 {
3222 const char * name;
3223 unsigned sysm = (given & 0x004f0000) >> 16;
3224
3225 sysm |= (given & 0x300) >> 4;
3226 name = banked_regname (sysm);
3227
3228 if (name != NULL)
3229 func (stream, "%s", name);
3230 else
3231 func (stream, "(UNDEF: %lu)", sysm);
3232 }
3233 else
3234 {
3235 func (stream, "%cPSR_",
3236 (given & 0x00400000) ? 'S' : 'C');
3237 if (given & 0x80000)
3238 func (stream, "f");
3239 if (given & 0x40000)
3240 func (stream, "s");
3241 if (given & 0x20000)
3242 func (stream, "x");
3243 if (given & 0x10000)
3244 func (stream, "c");
3245 }
3246 break;
3247
3248 case 'U':
3249 if ((given & 0xf0) == 0x60)
3250 {
3251 switch (given & 0xf)
3252 {
3253 case 0xf: func (stream, "sy"); break;
3254 default:
3255 func (stream, "#%d", (int) given & 0xf);
3256 break;
3257 }
3258 }
3259 else
3260 {
3261 switch (given & 0xf)
3262 {
3263 case 0xf: func (stream, "sy"); break;
3264 case 0x7: func (stream, "un"); break;
3265 case 0xe: func (stream, "st"); break;
3266 case 0x6: func (stream, "unst"); break;
3267 case 0xb: func (stream, "ish"); break;
3268 case 0xa: func (stream, "ishst"); break;
3269 case 0x3: func (stream, "osh"); break;
3270 case 0x2: func (stream, "oshst"); break;
3271 default:
3272 func (stream, "#%d", (int) given & 0xf);
3273 break;
3274 }
3275 }
3276 break;
3277
3278 case '0': case '1': case '2': case '3': case '4':
3279 case '5': case '6': case '7': case '8': case '9':
3280 {
3281 int width;
3282 unsigned long value;
3283
3284 c = arm_decode_bitfield (c, given, &value, &width);
3285
3286 switch (*c)
3287 {
3288 case 'R':
3289 if (value == 15)
3290 is_unpredictable = TRUE;
3291 /* Fall through. */
3292 case 'r':
3293 if (c[1] == 'u')
3294 {
3295 /* Eat the 'u' character. */
3296 ++ c;
3297
3298 if (u_reg == value)
3299 is_unpredictable = TRUE;
3300 u_reg = value;
3301 }
3302 if (c[1] == 'U')
3303 {
3304 /* Eat the 'U' character. */
3305 ++ c;
3306
3307 if (U_reg == value)
3308 is_unpredictable = TRUE;
3309 U_reg = value;
3310 }
3311 func (stream, "%s", arm_regnames[value]);
3312 break;
3313 case 'd':
3314 func (stream, "%ld", value);
3315 value_in_comment = value;
3316 break;
3317 case 'b':
3318 func (stream, "%ld", value * 8);
3319 value_in_comment = value * 8;
3320 break;
3321 case 'W':
3322 func (stream, "%ld", value + 1);
3323 value_in_comment = value + 1;
3324 break;
3325 case 'x':
3326 func (stream, "0x%08lx", value);
3327
3328 /* Some SWI instructions have special
3329 meanings. */
3330 if ((given & 0x0fffffff) == 0x0FF00000)
3331 func (stream, "\t; IMB");
3332 else if ((given & 0x0fffffff) == 0x0FF00001)
3333 func (stream, "\t; IMBRange");
3334 break;
3335 case 'X':
3336 func (stream, "%01lx", value & 0xf);
3337 value_in_comment = value;
3338 break;
3339 case '`':
3340 c++;
3341 if (value == 0)
3342 func (stream, "%c", *c);
3343 break;
3344 case '\'':
3345 c++;
3346 if (value == ((1ul << width) - 1))
3347 func (stream, "%c", *c);
3348 break;
3349 case '?':
3350 func (stream, "%c", c[(1 << width) - (int) value]);
3351 c += 1 << width;
3352 break;
3353 default:
3354 abort ();
3355 }
3356 break;
3357
3358 case 'e':
3359 {
3360 int imm;
3361
3362 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3363 func (stream, "%d", imm);
3364 value_in_comment = imm;
3365 }
3366 break;
3367
3368 case 'E':
3369 /* LSB and WIDTH fields of BFI or BFC. The machine-
3370 language instruction encodes LSB and MSB. */
3371 {
3372 long msb = (given & 0x001f0000) >> 16;
3373 long lsb = (given & 0x00000f80) >> 7;
3374 long w = msb - lsb + 1;
3375
3376 if (w > 0)
3377 func (stream, "#%lu, #%lu", lsb, w);
3378 else
3379 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3380 }
3381 break;
3382
3383 case 'R':
3384 /* Get the PSR/banked register name. */
3385 {
3386 const char * name;
3387 unsigned sysm = (given & 0x004f0000) >> 16;
3388
3389 sysm |= (given & 0x300) >> 4;
3390 name = banked_regname (sysm);
3391
3392 if (name != NULL)
3393 func (stream, "%s", name);
3394 else
3395 func (stream, "(UNDEF: %lu)", sysm);
3396 }
3397 break;
3398
3399 case 'V':
3400 /* 16-bit unsigned immediate from a MOVT or MOVW
3401 instruction, encoded in bits 0:11 and 15:19. */
3402 {
3403 long hi = (given & 0x000f0000) >> 4;
3404 long lo = (given & 0x00000fff);
3405 long imm16 = hi | lo;
3406
3407 func (stream, "#%lu", imm16);
3408 value_in_comment = imm16;
3409 }
3410 break;
3411
3412 default:
3413 abort ();
3414 }
3415 }
3416 }
3417 else
3418 func (stream, "%c", *c);
3419 }
3420
3421 if (value_in_comment > 32 || value_in_comment < -16)
3422 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3423
3424 if (is_unpredictable)
3425 func (stream, UNPREDICTABLE_INSTRUCTION);
3426
3427 return;
3428 }
3429 }
3430 abort ();
3431 }
3432
3433 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3434
3435 static void
3436 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3437 {
3438 const struct opcode16 *insn;
3439 void *stream = info->stream;
3440 fprintf_ftype func = info->fprintf_func;
3441
3442 for (insn = thumb_opcodes; insn->assembler; insn++)
3443 if ((given & insn->mask) == insn->value)
3444 {
3445 signed long value_in_comment = 0;
3446 const char *c = insn->assembler;
3447
3448 for (; *c; c++)
3449 {
3450 int domaskpc = 0;
3451 int domasklr = 0;
3452
3453 if (*c != '%')
3454 {
3455 func (stream, "%c", *c);
3456 continue;
3457 }
3458
3459 switch (*++c)
3460 {
3461 case '%':
3462 func (stream, "%%");
3463 break;
3464
3465 case 'c':
3466 if (ifthen_state)
3467 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3468 break;
3469
3470 case 'C':
3471 if (ifthen_state)
3472 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3473 else
3474 func (stream, "s");
3475 break;
3476
3477 case 'I':
3478 {
3479 unsigned int tmp;
3480
3481 ifthen_next_state = given & 0xff;
3482 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3483 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3484 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3485 }
3486 break;
3487
3488 case 'x':
3489 if (ifthen_next_state)
3490 func (stream, "\t; unpredictable branch in IT block\n");
3491 break;
3492
3493 case 'X':
3494 if (ifthen_state)
3495 func (stream, "\t; unpredictable <IT:%s>",
3496 arm_conditional[IFTHEN_COND]);
3497 break;
3498
3499 case 'S':
3500 {
3501 long reg;
3502
3503 reg = (given >> 3) & 0x7;
3504 if (given & (1 << 6))
3505 reg += 8;
3506
3507 func (stream, "%s", arm_regnames[reg]);
3508 }
3509 break;
3510
3511 case 'D':
3512 {
3513 long reg;
3514
3515 reg = given & 0x7;
3516 if (given & (1 << 7))
3517 reg += 8;
3518
3519 func (stream, "%s", arm_regnames[reg]);
3520 }
3521 break;
3522
3523 case 'N':
3524 if (given & (1 << 8))
3525 domasklr = 1;
3526 /* Fall through. */
3527 case 'O':
3528 if (*c == 'O' && (given & (1 << 8)))
3529 domaskpc = 1;
3530 /* Fall through. */
3531 case 'M':
3532 {
3533 int started = 0;
3534 int reg;
3535
3536 func (stream, "{");
3537
3538 /* It would be nice if we could spot
3539 ranges, and generate the rS-rE format: */
3540 for (reg = 0; (reg < 8); reg++)
3541 if ((given & (1 << reg)) != 0)
3542 {
3543 if (started)
3544 func (stream, ", ");
3545 started = 1;
3546 func (stream, "%s", arm_regnames[reg]);
3547 }
3548
3549 if (domasklr)
3550 {
3551 if (started)
3552 func (stream, ", ");
3553 started = 1;
3554 func (stream, arm_regnames[14] /* "lr" */);
3555 }
3556
3557 if (domaskpc)
3558 {
3559 if (started)
3560 func (stream, ", ");
3561 func (stream, arm_regnames[15] /* "pc" */);
3562 }
3563
3564 func (stream, "}");
3565 }
3566 break;
3567
3568 case 'W':
3569 /* Print writeback indicator for a LDMIA. We are doing a
3570 writeback if the base register is not in the register
3571 mask. */
3572 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3573 func (stream, "!");
3574 break;
3575
3576 case 'b':
3577 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3578 {
3579 bfd_vma address = (pc + 4
3580 + ((given & 0x00f8) >> 2)
3581 + ((given & 0x0200) >> 3));
3582 info->print_address_func (address, info);
3583 }
3584 break;
3585
3586 case 's':
3587 /* Right shift immediate -- bits 6..10; 1-31 print
3588 as themselves, 0 prints as 32. */
3589 {
3590 long imm = (given & 0x07c0) >> 6;
3591 if (imm == 0)
3592 imm = 32;
3593 func (stream, "#%ld", imm);
3594 }
3595 break;
3596
3597 case '0': case '1': case '2': case '3': case '4':
3598 case '5': case '6': case '7': case '8': case '9':
3599 {
3600 int bitstart = *c++ - '0';
3601 int bitend = 0;
3602
3603 while (*c >= '0' && *c <= '9')
3604 bitstart = (bitstart * 10) + *c++ - '0';
3605
3606 switch (*c)
3607 {
3608 case '-':
3609 {
3610 long reg;
3611
3612 c++;
3613 while (*c >= '0' && *c <= '9')
3614 bitend = (bitend * 10) + *c++ - '0';
3615 if (!bitend)
3616 abort ();
3617 reg = given >> bitstart;
3618 reg &= (2 << (bitend - bitstart)) - 1;
3619
3620 switch (*c)
3621 {
3622 case 'r':
3623 func (stream, "%s", arm_regnames[reg]);
3624 break;
3625
3626 case 'd':
3627 func (stream, "%ld", reg);
3628 value_in_comment = reg;
3629 break;
3630
3631 case 'H':
3632 func (stream, "%ld", reg << 1);
3633 value_in_comment = reg << 1;
3634 break;
3635
3636 case 'W':
3637 func (stream, "%ld", reg << 2);
3638 value_in_comment = reg << 2;
3639 break;
3640
3641 case 'a':
3642 /* PC-relative address -- the bottom two
3643 bits of the address are dropped
3644 before the calculation. */
3645 info->print_address_func
3646 (((pc + 4) & ~3) + (reg << 2), info);
3647 value_in_comment = 0;
3648 break;
3649
3650 case 'x':
3651 func (stream, "0x%04lx", reg);
3652 break;
3653
3654 case 'B':
3655 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3656 info->print_address_func (reg * 2 + pc + 4, info);
3657 value_in_comment = 0;
3658 break;
3659
3660 case 'c':
3661 func (stream, "%s", arm_conditional [reg]);
3662 break;
3663
3664 default:
3665 abort ();
3666 }
3667 }
3668 break;
3669
3670 case '\'':
3671 c++;
3672 if ((given & (1 << bitstart)) != 0)
3673 func (stream, "%c", *c);
3674 break;
3675
3676 case '?':
3677 ++c;
3678 if ((given & (1 << bitstart)) != 0)
3679 func (stream, "%c", *c++);
3680 else
3681 func (stream, "%c", *++c);
3682 break;
3683
3684 default:
3685 abort ();
3686 }
3687 }
3688 break;
3689
3690 default:
3691 abort ();
3692 }
3693 }
3694
3695 if (value_in_comment > 32 || value_in_comment < -16)
3696 func (stream, "\t; 0x%lx", value_in_comment);
3697 return;
3698 }
3699
3700 /* No match. */
3701 abort ();
3702 }
3703
3704 /* Return the name of an V7M special register. */
3705
3706 static const char *
3707 psr_name (int regno)
3708 {
3709 switch (regno)
3710 {
3711 case 0: return "APSR";
3712 case 1: return "IAPSR";
3713 case 2: return "EAPSR";
3714 case 3: return "PSR";
3715 case 5: return "IPSR";
3716 case 6: return "EPSR";
3717 case 7: return "IEPSR";
3718 case 8: return "MSP";
3719 case 9: return "PSP";
3720 case 16: return "PRIMASK";
3721 case 17: return "BASEPRI";
3722 case 18: return "BASEPRI_MASK";
3723 case 19: return "FAULTMASK";
3724 case 20: return "CONTROL";
3725 default: return "<unknown>";
3726 }
3727 }
3728
3729 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3730
3731 static void
3732 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3733 {
3734 const struct opcode32 *insn;
3735 void *stream = info->stream;
3736 fprintf_ftype func = info->fprintf_func;
3737
3738 if (print_insn_coprocessor (pc, info, given, TRUE))
3739 return;
3740
3741 if (print_insn_neon (info, given, TRUE))
3742 return;
3743
3744 for (insn = thumb32_opcodes; insn->assembler; insn++)
3745 if ((given & insn->mask) == insn->value)
3746 {
3747 bfd_boolean is_unpredictable = FALSE;
3748 signed long value_in_comment = 0;
3749 const char *c = insn->assembler;
3750
3751 for (; *c; c++)
3752 {
3753 if (*c != '%')
3754 {
3755 func (stream, "%c", *c);
3756 continue;
3757 }
3758
3759 switch (*++c)
3760 {
3761 case '%':
3762 func (stream, "%%");
3763 break;
3764
3765 case 'c':
3766 if (ifthen_state)
3767 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3768 break;
3769
3770 case 'x':
3771 if (ifthen_next_state)
3772 func (stream, "\t; unpredictable branch in IT block\n");
3773 break;
3774
3775 case 'X':
3776 if (ifthen_state)
3777 func (stream, "\t; unpredictable <IT:%s>",
3778 arm_conditional[IFTHEN_COND]);
3779 break;
3780
3781 case 'I':
3782 {
3783 unsigned int imm12 = 0;
3784
3785 imm12 |= (given & 0x000000ffu);
3786 imm12 |= (given & 0x00007000u) >> 4;
3787 imm12 |= (given & 0x04000000u) >> 15;
3788 func (stream, "#%u", imm12);
3789 value_in_comment = imm12;
3790 }
3791 break;
3792
3793 case 'M':
3794 {
3795 unsigned int bits = 0, imm, imm8, mod;
3796
3797 bits |= (given & 0x000000ffu);
3798 bits |= (given & 0x00007000u) >> 4;
3799 bits |= (given & 0x04000000u) >> 15;
3800 imm8 = (bits & 0x0ff);
3801 mod = (bits & 0xf00) >> 8;
3802 switch (mod)
3803 {
3804 case 0: imm = imm8; break;
3805 case 1: imm = ((imm8 << 16) | imm8); break;
3806 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3807 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3808 default:
3809 mod = (bits & 0xf80) >> 7;
3810 imm8 = (bits & 0x07f) | 0x80;
3811 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3812 }
3813 func (stream, "#%u", imm);
3814 value_in_comment = imm;
3815 }
3816 break;
3817
3818 case 'J':
3819 {
3820 unsigned int imm = 0;
3821
3822 imm |= (given & 0x000000ffu);
3823 imm |= (given & 0x00007000u) >> 4;
3824 imm |= (given & 0x04000000u) >> 15;
3825 imm |= (given & 0x000f0000u) >> 4;
3826 func (stream, "#%u", imm);
3827 value_in_comment = imm;
3828 }
3829 break;
3830
3831 case 'K':
3832 {
3833 unsigned int imm = 0;
3834
3835 imm |= (given & 0x000f0000u) >> 16;
3836 imm |= (given & 0x00000ff0u) >> 0;
3837 imm |= (given & 0x0000000fu) << 12;
3838 func (stream, "#%u", imm);
3839 value_in_comment = imm;
3840 }
3841 break;
3842
3843 case 'V':
3844 {
3845 unsigned int imm = 0;
3846
3847 imm |= (given & 0x00000fffu);
3848 imm |= (given & 0x000f0000u) >> 4;
3849 func (stream, "#%u", imm);
3850 value_in_comment = imm;
3851 }
3852 break;
3853
3854 case 'S':
3855 {
3856 unsigned int reg = (given & 0x0000000fu);
3857 unsigned int stp = (given & 0x00000030u) >> 4;
3858 unsigned int imm = 0;
3859 imm |= (given & 0x000000c0u) >> 6;
3860 imm |= (given & 0x00007000u) >> 10;
3861
3862 func (stream, "%s", arm_regnames[reg]);
3863 switch (stp)
3864 {
3865 case 0:
3866 if (imm > 0)
3867 func (stream, ", lsl #%u", imm);
3868 break;
3869
3870 case 1:
3871 if (imm == 0)
3872 imm = 32;
3873 func (stream, ", lsr #%u", imm);
3874 break;
3875
3876 case 2:
3877 if (imm == 0)
3878 imm = 32;
3879 func (stream, ", asr #%u", imm);
3880 break;
3881
3882 case 3:
3883 if (imm == 0)
3884 func (stream, ", rrx");
3885 else
3886 func (stream, ", ror #%u", imm);
3887 }
3888 }
3889 break;
3890
3891 case 'a':
3892 {
3893 unsigned int Rn = (given & 0x000f0000) >> 16;
3894 unsigned int U = ! NEGATIVE_BIT_SET;
3895 unsigned int op = (given & 0x00000f00) >> 8;
3896 unsigned int i12 = (given & 0x00000fff);
3897 unsigned int i8 = (given & 0x000000ff);
3898 bfd_boolean writeback = FALSE, postind = FALSE;
3899 int offset = 0;
3900
3901 func (stream, "[%s", arm_regnames[Rn]);
3902 if (U) /* 12-bit positive immediate offset. */
3903 {
3904 offset = i12;
3905 if (Rn != 15)
3906 value_in_comment = offset;
3907 }
3908 else if (Rn == 15) /* 12-bit negative immediate offset. */
3909 offset = - (int) i12;
3910 else if (op == 0x0) /* Shifted register offset. */
3911 {
3912 unsigned int Rm = (i8 & 0x0f);
3913 unsigned int sh = (i8 & 0x30) >> 4;
3914
3915 func (stream, ", %s", arm_regnames[Rm]);
3916 if (sh)
3917 func (stream, ", lsl #%u", sh);
3918 func (stream, "]");
3919 break;
3920 }
3921 else switch (op)
3922 {
3923 case 0xE: /* 8-bit positive immediate offset. */
3924 offset = i8;
3925 break;
3926
3927 case 0xC: /* 8-bit negative immediate offset. */
3928 offset = -i8;
3929 break;
3930
3931 case 0xF: /* 8-bit + preindex with wb. */
3932 offset = i8;
3933 writeback = TRUE;
3934 break;
3935
3936 case 0xD: /* 8-bit - preindex with wb. */
3937 offset = -i8;
3938 writeback = TRUE;
3939 break;
3940
3941 case 0xB: /* 8-bit + postindex. */
3942 offset = i8;
3943 postind = TRUE;
3944 break;
3945
3946 case 0x9: /* 8-bit - postindex. */
3947 offset = -i8;
3948 postind = TRUE;
3949 break;
3950
3951 default:
3952 func (stream, ", <undefined>]");
3953 goto skip;
3954 }
3955
3956 if (postind)
3957 func (stream, "], #%d", offset);
3958 else
3959 {
3960 if (offset)
3961 func (stream, ", #%d", offset);
3962 func (stream, writeback ? "]!" : "]");
3963 }
3964
3965 if (Rn == 15)
3966 {
3967 func (stream, "\t; ");
3968 info->print_address_func (((pc + 4) & ~3) + offset, info);
3969 }
3970 }
3971 skip:
3972 break;
3973
3974 case 'A':
3975 {
3976 unsigned int U = ! NEGATIVE_BIT_SET;
3977 unsigned int W = WRITEBACK_BIT_SET;
3978 unsigned int Rn = (given & 0x000f0000) >> 16;
3979 unsigned int off = (given & 0x000000ff);
3980
3981 func (stream, "[%s", arm_regnames[Rn]);
3982
3983 if (PRE_BIT_SET)
3984 {
3985 if (off || !U)
3986 {
3987 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3988 value_in_comment = off * 4 * U ? 1 : -1;
3989 }
3990 func (stream, "]");
3991 if (W)
3992 func (stream, "!");
3993 }
3994 else
3995 {
3996 func (stream, "], ");
3997 if (W)
3998 {
3999 func (stream, "#%c%u", U ? '+' : '-', off * 4);
4000 value_in_comment = off * 4 * U ? 1 : -1;
4001 }
4002 else
4003 {
4004 func (stream, "{%u}", off);
4005 value_in_comment = off;
4006 }
4007 }
4008 }
4009 break;
4010
4011 case 'w':
4012 {
4013 unsigned int Sbit = (given & 0x01000000) >> 24;
4014 unsigned int type = (given & 0x00600000) >> 21;
4015
4016 switch (type)
4017 {
4018 case 0: func (stream, Sbit ? "sb" : "b"); break;
4019 case 1: func (stream, Sbit ? "sh" : "h"); break;
4020 case 2:
4021 if (Sbit)
4022 func (stream, "??");
4023 break;
4024 case 3:
4025 func (stream, "??");
4026 break;
4027 }
4028 }
4029 break;
4030
4031 case 'm':
4032 {
4033 int started = 0;
4034 int reg;
4035
4036 func (stream, "{");
4037 for (reg = 0; reg < 16; reg++)
4038 if ((given & (1 << reg)) != 0)
4039 {
4040 if (started)
4041 func (stream, ", ");
4042 started = 1;
4043 func (stream, "%s", arm_regnames[reg]);
4044 }
4045 func (stream, "}");
4046 }
4047 break;
4048
4049 case 'E':
4050 {
4051 unsigned int msb = (given & 0x0000001f);
4052 unsigned int lsb = 0;
4053
4054 lsb |= (given & 0x000000c0u) >> 6;
4055 lsb |= (given & 0x00007000u) >> 10;
4056 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4057 }
4058 break;
4059
4060 case 'F':
4061 {
4062 unsigned int width = (given & 0x0000001f) + 1;
4063 unsigned int lsb = 0;
4064
4065 lsb |= (given & 0x000000c0u) >> 6;
4066 lsb |= (given & 0x00007000u) >> 10;
4067 func (stream, "#%u, #%u", lsb, width);
4068 }
4069 break;
4070
4071 case 'b':
4072 {
4073 unsigned int S = (given & 0x04000000u) >> 26;
4074 unsigned int J1 = (given & 0x00002000u) >> 13;
4075 unsigned int J2 = (given & 0x00000800u) >> 11;
4076 int offset = 0;
4077
4078 offset |= !S << 20;
4079 offset |= J2 << 19;
4080 offset |= J1 << 18;
4081 offset |= (given & 0x003f0000) >> 4;
4082 offset |= (given & 0x000007ff) << 1;
4083 offset -= (1 << 20);
4084
4085 info->print_address_func (pc + 4 + offset, info);
4086 }
4087 break;
4088
4089 case 'B':
4090 {
4091 unsigned int S = (given & 0x04000000u) >> 26;
4092 unsigned int I1 = (given & 0x00002000u) >> 13;
4093 unsigned int I2 = (given & 0x00000800u) >> 11;
4094 int offset = 0;
4095
4096 offset |= !S << 24;
4097 offset |= !(I1 ^ S) << 23;
4098 offset |= !(I2 ^ S) << 22;
4099 offset |= (given & 0x03ff0000u) >> 4;
4100 offset |= (given & 0x000007ffu) << 1;
4101 offset -= (1 << 24);
4102 offset += pc + 4;
4103
4104 /* BLX target addresses are always word aligned. */
4105 if ((given & 0x00001000u) == 0)
4106 offset &= ~2u;
4107
4108 info->print_address_func (offset, info);
4109 }
4110 break;
4111
4112 case 's':
4113 {
4114 unsigned int shift = 0;
4115
4116 shift |= (given & 0x000000c0u) >> 6;
4117 shift |= (given & 0x00007000u) >> 10;
4118 if (WRITEBACK_BIT_SET)
4119 func (stream, ", asr #%u", shift);
4120 else if (shift)
4121 func (stream, ", lsl #%u", shift);
4122 /* else print nothing - lsl #0 */
4123 }
4124 break;
4125
4126 case 'R':
4127 {
4128 unsigned int rot = (given & 0x00000030) >> 4;
4129
4130 if (rot)
4131 func (stream, ", ror #%u", rot * 8);
4132 }
4133 break;
4134
4135 case 'U':
4136 if ((given & 0xf0) == 0x60)
4137 {
4138 switch (given & 0xf)
4139 {
4140 case 0xf: func (stream, "sy"); break;
4141 default:
4142 func (stream, "#%d", (int) given & 0xf);
4143 break;
4144 }
4145 }
4146 else
4147 {
4148 switch (given & 0xf)
4149 {
4150 case 0xf: func (stream, "sy"); break;
4151 case 0x7: func (stream, "un"); break;
4152 case 0xe: func (stream, "st"); break;
4153 case 0x6: func (stream, "unst"); break;
4154 case 0xb: func (stream, "ish"); break;
4155 case 0xa: func (stream, "ishst"); break;
4156 case 0x3: func (stream, "osh"); break;
4157 case 0x2: func (stream, "oshst"); break;
4158 default:
4159 func (stream, "#%d", (int) given & 0xf);
4160 break;
4161 }
4162 }
4163 break;
4164
4165 case 'C':
4166 if ((given & 0xff) == 0)
4167 {
4168 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4169 if (given & 0x800)
4170 func (stream, "f");
4171 if (given & 0x400)
4172 func (stream, "s");
4173 if (given & 0x200)
4174 func (stream, "x");
4175 if (given & 0x100)
4176 func (stream, "c");
4177 }
4178 else if ((given & 0x20) == 0x20)
4179 {
4180 char const* name;
4181 unsigned sysm = (given & 0xf00) >> 8;
4182
4183 sysm |= (given & 0x30);
4184 sysm |= (given & 0x00100000) >> 14;
4185 name = banked_regname (sysm);
4186
4187 if (name != NULL)
4188 func (stream, "%s", name);
4189 else
4190 func (stream, "(UNDEF: %lu)", sysm);
4191 }
4192 else
4193 {
4194 func (stream, psr_name (given & 0xff));
4195 }
4196 break;
4197
4198 case 'D':
4199 if (((given & 0xff) == 0)
4200 || ((given & 0x20) == 0x20))
4201 {
4202 char const* name;
4203 unsigned sm = (given & 0xf0000) >> 16;
4204
4205 sm |= (given & 0x30);
4206 sm |= (given & 0x00100000) >> 14;
4207 name = banked_regname (sm);
4208
4209 if (name != NULL)
4210 func (stream, "%s", name);
4211 else
4212 func (stream, "(UNDEF: %lu)", sm);
4213 }
4214 else
4215 func (stream, psr_name (given & 0xff));
4216 break;
4217
4218 case '0': case '1': case '2': case '3': case '4':
4219 case '5': case '6': case '7': case '8': case '9':
4220 {
4221 int width;
4222 unsigned long val;
4223
4224 c = arm_decode_bitfield (c, given, &val, &width);
4225
4226 switch (*c)
4227 {
4228 case 'd':
4229 func (stream, "%lu", val);
4230 value_in_comment = val;
4231 break;
4232
4233 case 'W':
4234 func (stream, "%lu", val * 4);
4235 value_in_comment = val * 4;
4236 break;
4237
4238 case 'R':
4239 if (val == 15)
4240 is_unpredictable = TRUE;
4241 /* Fall through. */
4242 case 'r':
4243 func (stream, "%s", arm_regnames[val]);
4244 break;
4245
4246 case 'c':
4247 func (stream, "%s", arm_conditional[val]);
4248 break;
4249
4250 case '\'':
4251 c++;
4252 if (val == ((1ul << width) - 1))
4253 func (stream, "%c", *c);
4254 break;
4255
4256 case '`':
4257 c++;
4258 if (val == 0)
4259 func (stream, "%c", *c);
4260 break;
4261
4262 case '?':
4263 func (stream, "%c", c[(1 << width) - (int) val]);
4264 c += 1 << width;
4265 break;
4266
4267 case 'x':
4268 func (stream, "0x%lx", val & 0xffffffffUL);
4269 break;
4270
4271 default:
4272 abort ();
4273 }
4274 }
4275 break;
4276
4277 default:
4278 abort ();
4279 }
4280 }
4281
4282 if (value_in_comment > 32 || value_in_comment < -16)
4283 func (stream, "\t; 0x%lx", value_in_comment);
4284
4285 if (is_unpredictable)
4286 func (stream, UNPREDICTABLE_INSTRUCTION);
4287
4288 return;
4289 }
4290
4291 /* No match. */
4292 abort ();
4293 }
4294
4295 /* Print data bytes on INFO->STREAM. */
4296
4297 static void
4298 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4299 struct disassemble_info *info,
4300 long given)
4301 {
4302 switch (info->bytes_per_chunk)
4303 {
4304 case 1:
4305 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4306 break;
4307 case 2:
4308 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4309 break;
4310 case 4:
4311 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4312 break;
4313 default:
4314 abort ();
4315 }
4316 }
4317
4318 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4319 being displayed in symbol relative addresses. */
4320
4321 bfd_boolean
4322 arm_symbol_is_valid (asymbol * sym,
4323 struct disassemble_info * info ATTRIBUTE_UNUSED)
4324 {
4325 const char * name;
4326
4327 if (sym == NULL)
4328 return FALSE;
4329
4330 name = bfd_asymbol_name (sym);
4331
4332 return (name && *name != '$');
4333 }
4334
4335 /* Parse an individual disassembler option. */
4336
4337 void
4338 parse_arm_disassembler_option (char *option)
4339 {
4340 if (option == NULL)
4341 return;
4342
4343 if (CONST_STRNEQ (option, "reg-names-"))
4344 {
4345 int i;
4346
4347 option += 10;
4348
4349 for (i = NUM_ARM_REGNAMES; i--;)
4350 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4351 {
4352 regname_selected = i;
4353 break;
4354 }
4355
4356 if (i < 0)
4357 /* XXX - should break 'option' at following delimiter. */
4358 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4359 }
4360 else if (CONST_STRNEQ (option, "force-thumb"))
4361 force_thumb = 1;
4362 else if (CONST_STRNEQ (option, "no-force-thumb"))
4363 force_thumb = 0;
4364 else
4365 /* XXX - should break 'option' at following delimiter. */
4366 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4367
4368 return;
4369 }
4370
4371 /* Parse the string of disassembler options, spliting it at whitespaces
4372 or commas. (Whitespace separators supported for backwards compatibility). */
4373
4374 static void
4375 parse_disassembler_options (char *options)
4376 {
4377 if (options == NULL)
4378 return;
4379
4380 while (*options)
4381 {
4382 parse_arm_disassembler_option (options);
4383
4384 /* Skip forward to next seperator. */
4385 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4386 ++ options;
4387 /* Skip forward past seperators. */
4388 while (ISSPACE (*options) || (*options == ','))
4389 ++ options;
4390 }
4391 }
4392
4393 /* Search back through the insn stream to determine if this instruction is
4394 conditionally executed. */
4395
4396 static void
4397 find_ifthen_state (bfd_vma pc,
4398 struct disassemble_info *info,
4399 bfd_boolean little)
4400 {
4401 unsigned char b[2];
4402 unsigned int insn;
4403 int status;
4404 /* COUNT is twice the number of instructions seen. It will be odd if we
4405 just crossed an instruction boundary. */
4406 int count;
4407 int it_count;
4408 unsigned int seen_it;
4409 bfd_vma addr;
4410
4411 ifthen_address = pc;
4412 ifthen_state = 0;
4413
4414 addr = pc;
4415 count = 1;
4416 it_count = 0;
4417 seen_it = 0;
4418 /* Scan backwards looking for IT instructions, keeping track of where
4419 instruction boundaries are. We don't know if something is actually an
4420 IT instruction until we find a definite instruction boundary. */
4421 for (;;)
4422 {
4423 if (addr == 0 || info->symbol_at_address_func (addr, info))
4424 {
4425 /* A symbol must be on an instruction boundary, and will not
4426 be within an IT block. */
4427 if (seen_it && (count & 1))
4428 break;
4429
4430 return;
4431 }
4432 addr -= 2;
4433 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4434 if (status)
4435 return;
4436
4437 if (little)
4438 insn = (b[0]) | (b[1] << 8);
4439 else
4440 insn = (b[1]) | (b[0] << 8);
4441 if (seen_it)
4442 {
4443 if ((insn & 0xf800) < 0xe800)
4444 {
4445 /* Addr + 2 is an instruction boundary. See if this matches
4446 the expected boundary based on the position of the last
4447 IT candidate. */
4448 if (count & 1)
4449 break;
4450 seen_it = 0;
4451 }
4452 }
4453 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4454 {
4455 /* This could be an IT instruction. */
4456 seen_it = insn;
4457 it_count = count >> 1;
4458 }
4459 if ((insn & 0xf800) >= 0xe800)
4460 count++;
4461 else
4462 count = (count + 2) | 1;
4463 /* IT blocks contain at most 4 instructions. */
4464 if (count >= 8 && !seen_it)
4465 return;
4466 }
4467 /* We found an IT instruction. */
4468 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4469 if ((ifthen_state & 0xf) == 0)
4470 ifthen_state = 0;
4471 }
4472
4473 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4474 mapping symbol. */
4475
4476 static int
4477 is_mapping_symbol (struct disassemble_info *info, int n,
4478 enum map_type *map_type)
4479 {
4480 const char *name;
4481
4482 name = bfd_asymbol_name (info->symtab[n]);
4483 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4484 && (name[2] == 0 || name[2] == '.'))
4485 {
4486 *map_type = ((name[1] == 'a') ? MAP_ARM
4487 : (name[1] == 't') ? MAP_THUMB
4488 : MAP_DATA);
4489 return TRUE;
4490 }
4491
4492 return FALSE;
4493 }
4494
4495 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4496 Returns nonzero if *MAP_TYPE was set. */
4497
4498 static int
4499 get_map_sym_type (struct disassemble_info *info,
4500 int n,
4501 enum map_type *map_type)
4502 {
4503 /* If the symbol is in a different section, ignore it. */
4504 if (info->section != NULL && info->section != info->symtab[n]->section)
4505 return FALSE;
4506
4507 return is_mapping_symbol (info, n, map_type);
4508 }
4509
4510 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4511 Returns nonzero if *MAP_TYPE was set. */
4512
4513 static int
4514 get_sym_code_type (struct disassemble_info *info,
4515 int n,
4516 enum map_type *map_type)
4517 {
4518 elf_symbol_type *es;
4519 unsigned int type;
4520
4521 /* If the symbol is in a different section, ignore it. */
4522 if (info->section != NULL && info->section != info->symtab[n]->section)
4523 return FALSE;
4524
4525 es = *(elf_symbol_type **)(info->symtab + n);
4526 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4527
4528 /* If the symbol has function type then use that. */
4529 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4530 {
4531 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4532 *map_type = MAP_THUMB;
4533 else
4534 *map_type = MAP_ARM;
4535 return TRUE;
4536 }
4537
4538 return FALSE;
4539 }
4540
4541 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4542 of the supplied arm_feature_set structure with bitmasks indicating
4543 the support base architectures and coprocessor extensions.
4544
4545 FIXME: This could more efficiently implemented as a constant array,
4546 although it would also be less robust. */
4547
4548 static void
4549 select_arm_features (unsigned long mach,
4550 arm_feature_set * features)
4551 {
4552 #undef ARM_FEATURE
4553 #define ARM_FEATURE(ARCH,CEXT) \
4554 features->core = (ARCH); \
4555 features->coproc = (CEXT) | FPU_FPA; \
4556 return
4557
4558 switch (mach)
4559 {
4560 case bfd_mach_arm_2: ARM_ARCH_V2;
4561 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4562 case bfd_mach_arm_3: ARM_ARCH_V3;
4563 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4564 case bfd_mach_arm_4: ARM_ARCH_V4;
4565 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4566 case bfd_mach_arm_5: ARM_ARCH_V5;
4567 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4568 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4569 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4570 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4571 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4572 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4573 /* If the machine type is unknown allow all
4574 architecture types and all extensions. */
4575 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4576 default:
4577 abort ();
4578 }
4579 }
4580
4581
4582 /* NOTE: There are no checks in these routines that
4583 the relevant number of data bytes exist. */
4584
4585 static int
4586 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4587 {
4588 unsigned char b[4];
4589 long given;
4590 int status;
4591 int is_thumb = FALSE;
4592 int is_data = FALSE;
4593 int little_code;
4594 unsigned int size = 4;
4595 void (*printer) (bfd_vma, struct disassemble_info *, long);
4596 bfd_boolean found = FALSE;
4597 struct arm_private_data *private_data;
4598
4599 if (info->disassembler_options)
4600 {
4601 parse_disassembler_options (info->disassembler_options);
4602
4603 /* To avoid repeated parsing of these options, we remove them here. */
4604 info->disassembler_options = NULL;
4605 }
4606
4607 /* PR 10288: Control which instructions will be disassembled. */
4608 if (info->private_data == NULL)
4609 {
4610 static struct arm_private_data private;
4611
4612 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4613 /* If the user did not use the -m command line switch then default to
4614 disassembling all types of ARM instruction.
4615
4616 The info->mach value has to be ignored as this will be based on
4617 the default archictecture for the target and/or hints in the notes
4618 section, but it will never be greater than the current largest arm
4619 machine value (iWMMXt2), which is only equivalent to the V5TE
4620 architecture. ARM architectures have advanced beyond the machine
4621 value encoding, and these newer architectures would be ignored if
4622 the machine value was used.
4623
4624 Ie the -m switch is used to restrict which instructions will be
4625 disassembled. If it is necessary to use the -m switch to tell
4626 objdump that an ARM binary is being disassembled, eg because the
4627 input is a raw binary file, but it is also desired to disassemble
4628 all ARM instructions then use "-marm". This will select the
4629 "unknown" arm architecture which is compatible with any ARM
4630 instruction. */
4631 info->mach = bfd_mach_arm_unknown;
4632
4633 /* Compute the architecture bitmask from the machine number.
4634 Note: This assumes that the machine number will not change
4635 during disassembly.... */
4636 select_arm_features (info->mach, & private.features);
4637
4638 private.has_mapping_symbols = -1;
4639
4640 info->private_data = & private;
4641 }
4642
4643 private_data = info->private_data;
4644
4645 /* Decide if our code is going to be little-endian, despite what the
4646 function argument might say. */
4647 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4648
4649 /* For ELF, consult the symbol table to determine what kind of code
4650 or data we have. */
4651 if (info->symtab_size != 0
4652 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4653 {
4654 bfd_vma addr;
4655 int n, start;
4656 int last_sym = -1;
4657 enum map_type type = MAP_ARM;
4658
4659 /* Start scanning at the start of the function, or wherever
4660 we finished last time. */
4661 start = info->symtab_pos + 1;
4662 if (start < last_mapping_sym)
4663 start = last_mapping_sym;
4664 found = FALSE;
4665
4666 /* First, look for mapping symbols. */
4667 if (private_data->has_mapping_symbols != 0)
4668 {
4669 /* Scan up to the location being disassembled. */
4670 for (n = start; n < info->symtab_size; n++)
4671 {
4672 addr = bfd_asymbol_value (info->symtab[n]);
4673 if (addr > pc)
4674 break;
4675 if (get_map_sym_type (info, n, &type))
4676 {
4677 last_sym = n;
4678 found = TRUE;
4679 }
4680 }
4681
4682 if (!found)
4683 {
4684 /* No mapping symbol found at this address. Look backwards
4685 for a preceeding one. */
4686 for (n = start - 1; n >= 0; n--)
4687 {
4688 if (get_map_sym_type (info, n, &type))
4689 {
4690 last_sym = n;
4691 found = TRUE;
4692 break;
4693 }
4694 }
4695 }
4696
4697 if (found)
4698 private_data->has_mapping_symbols = 1;
4699
4700 /* No mapping symbols were found. A leading $d may be
4701 omitted for sections which start with data; but for
4702 compatibility with legacy and stripped binaries, only
4703 assume the leading $d if there is at least one mapping
4704 symbol in the file. */
4705 if (!found && private_data->has_mapping_symbols == -1)
4706 {
4707 /* Look for mapping symbols, in any section. */
4708 for (n = 0; n < info->symtab_size; n++)
4709 if (is_mapping_symbol (info, n, &type))
4710 {
4711 private_data->has_mapping_symbols = 1;
4712 break;
4713 }
4714 if (private_data->has_mapping_symbols == -1)
4715 private_data->has_mapping_symbols = 0;
4716 }
4717
4718 if (!found && private_data->has_mapping_symbols == 1)
4719 {
4720 type = MAP_DATA;
4721 found = TRUE;
4722 }
4723 }
4724
4725 /* Next search for function symbols to separate ARM from Thumb
4726 in binaries without mapping symbols. */
4727 if (!found)
4728 {
4729 /* Scan up to the location being disassembled. */
4730 for (n = start; n < info->symtab_size; n++)
4731 {
4732 addr = bfd_asymbol_value (info->symtab[n]);
4733 if (addr > pc)
4734 break;
4735 if (get_sym_code_type (info, n, &type))
4736 {
4737 last_sym = n;
4738 found = TRUE;
4739 }
4740 }
4741
4742 if (!found)
4743 {
4744 /* No mapping symbol found at this address. Look backwards
4745 for a preceeding one. */
4746 for (n = start - 1; n >= 0; n--)
4747 {
4748 if (get_sym_code_type (info, n, &type))
4749 {
4750 last_sym = n;
4751 found = TRUE;
4752 break;
4753 }
4754 }
4755 }
4756 }
4757
4758 last_mapping_sym = last_sym;
4759 last_type = type;
4760 is_thumb = (last_type == MAP_THUMB);
4761 is_data = (last_type == MAP_DATA);
4762
4763 /* Look a little bit ahead to see if we should print out
4764 two or four bytes of data. If there's a symbol,
4765 mapping or otherwise, after two bytes then don't
4766 print more. */
4767 if (is_data)
4768 {
4769 size = 4 - (pc & 3);
4770 for (n = last_sym + 1; n < info->symtab_size; n++)
4771 {
4772 addr = bfd_asymbol_value (info->symtab[n]);
4773 if (addr > pc
4774 && (info->section == NULL
4775 || info->section == info->symtab[n]->section))
4776 {
4777 if (addr - pc < size)
4778 size = addr - pc;
4779 break;
4780 }
4781 }
4782 /* If the next symbol is after three bytes, we need to
4783 print only part of the data, so that we can use either
4784 .byte or .short. */
4785 if (size == 3)
4786 size = (pc & 1) ? 1 : 2;
4787 }
4788 }
4789
4790 if (info->symbols != NULL)
4791 {
4792 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4793 {
4794 coff_symbol_type * cs;
4795
4796 cs = coffsymbol (*info->symbols);
4797 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4798 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4799 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4800 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4801 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4802 }
4803 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4804 && !found)
4805 {
4806 /* If no mapping symbol has been found then fall back to the type
4807 of the function symbol. */
4808 elf_symbol_type * es;
4809 unsigned int type;
4810
4811 es = *(elf_symbol_type **)(info->symbols);
4812 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4813
4814 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
4815 == ST_BRANCH_TO_THUMB)
4816 || type == STT_ARM_16BIT);
4817 }
4818 }
4819
4820 if (force_thumb)
4821 is_thumb = TRUE;
4822
4823 if (is_data)
4824 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4825 else
4826 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4827
4828 info->bytes_per_line = 4;
4829
4830 /* PR 10263: Disassemble data if requested to do so by the user. */
4831 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4832 {
4833 int i;
4834
4835 /* Size was already set above. */
4836 info->bytes_per_chunk = size;
4837 printer = print_insn_data;
4838
4839 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4840 given = 0;
4841 if (little)
4842 for (i = size - 1; i >= 0; i--)
4843 given = b[i] | (given << 8);
4844 else
4845 for (i = 0; i < (int) size; i++)
4846 given = b[i] | (given << 8);
4847 }
4848 else if (!is_thumb)
4849 {
4850 /* In ARM mode endianness is a straightforward issue: the instruction
4851 is four bytes long and is either ordered 0123 or 3210. */
4852 printer = print_insn_arm;
4853 info->bytes_per_chunk = 4;
4854 size = 4;
4855
4856 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4857 if (little_code)
4858 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4859 else
4860 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4861 }
4862 else
4863 {
4864 /* In Thumb mode we have the additional wrinkle of two
4865 instruction lengths. Fortunately, the bits that determine
4866 the length of the current instruction are always to be found
4867 in the first two bytes. */
4868 printer = print_insn_thumb16;
4869 info->bytes_per_chunk = 2;
4870 size = 2;
4871
4872 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4873 if (little_code)
4874 given = (b[0]) | (b[1] << 8);
4875 else
4876 given = (b[1]) | (b[0] << 8);
4877
4878 if (!status)
4879 {
4880 /* These bit patterns signal a four-byte Thumb
4881 instruction. */
4882 if ((given & 0xF800) == 0xF800
4883 || (given & 0xF800) == 0xF000
4884 || (given & 0xF800) == 0xE800)
4885 {
4886 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4887 if (little_code)
4888 given = (b[0]) | (b[1] << 8) | (given << 16);
4889 else
4890 given = (b[1]) | (b[0] << 8) | (given << 16);
4891
4892 printer = print_insn_thumb32;
4893 size = 4;
4894 }
4895 }
4896
4897 if (ifthen_address != pc)
4898 find_ifthen_state (pc, info, little_code);
4899
4900 if (ifthen_state)
4901 {
4902 if ((ifthen_state & 0xf) == 0x8)
4903 ifthen_next_state = 0;
4904 else
4905 ifthen_next_state = (ifthen_state & 0xe0)
4906 | ((ifthen_state & 0xf) << 1);
4907 }
4908 }
4909
4910 if (status)
4911 {
4912 info->memory_error_func (status, pc, info);
4913 return -1;
4914 }
4915 if (info->flags & INSN_HAS_RELOC)
4916 /* If the instruction has a reloc associated with it, then
4917 the offset field in the instruction will actually be the
4918 addend for the reloc. (We are using REL type relocs).
4919 In such cases, we can ignore the pc when computing
4920 addresses, since the addend is not currently pc-relative. */
4921 pc = 0;
4922
4923 printer (pc, info, given);
4924
4925 if (is_thumb)
4926 {
4927 ifthen_state = ifthen_next_state;
4928 ifthen_address += size;
4929 }
4930 return size;
4931 }
4932
4933 int
4934 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4935 {
4936 /* Detect BE8-ness and record it in the disassembler info. */
4937 if (info->flavour == bfd_target_elf_flavour
4938 && info->section != NULL
4939 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4940 info->endian_code = BFD_ENDIAN_LITTLE;
4941
4942 return print_insn (pc, info, FALSE);
4943 }
4944
4945 int
4946 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4947 {
4948 return print_insn (pc, info, TRUE);
4949 }
4950
4951 void
4952 print_arm_disassembler_options (FILE *stream)
4953 {
4954 int i;
4955
4956 fprintf (stream, _("\n\
4957 The following ARM specific disassembler options are supported for use with\n\
4958 the -M switch:\n"));
4959
4960 for (i = NUM_ARM_REGNAMES; i--;)
4961 fprintf (stream, " reg-names-%s %*c%s\n",
4962 regnames[i].name,
4963 (int)(14 - strlen (regnames[i].name)), ' ',
4964 regnames[i].description);
4965
4966 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4967 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
4968 }
4969