gas: blackfin: fix DBG/DBGCMPLX insn encoding
[binutils.git] / opcodes / arm-dis.c
blob831b26c909da04c261c6b416422fb331e67595bf
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. */
821 static const struct opcode32 arm_opcodes[] =
823 /* ARM instructions. */
824 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
825 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
826 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
827 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
828 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
829 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
830 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
832 /* V7 instructions. */
833 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
834 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
835 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
836 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
837 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
839 /* ARM V6T2 instructions. */
840 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
841 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
842 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
843 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
845 {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
846 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
848 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
849 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
850 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
851 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
853 /* ARM V6Z instructions. */
854 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
856 /* ARM V6K instructions. */
857 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
858 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
859 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
860 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
861 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
862 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
863 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
865 /* ARM V6K NOP hints. */
866 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
867 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
868 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
869 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
870 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
872 /* ARM V6 instructions. */
873 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
874 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
875 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
876 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
877 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
878 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
879 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
880 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
881 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
882 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
883 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
884 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
885 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
886 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
887 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
888 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
889 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
890 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
891 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
892 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
893 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
894 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
895 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
896 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
897 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
898 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
899 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
900 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
901 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
902 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
903 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
904 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
905 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
906 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
907 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
908 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
909 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
910 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
911 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
920 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
921 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
922 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
923 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
924 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
925 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
926 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
927 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
928 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
929 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
930 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
931 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
932 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
933 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
934 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
935 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
936 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
937 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
938 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
939 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
940 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
941 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
942 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
943 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
944 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
945 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
946 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
947 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
948 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
949 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
950 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
951 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
952 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
953 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
954 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
955 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
956 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
957 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
958 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
959 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
960 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
961 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
962 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
963 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
964 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
965 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
966 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
967 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
968 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
969 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
970 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
971 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
972 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
973 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
974 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
975 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
976 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
977 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
978 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
979 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
980 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
981 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
982 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
983 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
984 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
985 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
986 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
987 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
988 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
989 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
990 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
991 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
992 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
993 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
994 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
996 /* V5J instruction. */
997 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
999 /* V5 Instructions. */
1000 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1001 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
1002 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1003 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1005 /* V5E "El Segundo" Instructions. */
1006 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1007 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1008 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
1009 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1010 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1011 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1012 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1014 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1015 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1017 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1018 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1019 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1020 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1022 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1023 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1024 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1025 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1027 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1028 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1030 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1031 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1032 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1033 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1035 /* ARM Instructions. */
1036 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1038 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1039 {ARM_EXT_V1, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1040 {ARM_EXT_V1, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1041 {ARM_EXT_V1, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1042 {ARM_EXT_V1, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1043 {ARM_EXT_V1, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1045 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1046 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1047 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1048 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1050 {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
1051 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1052 {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
1053 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1055 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1056 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1057 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1059 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1060 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1061 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1063 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1064 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1065 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1067 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1068 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1069 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1071 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1072 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1073 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1075 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1076 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1077 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1079 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1081 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1083 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1085 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1087 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1088 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15R, %22?SCPSR"},
1090 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1091 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1092 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1094 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1095 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1096 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1098 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1099 {ARM_EXT_V3, 0x01400000, 0x0ff00010, "mrs%c\t%12-15R, %22?SCPSR"},
1100 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1101 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1103 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1104 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1105 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1107 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1108 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1109 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1111 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1112 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1113 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1114 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1115 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1116 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1117 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1119 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1120 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1121 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1123 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1124 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1125 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1127 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1128 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1130 {ARM_EXT_V1, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1132 {ARM_EXT_V1, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1133 {ARM_EXT_V1, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1135 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1136 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1137 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1138 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1139 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1140 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1141 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1142 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1144 /* The rest. */
1145 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1146 {0, 0x00000000, 0x00000000, 0}
1149 /* print_insn_thumb16 recognizes the following format control codes:
1151 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1152 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1153 %<bitfield>I print bitfield as a signed decimal
1154 (top bit of range being the sign bit)
1155 %N print Thumb register mask (with LR)
1156 %O print Thumb register mask (with PC)
1157 %M print Thumb register mask
1158 %b print CZB's 6-bit unsigned branch destination
1159 %s print Thumb right-shift immediate (6..10; 0 == 32).
1160 %c print the condition code
1161 %C print the condition code, or "s" if not conditional
1162 %x print warning if conditional an not at end of IT block"
1163 %X print "\t; unpredictable <IT:code>" if conditional
1164 %I print IT instruction suffix and operands
1165 %W print Thumb Writeback indicator for LDMIA
1166 %<bitfield>r print bitfield as an ARM register
1167 %<bitfield>d print bitfield as a decimal
1168 %<bitfield>H print (bitfield * 2) as a decimal
1169 %<bitfield>W print (bitfield * 4) as a decimal
1170 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1171 %<bitfield>B print Thumb branch destination (signed displacement)
1172 %<bitfield>c print bitfield as a condition code
1173 %<bitnum>'c print specified char iff bit is one
1174 %<bitnum>?ab print a if bit is one else print b. */
1176 static const struct opcode16 thumb_opcodes[] =
1178 /* Thumb instructions. */
1180 /* ARM V6K no-argument instructions. */
1181 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1182 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1183 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1184 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1185 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1186 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1188 /* ARM V6T2 instructions. */
1189 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1190 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1191 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1193 /* ARM V6. */
1194 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1195 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1196 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1197 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1198 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1199 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1200 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1201 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1202 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1203 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1204 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1206 /* ARM V5 ISA extends Thumb. */
1207 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1208 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1209 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1210 /* ARM V4T ISA (Thumb v1). */
1211 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1212 /* Format 4. */
1213 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1214 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1215 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1216 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1217 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1218 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1219 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1220 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1221 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1222 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1223 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1224 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1225 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1226 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1227 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1228 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1229 /* format 13 */
1230 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1231 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1232 /* format 5 */
1233 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1234 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1235 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1236 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1237 /* format 14 */
1238 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1239 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1240 /* format 2 */
1241 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1242 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1243 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1244 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1245 /* format 8 */
1246 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1247 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1248 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1249 /* format 7 */
1250 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1251 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1252 /* format 1 */
1253 {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1254 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1255 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1256 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1257 /* format 3 */
1258 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1259 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1260 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1261 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1262 /* format 6 */
1263 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1264 /* format 9 */
1265 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1266 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1267 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1268 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1269 /* format 10 */
1270 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1271 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1272 /* format 11 */
1273 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1274 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1275 /* format 12 */
1276 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1277 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1278 /* format 15 */
1279 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1280 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1281 /* format 17 */
1282 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1283 /* format 16 */
1284 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1285 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1286 /* format 18 */
1287 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1289 /* The E800 .. FFFF range is unconditionally redirected to the
1290 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1291 are processed via that table. Thus, we can never encounter a
1292 bare "second half of BL/BLX(1)" instruction here. */
1293 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1294 {0, 0, 0, 0}
1297 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1298 We adopt the convention that hw1 is the high 16 bits of .value and
1299 .mask, hw2 the low 16 bits.
1301 print_insn_thumb32 recognizes the following format control codes:
1303 %% %
1305 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1306 %M print a modified 12-bit immediate (same location)
1307 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1308 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1309 %S print a possibly-shifted Rm
1311 %a print the address of a plain load/store
1312 %w print the width and signedness of a core load/store
1313 %m print register mask for ldm/stm
1315 %E print the lsb and width fields of a bfc/bfi instruction
1316 %F print the lsb and width fields of a sbfx/ubfx instruction
1317 %b print a conditional branch offset
1318 %B print an unconditional branch offset
1319 %s print the shift field of an SSAT instruction
1320 %R print the rotation field of an SXT instruction
1321 %U print barrier type.
1322 %P print address for pli instruction.
1323 %c print the condition code
1324 %x print warning if conditional an not at end of IT block"
1325 %X print "\t; unpredictable <IT:code>" if conditional
1327 %<bitfield>d print bitfield in decimal
1328 %<bitfield>W print bitfield*4 in decimal
1329 %<bitfield>r print bitfield as an ARM register
1330 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1331 %<bitfield>c print bitfield as a condition code
1333 %<bitfield>'c print specified char iff bitfield is all ones
1334 %<bitfield>`c print specified char iff bitfield is all zeroes
1335 %<bitfield>?ab... select from array of values in big endian order
1337 With one exception at the bottom (done because BL and BLX(1) need
1338 to come dead last), this table was machine-sorted first in
1339 decreasing order of number of bits set in the mask, then in
1340 increasing numeric order of mask, then in increasing numeric order
1341 of opcode. This order is not the clearest for a human reader, but
1342 is guaranteed never to catch a special-case bit pattern with a more
1343 general mask, which is important, because this instruction encoding
1344 makes heavy use of special-case bit patterns. */
1345 static const struct opcode32 thumb32_opcodes[] =
1347 /* V7 instructions. */
1348 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1349 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1350 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1351 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1352 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1353 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1354 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1356 /* Instructions defined in the basic V6T2 set. */
1357 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1358 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1359 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1360 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1361 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1362 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1364 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1365 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1366 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1367 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1368 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1369 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1370 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1371 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1372 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1373 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1374 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1375 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1376 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1377 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1378 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1379 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1380 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1381 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1382 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1383 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1384 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1385 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1386 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1387 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1388 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1389 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1390 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1391 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1397 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1398 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1399 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1400 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1406 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1407 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1408 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1409 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1410 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1413 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1414 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1415 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1416 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1417 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1418 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1420 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1421 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1422 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1423 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1424 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1425 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1426 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1427 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1428 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1429 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1430 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1431 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1432 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1433 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1434 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1439 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1440 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1441 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1442 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1443 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1444 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1445 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1446 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1447 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1448 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1449 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1450 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1451 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1452 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1453 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1454 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1455 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1456 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1457 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1458 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1459 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1460 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1461 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1462 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1463 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1464 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1465 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1466 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1467 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1468 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1469 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1470 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1471 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1472 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1473 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1474 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1475 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1476 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1477 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1478 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1479 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1480 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1481 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1482 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1483 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1484 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1485 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1486 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1487 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1488 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1489 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1490 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1491 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1492 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1493 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1494 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1495 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1496 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1497 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1498 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1499 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1500 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1501 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1502 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1503 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1504 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1505 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1506 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1507 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1508 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1509 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1510 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1511 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1512 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1513 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1514 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1515 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1516 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1517 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1518 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1519 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1520 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1521 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1522 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1523 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1524 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1525 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1526 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1527 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1528 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1529 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1530 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1531 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1532 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1533 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1534 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1535 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1537 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1538 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1539 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1540 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1541 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1543 /* These have been 32-bit since the invention of Thumb. */
1544 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1545 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1547 /* Fallback. */
1548 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1549 {0, 0, 0, 0}
1552 static const char *const arm_conditional[] =
1553 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1554 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1556 static const char *const arm_fp_const[] =
1557 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1559 static const char *const arm_shift[] =
1560 {"lsl", "lsr", "asr", "ror"};
1562 typedef struct
1564 const char *name;
1565 const char *description;
1566 const char *reg_names[16];
1568 arm_regname;
1570 static const arm_regname regnames[] =
1572 { "raw" , "Select raw register names",
1573 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1574 { "gcc", "Select register names used by GCC",
1575 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1576 { "std", "Select register names used in ARM's ISA documentation",
1577 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1578 { "apcs", "Select register names used in the APCS",
1579 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1580 { "atpcs", "Select register names used in the ATPCS",
1581 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1582 { "special-atpcs", "Select special register names used in the ATPCS",
1583 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1586 static const char *const iwmmxt_wwnames[] =
1587 {"b", "h", "w", "d"};
1589 static const char *const iwmmxt_wwssnames[] =
1590 {"b", "bus", "bc", "bss",
1591 "h", "hus", "hc", "hss",
1592 "w", "wus", "wc", "wss",
1593 "d", "dus", "dc", "dss"
1596 static const char *const iwmmxt_regnames[] =
1597 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1598 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1601 static const char *const iwmmxt_cregnames[] =
1602 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1603 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1606 /* Default to GCC register name set. */
1607 static unsigned int regname_selected = 1;
1609 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1610 #define arm_regnames regnames[regname_selected].reg_names
1612 static bfd_boolean force_thumb = FALSE;
1614 /* Current IT instruction state. This contains the same state as the IT
1615 bits in the CPSR. */
1616 static unsigned int ifthen_state;
1617 /* IT state for the next instruction. */
1618 static unsigned int ifthen_next_state;
1619 /* The address of the insn for which the IT state is valid. */
1620 static bfd_vma ifthen_address;
1621 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1623 /* Cached mapping symbol state. */
1624 enum map_type
1626 MAP_ARM,
1627 MAP_THUMB,
1628 MAP_DATA
1631 enum map_type last_type;
1632 int last_mapping_sym = -1;
1633 bfd_vma last_mapping_addr = 0;
1636 /* Functions. */
1638 get_arm_regname_num_options (void)
1640 return NUM_ARM_REGNAMES;
1644 set_arm_regname_option (int option)
1646 int old = regname_selected;
1647 regname_selected = option;
1648 return old;
1652 get_arm_regnames (int option,
1653 const char **setname,
1654 const char **setdescription,
1655 const char *const **register_names)
1657 *setname = regnames[option].name;
1658 *setdescription = regnames[option].description;
1659 *register_names = regnames[option].reg_names;
1660 return 16;
1663 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1664 Returns pointer to following character of the format string and
1665 fills in *VALUEP and *WIDTHP with the extracted value and number of
1666 bits extracted. WIDTHP can be NULL. */
1668 static const char *
1669 arm_decode_bitfield (const char *ptr,
1670 unsigned long insn,
1671 unsigned long *valuep,
1672 int *widthp)
1674 unsigned long value = 0;
1675 int width = 0;
1679 int start, end;
1680 int bits;
1682 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1683 start = start * 10 + *ptr - '0';
1684 if (*ptr == '-')
1685 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1686 end = end * 10 + *ptr - '0';
1687 else
1688 end = start;
1689 bits = end - start;
1690 if (bits < 0)
1691 abort ();
1692 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1693 width += bits + 1;
1695 while (*ptr++ == ',');
1696 *valuep = value;
1697 if (widthp)
1698 *widthp = width;
1699 return ptr - 1;
1702 static void
1703 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1704 bfd_boolean print_shift)
1706 func (stream, "%s", arm_regnames[given & 0xf]);
1708 if ((given & 0xff0) != 0)
1710 if ((given & 0x10) == 0)
1712 int amount = (given & 0xf80) >> 7;
1713 int shift = (given & 0x60) >> 5;
1715 if (amount == 0)
1717 if (shift == 3)
1719 func (stream, ", rrx");
1720 return;
1723 amount = 32;
1726 if (print_shift)
1727 func (stream, ", %s #%d", arm_shift[shift], amount);
1728 else
1729 func (stream, ", #%d", amount);
1731 else if ((given & 0x80) == 0x80)
1732 func (stream, "\t; <illegal shifter operand>");
1733 else if (print_shift)
1734 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1735 arm_regnames[(given & 0xf00) >> 8]);
1736 else
1737 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1741 #define W_BIT 21
1742 #define I_BIT 22
1743 #define U_BIT 23
1744 #define P_BIT 24
1746 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1747 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1748 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1749 #define PRE_BIT_SET (given & (1 << P_BIT))
1751 /* Print one coprocessor instruction on INFO->STREAM.
1752 Return TRUE if the instuction matched, FALSE if this is not a
1753 recognised coprocessor instruction. */
1755 static bfd_boolean
1756 print_insn_coprocessor (bfd_vma pc,
1757 struct disassemble_info *info,
1758 long given,
1759 bfd_boolean thumb)
1761 const struct opcode32 *insn;
1762 void *stream = info->stream;
1763 fprintf_ftype func = info->fprintf_func;
1764 unsigned long mask;
1765 unsigned long value = 0;
1766 struct arm_private_data *private_data = info->private_data;
1767 unsigned long allowed_arches = private_data->features.coproc;
1768 int cond;
1770 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1772 unsigned long u_reg = 16;
1773 bfd_boolean is_unpredictable = FALSE;
1774 signed long value_in_comment = 0;
1775 const char *c;
1777 if (insn->arch == 0)
1778 switch (insn->value)
1780 case SENTINEL_IWMMXT_START:
1781 if (info->mach != bfd_mach_arm_XScale
1782 && info->mach != bfd_mach_arm_iWMMXt
1783 && info->mach != bfd_mach_arm_iWMMXt2)
1785 insn++;
1786 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1787 continue;
1789 case SENTINEL_IWMMXT_END:
1790 continue;
1792 case SENTINEL_GENERIC_START:
1793 allowed_arches = private_data->features.core;
1794 continue;
1796 default:
1797 abort ();
1800 mask = insn->mask;
1801 value = insn->value;
1802 if (thumb)
1804 /* The high 4 bits are 0xe for Arm conditional instructions, and
1805 0xe for arm unconditional instructions. The rest of the
1806 encoding is the same. */
1807 mask |= 0xf0000000;
1808 value |= 0xe0000000;
1809 if (ifthen_state)
1810 cond = IFTHEN_COND;
1811 else
1812 cond = 16;
1814 else
1816 /* Only match unconditional instuctions against unconditional
1817 patterns. */
1818 if ((given & 0xf0000000) == 0xf0000000)
1820 mask |= 0xf0000000;
1821 cond = 16;
1823 else
1825 cond = (given >> 28) & 0xf;
1826 if (cond == 0xe)
1827 cond = 16;
1831 if ((given & mask) != value)
1832 continue;
1834 if ((insn->arch & allowed_arches) == 0)
1835 continue;
1837 for (c = insn->assembler; *c; c++)
1839 if (*c == '%')
1841 switch (*++c)
1843 case '%':
1844 func (stream, "%%");
1845 break;
1847 case 'A':
1849 int rn = (given >> 16) & 0xf;
1850 int offset = given & 0xff;
1852 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1854 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1856 /* Not unindexed. The offset is scaled. */
1857 offset = offset * 4;
1858 if (NEGATIVE_BIT_SET)
1859 offset = - offset;
1860 if (rn != 15)
1861 value_in_comment = offset;
1864 if (PRE_BIT_SET)
1866 if (offset)
1867 func (stream, ", #%d]%s",
1868 offset,
1869 WRITEBACK_BIT_SET ? "!" : "");
1870 else
1871 func (stream, "]");
1873 else
1875 func (stream, "]");
1877 if (WRITEBACK_BIT_SET)
1879 if (offset)
1880 func (stream, ", #%d", offset);
1882 else
1884 func (stream, ", {%d}", offset);
1885 value_in_comment = offset;
1888 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1890 func (stream, "\t; ");
1891 info->print_address_func (offset + pc
1892 + info->bytes_per_chunk * 2, info);
1895 break;
1897 case 'B':
1899 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1900 int offset = (given >> 1) & 0x3f;
1902 if (offset == 1)
1903 func (stream, "{d%d}", regno);
1904 else if (regno + offset > 32)
1905 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1906 else
1907 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1909 break;
1911 case 'c':
1912 func (stream, "%s", arm_conditional[cond]);
1913 break;
1915 case 'I':
1916 /* Print a Cirrus/DSP shift immediate. */
1917 /* Immediates are 7bit signed ints with bits 0..3 in
1918 bits 0..3 of opcode and bits 4..6 in bits 5..7
1919 of opcode. */
1921 int imm;
1923 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1925 /* Is ``imm'' a negative number? */
1926 if (imm & 0x40)
1927 imm |= (-1 << 7);
1929 func (stream, "%d", imm);
1932 break;
1934 case 'F':
1935 switch (given & 0x00408000)
1937 case 0:
1938 func (stream, "4");
1939 break;
1940 case 0x8000:
1941 func (stream, "1");
1942 break;
1943 case 0x00400000:
1944 func (stream, "2");
1945 break;
1946 default:
1947 func (stream, "3");
1949 break;
1951 case 'P':
1952 switch (given & 0x00080080)
1954 case 0:
1955 func (stream, "s");
1956 break;
1957 case 0x80:
1958 func (stream, "d");
1959 break;
1960 case 0x00080000:
1961 func (stream, "e");
1962 break;
1963 default:
1964 func (stream, _("<illegal precision>"));
1965 break;
1967 break;
1969 case 'Q':
1970 switch (given & 0x00408000)
1972 case 0:
1973 func (stream, "s");
1974 break;
1975 case 0x8000:
1976 func (stream, "d");
1977 break;
1978 case 0x00400000:
1979 func (stream, "e");
1980 break;
1981 default:
1982 func (stream, "p");
1983 break;
1985 break;
1987 case 'R':
1988 switch (given & 0x60)
1990 case 0:
1991 break;
1992 case 0x20:
1993 func (stream, "p");
1994 break;
1995 case 0x40:
1996 func (stream, "m");
1997 break;
1998 default:
1999 func (stream, "z");
2000 break;
2002 break;
2004 case '0': case '1': case '2': case '3': case '4':
2005 case '5': case '6': case '7': case '8': case '9':
2007 int width;
2009 c = arm_decode_bitfield (c, given, &value, &width);
2011 switch (*c)
2013 case 'R':
2014 if (value == 15)
2015 is_unpredictable = TRUE;
2016 /* Fall through. */
2017 case 'r':
2018 if (c[1] == 'u')
2020 /* Eat the 'u' character. */
2021 ++ c;
2023 if (u_reg == value)
2024 is_unpredictable = TRUE;
2025 u_reg = value;
2027 func (stream, "%s", arm_regnames[value]);
2028 break;
2029 case 'D':
2030 func (stream, "d%ld", value);
2031 break;
2032 case 'Q':
2033 if (value & 1)
2034 func (stream, "<illegal reg q%ld.5>", value >> 1);
2035 else
2036 func (stream, "q%ld", value >> 1);
2037 break;
2038 case 'd':
2039 func (stream, "%ld", value);
2040 value_in_comment = value;
2041 break;
2042 case 'k':
2044 int from = (given & (1 << 7)) ? 32 : 16;
2045 func (stream, "%ld", from - value);
2047 break;
2049 case 'f':
2050 if (value > 7)
2051 func (stream, "#%s", arm_fp_const[value & 7]);
2052 else
2053 func (stream, "f%ld", value);
2054 break;
2056 case 'w':
2057 if (width == 2)
2058 func (stream, "%s", iwmmxt_wwnames[value]);
2059 else
2060 func (stream, "%s", iwmmxt_wwssnames[value]);
2061 break;
2063 case 'g':
2064 func (stream, "%s", iwmmxt_regnames[value]);
2065 break;
2066 case 'G':
2067 func (stream, "%s", iwmmxt_cregnames[value]);
2068 break;
2070 case 'x':
2071 func (stream, "0x%lx", (value & 0xffffffffUL));
2072 break;
2074 case '`':
2075 c++;
2076 if (value == 0)
2077 func (stream, "%c", *c);
2078 break;
2079 case '\'':
2080 c++;
2081 if (value == ((1ul << width) - 1))
2082 func (stream, "%c", *c);
2083 break;
2084 case '?':
2085 func (stream, "%c", c[(1 << width) - (int) value]);
2086 c += 1 << width;
2087 break;
2088 default:
2089 abort ();
2091 break;
2093 case 'y':
2094 case 'z':
2096 int single = *c++ == 'y';
2097 int regno;
2099 switch (*c)
2101 case '4': /* Sm pair */
2102 case '0': /* Sm, Dm */
2103 regno = given & 0x0000000f;
2104 if (single)
2106 regno <<= 1;
2107 regno += (given >> 5) & 1;
2109 else
2110 regno += ((given >> 5) & 1) << 4;
2111 break;
2113 case '1': /* Sd, Dd */
2114 regno = (given >> 12) & 0x0000000f;
2115 if (single)
2117 regno <<= 1;
2118 regno += (given >> 22) & 1;
2120 else
2121 regno += ((given >> 22) & 1) << 4;
2122 break;
2124 case '2': /* Sn, Dn */
2125 regno = (given >> 16) & 0x0000000f;
2126 if (single)
2128 regno <<= 1;
2129 regno += (given >> 7) & 1;
2131 else
2132 regno += ((given >> 7) & 1) << 4;
2133 break;
2135 case '3': /* List */
2136 func (stream, "{");
2137 regno = (given >> 12) & 0x0000000f;
2138 if (single)
2140 regno <<= 1;
2141 regno += (given >> 22) & 1;
2143 else
2144 regno += ((given >> 22) & 1) << 4;
2145 break;
2147 default:
2148 abort ();
2151 func (stream, "%c%d", single ? 's' : 'd', regno);
2153 if (*c == '3')
2155 int count = given & 0xff;
2157 if (single == 0)
2158 count >>= 1;
2160 if (--count)
2162 func (stream, "-%c%d",
2163 single ? 's' : 'd',
2164 regno + count);
2167 func (stream, "}");
2169 else if (*c == '4')
2170 func (stream, ", %c%d", single ? 's' : 'd',
2171 regno + 1);
2173 break;
2175 case 'L':
2176 switch (given & 0x00400100)
2178 case 0x00000000: func (stream, "b"); break;
2179 case 0x00400000: func (stream, "h"); break;
2180 case 0x00000100: func (stream, "w"); break;
2181 case 0x00400100: func (stream, "d"); break;
2182 default:
2183 break;
2185 break;
2187 case 'Z':
2189 /* given (20, 23) | given (0, 3) */
2190 value = ((given >> 16) & 0xf0) | (given & 0xf);
2191 func (stream, "%d", value);
2193 break;
2195 case 'l':
2196 /* This is like the 'A' operator, except that if
2197 the width field "M" is zero, then the offset is
2198 *not* multiplied by four. */
2200 int offset = given & 0xff;
2201 int multiplier = (given & 0x00000100) ? 4 : 1;
2203 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2205 if (multiplier > 1)
2207 value_in_comment = offset * multiplier;
2208 if (NEGATIVE_BIT_SET)
2209 value_in_comment = - value_in_comment;
2212 if (offset)
2214 if (PRE_BIT_SET)
2215 func (stream, ", #%s%d]%s",
2216 NEGATIVE_BIT_SET ? "-" : "",
2217 offset * multiplier,
2218 WRITEBACK_BIT_SET ? "!" : "");
2219 else
2220 func (stream, "], #%s%d",
2221 NEGATIVE_BIT_SET ? "-" : "",
2222 offset * multiplier);
2224 else
2225 func (stream, "]");
2227 break;
2229 case 'r':
2231 int imm4 = (given >> 4) & 0xf;
2232 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2233 int ubit = ! NEGATIVE_BIT_SET;
2234 const char *rm = arm_regnames [given & 0xf];
2235 const char *rn = arm_regnames [(given >> 16) & 0xf];
2237 switch (puw_bits)
2239 case 1:
2240 case 3:
2241 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2242 if (imm4)
2243 func (stream, ", lsl #%d", imm4);
2244 break;
2246 case 4:
2247 case 5:
2248 case 6:
2249 case 7:
2250 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2251 if (imm4 > 0)
2252 func (stream, ", lsl #%d", imm4);
2253 func (stream, "]");
2254 if (puw_bits == 5 || puw_bits == 7)
2255 func (stream, "!");
2256 break;
2258 default:
2259 func (stream, "INVALID");
2262 break;
2264 case 'i':
2266 long imm5;
2267 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2268 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2270 break;
2272 default:
2273 abort ();
2277 else
2278 func (stream, "%c", *c);
2281 if (value_in_comment > 32 || value_in_comment < -16)
2282 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2284 if (is_unpredictable)
2285 func (stream, UNPREDICTABLE_INSTRUCTION);
2287 return TRUE;
2289 return FALSE;
2292 /* Decodes and prints ARM addressing modes. Returns the offset
2293 used in the address, if any, if it is worthwhile printing the
2294 offset as a hexadecimal value in a comment at the end of the
2295 line of disassembly. */
2297 static signed long
2298 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2300 void *stream = info->stream;
2301 fprintf_ftype func = info->fprintf_func;
2302 int offset = 0;
2304 if (((given & 0x000f0000) == 0x000f0000)
2305 && ((given & 0x02000000) == 0))
2307 offset = given & 0xfff;
2309 func (stream, "[pc");
2311 if (NEGATIVE_BIT_SET)
2312 offset = - offset;
2314 if (PRE_BIT_SET)
2316 /* Pre-indexed. */
2317 func (stream, ", #%d]", offset);
2319 offset += pc + 8;
2321 /* Cope with the possibility of write-back
2322 being used. Probably a very dangerous thing
2323 for the programmer to do, but who are we to
2324 argue ? */
2325 if (WRITEBACK_BIT_SET)
2326 func (stream, "!");
2328 else /* Post indexed. */
2330 func (stream, "], #%d", offset);
2332 /* Ie ignore the offset. */
2333 offset = pc + 8;
2336 func (stream, "\t; ");
2337 info->print_address_func (offset, info);
2338 offset = 0;
2340 else
2342 func (stream, "[%s",
2343 arm_regnames[(given >> 16) & 0xf]);
2345 if (PRE_BIT_SET)
2347 if ((given & 0x02000000) == 0)
2349 offset = given & 0xfff;
2350 if (offset)
2351 func (stream, ", #%s%d",
2352 NEGATIVE_BIT_SET ? "-" : "", offset);
2354 else
2356 func (stream, ", %s",
2357 NEGATIVE_BIT_SET ? "-" : "");
2358 arm_decode_shift (given, func, stream, TRUE);
2361 func (stream, "]%s",
2362 WRITEBACK_BIT_SET ? "!" : "");
2364 else
2366 if ((given & 0x02000000) == 0)
2368 offset = given & 0xfff;
2369 if (offset)
2370 func (stream, "], #%s%d",
2371 NEGATIVE_BIT_SET ? "-" : "", offset);
2372 else
2373 func (stream, "]");
2375 else
2377 func (stream, "], %s",
2378 NEGATIVE_BIT_SET ? "-" : "");
2379 arm_decode_shift (given, func, stream, TRUE);
2384 return (signed long) offset;
2387 /* Print one neon instruction on INFO->STREAM.
2388 Return TRUE if the instuction matched, FALSE if this is not a
2389 recognised neon instruction. */
2391 static bfd_boolean
2392 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2394 const struct opcode32 *insn;
2395 void *stream = info->stream;
2396 fprintf_ftype func = info->fprintf_func;
2398 if (thumb)
2400 if ((given & 0xef000000) == 0xef000000)
2402 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2403 unsigned long bit28 = given & (1 << 28);
2405 given &= 0x00ffffff;
2406 if (bit28)
2407 given |= 0xf3000000;
2408 else
2409 given |= 0xf2000000;
2411 else if ((given & 0xff000000) == 0xf9000000)
2412 given ^= 0xf9000000 ^ 0xf4000000;
2413 else
2414 return FALSE;
2417 for (insn = neon_opcodes; insn->assembler; insn++)
2419 if ((given & insn->mask) == insn->value)
2421 signed long value_in_comment = 0;
2422 const char *c;
2424 for (c = insn->assembler; *c; c++)
2426 if (*c == '%')
2428 switch (*++c)
2430 case '%':
2431 func (stream, "%%");
2432 break;
2434 case 'c':
2435 if (thumb && ifthen_state)
2436 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2437 break;
2439 case 'A':
2441 static const unsigned char enc[16] =
2443 0x4, 0x14, /* st4 0,1 */
2444 0x4, /* st1 2 */
2445 0x4, /* st2 3 */
2446 0x3, /* st3 4 */
2447 0x13, /* st3 5 */
2448 0x3, /* st1 6 */
2449 0x1, /* st1 7 */
2450 0x2, /* st2 8 */
2451 0x12, /* st2 9 */
2452 0x2, /* st1 10 */
2453 0, 0, 0, 0, 0
2455 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2456 int rn = ((given >> 16) & 0xf);
2457 int rm = ((given >> 0) & 0xf);
2458 int align = ((given >> 4) & 0x3);
2459 int type = ((given >> 8) & 0xf);
2460 int n = enc[type] & 0xf;
2461 int stride = (enc[type] >> 4) + 1;
2462 int ix;
2464 func (stream, "{");
2465 if (stride > 1)
2466 for (ix = 0; ix != n; ix++)
2467 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2468 else if (n == 1)
2469 func (stream, "d%d", rd);
2470 else
2471 func (stream, "d%d-d%d", rd, rd + n - 1);
2472 func (stream, "}, [%s", arm_regnames[rn]);
2473 if (align)
2474 func (stream, " :%d", 32 << align);
2475 func (stream, "]");
2476 if (rm == 0xd)
2477 func (stream, "!");
2478 else if (rm != 0xf)
2479 func (stream, ", %s", arm_regnames[rm]);
2481 break;
2483 case 'B':
2485 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2486 int rn = ((given >> 16) & 0xf);
2487 int rm = ((given >> 0) & 0xf);
2488 int idx_align = ((given >> 4) & 0xf);
2489 int align = 0;
2490 int size = ((given >> 10) & 0x3);
2491 int idx = idx_align >> (size + 1);
2492 int length = ((given >> 8) & 3) + 1;
2493 int stride = 1;
2494 int i;
2496 if (length > 1 && size > 0)
2497 stride = (idx_align & (1 << size)) ? 2 : 1;
2499 switch (length)
2501 case 1:
2503 int amask = (1 << size) - 1;
2504 if ((idx_align & (1 << size)) != 0)
2505 return FALSE;
2506 if (size > 0)
2508 if ((idx_align & amask) == amask)
2509 align = 8 << size;
2510 else if ((idx_align & amask) != 0)
2511 return FALSE;
2514 break;
2516 case 2:
2517 if (size == 2 && (idx_align & 2) != 0)
2518 return FALSE;
2519 align = (idx_align & 1) ? 16 << size : 0;
2520 break;
2522 case 3:
2523 if ((size == 2 && (idx_align & 3) != 0)
2524 || (idx_align & 1) != 0)
2525 return FALSE;
2526 break;
2528 case 4:
2529 if (size == 2)
2531 if ((idx_align & 3) == 3)
2532 return FALSE;
2533 align = (idx_align & 3) * 64;
2535 else
2536 align = (idx_align & 1) ? 32 << size : 0;
2537 break;
2539 default:
2540 abort ();
2543 func (stream, "{");
2544 for (i = 0; i < length; i++)
2545 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2546 rd + i * stride, idx);
2547 func (stream, "}, [%s", arm_regnames[rn]);
2548 if (align)
2549 func (stream, " :%d", align);
2550 func (stream, "]");
2551 if (rm == 0xd)
2552 func (stream, "!");
2553 else if (rm != 0xf)
2554 func (stream, ", %s", arm_regnames[rm]);
2556 break;
2558 case 'C':
2560 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2561 int rn = ((given >> 16) & 0xf);
2562 int rm = ((given >> 0) & 0xf);
2563 int align = ((given >> 4) & 0x1);
2564 int size = ((given >> 6) & 0x3);
2565 int type = ((given >> 8) & 0x3);
2566 int n = type + 1;
2567 int stride = ((given >> 5) & 0x1);
2568 int ix;
2570 if (stride && (n == 1))
2571 n++;
2572 else
2573 stride++;
2575 func (stream, "{");
2576 if (stride > 1)
2577 for (ix = 0; ix != n; ix++)
2578 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2579 else if (n == 1)
2580 func (stream, "d%d[]", rd);
2581 else
2582 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2583 func (stream, "}, [%s", arm_regnames[rn]);
2584 if (align)
2586 align = (8 * (type + 1)) << size;
2587 if (type == 3)
2588 align = (size > 1) ? align >> 1 : align;
2589 if (type == 2 || (type == 0 && !size))
2590 func (stream, " :<bad align %d>", align);
2591 else
2592 func (stream, " :%d", align);
2594 func (stream, "]");
2595 if (rm == 0xd)
2596 func (stream, "!");
2597 else if (rm != 0xf)
2598 func (stream, ", %s", arm_regnames[rm]);
2600 break;
2602 case 'D':
2604 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2605 int size = (given >> 20) & 3;
2606 int reg = raw_reg & ((4 << size) - 1);
2607 int ix = raw_reg >> size >> 2;
2609 func (stream, "d%d[%d]", reg, ix);
2611 break;
2613 case 'E':
2614 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2616 int bits = 0;
2617 int cmode = (given >> 8) & 0xf;
2618 int op = (given >> 5) & 0x1;
2619 unsigned long value = 0, hival = 0;
2620 unsigned shift;
2621 int size = 0;
2622 int isfloat = 0;
2624 bits |= ((given >> 24) & 1) << 7;
2625 bits |= ((given >> 16) & 7) << 4;
2626 bits |= ((given >> 0) & 15) << 0;
2628 if (cmode < 8)
2630 shift = (cmode >> 1) & 3;
2631 value = (unsigned long) bits << (8 * shift);
2632 size = 32;
2634 else if (cmode < 12)
2636 shift = (cmode >> 1) & 1;
2637 value = (unsigned long) bits << (8 * shift);
2638 size = 16;
2640 else if (cmode < 14)
2642 shift = (cmode & 1) + 1;
2643 value = (unsigned long) bits << (8 * shift);
2644 value |= (1ul << (8 * shift)) - 1;
2645 size = 32;
2647 else if (cmode == 14)
2649 if (op)
2651 /* Bit replication into bytes. */
2652 int ix;
2653 unsigned long mask;
2655 value = 0;
2656 hival = 0;
2657 for (ix = 7; ix >= 0; ix--)
2659 mask = ((bits >> ix) & 1) ? 0xff : 0;
2660 if (ix <= 3)
2661 value = (value << 8) | mask;
2662 else
2663 hival = (hival << 8) | mask;
2665 size = 64;
2667 else
2669 /* Byte replication. */
2670 value = (unsigned long) bits;
2671 size = 8;
2674 else if (!op)
2676 /* Floating point encoding. */
2677 int tmp;
2679 value = (unsigned long) (bits & 0x7f) << 19;
2680 value |= (unsigned long) (bits & 0x80) << 24;
2681 tmp = bits & 0x40 ? 0x3c : 0x40;
2682 value |= (unsigned long) tmp << 24;
2683 size = 32;
2684 isfloat = 1;
2686 else
2688 func (stream, "<illegal constant %.8x:%x:%x>",
2689 bits, cmode, op);
2690 size = 32;
2691 break;
2693 switch (size)
2695 case 8:
2696 func (stream, "#%ld\t; 0x%.2lx", value, value);
2697 break;
2699 case 16:
2700 func (stream, "#%ld\t; 0x%.4lx", value, value);
2701 break;
2703 case 32:
2704 if (isfloat)
2706 unsigned char valbytes[4];
2707 double fvalue;
2709 /* Do this a byte at a time so we don't have to
2710 worry about the host's endianness. */
2711 valbytes[0] = value & 0xff;
2712 valbytes[1] = (value >> 8) & 0xff;
2713 valbytes[2] = (value >> 16) & 0xff;
2714 valbytes[3] = (value >> 24) & 0xff;
2716 floatformat_to_double
2717 (& floatformat_ieee_single_little, valbytes,
2718 & fvalue);
2720 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2721 value);
2723 else
2724 func (stream, "#%ld\t; 0x%.8lx",
2725 (long) (((value & 0x80000000L) != 0)
2726 ? value | ~0xffffffffL : value),
2727 value);
2728 break;
2730 case 64:
2731 func (stream, "#0x%.8lx%.8lx", hival, value);
2732 break;
2734 default:
2735 abort ();
2738 break;
2740 case 'F':
2742 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2743 int num = (given >> 8) & 0x3;
2745 if (!num)
2746 func (stream, "{d%d}", regno);
2747 else if (num + regno >= 32)
2748 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2749 else
2750 func (stream, "{d%d-d%d}", regno, regno + num);
2752 break;
2755 case '0': case '1': case '2': case '3': case '4':
2756 case '5': case '6': case '7': case '8': case '9':
2758 int width;
2759 unsigned long value;
2761 c = arm_decode_bitfield (c, given, &value, &width);
2763 switch (*c)
2765 case 'r':
2766 func (stream, "%s", arm_regnames[value]);
2767 break;
2768 case 'd':
2769 func (stream, "%ld", value);
2770 value_in_comment = value;
2771 break;
2772 case 'e':
2773 func (stream, "%ld", (1ul << width) - value);
2774 break;
2776 case 'S':
2777 case 'T':
2778 case 'U':
2779 /* Various width encodings. */
2781 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2782 int limit;
2783 unsigned low, high;
2785 c++;
2786 if (*c >= '0' && *c <= '9')
2787 limit = *c - '0';
2788 else if (*c >= 'a' && *c <= 'f')
2789 limit = *c - 'a' + 10;
2790 else
2791 abort ();
2792 low = limit >> 2;
2793 high = limit & 3;
2795 if (value < low || value > high)
2796 func (stream, "<illegal width %d>", base << value);
2797 else
2798 func (stream, "%d", base << value);
2800 break;
2801 case 'R':
2802 if (given & (1 << 6))
2803 goto Q;
2804 /* FALLTHROUGH */
2805 case 'D':
2806 func (stream, "d%ld", value);
2807 break;
2808 case 'Q':
2810 if (value & 1)
2811 func (stream, "<illegal reg q%ld.5>", value >> 1);
2812 else
2813 func (stream, "q%ld", value >> 1);
2814 break;
2816 case '`':
2817 c++;
2818 if (value == 0)
2819 func (stream, "%c", *c);
2820 break;
2821 case '\'':
2822 c++;
2823 if (value == ((1ul << width) - 1))
2824 func (stream, "%c", *c);
2825 break;
2826 case '?':
2827 func (stream, "%c", c[(1 << width) - (int) value]);
2828 c += 1 << width;
2829 break;
2830 default:
2831 abort ();
2833 break;
2835 default:
2836 abort ();
2840 else
2841 func (stream, "%c", *c);
2844 if (value_in_comment > 32 || value_in_comment < -16)
2845 func (stream, "\t; 0x%lx", value_in_comment);
2847 return TRUE;
2850 return FALSE;
2853 /* Print one ARM instruction from PC on INFO->STREAM. */
2855 static void
2856 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2858 const struct opcode32 *insn;
2859 void *stream = info->stream;
2860 fprintf_ftype func = info->fprintf_func;
2861 struct arm_private_data *private_data = info->private_data;
2863 if (print_insn_coprocessor (pc, info, given, FALSE))
2864 return;
2866 if (print_insn_neon (info, given, FALSE))
2867 return;
2869 for (insn = arm_opcodes; insn->assembler; insn++)
2871 if ((given & insn->mask) != insn->value)
2872 continue;
2874 if ((insn->arch & private_data->features.core) == 0)
2875 continue;
2877 /* Special case: an instruction with all bits set in the condition field
2878 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2879 or by the catchall at the end of the table. */
2880 if ((given & 0xF0000000) != 0xF0000000
2881 || (insn->mask & 0xF0000000) == 0xF0000000
2882 || (insn->mask == 0 && insn->value == 0))
2884 unsigned long u_reg = 16;
2885 unsigned long U_reg = 16;
2886 bfd_boolean is_unpredictable = FALSE;
2887 signed long value_in_comment = 0;
2888 const char *c;
2890 for (c = insn->assembler; *c; c++)
2892 if (*c == '%')
2894 bfd_boolean allow_unpredictable = FALSE;
2896 switch (*++c)
2898 case '%':
2899 func (stream, "%%");
2900 break;
2902 case 'a':
2903 value_in_comment = print_arm_address (pc, info, given);
2904 break;
2906 case 'P':
2907 /* Set P address bit and use normal address
2908 printing routine. */
2909 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
2910 break;
2912 case 'S':
2913 allow_unpredictable = TRUE;
2914 case 's':
2915 if ((given & 0x004f0000) == 0x004f0000)
2917 /* PC relative with immediate offset. */
2918 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2920 if (NEGATIVE_BIT_SET)
2921 offset = - offset;
2923 if (PRE_BIT_SET)
2925 if (offset)
2926 func (stream, "[pc, #%d]\t; ", offset);
2927 else
2928 func (stream, "[pc]\t; ");
2929 info->print_address_func (offset + pc + 8, info);
2931 else
2933 func (stream, "[pc], #%d", offset);
2934 if (! allow_unpredictable)
2935 is_unpredictable = TRUE;
2938 else
2940 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2942 if (NEGATIVE_BIT_SET)
2943 offset = - offset;
2945 func (stream, "[%s",
2946 arm_regnames[(given >> 16) & 0xf]);
2948 if (PRE_BIT_SET)
2950 if (IMMEDIATE_BIT_SET)
2952 if (WRITEBACK_BIT_SET)
2953 /* Immediate Pre-indexed. */
2954 /* PR 10924: Offset must be printed, even if it is zero. */
2955 func (stream, ", #%d", offset);
2956 else if (offset)
2957 /* Immediate Offset: printing zero offset is optional. */
2958 func (stream, ", #%d", offset);
2960 value_in_comment = offset;
2962 else
2964 /* Register Offset or Register Pre-Indexed. */
2965 func (stream, ", %s%s",
2966 NEGATIVE_BIT_SET ? "-" : "",
2967 arm_regnames[given & 0xf]);
2969 /* Writing back to the register that is the source/
2970 destination of the load/store is unpredictable. */
2971 if (! allow_unpredictable
2972 && WRITEBACK_BIT_SET
2973 && ((given & 0xf) == ((given >> 12) & 0xf)))
2974 is_unpredictable = TRUE;
2977 func (stream, "]%s",
2978 WRITEBACK_BIT_SET ? "!" : "");
2980 else
2982 if (IMMEDIATE_BIT_SET)
2984 /* Immediate Post-indexed. */
2985 /* PR 10924: Offset must be printed, even if it is zero. */
2986 func (stream, "], #%d", offset);
2987 value_in_comment = offset;
2989 else
2991 /* Register Post-indexed. */
2992 func (stream, "], %s%s",
2993 NEGATIVE_BIT_SET ? "-" : "",
2994 arm_regnames[given & 0xf]);
2996 /* Writing back to the register that is the source/
2997 destination of the load/store is unpredictable. */
2998 if (! allow_unpredictable
2999 && (given & 0xf) == ((given >> 12) & 0xf))
3000 is_unpredictable = TRUE;
3003 if (! allow_unpredictable)
3005 /* Writeback is automatically implied by post- addressing.
3006 Setting the W bit is unnecessary and ARM specify it as
3007 being unpredictable. */
3008 if (WRITEBACK_BIT_SET
3009 /* Specifying the PC register as the post-indexed
3010 registers is also unpredictable. */
3011 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3012 is_unpredictable = TRUE;
3016 break;
3018 case 'b':
3020 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3021 info->print_address_func (disp * 4 + pc + 8, info);
3023 break;
3025 case 'c':
3026 if (((given >> 28) & 0xf) != 0xe)
3027 func (stream, "%s",
3028 arm_conditional [(given >> 28) & 0xf]);
3029 break;
3031 case 'm':
3033 int started = 0;
3034 int reg;
3036 func (stream, "{");
3037 for (reg = 0; reg < 16; reg++)
3038 if ((given & (1 << reg)) != 0)
3040 if (started)
3041 func (stream, ", ");
3042 started = 1;
3043 func (stream, "%s", arm_regnames[reg]);
3045 func (stream, "}");
3046 if (! started)
3047 is_unpredictable = TRUE;
3049 break;
3051 case 'q':
3052 arm_decode_shift (given, func, stream, FALSE);
3053 break;
3055 case 'o':
3056 if ((given & 0x02000000) != 0)
3058 int rotate = (given & 0xf00) >> 7;
3059 int immed = (given & 0xff);
3061 immed = (((immed << (32 - rotate))
3062 | (immed >> rotate)) & 0xffffffff);
3063 func (stream, "#%d", immed);
3064 value_in_comment = immed;
3066 else
3067 arm_decode_shift (given, func, stream, TRUE);
3068 break;
3070 case 'p':
3071 if ((given & 0x0000f000) == 0x0000f000)
3073 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3074 mechanism for setting PSR flag bits. They are
3075 obsolete in V6 onwards. */
3076 if ((private_data->features.core & ARM_EXT_V6) == 0)
3077 func (stream, "p");
3079 break;
3081 case 't':
3082 if ((given & 0x01200000) == 0x00200000)
3083 func (stream, "t");
3084 break;
3086 case 'A':
3088 int offset = given & 0xff;
3090 value_in_comment = offset * 4;
3091 if (NEGATIVE_BIT_SET)
3092 value_in_comment = - value_in_comment;
3094 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3096 if (PRE_BIT_SET)
3098 if (offset)
3099 func (stream, ", #%d]%s",
3100 value_in_comment,
3101 WRITEBACK_BIT_SET ? "!" : "");
3102 else
3103 func (stream, "]");
3105 else
3107 func (stream, "]");
3109 if (WRITEBACK_BIT_SET)
3111 if (offset)
3112 func (stream, ", #%d", value_in_comment);
3114 else
3116 func (stream, ", {%d}", offset);
3117 value_in_comment = offset;
3121 break;
3123 case 'B':
3124 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3126 bfd_vma address;
3127 bfd_vma offset = 0;
3129 if (! NEGATIVE_BIT_SET)
3130 /* Is signed, hi bits should be ones. */
3131 offset = (-1) ^ 0x00ffffff;
3133 /* Offset is (SignExtend(offset field)<<2). */
3134 offset += given & 0x00ffffff;
3135 offset <<= 2;
3136 address = offset + pc + 8;
3138 if (given & 0x01000000)
3139 /* H bit allows addressing to 2-byte boundaries. */
3140 address += 2;
3142 info->print_address_func (address, info);
3144 break;
3146 case 'C':
3147 func (stream, "_");
3148 if (given & 0x80000)
3149 func (stream, "f");
3150 if (given & 0x40000)
3151 func (stream, "s");
3152 if (given & 0x20000)
3153 func (stream, "x");
3154 if (given & 0x10000)
3155 func (stream, "c");
3156 break;
3158 case 'U':
3159 if ((given & 0xf0) == 0x60)
3161 switch (given & 0xf)
3163 case 0xf: func (stream, "sy"); break;
3164 default:
3165 func (stream, "#%d", (int) given & 0xf);
3166 break;
3169 else
3171 switch (given & 0xf)
3173 case 0xf: func (stream, "sy"); break;
3174 case 0x7: func (stream, "un"); break;
3175 case 0xe: func (stream, "st"); break;
3176 case 0x6: func (stream, "unst"); break;
3177 case 0xb: func (stream, "ish"); break;
3178 case 0xa: func (stream, "ishst"); break;
3179 case 0x3: func (stream, "osh"); break;
3180 case 0x2: func (stream, "oshst"); break;
3181 default:
3182 func (stream, "#%d", (int) given & 0xf);
3183 break;
3186 break;
3188 case '0': case '1': case '2': case '3': case '4':
3189 case '5': case '6': case '7': case '8': case '9':
3191 int width;
3192 unsigned long value;
3194 c = arm_decode_bitfield (c, given, &value, &width);
3196 switch (*c)
3198 case 'R':
3199 if (value == 15)
3200 is_unpredictable = TRUE;
3201 /* Fall through. */
3202 case 'r':
3203 if (c[1] == 'u')
3205 /* Eat the 'u' character. */
3206 ++ c;
3208 if (u_reg == value)
3209 is_unpredictable = TRUE;
3210 u_reg = value;
3212 if (c[1] == 'U')
3214 /* Eat the 'U' character. */
3215 ++ c;
3217 if (U_reg == value)
3218 is_unpredictable = TRUE;
3219 U_reg = value;
3221 func (stream, "%s", arm_regnames[value]);
3222 break;
3223 case 'd':
3224 func (stream, "%ld", value);
3225 value_in_comment = value;
3226 break;
3227 case 'b':
3228 func (stream, "%ld", value * 8);
3229 value_in_comment = value * 8;
3230 break;
3231 case 'W':
3232 func (stream, "%ld", value + 1);
3233 value_in_comment = value + 1;
3234 break;
3235 case 'x':
3236 func (stream, "0x%08lx", value);
3238 /* Some SWI instructions have special
3239 meanings. */
3240 if ((given & 0x0fffffff) == 0x0FF00000)
3241 func (stream, "\t; IMB");
3242 else if ((given & 0x0fffffff) == 0x0FF00001)
3243 func (stream, "\t; IMBRange");
3244 break;
3245 case 'X':
3246 func (stream, "%01lx", value & 0xf);
3247 value_in_comment = value;
3248 break;
3249 case '`':
3250 c++;
3251 if (value == 0)
3252 func (stream, "%c", *c);
3253 break;
3254 case '\'':
3255 c++;
3256 if (value == ((1ul << width) - 1))
3257 func (stream, "%c", *c);
3258 break;
3259 case '?':
3260 func (stream, "%c", c[(1 << width) - (int) value]);
3261 c += 1 << width;
3262 break;
3263 default:
3264 abort ();
3266 break;
3268 case 'e':
3270 int imm;
3272 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3273 func (stream, "%d", imm);
3274 value_in_comment = imm;
3276 break;
3278 case 'E':
3279 /* LSB and WIDTH fields of BFI or BFC. The machine-
3280 language instruction encodes LSB and MSB. */
3282 long msb = (given & 0x001f0000) >> 16;
3283 long lsb = (given & 0x00000f80) >> 7;
3284 long w = msb - lsb + 1;
3286 if (w > 0)
3287 func (stream, "#%lu, #%lu", lsb, w);
3288 else
3289 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3291 break;
3293 case 'V':
3294 /* 16-bit unsigned immediate from a MOVT or MOVW
3295 instruction, encoded in bits 0:11 and 15:19. */
3297 long hi = (given & 0x000f0000) >> 4;
3298 long lo = (given & 0x00000fff);
3299 long imm16 = hi | lo;
3301 func (stream, "#%lu", imm16);
3302 value_in_comment = imm16;
3304 break;
3306 default:
3307 abort ();
3311 else
3312 func (stream, "%c", *c);
3315 if (value_in_comment > 32 || value_in_comment < -16)
3316 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3318 if (is_unpredictable)
3319 func (stream, UNPREDICTABLE_INSTRUCTION);
3321 return;
3324 abort ();
3327 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3329 static void
3330 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3332 const struct opcode16 *insn;
3333 void *stream = info->stream;
3334 fprintf_ftype func = info->fprintf_func;
3336 for (insn = thumb_opcodes; insn->assembler; insn++)
3337 if ((given & insn->mask) == insn->value)
3339 signed long value_in_comment = 0;
3340 const char *c = insn->assembler;
3342 for (; *c; c++)
3344 int domaskpc = 0;
3345 int domasklr = 0;
3347 if (*c != '%')
3349 func (stream, "%c", *c);
3350 continue;
3353 switch (*++c)
3355 case '%':
3356 func (stream, "%%");
3357 break;
3359 case 'c':
3360 if (ifthen_state)
3361 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3362 break;
3364 case 'C':
3365 if (ifthen_state)
3366 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3367 else
3368 func (stream, "s");
3369 break;
3371 case 'I':
3373 unsigned int tmp;
3375 ifthen_next_state = given & 0xff;
3376 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3377 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3378 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3380 break;
3382 case 'x':
3383 if (ifthen_next_state)
3384 func (stream, "\t; unpredictable branch in IT block\n");
3385 break;
3387 case 'X':
3388 if (ifthen_state)
3389 func (stream, "\t; unpredictable <IT:%s>",
3390 arm_conditional[IFTHEN_COND]);
3391 break;
3393 case 'S':
3395 long reg;
3397 reg = (given >> 3) & 0x7;
3398 if (given & (1 << 6))
3399 reg += 8;
3401 func (stream, "%s", arm_regnames[reg]);
3403 break;
3405 case 'D':
3407 long reg;
3409 reg = given & 0x7;
3410 if (given & (1 << 7))
3411 reg += 8;
3413 func (stream, "%s", arm_regnames[reg]);
3415 break;
3417 case 'N':
3418 if (given & (1 << 8))
3419 domasklr = 1;
3420 /* Fall through. */
3421 case 'O':
3422 if (*c == 'O' && (given & (1 << 8)))
3423 domaskpc = 1;
3424 /* Fall through. */
3425 case 'M':
3427 int started = 0;
3428 int reg;
3430 func (stream, "{");
3432 /* It would be nice if we could spot
3433 ranges, and generate the rS-rE format: */
3434 for (reg = 0; (reg < 8); reg++)
3435 if ((given & (1 << reg)) != 0)
3437 if (started)
3438 func (stream, ", ");
3439 started = 1;
3440 func (stream, "%s", arm_regnames[reg]);
3443 if (domasklr)
3445 if (started)
3446 func (stream, ", ");
3447 started = 1;
3448 func (stream, arm_regnames[14] /* "lr" */);
3451 if (domaskpc)
3453 if (started)
3454 func (stream, ", ");
3455 func (stream, arm_regnames[15] /* "pc" */);
3458 func (stream, "}");
3460 break;
3462 case 'W':
3463 /* Print writeback indicator for a LDMIA. We are doing a
3464 writeback if the base register is not in the register
3465 mask. */
3466 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3467 func (stream, "!");
3468 break;
3470 case 'b':
3471 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3473 bfd_vma address = (pc + 4
3474 + ((given & 0x00f8) >> 2)
3475 + ((given & 0x0200) >> 3));
3476 info->print_address_func (address, info);
3478 break;
3480 case 's':
3481 /* Right shift immediate -- bits 6..10; 1-31 print
3482 as themselves, 0 prints as 32. */
3484 long imm = (given & 0x07c0) >> 6;
3485 if (imm == 0)
3486 imm = 32;
3487 func (stream, "#%ld", imm);
3489 break;
3491 case '0': case '1': case '2': case '3': case '4':
3492 case '5': case '6': case '7': case '8': case '9':
3494 int bitstart = *c++ - '0';
3495 int bitend = 0;
3497 while (*c >= '0' && *c <= '9')
3498 bitstart = (bitstart * 10) + *c++ - '0';
3500 switch (*c)
3502 case '-':
3504 long reg;
3506 c++;
3507 while (*c >= '0' && *c <= '9')
3508 bitend = (bitend * 10) + *c++ - '0';
3509 if (!bitend)
3510 abort ();
3511 reg = given >> bitstart;
3512 reg &= (2 << (bitend - bitstart)) - 1;
3514 switch (*c)
3516 case 'r':
3517 func (stream, "%s", arm_regnames[reg]);
3518 break;
3520 case 'd':
3521 func (stream, "%ld", reg);
3522 value_in_comment = reg;
3523 break;
3525 case 'H':
3526 func (stream, "%ld", reg << 1);
3527 value_in_comment = reg << 1;
3528 break;
3530 case 'W':
3531 func (stream, "%ld", reg << 2);
3532 value_in_comment = reg << 2;
3533 break;
3535 case 'a':
3536 /* PC-relative address -- the bottom two
3537 bits of the address are dropped
3538 before the calculation. */
3539 info->print_address_func
3540 (((pc + 4) & ~3) + (reg << 2), info);
3541 value_in_comment = 0;
3542 break;
3544 case 'x':
3545 func (stream, "0x%04lx", reg);
3546 break;
3548 case 'B':
3549 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3550 info->print_address_func (reg * 2 + pc + 4, info);
3551 value_in_comment = 0;
3552 break;
3554 case 'c':
3555 func (stream, "%s", arm_conditional [reg]);
3556 break;
3558 default:
3559 abort ();
3562 break;
3564 case '\'':
3565 c++;
3566 if ((given & (1 << bitstart)) != 0)
3567 func (stream, "%c", *c);
3568 break;
3570 case '?':
3571 ++c;
3572 if ((given & (1 << bitstart)) != 0)
3573 func (stream, "%c", *c++);
3574 else
3575 func (stream, "%c", *++c);
3576 break;
3578 default:
3579 abort ();
3582 break;
3584 default:
3585 abort ();
3589 if (value_in_comment > 32 || value_in_comment < -16)
3590 func (stream, "\t; 0x%lx", value_in_comment);
3591 return;
3594 /* No match. */
3595 abort ();
3598 /* Return the name of an V7M special register. */
3600 static const char *
3601 psr_name (int regno)
3603 switch (regno)
3605 case 0: return "APSR";
3606 case 1: return "IAPSR";
3607 case 2: return "EAPSR";
3608 case 3: return "PSR";
3609 case 5: return "IPSR";
3610 case 6: return "EPSR";
3611 case 7: return "IEPSR";
3612 case 8: return "MSP";
3613 case 9: return "PSP";
3614 case 16: return "PRIMASK";
3615 case 17: return "BASEPRI";
3616 case 18: return "BASEPRI_MASK";
3617 case 19: return "FAULTMASK";
3618 case 20: return "CONTROL";
3619 default: return "<unknown>";
3623 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3625 static void
3626 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3628 const struct opcode32 *insn;
3629 void *stream = info->stream;
3630 fprintf_ftype func = info->fprintf_func;
3632 if (print_insn_coprocessor (pc, info, given, TRUE))
3633 return;
3635 if (print_insn_neon (info, given, TRUE))
3636 return;
3638 for (insn = thumb32_opcodes; insn->assembler; insn++)
3639 if ((given & insn->mask) == insn->value)
3641 bfd_boolean is_unpredictable = FALSE;
3642 signed long value_in_comment = 0;
3643 const char *c = insn->assembler;
3645 for (; *c; c++)
3647 if (*c != '%')
3649 func (stream, "%c", *c);
3650 continue;
3653 switch (*++c)
3655 case '%':
3656 func (stream, "%%");
3657 break;
3659 case 'c':
3660 if (ifthen_state)
3661 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3662 break;
3664 case 'x':
3665 if (ifthen_next_state)
3666 func (stream, "\t; unpredictable branch in IT block\n");
3667 break;
3669 case 'X':
3670 if (ifthen_state)
3671 func (stream, "\t; unpredictable <IT:%s>",
3672 arm_conditional[IFTHEN_COND]);
3673 break;
3675 case 'I':
3677 unsigned int imm12 = 0;
3679 imm12 |= (given & 0x000000ffu);
3680 imm12 |= (given & 0x00007000u) >> 4;
3681 imm12 |= (given & 0x04000000u) >> 15;
3682 func (stream, "#%u", imm12);
3683 value_in_comment = imm12;
3685 break;
3687 case 'M':
3689 unsigned int bits = 0, imm, imm8, mod;
3691 bits |= (given & 0x000000ffu);
3692 bits |= (given & 0x00007000u) >> 4;
3693 bits |= (given & 0x04000000u) >> 15;
3694 imm8 = (bits & 0x0ff);
3695 mod = (bits & 0xf00) >> 8;
3696 switch (mod)
3698 case 0: imm = imm8; break;
3699 case 1: imm = ((imm8 << 16) | imm8); break;
3700 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3701 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3702 default:
3703 mod = (bits & 0xf80) >> 7;
3704 imm8 = (bits & 0x07f) | 0x80;
3705 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3707 func (stream, "#%u", imm);
3708 value_in_comment = imm;
3710 break;
3712 case 'J':
3714 unsigned int imm = 0;
3716 imm |= (given & 0x000000ffu);
3717 imm |= (given & 0x00007000u) >> 4;
3718 imm |= (given & 0x04000000u) >> 15;
3719 imm |= (given & 0x000f0000u) >> 4;
3720 func (stream, "#%u", imm);
3721 value_in_comment = imm;
3723 break;
3725 case 'K':
3727 unsigned int imm = 0;
3729 imm |= (given & 0x000f0000u) >> 16;
3730 imm |= (given & 0x00000ff0u) >> 0;
3731 imm |= (given & 0x0000000fu) << 12;
3732 func (stream, "#%u", imm);
3733 value_in_comment = imm;
3735 break;
3737 case 'S':
3739 unsigned int reg = (given & 0x0000000fu);
3740 unsigned int stp = (given & 0x00000030u) >> 4;
3741 unsigned int imm = 0;
3742 imm |= (given & 0x000000c0u) >> 6;
3743 imm |= (given & 0x00007000u) >> 10;
3745 func (stream, "%s", arm_regnames[reg]);
3746 switch (stp)
3748 case 0:
3749 if (imm > 0)
3750 func (stream, ", lsl #%u", imm);
3751 break;
3753 case 1:
3754 if (imm == 0)
3755 imm = 32;
3756 func (stream, ", lsr #%u", imm);
3757 break;
3759 case 2:
3760 if (imm == 0)
3761 imm = 32;
3762 func (stream, ", asr #%u", imm);
3763 break;
3765 case 3:
3766 if (imm == 0)
3767 func (stream, ", rrx");
3768 else
3769 func (stream, ", ror #%u", imm);
3772 break;
3774 case 'a':
3776 unsigned int Rn = (given & 0x000f0000) >> 16;
3777 unsigned int U = ! NEGATIVE_BIT_SET;
3778 unsigned int op = (given & 0x00000f00) >> 8;
3779 unsigned int i12 = (given & 0x00000fff);
3780 unsigned int i8 = (given & 0x000000ff);
3781 bfd_boolean writeback = FALSE, postind = FALSE;
3782 int offset = 0;
3784 func (stream, "[%s", arm_regnames[Rn]);
3785 if (U) /* 12-bit positive immediate offset. */
3787 offset = i12;
3788 if (Rn != 15)
3789 value_in_comment = offset;
3791 else if (Rn == 15) /* 12-bit negative immediate offset. */
3792 offset = - (int) i12;
3793 else if (op == 0x0) /* Shifted register offset. */
3795 unsigned int Rm = (i8 & 0x0f);
3796 unsigned int sh = (i8 & 0x30) >> 4;
3798 func (stream, ", %s", arm_regnames[Rm]);
3799 if (sh)
3800 func (stream, ", lsl #%u", sh);
3801 func (stream, "]");
3802 break;
3804 else switch (op)
3806 case 0xE: /* 8-bit positive immediate offset. */
3807 offset = i8;
3808 break;
3810 case 0xC: /* 8-bit negative immediate offset. */
3811 offset = -i8;
3812 break;
3814 case 0xF: /* 8-bit + preindex with wb. */
3815 offset = i8;
3816 writeback = TRUE;
3817 break;
3819 case 0xD: /* 8-bit - preindex with wb. */
3820 offset = -i8;
3821 writeback = TRUE;
3822 break;
3824 case 0xB: /* 8-bit + postindex. */
3825 offset = i8;
3826 postind = TRUE;
3827 break;
3829 case 0x9: /* 8-bit - postindex. */
3830 offset = -i8;
3831 postind = TRUE;
3832 break;
3834 default:
3835 func (stream, ", <undefined>]");
3836 goto skip;
3839 if (postind)
3840 func (stream, "], #%d", offset);
3841 else
3843 if (offset)
3844 func (stream, ", #%d", offset);
3845 func (stream, writeback ? "]!" : "]");
3848 if (Rn == 15)
3850 func (stream, "\t; ");
3851 info->print_address_func (((pc + 4) & ~3) + offset, info);
3854 skip:
3855 break;
3857 case 'A':
3859 unsigned int U = ! NEGATIVE_BIT_SET;
3860 unsigned int W = WRITEBACK_BIT_SET;
3861 unsigned int Rn = (given & 0x000f0000) >> 16;
3862 unsigned int off = (given & 0x000000ff);
3864 func (stream, "[%s", arm_regnames[Rn]);
3866 if (PRE_BIT_SET)
3868 if (off || !U)
3870 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3871 value_in_comment = off * 4 * U ? 1 : -1;
3873 func (stream, "]");
3874 if (W)
3875 func (stream, "!");
3877 else
3879 func (stream, "], ");
3880 if (W)
3882 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3883 value_in_comment = off * 4 * U ? 1 : -1;
3885 else
3887 func (stream, "{%u}", off);
3888 value_in_comment = off;
3892 break;
3894 case 'w':
3896 unsigned int Sbit = (given & 0x01000000) >> 24;
3897 unsigned int type = (given & 0x00600000) >> 21;
3899 switch (type)
3901 case 0: func (stream, Sbit ? "sb" : "b"); break;
3902 case 1: func (stream, Sbit ? "sh" : "h"); break;
3903 case 2:
3904 if (Sbit)
3905 func (stream, "??");
3906 break;
3907 case 3:
3908 func (stream, "??");
3909 break;
3912 break;
3914 case 'm':
3916 int started = 0;
3917 int reg;
3919 func (stream, "{");
3920 for (reg = 0; reg < 16; reg++)
3921 if ((given & (1 << reg)) != 0)
3923 if (started)
3924 func (stream, ", ");
3925 started = 1;
3926 func (stream, "%s", arm_regnames[reg]);
3928 func (stream, "}");
3930 break;
3932 case 'E':
3934 unsigned int msb = (given & 0x0000001f);
3935 unsigned int lsb = 0;
3937 lsb |= (given & 0x000000c0u) >> 6;
3938 lsb |= (given & 0x00007000u) >> 10;
3939 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3941 break;
3943 case 'F':
3945 unsigned int width = (given & 0x0000001f) + 1;
3946 unsigned int lsb = 0;
3948 lsb |= (given & 0x000000c0u) >> 6;
3949 lsb |= (given & 0x00007000u) >> 10;
3950 func (stream, "#%u, #%u", lsb, width);
3952 break;
3954 case 'b':
3956 unsigned int S = (given & 0x04000000u) >> 26;
3957 unsigned int J1 = (given & 0x00002000u) >> 13;
3958 unsigned int J2 = (given & 0x00000800u) >> 11;
3959 int offset = 0;
3961 offset |= !S << 20;
3962 offset |= J2 << 19;
3963 offset |= J1 << 18;
3964 offset |= (given & 0x003f0000) >> 4;
3965 offset |= (given & 0x000007ff) << 1;
3966 offset -= (1 << 20);
3968 info->print_address_func (pc + 4 + offset, info);
3970 break;
3972 case 'B':
3974 unsigned int S = (given & 0x04000000u) >> 26;
3975 unsigned int I1 = (given & 0x00002000u) >> 13;
3976 unsigned int I2 = (given & 0x00000800u) >> 11;
3977 int offset = 0;
3979 offset |= !S << 24;
3980 offset |= !(I1 ^ S) << 23;
3981 offset |= !(I2 ^ S) << 22;
3982 offset |= (given & 0x03ff0000u) >> 4;
3983 offset |= (given & 0x000007ffu) << 1;
3984 offset -= (1 << 24);
3985 offset += pc + 4;
3987 /* BLX target addresses are always word aligned. */
3988 if ((given & 0x00001000u) == 0)
3989 offset &= ~2u;
3991 info->print_address_func (offset, info);
3993 break;
3995 case 's':
3997 unsigned int shift = 0;
3999 shift |= (given & 0x000000c0u) >> 6;
4000 shift |= (given & 0x00007000u) >> 10;
4001 if (WRITEBACK_BIT_SET)
4002 func (stream, ", asr #%u", shift);
4003 else if (shift)
4004 func (stream, ", lsl #%u", shift);
4005 /* else print nothing - lsl #0 */
4007 break;
4009 case 'R':
4011 unsigned int rot = (given & 0x00000030) >> 4;
4013 if (rot)
4014 func (stream, ", ror #%u", rot * 8);
4016 break;
4018 case 'U':
4019 if ((given & 0xf0) == 0x60)
4021 switch (given & 0xf)
4023 case 0xf: func (stream, "sy"); break;
4024 default:
4025 func (stream, "#%d", (int) given & 0xf);
4026 break;
4029 else
4031 switch (given & 0xf)
4033 case 0xf: func (stream, "sy"); break;
4034 case 0x7: func (stream, "un"); break;
4035 case 0xe: func (stream, "st"); break;
4036 case 0x6: func (stream, "unst"); break;
4037 case 0xb: func (stream, "ish"); break;
4038 case 0xa: func (stream, "ishst"); break;
4039 case 0x3: func (stream, "osh"); break;
4040 case 0x2: func (stream, "oshst"); break;
4041 default:
4042 func (stream, "#%d", (int) given & 0xf);
4043 break;
4046 break;
4048 case 'C':
4049 if ((given & 0xff) == 0)
4051 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4052 if (given & 0x800)
4053 func (stream, "f");
4054 if (given & 0x400)
4055 func (stream, "s");
4056 if (given & 0x200)
4057 func (stream, "x");
4058 if (given & 0x100)
4059 func (stream, "c");
4061 else
4063 func (stream, psr_name (given & 0xff));
4065 break;
4067 case 'D':
4068 if ((given & 0xff) == 0)
4069 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
4070 else
4071 func (stream, psr_name (given & 0xff));
4072 break;
4074 case '0': case '1': case '2': case '3': case '4':
4075 case '5': case '6': case '7': case '8': case '9':
4077 int width;
4078 unsigned long val;
4080 c = arm_decode_bitfield (c, given, &val, &width);
4082 switch (*c)
4084 case 'd':
4085 func (stream, "%lu", val);
4086 value_in_comment = val;
4087 break;
4089 case 'W':
4090 func (stream, "%lu", val * 4);
4091 value_in_comment = val * 4;
4092 break;
4094 case 'R':
4095 if (val == 15)
4096 is_unpredictable = TRUE;
4097 /* Fall through. */
4098 case 'r':
4099 func (stream, "%s", arm_regnames[val]);
4100 break;
4102 case 'c':
4103 func (stream, "%s", arm_conditional[val]);
4104 break;
4106 case '\'':
4107 c++;
4108 if (val == ((1ul << width) - 1))
4109 func (stream, "%c", *c);
4110 break;
4112 case '`':
4113 c++;
4114 if (val == 0)
4115 func (stream, "%c", *c);
4116 break;
4118 case '?':
4119 func (stream, "%c", c[(1 << width) - (int) val]);
4120 c += 1 << width;
4121 break;
4123 case 'x':
4124 func (stream, "0x%lx", val & 0xffffffffUL);
4125 break;
4127 default:
4128 abort ();
4131 break;
4133 default:
4134 abort ();
4138 if (value_in_comment > 32 || value_in_comment < -16)
4139 func (stream, "\t; 0x%lx", value_in_comment);
4141 if (is_unpredictable)
4142 func (stream, UNPREDICTABLE_INSTRUCTION);
4144 return;
4147 /* No match. */
4148 abort ();
4151 /* Print data bytes on INFO->STREAM. */
4153 static void
4154 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4155 struct disassemble_info *info,
4156 long given)
4158 switch (info->bytes_per_chunk)
4160 case 1:
4161 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4162 break;
4163 case 2:
4164 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4165 break;
4166 case 4:
4167 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4168 break;
4169 default:
4170 abort ();
4174 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4175 being displayed in symbol relative addresses. */
4177 bfd_boolean
4178 arm_symbol_is_valid (asymbol * sym,
4179 struct disassemble_info * info ATTRIBUTE_UNUSED)
4181 const char * name;
4183 if (sym == NULL)
4184 return FALSE;
4186 name = bfd_asymbol_name (sym);
4188 return (name && *name != '$');
4191 /* Parse an individual disassembler option. */
4193 void
4194 parse_arm_disassembler_option (char *option)
4196 if (option == NULL)
4197 return;
4199 if (CONST_STRNEQ (option, "reg-names-"))
4201 int i;
4203 option += 10;
4205 for (i = NUM_ARM_REGNAMES; i--;)
4206 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4208 regname_selected = i;
4209 break;
4212 if (i < 0)
4213 /* XXX - should break 'option' at following delimiter. */
4214 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4216 else if (CONST_STRNEQ (option, "force-thumb"))
4217 force_thumb = 1;
4218 else if (CONST_STRNEQ (option, "no-force-thumb"))
4219 force_thumb = 0;
4220 else
4221 /* XXX - should break 'option' at following delimiter. */
4222 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4224 return;
4227 /* Parse the string of disassembler options, spliting it at whitespaces
4228 or commas. (Whitespace separators supported for backwards compatibility). */
4230 static void
4231 parse_disassembler_options (char *options)
4233 if (options == NULL)
4234 return;
4236 while (*options)
4238 parse_arm_disassembler_option (options);
4240 /* Skip forward to next seperator. */
4241 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4242 ++ options;
4243 /* Skip forward past seperators. */
4244 while (ISSPACE (*options) || (*options == ','))
4245 ++ options;
4249 /* Search back through the insn stream to determine if this instruction is
4250 conditionally executed. */
4252 static void
4253 find_ifthen_state (bfd_vma pc,
4254 struct disassemble_info *info,
4255 bfd_boolean little)
4257 unsigned char b[2];
4258 unsigned int insn;
4259 int status;
4260 /* COUNT is twice the number of instructions seen. It will be odd if we
4261 just crossed an instruction boundary. */
4262 int count;
4263 int it_count;
4264 unsigned int seen_it;
4265 bfd_vma addr;
4267 ifthen_address = pc;
4268 ifthen_state = 0;
4270 addr = pc;
4271 count = 1;
4272 it_count = 0;
4273 seen_it = 0;
4274 /* Scan backwards looking for IT instructions, keeping track of where
4275 instruction boundaries are. We don't know if something is actually an
4276 IT instruction until we find a definite instruction boundary. */
4277 for (;;)
4279 if (addr == 0 || info->symbol_at_address_func (addr, info))
4281 /* A symbol must be on an instruction boundary, and will not
4282 be within an IT block. */
4283 if (seen_it && (count & 1))
4284 break;
4286 return;
4288 addr -= 2;
4289 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4290 if (status)
4291 return;
4293 if (little)
4294 insn = (b[0]) | (b[1] << 8);
4295 else
4296 insn = (b[1]) | (b[0] << 8);
4297 if (seen_it)
4299 if ((insn & 0xf800) < 0xe800)
4301 /* Addr + 2 is an instruction boundary. See if this matches
4302 the expected boundary based on the position of the last
4303 IT candidate. */
4304 if (count & 1)
4305 break;
4306 seen_it = 0;
4309 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4311 /* This could be an IT instruction. */
4312 seen_it = insn;
4313 it_count = count >> 1;
4315 if ((insn & 0xf800) >= 0xe800)
4316 count++;
4317 else
4318 count = (count + 2) | 1;
4319 /* IT blocks contain at most 4 instructions. */
4320 if (count >= 8 && !seen_it)
4321 return;
4323 /* We found an IT instruction. */
4324 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4325 if ((ifthen_state & 0xf) == 0)
4326 ifthen_state = 0;
4329 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4330 mapping symbol. */
4332 static int
4333 is_mapping_symbol (struct disassemble_info *info, int n,
4334 enum map_type *map_type)
4336 const char *name;
4338 name = bfd_asymbol_name (info->symtab[n]);
4339 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4340 && (name[2] == 0 || name[2] == '.'))
4342 *map_type = ((name[1] == 'a') ? MAP_ARM
4343 : (name[1] == 't') ? MAP_THUMB
4344 : MAP_DATA);
4345 return TRUE;
4348 return FALSE;
4351 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4352 Returns nonzero if *MAP_TYPE was set. */
4354 static int
4355 get_map_sym_type (struct disassemble_info *info,
4356 int n,
4357 enum map_type *map_type)
4359 /* If the symbol is in a different section, ignore it. */
4360 if (info->section != NULL && info->section != info->symtab[n]->section)
4361 return FALSE;
4363 return is_mapping_symbol (info, n, map_type);
4366 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4367 Returns nonzero if *MAP_TYPE was set. */
4369 static int
4370 get_sym_code_type (struct disassemble_info *info,
4371 int n,
4372 enum map_type *map_type)
4374 elf_symbol_type *es;
4375 unsigned int type;
4377 /* If the symbol is in a different section, ignore it. */
4378 if (info->section != NULL && info->section != info->symtab[n]->section)
4379 return FALSE;
4381 es = *(elf_symbol_type **)(info->symtab + n);
4382 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4384 /* If the symbol has function type then use that. */
4385 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4387 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4388 return TRUE;
4391 return FALSE;
4394 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4395 of the supplied arm_feature_set structure with bitmasks indicating
4396 the support base architectures and coprocessor extensions.
4398 FIXME: This could more efficiently implemented as a constant array,
4399 although it would also be less robust. */
4401 static void
4402 select_arm_features (unsigned long mach,
4403 arm_feature_set * features)
4405 #undef ARM_FEATURE
4406 #define ARM_FEATURE(ARCH,CEXT) \
4407 features->core = (ARCH); \
4408 features->coproc = (CEXT) | FPU_FPA; \
4409 return
4411 switch (mach)
4413 case bfd_mach_arm_2: ARM_ARCH_V2;
4414 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4415 case bfd_mach_arm_3: ARM_ARCH_V3;
4416 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4417 case bfd_mach_arm_4: ARM_ARCH_V4;
4418 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4419 case bfd_mach_arm_5: ARM_ARCH_V5;
4420 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4421 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4422 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4423 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4424 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4425 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4426 /* If the machine type is unknown allow all
4427 architecture types and all extensions. */
4428 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4429 default:
4430 abort ();
4435 /* NOTE: There are no checks in these routines that
4436 the relevant number of data bytes exist. */
4438 static int
4439 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4441 unsigned char b[4];
4442 long given;
4443 int status;
4444 int is_thumb = FALSE;
4445 int is_data = FALSE;
4446 int little_code;
4447 unsigned int size = 4;
4448 void (*printer) (bfd_vma, struct disassemble_info *, long);
4449 bfd_boolean found = FALSE;
4450 struct arm_private_data *private_data;
4452 if (info->disassembler_options)
4454 parse_disassembler_options (info->disassembler_options);
4456 /* To avoid repeated parsing of these options, we remove them here. */
4457 info->disassembler_options = NULL;
4460 /* PR 10288: Control which instructions will be disassembled. */
4461 if (info->private_data == NULL)
4463 static struct arm_private_data private;
4465 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4466 /* If the user did not use the -m command line switch then default to
4467 disassembling all types of ARM instruction.
4469 The info->mach value has to be ignored as this will be based on
4470 the default archictecture for the target and/or hints in the notes
4471 section, but it will never be greater than the current largest arm
4472 machine value (iWMMXt2), which is only equivalent to the V5TE
4473 architecture. ARM architectures have advanced beyond the machine
4474 value encoding, and these newer architectures would be ignored if
4475 the machine value was used.
4477 Ie the -m switch is used to restrict which instructions will be
4478 disassembled. If it is necessary to use the -m switch to tell
4479 objdump that an ARM binary is being disassembled, eg because the
4480 input is a raw binary file, but it is also desired to disassemble
4481 all ARM instructions then use "-marm". This will select the
4482 "unknown" arm architecture which is compatible with any ARM
4483 instruction. */
4484 info->mach = bfd_mach_arm_unknown;
4486 /* Compute the architecture bitmask from the machine number.
4487 Note: This assumes that the machine number will not change
4488 during disassembly.... */
4489 select_arm_features (info->mach, & private.features);
4491 private.has_mapping_symbols = -1;
4493 info->private_data = & private;
4496 private_data = info->private_data;
4498 /* Decide if our code is going to be little-endian, despite what the
4499 function argument might say. */
4500 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4502 /* For ELF, consult the symbol table to determine what kind of code
4503 or data we have. */
4504 if (info->symtab_size != 0
4505 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4507 bfd_vma addr;
4508 int n, start;
4509 int last_sym = -1;
4510 enum map_type type = MAP_ARM;
4512 /* Start scanning at the start of the function, or wherever
4513 we finished last time. */
4514 start = info->symtab_pos + 1;
4515 if (start < last_mapping_sym)
4516 start = last_mapping_sym;
4517 found = FALSE;
4519 /* First, look for mapping symbols. */
4520 if (private_data->has_mapping_symbols != 0)
4522 /* Scan up to the location being disassembled. */
4523 for (n = start; n < info->symtab_size; n++)
4525 addr = bfd_asymbol_value (info->symtab[n]);
4526 if (addr > pc)
4527 break;
4528 if (get_map_sym_type (info, n, &type))
4530 last_sym = n;
4531 found = TRUE;
4535 if (!found)
4537 /* No mapping symbol found at this address. Look backwards
4538 for a preceeding one. */
4539 for (n = start - 1; n >= 0; n--)
4541 if (get_map_sym_type (info, n, &type))
4543 last_sym = n;
4544 found = TRUE;
4545 break;
4550 if (found)
4551 private_data->has_mapping_symbols = 1;
4553 /* No mapping symbols were found. A leading $d may be
4554 omitted for sections which start with data; but for
4555 compatibility with legacy and stripped binaries, only
4556 assume the leading $d if there is at least one mapping
4557 symbol in the file. */
4558 if (!found && private_data->has_mapping_symbols == -1)
4560 /* Look for mapping symbols, in any section. */
4561 for (n = 0; n < info->symtab_size; n++)
4562 if (is_mapping_symbol (info, n, &type))
4564 private_data->has_mapping_symbols = 1;
4565 break;
4567 if (private_data->has_mapping_symbols == -1)
4568 private_data->has_mapping_symbols = 0;
4571 if (!found && private_data->has_mapping_symbols == 1)
4573 type = MAP_DATA;
4574 found = TRUE;
4578 /* Next search for function symbols to separate ARM from Thumb
4579 in binaries without mapping symbols. */
4580 if (!found)
4582 /* Scan up to the location being disassembled. */
4583 for (n = start; n < info->symtab_size; n++)
4585 addr = bfd_asymbol_value (info->symtab[n]);
4586 if (addr > pc)
4587 break;
4588 if (get_sym_code_type (info, n, &type))
4590 last_sym = n;
4591 found = TRUE;
4595 if (!found)
4597 /* No mapping symbol found at this address. Look backwards
4598 for a preceeding one. */
4599 for (n = start - 1; n >= 0; n--)
4601 if (get_sym_code_type (info, n, &type))
4603 last_sym = n;
4604 found = TRUE;
4605 break;
4611 last_mapping_sym = last_sym;
4612 last_type = type;
4613 is_thumb = (last_type == MAP_THUMB);
4614 is_data = (last_type == MAP_DATA);
4616 /* Look a little bit ahead to see if we should print out
4617 two or four bytes of data. If there's a symbol,
4618 mapping or otherwise, after two bytes then don't
4619 print more. */
4620 if (is_data)
4622 size = 4 - (pc & 3);
4623 for (n = last_sym + 1; n < info->symtab_size; n++)
4625 addr = bfd_asymbol_value (info->symtab[n]);
4626 if (addr > pc
4627 && (info->section == NULL
4628 || info->section == info->symtab[n]->section))
4630 if (addr - pc < size)
4631 size = addr - pc;
4632 break;
4635 /* If the next symbol is after three bytes, we need to
4636 print only part of the data, so that we can use either
4637 .byte or .short. */
4638 if (size == 3)
4639 size = (pc & 1) ? 1 : 2;
4643 if (info->symbols != NULL)
4645 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4647 coff_symbol_type * cs;
4649 cs = coffsymbol (*info->symbols);
4650 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4651 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4652 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4653 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4654 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4656 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4657 && !found)
4659 /* If no mapping symbol has been found then fall back to the type
4660 of the function symbol. */
4661 elf_symbol_type * es;
4662 unsigned int type;
4664 es = *(elf_symbol_type **)(info->symbols);
4665 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4667 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4671 if (force_thumb)
4672 is_thumb = TRUE;
4674 if (is_data)
4675 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4676 else
4677 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4679 info->bytes_per_line = 4;
4681 /* PR 10263: Disassemble data if requested to do so by the user. */
4682 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4684 int i;
4686 /* Size was already set above. */
4687 info->bytes_per_chunk = size;
4688 printer = print_insn_data;
4690 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4691 given = 0;
4692 if (little)
4693 for (i = size - 1; i >= 0; i--)
4694 given = b[i] | (given << 8);
4695 else
4696 for (i = 0; i < (int) size; i++)
4697 given = b[i] | (given << 8);
4699 else if (!is_thumb)
4701 /* In ARM mode endianness is a straightforward issue: the instruction
4702 is four bytes long and is either ordered 0123 or 3210. */
4703 printer = print_insn_arm;
4704 info->bytes_per_chunk = 4;
4705 size = 4;
4707 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4708 if (little_code)
4709 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4710 else
4711 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4713 else
4715 /* In Thumb mode we have the additional wrinkle of two
4716 instruction lengths. Fortunately, the bits that determine
4717 the length of the current instruction are always to be found
4718 in the first two bytes. */
4719 printer = print_insn_thumb16;
4720 info->bytes_per_chunk = 2;
4721 size = 2;
4723 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4724 if (little_code)
4725 given = (b[0]) | (b[1] << 8);
4726 else
4727 given = (b[1]) | (b[0] << 8);
4729 if (!status)
4731 /* These bit patterns signal a four-byte Thumb
4732 instruction. */
4733 if ((given & 0xF800) == 0xF800
4734 || (given & 0xF800) == 0xF000
4735 || (given & 0xF800) == 0xE800)
4737 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4738 if (little_code)
4739 given = (b[0]) | (b[1] << 8) | (given << 16);
4740 else
4741 given = (b[1]) | (b[0] << 8) | (given << 16);
4743 printer = print_insn_thumb32;
4744 size = 4;
4748 if (ifthen_address != pc)
4749 find_ifthen_state (pc, info, little_code);
4751 if (ifthen_state)
4753 if ((ifthen_state & 0xf) == 0x8)
4754 ifthen_next_state = 0;
4755 else
4756 ifthen_next_state = (ifthen_state & 0xe0)
4757 | ((ifthen_state & 0xf) << 1);
4761 if (status)
4763 info->memory_error_func (status, pc, info);
4764 return -1;
4766 if (info->flags & INSN_HAS_RELOC)
4767 /* If the instruction has a reloc associated with it, then
4768 the offset field in the instruction will actually be the
4769 addend for the reloc. (We are using REL type relocs).
4770 In such cases, we can ignore the pc when computing
4771 addresses, since the addend is not currently pc-relative. */
4772 pc = 0;
4774 printer (pc, info, given);
4776 if (is_thumb)
4778 ifthen_state = ifthen_next_state;
4779 ifthen_address += size;
4781 return size;
4785 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4787 /* Detect BE8-ness and record it in the disassembler info. */
4788 if (info->flavour == bfd_target_elf_flavour
4789 && info->section != NULL
4790 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4791 info->endian_code = BFD_ENDIAN_LITTLE;
4793 return print_insn (pc, info, FALSE);
4797 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4799 return print_insn (pc, info, TRUE);
4802 void
4803 print_arm_disassembler_options (FILE *stream)
4805 int i;
4807 fprintf (stream, _("\n\
4808 The following ARM specific disassembler options are supported for use with\n\
4809 the -M switch:\n"));
4811 for (i = NUM_ARM_REGNAMES; i--;)
4812 fprintf (stream, " reg-names-%s %*c%s\n",
4813 regnames[i].name,
4814 (int)(14 - strlen (regnames[i].name)), ' ',
4815 regnames[i].description);
4817 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4818 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");