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