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