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. */
27 #include "opcode/arm.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
32 /* FIXME: This shouldn't be done here. */
33 #include "coff/internal.h"
36 #include "elf/internal.h"
39 /* FIXME: Belongs in global header. */
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
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;
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. */
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:
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'
116 %i print 5-bit immediate in bits 8,3..0
118 %r print register offset address for wldt/wstr instruction. */
120 enum opcode_sentinel_enum
122 SENTINEL_IWMMXT_START = 1,
124 SENTINEL_GENERIC_START
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}"},
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:
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
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[] =
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]"},
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"},
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
786 /* print_insn_arm recognizes the following format control codes:
790 %a print address for ldr/str instruction
791 %s print address for ldr/str halfword/signextend instruction
792 %S like %s but allow UNPREDICTABLE addressing
793 %b print branch destination
794 %c print condition code (always bits 28-31)
795 %m print register mask for ldm/stm instruction
796 %o print operand2 (immediate or register + shift)
797 %p print 'p' iff bits 12-15 are 15
798 %t print 't' iff bit 21 set and bit 24 clear
799 %B print arm BLX(1) destination
800 %C print the PSR sub type.
801 %U print barrier type.
802 %P print address for pli instruction.
804 %<bitfield>r print as an ARM register
805 %<bitfield>R as %r but r15 is UNPREDICTABLE
806 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
807 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
808 %<bitfield>d print the bitfield in decimal
809 %<bitfield>W print the bitfield plus one in decimal
810 %<bitfield>x print the bitfield in hex
811 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
813 %<bitfield>'c print specified char iff bitfield is all ones
814 %<bitfield>`c print specified char iff bitfield is all zeroes
815 %<bitfield>?ab... select from array of values in big endian order
817 %e print arm SMI operand (bits 0..7,8..19).
818 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
819 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
820 %R print the SPSR/CPSR or banked register of an MRS. */
822 static const struct opcode32 arm_opcodes[] =
824 /* ARM instructions. */
825 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
826 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
827 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
828 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
829 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
830 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
831 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
833 /* Virtualization Extension instructions. */
834 {ARM_EXT_VIRT, 0x0160006e, 0x0fffffff, "eret%c"},
835 {ARM_EXT_VIRT, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
837 /* Integer Divide Extension instructions. */
838 {ARM_EXT_ADIV, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
839 {ARM_EXT_ADIV, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
841 /* MP Extension instructions. */
842 {ARM_EXT_MP, 0xf410f000, 0xfc70f000, "pldw\t%a"},
844 /* V7 instructions. */
845 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
846 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
847 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
848 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
849 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
851 /* ARM V6T2 instructions. */
852 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
853 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
854 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
855 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
857 {ARM_EXT_V6T2, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION },
858 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
860 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
861 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
862 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
863 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
865 /* ARM Security extension instructions. */
866 {ARM_EXT_SEC, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
868 /* ARM V6K instructions. */
869 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
870 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
871 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
872 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
873 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
874 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
875 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
877 /* ARM V6K NOP hints. */
878 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
879 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
880 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
881 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
882 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
884 /* ARM V6 instructions. */
885 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
886 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
887 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
888 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
889 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
890 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
891 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
892 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
893 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
894 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
895 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
896 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
897 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
898 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
899 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
900 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
901 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
902 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
903 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
904 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
905 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
906 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
907 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
908 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
909 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
910 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
911 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
920 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
921 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
922 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
923 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
924 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
925 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
926 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
927 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
928 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
929 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
930 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
931 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
932 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
933 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
934 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
935 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
936 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
937 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
938 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
939 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
940 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
941 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
942 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
943 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
944 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
945 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
946 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
947 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
948 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
949 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
950 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
951 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
952 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
953 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
954 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
955 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
956 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
957 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
958 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
959 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
960 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
961 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
962 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
963 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
964 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
965 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
966 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
967 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
968 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
969 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
970 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
971 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
972 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
973 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
974 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
975 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
976 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
977 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
978 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
979 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
980 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
981 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
982 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
983 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
984 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
985 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
986 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
987 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
988 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
989 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
990 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
991 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
992 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
993 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
994 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
995 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
996 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
997 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
998 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
999 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1000 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1001 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1002 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1003 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1004 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1005 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1006 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1008 /* V5J instruction. */
1009 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1011 /* V5 Instructions. */
1012 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1013 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
1014 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1015 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1017 /* V5E "El Segundo" Instructions. */
1018 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1019 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1020 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
1021 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1022 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1023 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1024 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1026 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1027 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1029 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1030 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1031 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1032 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1034 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1035 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1036 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1037 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1039 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1040 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1042 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1043 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1044 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1045 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1047 /* ARM Instructions. */
1048 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1050 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1051 {ARM_EXT_V1, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1052 {ARM_EXT_V1, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1053 {ARM_EXT_V1, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1054 {ARM_EXT_V1, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1055 {ARM_EXT_V1, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1057 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1058 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1059 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1060 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1062 {ARM_EXT_V1, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION},
1063 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1064 {ARM_EXT_V1, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION},
1065 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1067 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1068 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1069 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1071 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1072 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1073 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1075 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1076 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1077 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1079 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1081 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1083 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1085 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1087 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1089 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1091 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1093 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1095 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1096 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1097 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1099 {ARM_EXT_VIRT, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1100 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1101 {ARM_EXT_V3, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1103 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1104 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1105 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1107 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1108 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1109 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1111 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1112 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1113 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1115 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1116 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1117 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1119 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1120 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1121 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1123 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1124 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1125 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1126 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1127 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1128 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1129 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1131 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1132 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1133 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1135 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1136 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1137 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1139 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1140 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1142 {ARM_EXT_V1, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1144 {ARM_EXT_V1, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1145 {ARM_EXT_V1, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1147 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1148 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1149 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1150 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1151 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1152 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1153 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1154 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1157 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1158 {0, 0x00000000, 0x00000000, 0}
1161 /* print_insn_thumb16 recognizes the following format control codes:
1163 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1164 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1165 %<bitfield>I print bitfield as a signed decimal
1166 (top bit of range being the sign bit)
1167 %N print Thumb register mask (with LR)
1168 %O print Thumb register mask (with PC)
1169 %M print Thumb register mask
1170 %b print CZB's 6-bit unsigned branch destination
1171 %s print Thumb right-shift immediate (6..10; 0 == 32).
1172 %c print the condition code
1173 %C print the condition code, or "s" if not conditional
1174 %x print warning if conditional an not at end of IT block"
1175 %X print "\t; unpredictable <IT:code>" if conditional
1176 %I print IT instruction suffix and operands
1177 %W print Thumb Writeback indicator for LDMIA
1178 %<bitfield>r print bitfield as an ARM register
1179 %<bitfield>d print bitfield as a decimal
1180 %<bitfield>H print (bitfield * 2) as a decimal
1181 %<bitfield>W print (bitfield * 4) as a decimal
1182 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1183 %<bitfield>B print Thumb branch destination (signed displacement)
1184 %<bitfield>c print bitfield as a condition code
1185 %<bitnum>'c print specified char iff bit is one
1186 %<bitnum>?ab print a if bit is one else print b. */
1188 static const struct opcode16 thumb_opcodes[] =
1190 /* Thumb instructions. */
1192 /* ARM V6K no-argument instructions. */
1193 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1194 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1195 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1196 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1197 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1198 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1200 /* ARM V6T2 instructions. */
1201 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1202 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1203 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1206 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1207 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1208 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1209 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1210 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1211 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1212 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1213 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1214 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1215 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1216 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1218 /* ARM V5 ISA extends Thumb. */
1219 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1220 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1221 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1222 /* ARM V4T ISA (Thumb v1). */
1223 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1225 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1226 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1227 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1228 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1229 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1230 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1231 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1232 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1233 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1234 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1235 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1236 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1237 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1238 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1239 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1240 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1242 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1243 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1245 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1246 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1247 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1248 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1250 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1251 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1253 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1254 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1255 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1256 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1258 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1259 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1260 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1262 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1263 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1265 {ARM_EXT_V4T, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1266 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1267 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1268 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1270 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1271 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1272 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1273 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1275 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1277 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1278 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1279 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1280 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1282 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1283 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1285 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1286 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1288 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1289 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1291 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1292 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1294 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1296 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1297 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1299 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1301 /* The E800 .. FFFF range is unconditionally redirected to the
1302 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1303 are processed via that table. Thus, we can never encounter a
1304 bare "second half of BL/BLX(1)" instruction here. */
1305 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1309 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1310 We adopt the convention that hw1 is the high 16 bits of .value and
1311 .mask, hw2 the low 16 bits.
1313 print_insn_thumb32 recognizes the following format control codes:
1317 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1318 %M print a modified 12-bit immediate (same location)
1319 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1320 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1321 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1322 %S print a possibly-shifted Rm
1324 %a print the address of a plain load/store
1325 %w print the width and signedness of a core load/store
1326 %m print register mask for ldm/stm
1328 %E print the lsb and width fields of a bfc/bfi instruction
1329 %F print the lsb and width fields of a sbfx/ubfx instruction
1330 %b print a conditional branch offset
1331 %B print an unconditional branch offset
1332 %s print the shift field of an SSAT instruction
1333 %R print the rotation field of an SXT instruction
1334 %U print barrier type.
1335 %P print address for pli instruction.
1336 %c print the condition code
1337 %x print warning if conditional an not at end of IT block"
1338 %X print "\t; unpredictable <IT:code>" if conditional
1340 %<bitfield>d print bitfield in decimal
1341 %<bitfield>W print bitfield*4 in decimal
1342 %<bitfield>r print bitfield as an ARM register
1343 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1344 %<bitfield>c print bitfield as a condition code
1346 %<bitfield>'c print specified char iff bitfield is all ones
1347 %<bitfield>`c print specified char iff bitfield is all zeroes
1348 %<bitfield>?ab... select from array of values in big endian order
1350 With one exception at the bottom (done because BL and BLX(1) need
1351 to come dead last), this table was machine-sorted first in
1352 decreasing order of number of bits set in the mask, then in
1353 increasing numeric order of mask, then in increasing numeric order
1354 of opcode. This order is not the clearest for a human reader, but
1355 is guaranteed never to catch a special-case bit pattern with a more
1356 general mask, which is important, because this instruction encoding
1357 makes heavy use of special-case bit patterns. */
1358 static const struct opcode32 thumb32_opcodes[] =
1360 /* V7 instructions. */
1361 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1362 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1363 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1364 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1365 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1366 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1369 /* Virtualization Extension instructions. */
1370 {ARM_EXT_VIRT, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1371 /* We skip ERET as that is SUBS pc, lr, #0. */
1373 /* MP Extension instructions. */
1374 {ARM_EXT_MP, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1376 /* Security extension instructions. */
1377 {ARM_EXT_SEC, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1379 /* Instructions defined in the basic V6T2 set. */
1380 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1381 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1382 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1383 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1384 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1385 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1387 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1388 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1389 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1390 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1391 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1392 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1393 {ARM_EXT_V6T2, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1394 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1395 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1396 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1397 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1398 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1399 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1400 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1401 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1402 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1403 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1404 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1405 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1406 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1407 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1408 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1409 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1410 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1411 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1412 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1413 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1414 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1415 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1416 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1417 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1418 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1420 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1421 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1422 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1423 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1424 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1425 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1426 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1427 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1428 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1429 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1430 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1431 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1432 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1433 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1434 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1440 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1441 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1442 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1443 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1444 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1445 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1446 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1447 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1448 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1449 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1452 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1453 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1454 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1455 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1456 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1457 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1459 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1460 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1461 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1462 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1463 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1464 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1466 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1467 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1468 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1469 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1470 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1471 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1472 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1473 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1474 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1475 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1476 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1477 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1478 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1479 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1480 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1481 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1482 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1483 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1484 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1485 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1486 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1487 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1488 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1489 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1490 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1491 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1492 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1493 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1494 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1495 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1496 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1497 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1498 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1499 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1500 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1501 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1502 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1503 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1504 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1505 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1506 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1507 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1508 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1509 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1510 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1511 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1512 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1513 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1514 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1515 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1516 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1517 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1518 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1519 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1520 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1521 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1522 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1523 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1524 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1525 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1526 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1527 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1528 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1529 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1530 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1531 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1532 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1533 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1534 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1535 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1536 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1537 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1538 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1539 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1540 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1541 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1542 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1543 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1544 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1545 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1546 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1547 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1548 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1549 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1550 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1551 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1552 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1553 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1554 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1555 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1556 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1557 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1559 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1560 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1561 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1562 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1563 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1565 /* These have been 32-bit since the invention of Thumb. */
1566 {ARM_EXT_V4T, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1567 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1570 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1574 static const char *const arm_conditional[] =
1575 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1576 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1578 static const char *const arm_fp_const[] =
1579 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1581 static const char *const arm_shift[] =
1582 {"lsl", "lsr", "asr", "ror"};
1587 const char *description;
1588 const char *reg_names[16];
1592 static const arm_regname regnames[] =
1594 { "raw" , "Select raw register names",
1595 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1596 { "gcc", "Select register names used by GCC",
1597 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1598 { "std", "Select register names used in ARM's ISA documentation",
1599 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1600 { "apcs", "Select register names used in the APCS",
1601 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1602 { "atpcs", "Select register names used in the ATPCS",
1603 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1604 { "special-atpcs", "Select special register names used in the ATPCS",
1605 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1608 static const char *const iwmmxt_wwnames[] =
1609 {"b", "h", "w", "d"};
1611 static const char *const iwmmxt_wwssnames[] =
1612 {"b", "bus", "bc", "bss",
1613 "h", "hus", "hc", "hss",
1614 "w", "wus", "wc", "wss",
1615 "d", "dus", "dc", "dss"
1618 static const char *const iwmmxt_regnames[] =
1619 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1620 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1623 static const char *const iwmmxt_cregnames[] =
1624 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1625 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1628 /* Default to GCC register name set. */
1629 static unsigned int regname_selected = 1;
1631 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1632 #define arm_regnames regnames[regname_selected].reg_names
1634 static bfd_boolean force_thumb = FALSE;
1636 /* Current IT instruction state. This contains the same state as the IT
1637 bits in the CPSR. */
1638 static unsigned int ifthen_state;
1639 /* IT state for the next instruction. */
1640 static unsigned int ifthen_next_state;
1641 /* The address of the insn for which the IT state is valid. */
1642 static bfd_vma ifthen_address;
1643 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1645 /* Cached mapping symbol state. */
1653 enum map_type last_type;
1654 int last_mapping_sym = -1;
1655 bfd_vma last_mapping_addr = 0;
1660 get_arm_regname_num_options (void)
1662 return NUM_ARM_REGNAMES;
1666 set_arm_regname_option (int option)
1668 int old = regname_selected;
1669 regname_selected = option;
1674 get_arm_regnames (int option,
1675 const char **setname,
1676 const char **setdescription,
1677 const char *const **register_names)
1679 *setname = regnames[option].name;
1680 *setdescription = regnames[option].description;
1681 *register_names = regnames[option].reg_names;
1685 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1686 Returns pointer to following character of the format string and
1687 fills in *VALUEP and *WIDTHP with the extracted value and number of
1688 bits extracted. WIDTHP can be NULL. */
1691 arm_decode_bitfield (const char *ptr,
1693 unsigned long *valuep,
1696 unsigned long value = 0;
1704 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1705 start = start * 10 + *ptr - '0';
1707 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1708 end = end * 10 + *ptr - '0';
1714 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1717 while (*ptr++ == ',');
1725 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1726 bfd_boolean print_shift)
1728 func (stream, "%s", arm_regnames[given & 0xf]);
1730 if ((given & 0xff0) != 0)
1732 if ((given & 0x10) == 0)
1734 int amount = (given & 0xf80) >> 7;
1735 int shift = (given & 0x60) >> 5;
1741 func (stream, ", rrx");
1749 func (stream, ", %s #%d", arm_shift[shift], amount);
1751 func (stream, ", #%d", amount);
1753 else if ((given & 0x80) == 0x80)
1754 func (stream, "\t; <illegal shifter operand>");
1755 else if (print_shift)
1756 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1757 arm_regnames[(given & 0xf00) >> 8]);
1759 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1768 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1769 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1770 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1771 #define PRE_BIT_SET (given & (1 << P_BIT))
1773 /* Print one coprocessor instruction on INFO->STREAM.
1774 Return TRUE if the instuction matched, FALSE if this is not a
1775 recognised coprocessor instruction. */
1778 print_insn_coprocessor (bfd_vma pc,
1779 struct disassemble_info *info,
1783 const struct opcode32 *insn;
1784 void *stream = info->stream;
1785 fprintf_ftype func = info->fprintf_func;
1787 unsigned long value = 0;
1788 struct arm_private_data *private_data = info->private_data;
1789 unsigned long allowed_arches = private_data->features.coproc;
1792 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1794 unsigned long u_reg = 16;
1795 bfd_boolean is_unpredictable = FALSE;
1796 signed long value_in_comment = 0;
1799 if (insn->arch == 0)
1800 switch (insn->value)
1802 case SENTINEL_IWMMXT_START:
1803 if (info->mach != bfd_mach_arm_XScale
1804 && info->mach != bfd_mach_arm_iWMMXt
1805 && info->mach != bfd_mach_arm_iWMMXt2)
1808 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1811 case SENTINEL_IWMMXT_END:
1814 case SENTINEL_GENERIC_START:
1815 allowed_arches = private_data->features.core;
1823 value = insn->value;
1826 /* The high 4 bits are 0xe for Arm conditional instructions, and
1827 0xe for arm unconditional instructions. The rest of the
1828 encoding is the same. */
1830 value |= 0xe0000000;
1838 /* Only match unconditional instuctions against unconditional
1840 if ((given & 0xf0000000) == 0xf0000000)
1847 cond = (given >> 28) & 0xf;
1853 if ((given & mask) != value)
1856 if ((insn->arch & allowed_arches) == 0)
1859 for (c = insn->assembler; *c; c++)
1866 func (stream, "%%");
1871 int rn = (given >> 16) & 0xf;
1872 int offset = given & 0xff;
1874 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1876 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1878 /* Not unindexed. The offset is scaled. */
1879 offset = offset * 4;
1880 if (NEGATIVE_BIT_SET)
1883 value_in_comment = offset;
1889 func (stream, ", #%d]%s",
1891 WRITEBACK_BIT_SET ? "!" : "");
1899 if (WRITEBACK_BIT_SET)
1902 func (stream, ", #%d", offset);
1906 func (stream, ", {%d}", offset);
1907 value_in_comment = offset;
1910 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1912 func (stream, "\t; ");
1913 /* For unaligned PCs, apply off-by-alignment
1915 info->print_address_func (offset + pc
1916 + info->bytes_per_chunk * 2
1925 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1926 int offset = (given >> 1) & 0x3f;
1929 func (stream, "{d%d}", regno);
1930 else if (regno + offset > 32)
1931 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1933 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1938 func (stream, "%s", arm_conditional[cond]);
1942 /* Print a Cirrus/DSP shift immediate. */
1943 /* Immediates are 7bit signed ints with bits 0..3 in
1944 bits 0..3 of opcode and bits 4..6 in bits 5..7
1949 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1951 /* Is ``imm'' a negative number? */
1955 func (stream, "%d", imm);
1961 switch (given & 0x00408000)
1978 switch (given & 0x00080080)
1990 func (stream, _("<illegal precision>"));
1996 switch (given & 0x00408000)
2014 switch (given & 0x60)
2030 case '0': case '1': case '2': case '3': case '4':
2031 case '5': case '6': case '7': case '8': case '9':
2035 c = arm_decode_bitfield (c, given, &value, &width);
2041 is_unpredictable = TRUE;
2046 /* Eat the 'u' character. */
2050 is_unpredictable = TRUE;
2053 func (stream, "%s", arm_regnames[value]);
2056 func (stream, "d%ld", value);
2060 func (stream, "<illegal reg q%ld.5>", value >> 1);
2062 func (stream, "q%ld", value >> 1);
2065 func (stream, "%ld", value);
2066 value_in_comment = value;
2070 int from = (given & (1 << 7)) ? 32 : 16;
2071 func (stream, "%ld", from - value);
2077 func (stream, "#%s", arm_fp_const[value & 7]);
2079 func (stream, "f%ld", value);
2084 func (stream, "%s", iwmmxt_wwnames[value]);
2086 func (stream, "%s", iwmmxt_wwssnames[value]);
2090 func (stream, "%s", iwmmxt_regnames[value]);
2093 func (stream, "%s", iwmmxt_cregnames[value]);
2097 func (stream, "0x%lx", (value & 0xffffffffUL));
2103 func (stream, "%c", *c);
2107 if (value == ((1ul << width) - 1))
2108 func (stream, "%c", *c);
2111 func (stream, "%c", c[(1 << width) - (int) value]);
2122 int single = *c++ == 'y';
2127 case '4': /* Sm pair */
2128 case '0': /* Sm, Dm */
2129 regno = given & 0x0000000f;
2133 regno += (given >> 5) & 1;
2136 regno += ((given >> 5) & 1) << 4;
2139 case '1': /* Sd, Dd */
2140 regno = (given >> 12) & 0x0000000f;
2144 regno += (given >> 22) & 1;
2147 regno += ((given >> 22) & 1) << 4;
2150 case '2': /* Sn, Dn */
2151 regno = (given >> 16) & 0x0000000f;
2155 regno += (given >> 7) & 1;
2158 regno += ((given >> 7) & 1) << 4;
2161 case '3': /* List */
2163 regno = (given >> 12) & 0x0000000f;
2167 regno += (given >> 22) & 1;
2170 regno += ((given >> 22) & 1) << 4;
2177 func (stream, "%c%d", single ? 's' : 'd', regno);
2181 int count = given & 0xff;
2188 func (stream, "-%c%d",
2196 func (stream, ", %c%d", single ? 's' : 'd',
2202 switch (given & 0x00400100)
2204 case 0x00000000: func (stream, "b"); break;
2205 case 0x00400000: func (stream, "h"); break;
2206 case 0x00000100: func (stream, "w"); break;
2207 case 0x00400100: func (stream, "d"); break;
2215 /* given (20, 23) | given (0, 3) */
2216 value = ((given >> 16) & 0xf0) | (given & 0xf);
2217 func (stream, "%d", value);
2222 /* This is like the 'A' operator, except that if
2223 the width field "M" is zero, then the offset is
2224 *not* multiplied by four. */
2226 int offset = given & 0xff;
2227 int multiplier = (given & 0x00000100) ? 4 : 1;
2229 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2233 value_in_comment = offset * multiplier;
2234 if (NEGATIVE_BIT_SET)
2235 value_in_comment = - value_in_comment;
2241 func (stream, ", #%s%d]%s",
2242 NEGATIVE_BIT_SET ? "-" : "",
2243 offset * multiplier,
2244 WRITEBACK_BIT_SET ? "!" : "");
2246 func (stream, "], #%s%d",
2247 NEGATIVE_BIT_SET ? "-" : "",
2248 offset * multiplier);
2257 int imm4 = (given >> 4) & 0xf;
2258 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2259 int ubit = ! NEGATIVE_BIT_SET;
2260 const char *rm = arm_regnames [given & 0xf];
2261 const char *rn = arm_regnames [(given >> 16) & 0xf];
2267 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2269 func (stream, ", lsl #%d", imm4);
2276 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2278 func (stream, ", lsl #%d", imm4);
2280 if (puw_bits == 5 || puw_bits == 7)
2285 func (stream, "INVALID");
2293 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2294 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2304 func (stream, "%c", *c);
2307 if (value_in_comment > 32 || value_in_comment < -16)
2308 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2310 if (is_unpredictable)
2311 func (stream, UNPREDICTABLE_INSTRUCTION);
2318 /* Decodes and prints ARM addressing modes. Returns the offset
2319 used in the address, if any, if it is worthwhile printing the
2320 offset as a hexadecimal value in a comment at the end of the
2321 line of disassembly. */
2324 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2326 void *stream = info->stream;
2327 fprintf_ftype func = info->fprintf_func;
2330 if (((given & 0x000f0000) == 0x000f0000)
2331 && ((given & 0x02000000) == 0))
2333 offset = given & 0xfff;
2335 func (stream, "[pc");
2337 if (NEGATIVE_BIT_SET)
2343 func (stream, ", #%d]", offset);
2347 /* Cope with the possibility of write-back
2348 being used. Probably a very dangerous thing
2349 for the programmer to do, but who are we to
2351 if (WRITEBACK_BIT_SET)
2354 else /* Post indexed. */
2356 func (stream, "], #%d", offset);
2358 /* Ie ignore the offset. */
2362 func (stream, "\t; ");
2363 info->print_address_func (offset, info);
2368 func (stream, "[%s",
2369 arm_regnames[(given >> 16) & 0xf]);
2373 if ((given & 0x02000000) == 0)
2375 offset = given & 0xfff;
2377 func (stream, ", #%s%d",
2378 NEGATIVE_BIT_SET ? "-" : "", offset);
2382 func (stream, ", %s",
2383 NEGATIVE_BIT_SET ? "-" : "");
2384 arm_decode_shift (given, func, stream, TRUE);
2387 func (stream, "]%s",
2388 WRITEBACK_BIT_SET ? "!" : "");
2392 if ((given & 0x02000000) == 0)
2394 offset = given & 0xfff;
2396 func (stream, "], #%s%d",
2397 NEGATIVE_BIT_SET ? "-" : "", offset);
2403 func (stream, "], %s",
2404 NEGATIVE_BIT_SET ? "-" : "");
2405 arm_decode_shift (given, func, stream, TRUE);
2410 return (signed long) offset;
2413 /* Print one neon instruction on INFO->STREAM.
2414 Return TRUE if the instuction matched, FALSE if this is not a
2415 recognised neon instruction. */
2418 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2420 const struct opcode32 *insn;
2421 void *stream = info->stream;
2422 fprintf_ftype func = info->fprintf_func;
2426 if ((given & 0xef000000) == 0xef000000)
2428 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2429 unsigned long bit28 = given & (1 << 28);
2431 given &= 0x00ffffff;
2433 given |= 0xf3000000;
2435 given |= 0xf2000000;
2437 else if ((given & 0xff000000) == 0xf9000000)
2438 given ^= 0xf9000000 ^ 0xf4000000;
2443 for (insn = neon_opcodes; insn->assembler; insn++)
2445 if ((given & insn->mask) == insn->value)
2447 signed long value_in_comment = 0;
2450 for (c = insn->assembler; *c; c++)
2457 func (stream, "%%");
2461 if (thumb && ifthen_state)
2462 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2467 static const unsigned char enc[16] =
2469 0x4, 0x14, /* st4 0,1 */
2481 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2482 int rn = ((given >> 16) & 0xf);
2483 int rm = ((given >> 0) & 0xf);
2484 int align = ((given >> 4) & 0x3);
2485 int type = ((given >> 8) & 0xf);
2486 int n = enc[type] & 0xf;
2487 int stride = (enc[type] >> 4) + 1;
2492 for (ix = 0; ix != n; ix++)
2493 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2495 func (stream, "d%d", rd);
2497 func (stream, "d%d-d%d", rd, rd + n - 1);
2498 func (stream, "}, [%s", arm_regnames[rn]);
2500 func (stream, " :%d", 32 << align);
2505 func (stream, ", %s", arm_regnames[rm]);
2511 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2512 int rn = ((given >> 16) & 0xf);
2513 int rm = ((given >> 0) & 0xf);
2514 int idx_align = ((given >> 4) & 0xf);
2516 int size = ((given >> 10) & 0x3);
2517 int idx = idx_align >> (size + 1);
2518 int length = ((given >> 8) & 3) + 1;
2522 if (length > 1 && size > 0)
2523 stride = (idx_align & (1 << size)) ? 2 : 1;
2529 int amask = (1 << size) - 1;
2530 if ((idx_align & (1 << size)) != 0)
2534 if ((idx_align & amask) == amask)
2536 else if ((idx_align & amask) != 0)
2543 if (size == 2 && (idx_align & 2) != 0)
2545 align = (idx_align & 1) ? 16 << size : 0;
2549 if ((size == 2 && (idx_align & 3) != 0)
2550 || (idx_align & 1) != 0)
2557 if ((idx_align & 3) == 3)
2559 align = (idx_align & 3) * 64;
2562 align = (idx_align & 1) ? 32 << size : 0;
2570 for (i = 0; i < length; i++)
2571 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2572 rd + i * stride, idx);
2573 func (stream, "}, [%s", arm_regnames[rn]);
2575 func (stream, " :%d", align);
2580 func (stream, ", %s", arm_regnames[rm]);
2586 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2587 int rn = ((given >> 16) & 0xf);
2588 int rm = ((given >> 0) & 0xf);
2589 int align = ((given >> 4) & 0x1);
2590 int size = ((given >> 6) & 0x3);
2591 int type = ((given >> 8) & 0x3);
2593 int stride = ((given >> 5) & 0x1);
2596 if (stride && (n == 1))
2603 for (ix = 0; ix != n; ix++)
2604 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2606 func (stream, "d%d[]", rd);
2608 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2609 func (stream, "}, [%s", arm_regnames[rn]);
2612 align = (8 * (type + 1)) << size;
2614 align = (size > 1) ? align >> 1 : align;
2615 if (type == 2 || (type == 0 && !size))
2616 func (stream, " :<bad align %d>", align);
2618 func (stream, " :%d", align);
2624 func (stream, ", %s", arm_regnames[rm]);
2630 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2631 int size = (given >> 20) & 3;
2632 int reg = raw_reg & ((4 << size) - 1);
2633 int ix = raw_reg >> size >> 2;
2635 func (stream, "d%d[%d]", reg, ix);
2640 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2643 int cmode = (given >> 8) & 0xf;
2644 int op = (given >> 5) & 0x1;
2645 unsigned long value = 0, hival = 0;
2650 bits |= ((given >> 24) & 1) << 7;
2651 bits |= ((given >> 16) & 7) << 4;
2652 bits |= ((given >> 0) & 15) << 0;
2656 shift = (cmode >> 1) & 3;
2657 value = (unsigned long) bits << (8 * shift);
2660 else if (cmode < 12)
2662 shift = (cmode >> 1) & 1;
2663 value = (unsigned long) bits << (8 * shift);
2666 else if (cmode < 14)
2668 shift = (cmode & 1) + 1;
2669 value = (unsigned long) bits << (8 * shift);
2670 value |= (1ul << (8 * shift)) - 1;
2673 else if (cmode == 14)
2677 /* Bit replication into bytes. */
2683 for (ix = 7; ix >= 0; ix--)
2685 mask = ((bits >> ix) & 1) ? 0xff : 0;
2687 value = (value << 8) | mask;
2689 hival = (hival << 8) | mask;
2695 /* Byte replication. */
2696 value = (unsigned long) bits;
2702 /* Floating point encoding. */
2705 value = (unsigned long) (bits & 0x7f) << 19;
2706 value |= (unsigned long) (bits & 0x80) << 24;
2707 tmp = bits & 0x40 ? 0x3c : 0x40;
2708 value |= (unsigned long) tmp << 24;
2714 func (stream, "<illegal constant %.8x:%x:%x>",
2722 func (stream, "#%ld\t; 0x%.2lx", value, value);
2726 func (stream, "#%ld\t; 0x%.4lx", value, value);
2732 unsigned char valbytes[4];
2735 /* Do this a byte at a time so we don't have to
2736 worry about the host's endianness. */
2737 valbytes[0] = value & 0xff;
2738 valbytes[1] = (value >> 8) & 0xff;
2739 valbytes[2] = (value >> 16) & 0xff;
2740 valbytes[3] = (value >> 24) & 0xff;
2742 floatformat_to_double
2743 (& floatformat_ieee_single_little, valbytes,
2746 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2750 func (stream, "#%ld\t; 0x%.8lx",
2751 (long) (((value & 0x80000000L) != 0)
2752 ? value | ~0xffffffffL : value),
2757 func (stream, "#0x%.8lx%.8lx", hival, value);
2768 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2769 int num = (given >> 8) & 0x3;
2772 func (stream, "{d%d}", regno);
2773 else if (num + regno >= 32)
2774 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2776 func (stream, "{d%d-d%d}", regno, regno + num);
2781 case '0': case '1': case '2': case '3': case '4':
2782 case '5': case '6': case '7': case '8': case '9':
2785 unsigned long value;
2787 c = arm_decode_bitfield (c, given, &value, &width);
2792 func (stream, "%s", arm_regnames[value]);
2795 func (stream, "%ld", value);
2796 value_in_comment = value;
2799 func (stream, "%ld", (1ul << width) - value);
2805 /* Various width encodings. */
2807 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2812 if (*c >= '0' && *c <= '9')
2814 else if (*c >= 'a' && *c <= 'f')
2815 limit = *c - 'a' + 10;
2821 if (value < low || value > high)
2822 func (stream, "<illegal width %d>", base << value);
2824 func (stream, "%d", base << value);
2828 if (given & (1 << 6))
2832 func (stream, "d%ld", value);
2837 func (stream, "<illegal reg q%ld.5>", value >> 1);
2839 func (stream, "q%ld", value >> 1);
2845 func (stream, "%c", *c);
2849 if (value == ((1ul << width) - 1))
2850 func (stream, "%c", *c);
2853 func (stream, "%c", c[(1 << width) - (int) value]);
2867 func (stream, "%c", *c);
2870 if (value_in_comment > 32 || value_in_comment < -16)
2871 func (stream, "\t; 0x%lx", value_in_comment);
2879 /* Return the name of a v7A special register. */
2882 banked_regname (unsigned reg)
2886 case 15: return "CPSR";
2887 case 32: return "R8_usr";
2888 case 33: return "R9_usr";
2889 case 34: return "R10_usr";
2890 case 35: return "R11_usr";
2891 case 36: return "R12_usr";
2892 case 37: return "SP_usr";
2893 case 38: return "LR_usr";
2894 case 40: return "R8_fiq";
2895 case 41: return "R9_fiq";
2896 case 42: return "R10_fiq";
2897 case 43: return "R11_fiq";
2898 case 44: return "R12_fiq";
2899 case 45: return "SP_fiq";
2900 case 46: return "LR_fiq";
2901 case 48: return "LR_irq";
2902 case 49: return "SP_irq";
2903 case 50: return "LR_svc";
2904 case 51: return "SP_svc";
2905 case 52: return "LR_abt";
2906 case 53: return "SP_abt";
2907 case 54: return "LR_und";
2908 case 55: return "SP_und";
2909 case 60: return "LR_mon";
2910 case 61: return "SP_mon";
2911 case 62: return "ELR_hyp";
2912 case 63: return "SP_hyp";
2913 case 79: return "SPSR";
2914 case 110: return "SPSR_fiq";
2915 case 112: return "SPSR_irq";
2916 case 114: return "SPSR_svc";
2917 case 116: return "SPSR_abt";
2918 case 118: return "SPSR_und";
2919 case 124: return "SPSR_mon";
2920 case 126: return "SPSR_hyp";
2921 default: return NULL;
2925 /* Print one ARM instruction from PC on INFO->STREAM. */
2928 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2930 const struct opcode32 *insn;
2931 void *stream = info->stream;
2932 fprintf_ftype func = info->fprintf_func;
2933 struct arm_private_data *private_data = info->private_data;
2935 if (print_insn_coprocessor (pc, info, given, FALSE))
2938 if (print_insn_neon (info, given, FALSE))
2941 for (insn = arm_opcodes; insn->assembler; insn++)
2943 if ((given & insn->mask) != insn->value)
2946 if ((insn->arch & private_data->features.core) == 0)
2949 /* Special case: an instruction with all bits set in the condition field
2950 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2951 or by the catchall at the end of the table. */
2952 if ((given & 0xF0000000) != 0xF0000000
2953 || (insn->mask & 0xF0000000) == 0xF0000000
2954 || (insn->mask == 0 && insn->value == 0))
2956 unsigned long u_reg = 16;
2957 unsigned long U_reg = 16;
2958 bfd_boolean is_unpredictable = FALSE;
2959 signed long value_in_comment = 0;
2962 for (c = insn->assembler; *c; c++)
2966 bfd_boolean allow_unpredictable = FALSE;
2971 func (stream, "%%");
2975 value_in_comment = print_arm_address (pc, info, given);
2979 /* Set P address bit and use normal address
2980 printing routine. */
2981 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
2985 allow_unpredictable = TRUE;
2987 if ((given & 0x004f0000) == 0x004f0000)
2989 /* PC relative with immediate offset. */
2990 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2992 if (NEGATIVE_BIT_SET)
2998 func (stream, "[pc, #%d]\t; ", offset);
3000 func (stream, "[pc]\t; ");
3001 info->print_address_func (offset + pc + 8, info);
3005 func (stream, "[pc], #%d", offset);
3006 if (! allow_unpredictable)
3007 is_unpredictable = TRUE;
3012 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
3014 if (NEGATIVE_BIT_SET)
3017 func (stream, "[%s",
3018 arm_regnames[(given >> 16) & 0xf]);
3022 if (IMMEDIATE_BIT_SET)
3024 if (WRITEBACK_BIT_SET)
3025 /* Immediate Pre-indexed. */
3026 /* PR 10924: Offset must be printed, even if it is zero. */
3027 func (stream, ", #%d", offset);
3029 /* Immediate Offset: printing zero offset is optional. */
3030 func (stream, ", #%d", offset);
3032 value_in_comment = offset;
3036 /* Register Offset or Register Pre-Indexed. */
3037 func (stream, ", %s%s",
3038 NEGATIVE_BIT_SET ? "-" : "",
3039 arm_regnames[given & 0xf]);
3041 /* Writing back to the register that is the source/
3042 destination of the load/store is unpredictable. */
3043 if (! allow_unpredictable
3044 && WRITEBACK_BIT_SET
3045 && ((given & 0xf) == ((given >> 12) & 0xf)))
3046 is_unpredictable = TRUE;
3049 func (stream, "]%s",
3050 WRITEBACK_BIT_SET ? "!" : "");
3054 if (IMMEDIATE_BIT_SET)
3056 /* Immediate Post-indexed. */
3057 /* PR 10924: Offset must be printed, even if it is zero. */
3058 func (stream, "], #%d", offset);
3059 value_in_comment = offset;
3063 /* Register Post-indexed. */
3064 func (stream, "], %s%s",
3065 NEGATIVE_BIT_SET ? "-" : "",
3066 arm_regnames[given & 0xf]);
3068 /* Writing back to the register that is the source/
3069 destination of the load/store is unpredictable. */
3070 if (! allow_unpredictable
3071 && (given & 0xf) == ((given >> 12) & 0xf))
3072 is_unpredictable = TRUE;
3075 if (! allow_unpredictable)
3077 /* Writeback is automatically implied by post- addressing.
3078 Setting the W bit is unnecessary and ARM specify it as
3079 being unpredictable. */
3080 if (WRITEBACK_BIT_SET
3081 /* Specifying the PC register as the post-indexed
3082 registers is also unpredictable. */
3083 || (! IMMEDIATE_BIT_SET && ((given & 0xf) == 0xf)))
3084 is_unpredictable = TRUE;
3092 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
3093 info->print_address_func (disp * 4 + pc + 8, info);
3098 if (((given >> 28) & 0xf) != 0xe)
3100 arm_conditional [(given >> 28) & 0xf]);
3109 for (reg = 0; reg < 16; reg++)
3110 if ((given & (1 << reg)) != 0)
3113 func (stream, ", ");
3115 func (stream, "%s", arm_regnames[reg]);
3119 is_unpredictable = TRUE;
3124 arm_decode_shift (given, func, stream, FALSE);
3128 if ((given & 0x02000000) != 0)
3130 int rotate = (given & 0xf00) >> 7;
3131 int immed = (given & 0xff);
3133 immed = (((immed << (32 - rotate))
3134 | (immed >> rotate)) & 0xffffffff);
3135 func (stream, "#%d", immed);
3136 value_in_comment = immed;
3139 arm_decode_shift (given, func, stream, TRUE);
3143 if ((given & 0x0000f000) == 0x0000f000)
3145 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3146 mechanism for setting PSR flag bits. They are
3147 obsolete in V6 onwards. */
3148 if ((private_data->features.core & ARM_EXT_V6) == 0)
3154 if ((given & 0x01200000) == 0x00200000)
3160 int offset = given & 0xff;
3162 value_in_comment = offset * 4;
3163 if (NEGATIVE_BIT_SET)
3164 value_in_comment = - value_in_comment;
3166 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3171 func (stream, ", #%d]%s",
3173 WRITEBACK_BIT_SET ? "!" : "");
3181 if (WRITEBACK_BIT_SET)
3184 func (stream, ", #%d", value_in_comment);
3188 func (stream, ", {%d}", offset);
3189 value_in_comment = offset;
3196 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3201 if (! NEGATIVE_BIT_SET)
3202 /* Is signed, hi bits should be ones. */
3203 offset = (-1) ^ 0x00ffffff;
3205 /* Offset is (SignExtend(offset field)<<2). */
3206 offset += given & 0x00ffffff;
3208 address = offset + pc + 8;
3210 if (given & 0x01000000)
3211 /* H bit allows addressing to 2-byte boundaries. */
3214 info->print_address_func (address, info);
3219 if ((given & 0x02000200) == 0x200)
3222 unsigned sysm = (given & 0x004f0000) >> 16;
3224 sysm |= (given & 0x300) >> 4;
3225 name = banked_regname (sysm);
3228 func (stream, "%s", name);
3230 func (stream, "(UNDEF: %lu)", sysm);
3234 func (stream, "%cPSR_",
3235 (given & 0x00400000) ? 'S' : 'C');
3236 if (given & 0x80000)
3238 if (given & 0x40000)
3240 if (given & 0x20000)
3242 if (given & 0x10000)
3248 if ((given & 0xf0) == 0x60)
3250 switch (given & 0xf)
3252 case 0xf: func (stream, "sy"); break;
3254 func (stream, "#%d", (int) given & 0xf);
3260 switch (given & 0xf)
3262 case 0xf: func (stream, "sy"); break;
3263 case 0x7: func (stream, "un"); break;
3264 case 0xe: func (stream, "st"); break;
3265 case 0x6: func (stream, "unst"); break;
3266 case 0xb: func (stream, "ish"); break;
3267 case 0xa: func (stream, "ishst"); break;
3268 case 0x3: func (stream, "osh"); break;
3269 case 0x2: func (stream, "oshst"); break;
3271 func (stream, "#%d", (int) given & 0xf);
3277 case '0': case '1': case '2': case '3': case '4':
3278 case '5': case '6': case '7': case '8': case '9':
3281 unsigned long value;
3283 c = arm_decode_bitfield (c, given, &value, &width);
3289 is_unpredictable = TRUE;
3294 /* Eat the 'u' character. */
3298 is_unpredictable = TRUE;
3303 /* Eat the 'U' character. */
3307 is_unpredictable = TRUE;
3310 func (stream, "%s", arm_regnames[value]);
3313 func (stream, "%ld", value);
3314 value_in_comment = value;
3317 func (stream, "%ld", value * 8);
3318 value_in_comment = value * 8;
3321 func (stream, "%ld", value + 1);
3322 value_in_comment = value + 1;
3325 func (stream, "0x%08lx", value);
3327 /* Some SWI instructions have special
3329 if ((given & 0x0fffffff) == 0x0FF00000)
3330 func (stream, "\t; IMB");
3331 else if ((given & 0x0fffffff) == 0x0FF00001)
3332 func (stream, "\t; IMBRange");
3335 func (stream, "%01lx", value & 0xf);
3336 value_in_comment = value;
3341 func (stream, "%c", *c);
3345 if (value == ((1ul << width) - 1))
3346 func (stream, "%c", *c);
3349 func (stream, "%c", c[(1 << width) - (int) value]);
3361 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3362 func (stream, "%d", imm);
3363 value_in_comment = imm;
3368 /* LSB and WIDTH fields of BFI or BFC. The machine-
3369 language instruction encodes LSB and MSB. */
3371 long msb = (given & 0x001f0000) >> 16;
3372 long lsb = (given & 0x00000f80) >> 7;
3373 long w = msb - lsb + 1;
3376 func (stream, "#%lu, #%lu", lsb, w);
3378 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3383 /* Get the PSR/banked register name. */
3386 unsigned sysm = (given & 0x004f0000) >> 16;
3388 sysm |= (given & 0x300) >> 4;
3389 name = banked_regname (sysm);
3392 func (stream, "%s", name);
3394 func (stream, "(UNDEF: %lu)", sysm);
3399 /* 16-bit unsigned immediate from a MOVT or MOVW
3400 instruction, encoded in bits 0:11 and 15:19. */
3402 long hi = (given & 0x000f0000) >> 4;
3403 long lo = (given & 0x00000fff);
3404 long imm16 = hi | lo;
3406 func (stream, "#%lu", imm16);
3407 value_in_comment = imm16;
3417 func (stream, "%c", *c);
3420 if (value_in_comment > 32 || value_in_comment < -16)
3421 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3423 if (is_unpredictable)
3424 func (stream, UNPREDICTABLE_INSTRUCTION);
3432 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3435 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3437 const struct opcode16 *insn;
3438 void *stream = info->stream;
3439 fprintf_ftype func = info->fprintf_func;
3441 for (insn = thumb_opcodes; insn->assembler; insn++)
3442 if ((given & insn->mask) == insn->value)
3444 signed long value_in_comment = 0;
3445 const char *c = insn->assembler;
3454 func (stream, "%c", *c);
3461 func (stream, "%%");
3466 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3471 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3480 ifthen_next_state = given & 0xff;
3481 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3482 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3483 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3488 if (ifthen_next_state)
3489 func (stream, "\t; unpredictable branch in IT block\n");
3494 func (stream, "\t; unpredictable <IT:%s>",
3495 arm_conditional[IFTHEN_COND]);
3502 reg = (given >> 3) & 0x7;
3503 if (given & (1 << 6))
3506 func (stream, "%s", arm_regnames[reg]);
3515 if (given & (1 << 7))
3518 func (stream, "%s", arm_regnames[reg]);
3523 if (given & (1 << 8))
3527 if (*c == 'O' && (given & (1 << 8)))
3537 /* It would be nice if we could spot
3538 ranges, and generate the rS-rE format: */
3539 for (reg = 0; (reg < 8); reg++)
3540 if ((given & (1 << reg)) != 0)
3543 func (stream, ", ");
3545 func (stream, "%s", arm_regnames[reg]);
3551 func (stream, ", ");
3553 func (stream, arm_regnames[14] /* "lr" */);
3559 func (stream, ", ");
3560 func (stream, arm_regnames[15] /* "pc" */);
3568 /* Print writeback indicator for a LDMIA. We are doing a
3569 writeback if the base register is not in the register
3571 if ((given & (1 << ((given & 0x0700) >> 8))) == 0)
3576 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3578 bfd_vma address = (pc + 4
3579 + ((given & 0x00f8) >> 2)
3580 + ((given & 0x0200) >> 3));
3581 info->print_address_func (address, info);
3586 /* Right shift immediate -- bits 6..10; 1-31 print
3587 as themselves, 0 prints as 32. */
3589 long imm = (given & 0x07c0) >> 6;
3592 func (stream, "#%ld", imm);
3596 case '0': case '1': case '2': case '3': case '4':
3597 case '5': case '6': case '7': case '8': case '9':
3599 int bitstart = *c++ - '0';
3602 while (*c >= '0' && *c <= '9')
3603 bitstart = (bitstart * 10) + *c++ - '0';
3612 while (*c >= '0' && *c <= '9')
3613 bitend = (bitend * 10) + *c++ - '0';
3616 reg = given >> bitstart;
3617 reg &= (2 << (bitend - bitstart)) - 1;
3622 func (stream, "%s", arm_regnames[reg]);
3626 func (stream, "%ld", reg);
3627 value_in_comment = reg;
3631 func (stream, "%ld", reg << 1);
3632 value_in_comment = reg << 1;
3636 func (stream, "%ld", reg << 2);
3637 value_in_comment = reg << 2;
3641 /* PC-relative address -- the bottom two
3642 bits of the address are dropped
3643 before the calculation. */
3644 info->print_address_func
3645 (((pc + 4) & ~3) + (reg << 2), info);
3646 value_in_comment = 0;
3650 func (stream, "0x%04lx", reg);
3654 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3655 info->print_address_func (reg * 2 + pc + 4, info);
3656 value_in_comment = 0;
3660 func (stream, "%s", arm_conditional [reg]);
3671 if ((given & (1 << bitstart)) != 0)
3672 func (stream, "%c", *c);
3677 if ((given & (1 << bitstart)) != 0)
3678 func (stream, "%c", *c++);
3680 func (stream, "%c", *++c);
3694 if (value_in_comment > 32 || value_in_comment < -16)
3695 func (stream, "\t; 0x%lx", value_in_comment);
3703 /* Return the name of an V7M special register. */
3706 psr_name (int regno)
3710 case 0: return "APSR";
3711 case 1: return "IAPSR";
3712 case 2: return "EAPSR";
3713 case 3: return "PSR";
3714 case 5: return "IPSR";
3715 case 6: return "EPSR";
3716 case 7: return "IEPSR";
3717 case 8: return "MSP";
3718 case 9: return "PSP";
3719 case 16: return "PRIMASK";
3720 case 17: return "BASEPRI";
3721 case 18: return "BASEPRI_MASK";
3722 case 19: return "FAULTMASK";
3723 case 20: return "CONTROL";
3724 default: return "<unknown>";
3728 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3731 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3733 const struct opcode32 *insn;
3734 void *stream = info->stream;
3735 fprintf_ftype func = info->fprintf_func;
3737 if (print_insn_coprocessor (pc, info, given, TRUE))
3740 if (print_insn_neon (info, given, TRUE))
3743 for (insn = thumb32_opcodes; insn->assembler; insn++)
3744 if ((given & insn->mask) == insn->value)
3746 bfd_boolean is_unpredictable = FALSE;
3747 signed long value_in_comment = 0;
3748 const char *c = insn->assembler;
3754 func (stream, "%c", *c);
3761 func (stream, "%%");
3766 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3770 if (ifthen_next_state)
3771 func (stream, "\t; unpredictable branch in IT block\n");
3776 func (stream, "\t; unpredictable <IT:%s>",
3777 arm_conditional[IFTHEN_COND]);
3782 unsigned int imm12 = 0;
3784 imm12 |= (given & 0x000000ffu);
3785 imm12 |= (given & 0x00007000u) >> 4;
3786 imm12 |= (given & 0x04000000u) >> 15;
3787 func (stream, "#%u", imm12);
3788 value_in_comment = imm12;
3794 unsigned int bits = 0, imm, imm8, mod;
3796 bits |= (given & 0x000000ffu);
3797 bits |= (given & 0x00007000u) >> 4;
3798 bits |= (given & 0x04000000u) >> 15;
3799 imm8 = (bits & 0x0ff);
3800 mod = (bits & 0xf00) >> 8;
3803 case 0: imm = imm8; break;
3804 case 1: imm = ((imm8 << 16) | imm8); break;
3805 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3806 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3808 mod = (bits & 0xf80) >> 7;
3809 imm8 = (bits & 0x07f) | 0x80;
3810 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3812 func (stream, "#%u", imm);
3813 value_in_comment = imm;
3819 unsigned int imm = 0;
3821 imm |= (given & 0x000000ffu);
3822 imm |= (given & 0x00007000u) >> 4;
3823 imm |= (given & 0x04000000u) >> 15;
3824 imm |= (given & 0x000f0000u) >> 4;
3825 func (stream, "#%u", imm);
3826 value_in_comment = imm;
3832 unsigned int imm = 0;
3834 imm |= (given & 0x000f0000u) >> 16;
3835 imm |= (given & 0x00000ff0u) >> 0;
3836 imm |= (given & 0x0000000fu) << 12;
3837 func (stream, "#%u", imm);
3838 value_in_comment = imm;
3844 unsigned int imm = 0;
3846 imm |= (given & 0x00000fffu);
3847 imm |= (given & 0x000f0000u) >> 4;
3848 func (stream, "#%u", imm);
3849 value_in_comment = imm;
3855 unsigned int reg = (given & 0x0000000fu);
3856 unsigned int stp = (given & 0x00000030u) >> 4;
3857 unsigned int imm = 0;
3858 imm |= (given & 0x000000c0u) >> 6;
3859 imm |= (given & 0x00007000u) >> 10;
3861 func (stream, "%s", arm_regnames[reg]);
3866 func (stream, ", lsl #%u", imm);
3872 func (stream, ", lsr #%u", imm);
3878 func (stream, ", asr #%u", imm);
3883 func (stream, ", rrx");
3885 func (stream, ", ror #%u", imm);
3892 unsigned int Rn = (given & 0x000f0000) >> 16;
3893 unsigned int U = ! NEGATIVE_BIT_SET;
3894 unsigned int op = (given & 0x00000f00) >> 8;
3895 unsigned int i12 = (given & 0x00000fff);
3896 unsigned int i8 = (given & 0x000000ff);
3897 bfd_boolean writeback = FALSE, postind = FALSE;
3900 func (stream, "[%s", arm_regnames[Rn]);
3901 if (U) /* 12-bit positive immediate offset. */
3905 value_in_comment = offset;
3907 else if (Rn == 15) /* 12-bit negative immediate offset. */
3908 offset = - (int) i12;
3909 else if (op == 0x0) /* Shifted register offset. */
3911 unsigned int Rm = (i8 & 0x0f);
3912 unsigned int sh = (i8 & 0x30) >> 4;
3914 func (stream, ", %s", arm_regnames[Rm]);
3916 func (stream, ", lsl #%u", sh);
3922 case 0xE: /* 8-bit positive immediate offset. */
3926 case 0xC: /* 8-bit negative immediate offset. */
3930 case 0xF: /* 8-bit + preindex with wb. */
3935 case 0xD: /* 8-bit - preindex with wb. */
3940 case 0xB: /* 8-bit + postindex. */
3945 case 0x9: /* 8-bit - postindex. */
3951 func (stream, ", <undefined>]");
3956 func (stream, "], #%d", offset);
3960 func (stream, ", #%d", offset);
3961 func (stream, writeback ? "]!" : "]");
3966 func (stream, "\t; ");
3967 info->print_address_func (((pc + 4) & ~3) + offset, info);
3975 unsigned int U = ! NEGATIVE_BIT_SET;
3976 unsigned int W = WRITEBACK_BIT_SET;
3977 unsigned int Rn = (given & 0x000f0000) >> 16;
3978 unsigned int off = (given & 0x000000ff);
3980 func (stream, "[%s", arm_regnames[Rn]);
3986 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3987 value_in_comment = off * 4 * U ? 1 : -1;
3995 func (stream, "], ");
3998 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3999 value_in_comment = off * 4 * U ? 1 : -1;
4003 func (stream, "{%u}", off);
4004 value_in_comment = off;
4012 unsigned int Sbit = (given & 0x01000000) >> 24;
4013 unsigned int type = (given & 0x00600000) >> 21;
4017 case 0: func (stream, Sbit ? "sb" : "b"); break;
4018 case 1: func (stream, Sbit ? "sh" : "h"); break;
4021 func (stream, "??");
4024 func (stream, "??");
4036 for (reg = 0; reg < 16; reg++)
4037 if ((given & (1 << reg)) != 0)
4040 func (stream, ", ");
4042 func (stream, "%s", arm_regnames[reg]);
4050 unsigned int msb = (given & 0x0000001f);
4051 unsigned int lsb = 0;
4053 lsb |= (given & 0x000000c0u) >> 6;
4054 lsb |= (given & 0x00007000u) >> 10;
4055 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
4061 unsigned int width = (given & 0x0000001f) + 1;
4062 unsigned int lsb = 0;
4064 lsb |= (given & 0x000000c0u) >> 6;
4065 lsb |= (given & 0x00007000u) >> 10;
4066 func (stream, "#%u, #%u", lsb, width);
4072 unsigned int S = (given & 0x04000000u) >> 26;
4073 unsigned int J1 = (given & 0x00002000u) >> 13;
4074 unsigned int J2 = (given & 0x00000800u) >> 11;
4080 offset |= (given & 0x003f0000) >> 4;
4081 offset |= (given & 0x000007ff) << 1;
4082 offset -= (1 << 20);
4084 info->print_address_func (pc + 4 + offset, info);
4090 unsigned int S = (given & 0x04000000u) >> 26;
4091 unsigned int I1 = (given & 0x00002000u) >> 13;
4092 unsigned int I2 = (given & 0x00000800u) >> 11;
4096 offset |= !(I1 ^ S) << 23;
4097 offset |= !(I2 ^ S) << 22;
4098 offset |= (given & 0x03ff0000u) >> 4;
4099 offset |= (given & 0x000007ffu) << 1;
4100 offset -= (1 << 24);
4103 /* BLX target addresses are always word aligned. */
4104 if ((given & 0x00001000u) == 0)
4107 info->print_address_func (offset, info);
4113 unsigned int shift = 0;
4115 shift |= (given & 0x000000c0u) >> 6;
4116 shift |= (given & 0x00007000u) >> 10;
4117 if (WRITEBACK_BIT_SET)
4118 func (stream, ", asr #%u", shift);
4120 func (stream, ", lsl #%u", shift);
4121 /* else print nothing - lsl #0 */
4127 unsigned int rot = (given & 0x00000030) >> 4;
4130 func (stream, ", ror #%u", rot * 8);
4135 if ((given & 0xf0) == 0x60)
4137 switch (given & 0xf)
4139 case 0xf: func (stream, "sy"); break;
4141 func (stream, "#%d", (int) given & 0xf);
4147 switch (given & 0xf)
4149 case 0xf: func (stream, "sy"); break;
4150 case 0x7: func (stream, "un"); break;
4151 case 0xe: func (stream, "st"); break;
4152 case 0x6: func (stream, "unst"); break;
4153 case 0xb: func (stream, "ish"); break;
4154 case 0xa: func (stream, "ishst"); break;
4155 case 0x3: func (stream, "osh"); break;
4156 case 0x2: func (stream, "oshst"); break;
4158 func (stream, "#%d", (int) given & 0xf);
4165 if ((given & 0xff) == 0)
4167 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
4177 else if ((given & 0x20) == 0x20)
4180 unsigned sysm = (given & 0xf00) >> 8;
4182 sysm |= (given & 0x30);
4183 sysm |= (given & 0x00100000) >> 14;
4184 name = banked_regname (sysm);
4187 func (stream, "%s", name);
4189 func (stream, "(UNDEF: %lu)", sysm);
4193 func (stream, psr_name (given & 0xff));
4198 if (((given & 0xff) == 0)
4199 || ((given & 0x20) == 0x20))
4202 unsigned sm = (given & 0xf0000) >> 16;
4204 sm |= (given & 0x30);
4205 sm |= (given & 0x00100000) >> 14;
4206 name = banked_regname (sm);
4209 func (stream, "%s", name);
4211 func (stream, "(UNDEF: %lu)", sm);
4214 func (stream, psr_name (given & 0xff));
4217 case '0': case '1': case '2': case '3': case '4':
4218 case '5': case '6': case '7': case '8': case '9':
4223 c = arm_decode_bitfield (c, given, &val, &width);
4228 func (stream, "%lu", val);
4229 value_in_comment = val;
4233 func (stream, "%lu", val * 4);
4234 value_in_comment = val * 4;
4239 is_unpredictable = TRUE;
4242 func (stream, "%s", arm_regnames[val]);
4246 func (stream, "%s", arm_conditional[val]);
4251 if (val == ((1ul << width) - 1))
4252 func (stream, "%c", *c);
4258 func (stream, "%c", *c);
4262 func (stream, "%c", c[(1 << width) - (int) val]);
4267 func (stream, "0x%lx", val & 0xffffffffUL);
4281 if (value_in_comment > 32 || value_in_comment < -16)
4282 func (stream, "\t; 0x%lx", value_in_comment);
4284 if (is_unpredictable)
4285 func (stream, UNPREDICTABLE_INSTRUCTION);
4294 /* Print data bytes on INFO->STREAM. */
4297 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4298 struct disassemble_info *info,
4301 switch (info->bytes_per_chunk)
4304 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4307 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4310 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4317 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4318 being displayed in symbol relative addresses. */
4321 arm_symbol_is_valid (asymbol * sym,
4322 struct disassemble_info * info ATTRIBUTE_UNUSED)
4329 name = bfd_asymbol_name (sym);
4331 return (name && *name != '$');
4334 /* Parse an individual disassembler option. */
4337 parse_arm_disassembler_option (char *option)
4342 if (CONST_STRNEQ (option, "reg-names-"))
4348 for (i = NUM_ARM_REGNAMES; i--;)
4349 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4351 regname_selected = i;
4356 /* XXX - should break 'option' at following delimiter. */
4357 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4359 else if (CONST_STRNEQ (option, "force-thumb"))
4361 else if (CONST_STRNEQ (option, "no-force-thumb"))
4364 /* XXX - should break 'option' at following delimiter. */
4365 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4370 /* Parse the string of disassembler options, spliting it at whitespaces
4371 or commas. (Whitespace separators supported for backwards compatibility). */
4374 parse_disassembler_options (char *options)
4376 if (options == NULL)
4381 parse_arm_disassembler_option (options);
4383 /* Skip forward to next seperator. */
4384 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4386 /* Skip forward past seperators. */
4387 while (ISSPACE (*options) || (*options == ','))
4392 /* Search back through the insn stream to determine if this instruction is
4393 conditionally executed. */
4396 find_ifthen_state (bfd_vma pc,
4397 struct disassemble_info *info,
4403 /* COUNT is twice the number of instructions seen. It will be odd if we
4404 just crossed an instruction boundary. */
4407 unsigned int seen_it;
4410 ifthen_address = pc;
4417 /* Scan backwards looking for IT instructions, keeping track of where
4418 instruction boundaries are. We don't know if something is actually an
4419 IT instruction until we find a definite instruction boundary. */
4422 if (addr == 0 || info->symbol_at_address_func (addr, info))
4424 /* A symbol must be on an instruction boundary, and will not
4425 be within an IT block. */
4426 if (seen_it && (count & 1))
4432 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4437 insn = (b[0]) | (b[1] << 8);
4439 insn = (b[1]) | (b[0] << 8);
4442 if ((insn & 0xf800) < 0xe800)
4444 /* Addr + 2 is an instruction boundary. See if this matches
4445 the expected boundary based on the position of the last
4452 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4454 /* This could be an IT instruction. */
4456 it_count = count >> 1;
4458 if ((insn & 0xf800) >= 0xe800)
4461 count = (count + 2) | 1;
4462 /* IT blocks contain at most 4 instructions. */
4463 if (count >= 8 && !seen_it)
4466 /* We found an IT instruction. */
4467 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4468 if ((ifthen_state & 0xf) == 0)
4472 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4476 is_mapping_symbol (struct disassemble_info *info, int n,
4477 enum map_type *map_type)
4481 name = bfd_asymbol_name (info->symtab[n]);
4482 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4483 && (name[2] == 0 || name[2] == '.'))
4485 *map_type = ((name[1] == 'a') ? MAP_ARM
4486 : (name[1] == 't') ? MAP_THUMB
4494 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4495 Returns nonzero if *MAP_TYPE was set. */
4498 get_map_sym_type (struct disassemble_info *info,
4500 enum map_type *map_type)
4502 /* If the symbol is in a different section, ignore it. */
4503 if (info->section != NULL && info->section != info->symtab[n]->section)
4506 return is_mapping_symbol (info, n, map_type);
4509 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4510 Returns nonzero if *MAP_TYPE was set. */
4513 get_sym_code_type (struct disassemble_info *info,
4515 enum map_type *map_type)
4517 elf_symbol_type *es;
4520 /* If the symbol is in a different section, ignore it. */
4521 if (info->section != NULL && info->section != info->symtab[n]->section)
4524 es = *(elf_symbol_type **)(info->symtab + n);
4525 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4527 /* If the symbol has function type then use that. */
4528 if (type == STT_FUNC || type == STT_GNU_IFUNC)
4530 if (ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym) == ST_BRANCH_TO_THUMB)
4531 *map_type = MAP_THUMB;
4533 *map_type = MAP_ARM;
4540 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4541 of the supplied arm_feature_set structure with bitmasks indicating
4542 the support base architectures and coprocessor extensions.
4544 FIXME: This could more efficiently implemented as a constant array,
4545 although it would also be less robust. */
4548 select_arm_features (unsigned long mach,
4549 arm_feature_set * features)
4552 #define ARM_FEATURE(ARCH,CEXT) \
4553 features->core = (ARCH); \
4554 features->coproc = (CEXT) | FPU_FPA; \
4559 case bfd_mach_arm_2: ARM_ARCH_V2;
4560 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4561 case bfd_mach_arm_3: ARM_ARCH_V3;
4562 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4563 case bfd_mach_arm_4: ARM_ARCH_V4;
4564 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4565 case bfd_mach_arm_5: ARM_ARCH_V5;
4566 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4567 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4568 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4569 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4570 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4571 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4572 /* If the machine type is unknown allow all
4573 architecture types and all extensions. */
4574 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4581 /* NOTE: There are no checks in these routines that
4582 the relevant number of data bytes exist. */
4585 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4590 int is_thumb = FALSE;
4591 int is_data = FALSE;
4593 unsigned int size = 4;
4594 void (*printer) (bfd_vma, struct disassemble_info *, long);
4595 bfd_boolean found = FALSE;
4596 struct arm_private_data *private_data;
4598 if (info->disassembler_options)
4600 parse_disassembler_options (info->disassembler_options);
4602 /* To avoid repeated parsing of these options, we remove them here. */
4603 info->disassembler_options = NULL;
4606 /* PR 10288: Control which instructions will be disassembled. */
4607 if (info->private_data == NULL)
4609 static struct arm_private_data private;
4611 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4612 /* If the user did not use the -m command line switch then default to
4613 disassembling all types of ARM instruction.
4615 The info->mach value has to be ignored as this will be based on
4616 the default archictecture for the target and/or hints in the notes
4617 section, but it will never be greater than the current largest arm
4618 machine value (iWMMXt2), which is only equivalent to the V5TE
4619 architecture. ARM architectures have advanced beyond the machine
4620 value encoding, and these newer architectures would be ignored if
4621 the machine value was used.
4623 Ie the -m switch is used to restrict which instructions will be
4624 disassembled. If it is necessary to use the -m switch to tell
4625 objdump that an ARM binary is being disassembled, eg because the
4626 input is a raw binary file, but it is also desired to disassemble
4627 all ARM instructions then use "-marm". This will select the
4628 "unknown" arm architecture which is compatible with any ARM
4630 info->mach = bfd_mach_arm_unknown;
4632 /* Compute the architecture bitmask from the machine number.
4633 Note: This assumes that the machine number will not change
4634 during disassembly.... */
4635 select_arm_features (info->mach, & private.features);
4637 private.has_mapping_symbols = -1;
4639 info->private_data = & private;
4642 private_data = info->private_data;
4644 /* Decide if our code is going to be little-endian, despite what the
4645 function argument might say. */
4646 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4648 /* For ELF, consult the symbol table to determine what kind of code
4650 if (info->symtab_size != 0
4651 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4656 enum map_type type = MAP_ARM;
4658 /* Start scanning at the start of the function, or wherever
4659 we finished last time. */
4660 start = info->symtab_pos + 1;
4661 if (start < last_mapping_sym)
4662 start = last_mapping_sym;
4665 /* First, look for mapping symbols. */
4666 if (private_data->has_mapping_symbols != 0)
4668 /* Scan up to the location being disassembled. */
4669 for (n = start; n < info->symtab_size; n++)
4671 addr = bfd_asymbol_value (info->symtab[n]);
4674 if (get_map_sym_type (info, n, &type))
4683 /* No mapping symbol found at this address. Look backwards
4684 for a preceeding one. */
4685 for (n = start - 1; n >= 0; n--)
4687 if (get_map_sym_type (info, n, &type))
4697 private_data->has_mapping_symbols = 1;
4699 /* No mapping symbols were found. A leading $d may be
4700 omitted for sections which start with data; but for
4701 compatibility with legacy and stripped binaries, only
4702 assume the leading $d if there is at least one mapping
4703 symbol in the file. */
4704 if (!found && private_data->has_mapping_symbols == -1)
4706 /* Look for mapping symbols, in any section. */
4707 for (n = 0; n < info->symtab_size; n++)
4708 if (is_mapping_symbol (info, n, &type))
4710 private_data->has_mapping_symbols = 1;
4713 if (private_data->has_mapping_symbols == -1)
4714 private_data->has_mapping_symbols = 0;
4717 if (!found && private_data->has_mapping_symbols == 1)
4724 /* Next search for function symbols to separate ARM from Thumb
4725 in binaries without mapping symbols. */
4728 /* Scan up to the location being disassembled. */
4729 for (n = start; n < info->symtab_size; n++)
4731 addr = bfd_asymbol_value (info->symtab[n]);
4734 if (get_sym_code_type (info, n, &type))
4743 /* No mapping symbol found at this address. Look backwards
4744 for a preceeding one. */
4745 for (n = start - 1; n >= 0; n--)
4747 if (get_sym_code_type (info, n, &type))
4757 last_mapping_sym = last_sym;
4759 is_thumb = (last_type == MAP_THUMB);
4760 is_data = (last_type == MAP_DATA);
4762 /* Look a little bit ahead to see if we should print out
4763 two or four bytes of data. If there's a symbol,
4764 mapping or otherwise, after two bytes then don't
4768 size = 4 - (pc & 3);
4769 for (n = last_sym + 1; n < info->symtab_size; n++)
4771 addr = bfd_asymbol_value (info->symtab[n]);
4773 && (info->section == NULL
4774 || info->section == info->symtab[n]->section))
4776 if (addr - pc < size)
4781 /* If the next symbol is after three bytes, we need to
4782 print only part of the data, so that we can use either
4785 size = (pc & 1) ? 1 : 2;
4789 if (info->symbols != NULL)
4791 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4793 coff_symbol_type * cs;
4795 cs = coffsymbol (*info->symbols);
4796 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4797 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4798 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4799 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4800 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4802 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4805 /* If no mapping symbol has been found then fall back to the type
4806 of the function symbol. */
4807 elf_symbol_type * es;
4810 es = *(elf_symbol_type **)(info->symbols);
4811 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4813 is_thumb = ((ARM_SYM_BRANCH_TYPE (&es->internal_elf_sym)
4814 == ST_BRANCH_TO_THUMB)
4815 || type == STT_ARM_16BIT);
4823 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4825 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4827 info->bytes_per_line = 4;
4829 /* PR 10263: Disassemble data if requested to do so by the user. */
4830 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4834 /* Size was already set above. */
4835 info->bytes_per_chunk = size;
4836 printer = print_insn_data;
4838 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4841 for (i = size - 1; i >= 0; i--)
4842 given = b[i] | (given << 8);
4844 for (i = 0; i < (int) size; i++)
4845 given = b[i] | (given << 8);
4849 /* In ARM mode endianness is a straightforward issue: the instruction
4850 is four bytes long and is either ordered 0123 or 3210. */
4851 printer = print_insn_arm;
4852 info->bytes_per_chunk = 4;
4855 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4857 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4859 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4863 /* In Thumb mode we have the additional wrinkle of two
4864 instruction lengths. Fortunately, the bits that determine
4865 the length of the current instruction are always to be found
4866 in the first two bytes. */
4867 printer = print_insn_thumb16;
4868 info->bytes_per_chunk = 2;
4871 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4873 given = (b[0]) | (b[1] << 8);
4875 given = (b[1]) | (b[0] << 8);
4879 /* These bit patterns signal a four-byte Thumb
4881 if ((given & 0xF800) == 0xF800
4882 || (given & 0xF800) == 0xF000
4883 || (given & 0xF800) == 0xE800)
4885 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4887 given = (b[0]) | (b[1] << 8) | (given << 16);
4889 given = (b[1]) | (b[0] << 8) | (given << 16);
4891 printer = print_insn_thumb32;
4896 if (ifthen_address != pc)
4897 find_ifthen_state (pc, info, little_code);
4901 if ((ifthen_state & 0xf) == 0x8)
4902 ifthen_next_state = 0;
4904 ifthen_next_state = (ifthen_state & 0xe0)
4905 | ((ifthen_state & 0xf) << 1);
4911 info->memory_error_func (status, pc, info);
4914 if (info->flags & INSN_HAS_RELOC)
4915 /* If the instruction has a reloc associated with it, then
4916 the offset field in the instruction will actually be the
4917 addend for the reloc. (We are using REL type relocs).
4918 In such cases, we can ignore the pc when computing
4919 addresses, since the addend is not currently pc-relative. */
4922 printer (pc, info, given);
4926 ifthen_state = ifthen_next_state;
4927 ifthen_address += size;
4933 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4935 /* Detect BE8-ness and record it in the disassembler info. */
4936 if (info->flavour == bfd_target_elf_flavour
4937 && info->section != NULL
4938 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4939 info->endian_code = BFD_ENDIAN_LITTLE;
4941 return print_insn (pc, info, FALSE);
4945 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4947 return print_insn (pc, info, TRUE);
4951 print_arm_disassembler_options (FILE *stream)
4955 fprintf (stream, _("\n\
4956 The following ARM specific disassembler options are supported for use with\n\
4957 the -M switch:\n"));
4959 for (i = NUM_ARM_REGNAMES; i--;)
4960 fprintf (stream, " reg-names-%s %*c%s\n",
4962 (int)(14 - strlen (regnames[i].name)), ' ',
4963 regnames[i].description);
4965 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4966 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");