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 /* Cached mapping symbol state. */
56 struct arm_private_data
58 /* The features to use when disassembling optional instructions. */
59 arm_feature_set features
;
61 /* Whether any mapping symbols are present in the provided symbol
62 table. -1 if we do not know yet, otherwise 0 or 1. */
63 int has_mapping_symbols
;
65 /* Track the last type (although this doesn't seem to be useful) */
66 enum map_type last_type
;
68 /* Tracking symbol table information */
70 bfd_vma last_mapping_addr
;
75 unsigned long arch
; /* Architecture defining this insn. */
76 unsigned long value
; /* If arch == 0 then value is a sentinel. */
77 unsigned long mask
; /* Recognise insn if (op & mask) == value. */
78 const char * assembler
; /* How to disassemble this insn. */
83 unsigned long arch
; /* Architecture defining this insn. */
84 unsigned short value
, mask
; /* Recognise insn if (op & mask) == value. */
85 const char *assembler
; /* How to disassemble this insn. */
88 /* print_insn_coprocessor recognizes the following format control codes:
92 %c print condition code (always bits 28-31 in ARM mode)
93 %q print shifter argument
94 %u print condition code (unconditional in ARM mode)
95 %A print address for ldc/stc/ldf/stf instruction
96 %B print vstm/vldm register list
97 %I print cirrus signed shift immediate: bits 0..3|4..6
98 %F print the COUNT field of a LFM/SFM instruction.
99 %P print floating point precision in arithmetic insn
100 %Q print floating point precision in ldf/stf insn
101 %R print floating point rounding mode
103 %<bitfield>r print as an ARM register
104 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
105 %<bitfield>ru as %<>r but each u register must be unique.
106 %<bitfield>d print the bitfield in decimal
107 %<bitfield>k print immediate for VFPv3 conversion instruction
108 %<bitfield>x print the bitfield in hex
109 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
110 %<bitfield>f print a floating point constant if >7 else a
111 floating point register
112 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
113 %<bitfield>g print as an iWMMXt 64-bit register
114 %<bitfield>G print as an iWMMXt general purpose or control register
115 %<bitfield>D print as a NEON D register
116 %<bitfield>Q print as a NEON Q register
118 %y<code> print a single precision VFP reg.
119 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
120 %z<code> print a double precision VFP reg
121 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
123 %<bitfield>'c print specified char iff bitfield is all ones
124 %<bitfield>`c print specified char iff bitfield is all zeroes
125 %<bitfield>?ab... select from array of values in big endian order
127 %L print as an iWMMXt N/M width field.
128 %Z print the Immediate of a WSHUFH instruction.
129 %l like 'A' except use byte offsets for 'B' & 'H'
131 %i print 5-bit immediate in bits 8,3..0
133 %r print register offset address for wldt/wstr instruction. */
135 enum opcode_sentinel_enum
137 SENTINEL_IWMMXT_START
= 1,
139 SENTINEL_GENERIC_START
142 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
143 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
145 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
147 static const struct opcode32 coprocessor_opcodes
[] =
149 /* XScale instructions. */
150 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
151 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
152 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
153 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
154 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
156 /* Intel Wireless MMX technology instructions. */
157 { 0, SENTINEL_IWMMXT_START
, 0, "" },
158 {ARM_CEXT_IWMMXT
, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
159 {ARM_CEXT_XSCALE
, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
160 {ARM_CEXT_XSCALE
, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
161 {ARM_CEXT_XSCALE
, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
162 {ARM_CEXT_XSCALE
, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
163 {ARM_CEXT_XSCALE
, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
164 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
165 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
166 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
167 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
168 {ARM_CEXT_XSCALE
, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
169 {ARM_CEXT_XSCALE
, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
170 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
171 {ARM_CEXT_XSCALE
, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
172 {ARM_CEXT_XSCALE
, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
173 {ARM_CEXT_XSCALE
, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
174 {ARM_CEXT_XSCALE
, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
175 {ARM_CEXT_XSCALE
, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
176 {ARM_CEXT_XSCALE
, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
177 {ARM_CEXT_XSCALE
, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
178 {ARM_CEXT_XSCALE
, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
179 {ARM_CEXT_XSCALE
, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
180 {ARM_CEXT_XSCALE
, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE
, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE
, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE
, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE
, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE
, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
186 {ARM_CEXT_XSCALE
, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
187 {ARM_CEXT_XSCALE
, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
188 {ARM_CEXT_XSCALE
, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE
, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
190 {ARM_CEXT_XSCALE
, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
191 {ARM_CEXT_XSCALE
, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
192 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
193 {ARM_CEXT_XSCALE
, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
194 {ARM_CEXT_XSCALE
, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE
, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
196 {ARM_CEXT_XSCALE
, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
197 {ARM_CEXT_XSCALE
, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE
, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
199 {ARM_CEXT_XSCALE
, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
200 {ARM_CEXT_XSCALE
, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE
, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
202 {ARM_CEXT_XSCALE
, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
203 {ARM_CEXT_XSCALE
, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE
, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
205 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
206 {ARM_CEXT_XSCALE
, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
207 {ARM_CEXT_XSCALE
, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
208 {ARM_CEXT_XSCALE
, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
209 {ARM_CEXT_XSCALE
, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
210 {ARM_CEXT_XSCALE
, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
211 {ARM_CEXT_XSCALE
, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
212 {ARM_CEXT_XSCALE
, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
213 {ARM_CEXT_XSCALE
, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
214 {ARM_CEXT_XSCALE
, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
215 {ARM_CEXT_XSCALE
, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
216 {ARM_CEXT_XSCALE
, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
217 {ARM_CEXT_XSCALE
, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
218 {ARM_CEXT_XSCALE
, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
219 {ARM_CEXT_XSCALE
, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
220 {ARM_CEXT_XSCALE
, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
221 {ARM_CEXT_XSCALE
, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
222 {ARM_CEXT_XSCALE
, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
223 {ARM_CEXT_XSCALE
, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
224 {ARM_CEXT_XSCALE
, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
225 {ARM_CEXT_XSCALE
, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
226 {ARM_CEXT_XSCALE
, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
227 {ARM_CEXT_XSCALE
, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
228 {ARM_CEXT_XSCALE
, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
229 {ARM_CEXT_XSCALE
, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
230 {ARM_CEXT_XSCALE
, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
231 {ARM_CEXT_XSCALE
, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
232 {ARM_CEXT_XSCALE
, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
233 { 0, SENTINEL_IWMMXT_END
, 0, "" },
235 /* Floating point coprocessor (FPA) instructions. */
236 {FPU_FPA_EXT_V1
, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
237 {FPU_FPA_EXT_V1
, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
238 {FPU_FPA_EXT_V1
, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
239 {FPU_FPA_EXT_V1
, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
240 {FPU_FPA_EXT_V1
, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
241 {FPU_FPA_EXT_V1
, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
242 {FPU_FPA_EXT_V1
, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
243 {FPU_FPA_EXT_V1
, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
244 {FPU_FPA_EXT_V1
, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
245 {FPU_FPA_EXT_V1
, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
246 {FPU_FPA_EXT_V1
, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
247 {FPU_FPA_EXT_V1
, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
248 {FPU_FPA_EXT_V1
, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
249 {FPU_FPA_EXT_V1
, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
250 {FPU_FPA_EXT_V1
, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
251 {FPU_FPA_EXT_V1
, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
252 {FPU_FPA_EXT_V1
, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
253 {FPU_FPA_EXT_V1
, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
254 {FPU_FPA_EXT_V1
, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
255 {FPU_FPA_EXT_V1
, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
256 {FPU_FPA_EXT_V1
, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
257 {FPU_FPA_EXT_V1
, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
258 {FPU_FPA_EXT_V1
, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
259 {FPU_FPA_EXT_V1
, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
260 {FPU_FPA_EXT_V1
, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
261 {FPU_FPA_EXT_V1
, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
262 {FPU_FPA_EXT_V1
, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
263 {FPU_FPA_EXT_V1
, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
264 {FPU_FPA_EXT_V1
, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
265 {FPU_FPA_EXT_V1
, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
266 {FPU_FPA_EXT_V1
, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
267 {FPU_FPA_EXT_V1
, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
268 {FPU_FPA_EXT_V1
, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
269 {FPU_FPA_EXT_V1
, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
270 {FPU_FPA_EXT_V1
, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
271 {FPU_FPA_EXT_V1
, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
272 {FPU_FPA_EXT_V1
, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
273 {FPU_FPA_EXT_V1
, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
274 {FPU_FPA_EXT_V1
, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
275 {FPU_FPA_EXT_V1
, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
276 {FPU_FPA_EXT_V1
, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
277 {FPU_FPA_EXT_V2
, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
278 {FPU_FPA_EXT_V2
, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
280 /* Register load/store. */
281 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
282 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
283 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
284 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
285 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
286 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
287 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
288 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
289 {FPU_VFP_EXT_V1xD
, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
290 {FPU_VFP_EXT_V1xD
, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
291 {FPU_VFP_EXT_V1xD
, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
292 {FPU_VFP_EXT_V1xD
, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
293 {FPU_VFP_EXT_V1xD
, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
294 {FPU_VFP_EXT_V1xD
, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
295 {FPU_VFP_EXT_V1xD
, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
296 {FPU_VFP_EXT_V1xD
, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
298 {FPU_VFP_EXT_V1xD
, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
299 {FPU_VFP_EXT_V1xD
, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
300 {FPU_VFP_EXT_V1xD
, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
301 {FPU_VFP_EXT_V1xD
, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
303 /* Data transfer between ARM and NEON registers. */
304 {FPU_NEON_EXT_V1
, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
305 {FPU_NEON_EXT_V1
, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
306 {FPU_NEON_EXT_V1
, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
307 {FPU_NEON_EXT_V1
, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
308 {FPU_NEON_EXT_V1
, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
309 {FPU_NEON_EXT_V1
, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
310 {FPU_NEON_EXT_V1
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
311 {FPU_NEON_EXT_V1
, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
312 {FPU_NEON_EXT_V1
, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
313 {FPU_NEON_EXT_V1
, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
314 {FPU_NEON_EXT_V1
, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
315 {FPU_NEON_EXT_V1
, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
316 {FPU_NEON_EXT_V1
, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
317 {FPU_NEON_EXT_V1
, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
318 /* Half-precision conversion instructions. */
319 {FPU_VFP_EXT_FP16
, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
320 {FPU_VFP_EXT_FP16
, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
322 /* Floating point coprocessor (VFP) instructions. */
323 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
324 {FPU_VFP_EXT_V1xD
, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
325 {FPU_VFP_EXT_V1xD
, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
326 {FPU_VFP_EXT_V1xD
, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
327 {FPU_VFP_EXT_V1xD
, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
328 {FPU_VFP_EXT_V1xD
, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
329 {FPU_VFP_EXT_V1xD
, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
330 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
331 {FPU_VFP_EXT_V1xD
, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
332 {FPU_VFP_EXT_V1xD
, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
333 {FPU_VFP_EXT_V1xD
, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
334 {FPU_VFP_EXT_V1xD
, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
335 {FPU_VFP_EXT_V1xD
, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
336 {FPU_VFP_EXT_V1xD
, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
337 {FPU_VFP_EXT_V1xD
, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
338 {FPU_VFP_EXT_V1
, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
339 {FPU_VFP_EXT_V1
, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
340 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
341 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
342 {FPU_VFP_EXT_V1xD
, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
343 {FPU_VFP_EXT_V1xD
, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
344 {FPU_VFP_EXT_V1xD
, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
345 {FPU_VFP_EXT_V1
, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
346 {FPU_VFP_EXT_V1xD
, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
347 {FPU_VFP_EXT_V1xD
, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
348 {FPU_VFP_EXT_V1
, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
349 {FPU_VFP_EXT_V1
, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
350 {FPU_VFP_EXT_V1xD
, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
351 {FPU_VFP_EXT_V1xD
, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
352 {FPU_VFP_EXT_V1
, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
353 {FPU_VFP_EXT_V1
, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
354 {FPU_VFP_EXT_V1
, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
355 {FPU_VFP_EXT_V1
, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
356 {FPU_VFP_EXT_V1xD
, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
357 {FPU_VFP_EXT_V1
, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
358 {FPU_VFP_EXT_V1xD
, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
359 {FPU_VFP_EXT_V1
, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
360 {FPU_VFP_EXT_V3xD
, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
361 {FPU_VFP_EXT_V3
, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
362 {FPU_VFP_EXT_V1xD
, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
363 {FPU_VFP_EXT_V1
, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
364 {FPU_VFP_EXT_V3xD
, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
365 {FPU_VFP_EXT_V3
, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
366 {FPU_VFP_EXT_V1
, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
367 {FPU_VFP_EXT_V3xD
, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
368 {FPU_VFP_EXT_V3
, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
369 {FPU_VFP_EXT_V2
, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
370 {FPU_VFP_EXT_V2
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
371 {FPU_VFP_EXT_V2
, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
372 {FPU_VFP_EXT_V1xD
, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
373 {FPU_VFP_EXT_V1xD
, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
374 {FPU_VFP_EXT_V1
, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
375 {FPU_VFP_EXT_V1
, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
376 {FPU_VFP_EXT_V1xD
, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
377 {FPU_VFP_EXT_V1xD
, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
378 {FPU_VFP_EXT_V1
, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
379 {FPU_VFP_EXT_V1
, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
380 {FPU_VFP_EXT_V1xD
, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
381 {FPU_VFP_EXT_V1xD
, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
382 {FPU_VFP_EXT_V1
, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
383 {FPU_VFP_EXT_V1
, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
384 {FPU_VFP_EXT_V1xD
, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
385 {FPU_VFP_EXT_V1xD
, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
386 {FPU_VFP_EXT_V1
, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
387 {FPU_VFP_EXT_V1
, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
388 {FPU_VFP_EXT_V1xD
, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
389 {FPU_VFP_EXT_V1
, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
391 /* Cirrus coprocessor instructions. */
392 {ARM_CEXT_MAVERICK
, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
393 {ARM_CEXT_MAVERICK
, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
394 {ARM_CEXT_MAVERICK
, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
395 {ARM_CEXT_MAVERICK
, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
396 {ARM_CEXT_MAVERICK
, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
397 {ARM_CEXT_MAVERICK
, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
398 {ARM_CEXT_MAVERICK
, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
399 {ARM_CEXT_MAVERICK
, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
400 {ARM_CEXT_MAVERICK
, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
401 {ARM_CEXT_MAVERICK
, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
402 {ARM_CEXT_MAVERICK
, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
403 {ARM_CEXT_MAVERICK
, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
404 {ARM_CEXT_MAVERICK
, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
405 {ARM_CEXT_MAVERICK
, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
406 {ARM_CEXT_MAVERICK
, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
407 {ARM_CEXT_MAVERICK
, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
408 {ARM_CEXT_MAVERICK
, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
409 {ARM_CEXT_MAVERICK
, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
410 {ARM_CEXT_MAVERICK
, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
411 {ARM_CEXT_MAVERICK
, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
412 {ARM_CEXT_MAVERICK
, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
413 {ARM_CEXT_MAVERICK
, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
414 {ARM_CEXT_MAVERICK
, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
415 {ARM_CEXT_MAVERICK
, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
416 {ARM_CEXT_MAVERICK
, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
417 {ARM_CEXT_MAVERICK
, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
418 {ARM_CEXT_MAVERICK
, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
419 {ARM_CEXT_MAVERICK
, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
420 {ARM_CEXT_MAVERICK
, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
421 {ARM_CEXT_MAVERICK
, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
422 {ARM_CEXT_MAVERICK
, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
423 {ARM_CEXT_MAVERICK
, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
424 {ARM_CEXT_MAVERICK
, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
425 {ARM_CEXT_MAVERICK
, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
426 {ARM_CEXT_MAVERICK
, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
427 {ARM_CEXT_MAVERICK
, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
428 {ARM_CEXT_MAVERICK
, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
429 {ARM_CEXT_MAVERICK
, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
430 {ARM_CEXT_MAVERICK
, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
431 {ARM_CEXT_MAVERICK
, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
432 {ARM_CEXT_MAVERICK
, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
433 {ARM_CEXT_MAVERICK
, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
434 {ARM_CEXT_MAVERICK
, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
435 {ARM_CEXT_MAVERICK
, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
436 {ARM_CEXT_MAVERICK
, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
437 {ARM_CEXT_MAVERICK
, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
438 {ARM_CEXT_MAVERICK
, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
439 {ARM_CEXT_MAVERICK
, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
440 {ARM_CEXT_MAVERICK
, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
441 {ARM_CEXT_MAVERICK
, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
442 {ARM_CEXT_MAVERICK
, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
443 {ARM_CEXT_MAVERICK
, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
444 {ARM_CEXT_MAVERICK
, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
445 {ARM_CEXT_MAVERICK
, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
446 {ARM_CEXT_MAVERICK
, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
447 {ARM_CEXT_MAVERICK
, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
448 {ARM_CEXT_MAVERICK
, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
449 {ARM_CEXT_MAVERICK
, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
450 {ARM_CEXT_MAVERICK
, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
451 {ARM_CEXT_MAVERICK
, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
452 {ARM_CEXT_MAVERICK
, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
453 {ARM_CEXT_MAVERICK
, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
454 {ARM_CEXT_MAVERICK
, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
455 {ARM_CEXT_MAVERICK
, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
456 {ARM_CEXT_MAVERICK
, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
457 {ARM_CEXT_MAVERICK
, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
458 {ARM_CEXT_MAVERICK
, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
459 {ARM_CEXT_MAVERICK
, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
460 {ARM_CEXT_MAVERICK
, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
461 {ARM_CEXT_MAVERICK
, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
462 {ARM_CEXT_MAVERICK
, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
463 {ARM_CEXT_MAVERICK
, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
464 {ARM_CEXT_MAVERICK
, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
465 {ARM_CEXT_MAVERICK
, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
466 {ARM_CEXT_MAVERICK
, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
467 {ARM_CEXT_MAVERICK
, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
468 {ARM_CEXT_MAVERICK
, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
469 {ARM_CEXT_MAVERICK
, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
470 {ARM_CEXT_MAVERICK
, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
471 {ARM_CEXT_MAVERICK
, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
472 {ARM_CEXT_MAVERICK
, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
473 {ARM_CEXT_MAVERICK
, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
474 {ARM_CEXT_MAVERICK
, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
475 {ARM_CEXT_MAVERICK
, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
477 /* VFP Fused multiply add instructions. */
478 {FPU_VFP_EXT_FMA
, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
479 {FPU_VFP_EXT_FMA
, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
480 {FPU_VFP_EXT_FMA
, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
481 {FPU_VFP_EXT_FMA
, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
482 {FPU_VFP_EXT_FMA
, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
483 {FPU_VFP_EXT_FMA
, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
484 {FPU_VFP_EXT_FMA
, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
485 {FPU_VFP_EXT_FMA
, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
487 /* Generic coprocessor instructions. */
488 { 0, SENTINEL_GENERIC_START
, 0, "" },
489 {ARM_EXT_V5E
, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
490 {ARM_EXT_V5E
, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
491 {ARM_EXT_V2
, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
492 {ARM_EXT_V2
, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
493 {ARM_EXT_V2
, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
494 {ARM_EXT_V2
, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
495 {ARM_EXT_V2
, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
496 {ARM_EXT_V2
, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
498 /* V6 coprocessor instructions. */
499 {ARM_EXT_V6
, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
500 {ARM_EXT_V6
, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
502 /* V5 coprocessor instructions. */
503 {ARM_EXT_V5
, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
504 {ARM_EXT_V5
, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
505 {ARM_EXT_V5
, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
506 {ARM_EXT_V5
, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
507 {ARM_EXT_V5
, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
512 /* Neon opcode table: This does not encode the top byte -- that is
513 checked by the print_insn_neon routine, as it depends on whether we are
514 doing thumb32 or arm32 disassembly. */
516 /* print_insn_neon recognizes the following format control codes:
520 %c print condition code
521 %A print v{st,ld}[1234] operands
522 %B print v{st,ld}[1234] any one operands
523 %C print v{st,ld}[1234] single->all operands
525 %E print vmov, vmvn, vorr, vbic encoded constant
526 %F print vtbl,vtbx register list
528 %<bitfield>r print as an ARM register
529 %<bitfield>d print the bitfield in decimal
530 %<bitfield>e print the 2^N - bitfield in decimal
531 %<bitfield>D print as a NEON D register
532 %<bitfield>Q print as a NEON Q register
533 %<bitfield>R print as a NEON D or Q register
534 %<bitfield>Sn print byte scaled width limited by n
535 %<bitfield>Tn print short scaled width limited by n
536 %<bitfield>Un print long scaled width limited by n
538 %<bitfield>'c print specified char iff bitfield is all ones
539 %<bitfield>`c print specified char iff bitfield is all zeroes
540 %<bitfield>?ab... select from array of values in big endian order. */
542 static const struct opcode32 neon_opcodes
[] =
545 {FPU_NEON_EXT_V1
, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
546 {FPU_NEON_EXT_V1
, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
548 /* Move data element to all lanes. */
549 {FPU_NEON_EXT_V1
, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
550 {FPU_NEON_EXT_V1
, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
551 {FPU_NEON_EXT_V1
, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
554 {FPU_NEON_EXT_V1
, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
555 {FPU_NEON_EXT_V1
, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
557 /* Half-precision conversions. */
558 {FPU_VFP_EXT_FP16
, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
559 {FPU_VFP_EXT_FP16
, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
561 /* NEON fused multiply add instructions. */
562 {FPU_NEON_EXT_FMA
, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
563 {FPU_NEON_EXT_FMA
, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
565 /* Two registers, miscellaneous. */
566 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
567 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
568 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
569 {FPU_NEON_EXT_V1
, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
570 {FPU_NEON_EXT_V1
, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
571 {FPU_NEON_EXT_V1
, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
572 {FPU_NEON_EXT_V1
, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
573 {FPU_NEON_EXT_V1
, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
574 {FPU_NEON_EXT_V1
, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
575 {FPU_NEON_EXT_V1
, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
576 {FPU_NEON_EXT_V1
, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
577 {FPU_NEON_EXT_V1
, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
578 {FPU_NEON_EXT_V1
, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
579 {FPU_NEON_EXT_V1
, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
580 {FPU_NEON_EXT_V1
, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
581 {FPU_NEON_EXT_V1
, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
582 {FPU_NEON_EXT_V1
, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
583 {FPU_NEON_EXT_V1
, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
584 {FPU_NEON_EXT_V1
, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
585 {FPU_NEON_EXT_V1
, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
586 {FPU_NEON_EXT_V1
, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
587 {FPU_NEON_EXT_V1
, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
588 {FPU_NEON_EXT_V1
, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
589 {FPU_NEON_EXT_V1
, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
590 {FPU_NEON_EXT_V1
, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
591 {FPU_NEON_EXT_V1
, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
592 {FPU_NEON_EXT_V1
, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
593 {FPU_NEON_EXT_V1
, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
594 {FPU_NEON_EXT_V1
, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
595 {FPU_NEON_EXT_V1
, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
596 {FPU_NEON_EXT_V1
, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
597 {FPU_NEON_EXT_V1
, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
598 {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"},
600 /* Three registers of the same length. */
601 {FPU_NEON_EXT_V1
, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
602 {FPU_NEON_EXT_V1
, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1
, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1
, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1
, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1
, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1
, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1
, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1
, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1
, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1
, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1
, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1
, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1
, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1
, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
616 {FPU_NEON_EXT_V1
, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
617 {FPU_NEON_EXT_V1
, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
618 {FPU_NEON_EXT_V1
, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
619 {FPU_NEON_EXT_V1
, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1
, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1
, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1
, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1
, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1
, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
625 {FPU_NEON_EXT_V1
, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
626 {FPU_NEON_EXT_V1
, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
627 {FPU_NEON_EXT_V1
, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
628 {FPU_NEON_EXT_V1
, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
629 {FPU_NEON_EXT_V1
, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
630 {FPU_NEON_EXT_V1
, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
631 {FPU_NEON_EXT_V1
, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
632 {FPU_NEON_EXT_V1
, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
633 {FPU_NEON_EXT_V1
, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
634 {FPU_NEON_EXT_V1
, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635 {FPU_NEON_EXT_V1
, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
636 {FPU_NEON_EXT_V1
, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
637 {FPU_NEON_EXT_V1
, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
638 {FPU_NEON_EXT_V1
, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
639 {FPU_NEON_EXT_V1
, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 {FPU_NEON_EXT_V1
, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
641 {FPU_NEON_EXT_V1
, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
642 {FPU_NEON_EXT_V1
, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
643 {FPU_NEON_EXT_V1
, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
644 {FPU_NEON_EXT_V1
, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
645 {FPU_NEON_EXT_V1
, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
646 {FPU_NEON_EXT_V1
, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
647 {FPU_NEON_EXT_V1
, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
648 {FPU_NEON_EXT_V1
, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
649 {FPU_NEON_EXT_V1
, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
650 {FPU_NEON_EXT_V1
, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
651 {FPU_NEON_EXT_V1
, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
652 {FPU_NEON_EXT_V1
, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
653 {FPU_NEON_EXT_V1
, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
655 /* One register and an immediate value. */
656 {FPU_NEON_EXT_V1
, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
657 {FPU_NEON_EXT_V1
, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
658 {FPU_NEON_EXT_V1
, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
659 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
660 {FPU_NEON_EXT_V1
, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
661 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
662 {FPU_NEON_EXT_V1
, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
663 {FPU_NEON_EXT_V1
, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
664 {FPU_NEON_EXT_V1
, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
665 {FPU_NEON_EXT_V1
, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
666 {FPU_NEON_EXT_V1
, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
667 {FPU_NEON_EXT_V1
, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
668 {FPU_NEON_EXT_V1
, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
670 /* Two registers and a shift amount. */
671 {FPU_NEON_EXT_V1
, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
672 {FPU_NEON_EXT_V1
, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
673 {FPU_NEON_EXT_V1
, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
674 {FPU_NEON_EXT_V1
, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
675 {FPU_NEON_EXT_V1
, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
676 {FPU_NEON_EXT_V1
, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
677 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
678 {FPU_NEON_EXT_V1
, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
679 {FPU_NEON_EXT_V1
, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
680 {FPU_NEON_EXT_V1
, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
681 {FPU_NEON_EXT_V1
, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
682 {FPU_NEON_EXT_V1
, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
683 {FPU_NEON_EXT_V1
, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
684 {FPU_NEON_EXT_V1
, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
685 {FPU_NEON_EXT_V1
, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
686 {FPU_NEON_EXT_V1
, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
687 {FPU_NEON_EXT_V1
, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
688 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
689 {FPU_NEON_EXT_V1
, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
690 {FPU_NEON_EXT_V1
, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
691 {FPU_NEON_EXT_V1
, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
692 {FPU_NEON_EXT_V1
, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
693 {FPU_NEON_EXT_V1
, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
694 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
695 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
696 {FPU_NEON_EXT_V1
, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
697 {FPU_NEON_EXT_V1
, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
698 {FPU_NEON_EXT_V1
, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
699 {FPU_NEON_EXT_V1
, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
700 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
701 {FPU_NEON_EXT_V1
, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
702 {FPU_NEON_EXT_V1
, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
703 {FPU_NEON_EXT_V1
, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
704 {FPU_NEON_EXT_V1
, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
705 {FPU_NEON_EXT_V1
, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
706 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
707 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
708 {FPU_NEON_EXT_V1
, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
709 {FPU_NEON_EXT_V1
, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
710 {FPU_NEON_EXT_V1
, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
711 {FPU_NEON_EXT_V1
, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
712 {FPU_NEON_EXT_V1
, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
713 {FPU_NEON_EXT_V1
, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
714 {FPU_NEON_EXT_V1
, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
715 {FPU_NEON_EXT_V1
, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
716 {FPU_NEON_EXT_V1
, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
717 {FPU_NEON_EXT_V1
, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
718 {FPU_NEON_EXT_V1
, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
719 {FPU_NEON_EXT_V1
, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
720 {FPU_NEON_EXT_V1
, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
721 {FPU_NEON_EXT_V1
, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
722 {FPU_NEON_EXT_V1
, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
723 {FPU_NEON_EXT_V1
, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
724 {FPU_NEON_EXT_V1
, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
725 {FPU_NEON_EXT_V1
, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
726 {FPU_NEON_EXT_V1
, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
727 {FPU_NEON_EXT_V1
, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
728 {FPU_NEON_EXT_V1
, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
730 /* Three registers of different lengths. */
731 {FPU_NEON_EXT_V1
, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
732 {FPU_NEON_EXT_V1
, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
733 {FPU_NEON_EXT_V1
, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
734 {FPU_NEON_EXT_V1
, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
735 {FPU_NEON_EXT_V1
, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
736 {FPU_NEON_EXT_V1
, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
737 {FPU_NEON_EXT_V1
, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
738 {FPU_NEON_EXT_V1
, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
739 {FPU_NEON_EXT_V1
, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
740 {FPU_NEON_EXT_V1
, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
741 {FPU_NEON_EXT_V1
, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
742 {FPU_NEON_EXT_V1
, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
743 {FPU_NEON_EXT_V1
, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
744 {FPU_NEON_EXT_V1
, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
745 {FPU_NEON_EXT_V1
, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
746 {FPU_NEON_EXT_V1
, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
747 {FPU_NEON_EXT_V1
, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
749 /* Two registers and a scalar. */
750 {FPU_NEON_EXT_V1
, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
751 {FPU_NEON_EXT_V1
, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
752 {FPU_NEON_EXT_V1
, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
753 {FPU_NEON_EXT_V1
, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
754 {FPU_NEON_EXT_V1
, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
755 {FPU_NEON_EXT_V1
, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
756 {FPU_NEON_EXT_V1
, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
757 {FPU_NEON_EXT_V1
, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
758 {FPU_NEON_EXT_V1
, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
759 {FPU_NEON_EXT_V1
, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
760 {FPU_NEON_EXT_V1
, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
761 {FPU_NEON_EXT_V1
, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
762 {FPU_NEON_EXT_V1
, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
763 {FPU_NEON_EXT_V1
, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
764 {FPU_NEON_EXT_V1
, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
765 {FPU_NEON_EXT_V1
, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
766 {FPU_NEON_EXT_V1
, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
767 {FPU_NEON_EXT_V1
, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
768 {FPU_NEON_EXT_V1
, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
769 {FPU_NEON_EXT_V1
, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
770 {FPU_NEON_EXT_V1
, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
771 {FPU_NEON_EXT_V1
, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
773 /* Element and structure load/store. */
774 {FPU_NEON_EXT_V1
, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
775 {FPU_NEON_EXT_V1
, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
776 {FPU_NEON_EXT_V1
, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
777 {FPU_NEON_EXT_V1
, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
778 {FPU_NEON_EXT_V1
, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
779 {FPU_NEON_EXT_V1
, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
780 {FPU_NEON_EXT_V1
, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
781 {FPU_NEON_EXT_V1
, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
782 {FPU_NEON_EXT_V1
, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
783 {FPU_NEON_EXT_V1
, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
784 {FPU_NEON_EXT_V1
, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
785 {FPU_NEON_EXT_V1
, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
786 {FPU_NEON_EXT_V1
, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
787 {FPU_NEON_EXT_V1
, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
788 {FPU_NEON_EXT_V1
, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
789 {FPU_NEON_EXT_V1
, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
790 {FPU_NEON_EXT_V1
, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
791 {FPU_NEON_EXT_V1
, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
792 {FPU_NEON_EXT_V1
, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
797 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
798 ordered: they must be searched linearly from the top to obtain a correct
801 /* print_insn_arm recognizes the following format control codes:
805 %a print address for ldr/str instruction
806 %s print address for ldr/str halfword/signextend instruction
807 %S like %s but allow UNPREDICTABLE addressing
808 %b print branch destination
809 %c print condition code (always bits 28-31)
810 %m print register mask for ldm/stm instruction
811 %o print operand2 (immediate or register + shift)
812 %p print 'p' iff bits 12-15 are 15
813 %t print 't' iff bit 21 set and bit 24 clear
814 %B print arm BLX(1) destination
815 %C print the PSR sub type.
816 %U print barrier type.
817 %P print address for pli instruction.
819 %<bitfield>r print as an ARM register
820 %<bitfield>R as %r but r15 is UNPREDICTABLE
821 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
822 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
823 %<bitfield>d print the bitfield in decimal
824 %<bitfield>W print the bitfield plus one in decimal
825 %<bitfield>x print the bitfield in hex
826 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
828 %<bitfield>'c print specified char iff bitfield is all ones
829 %<bitfield>`c print specified char iff bitfield is all zeroes
830 %<bitfield>?ab... select from array of values in big endian order
832 %e print arm SMI operand (bits 0..7,8..19).
833 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
834 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
835 %R print the SPSR/CPSR or banked register of an MRS. */
837 static const struct opcode32 arm_opcodes
[] =
839 /* ARM instructions. */
840 {ARM_EXT_V1
, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
841 {ARM_EXT_V4T
| ARM_EXT_V5
, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
842 {ARM_EXT_V2
, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
843 {ARM_EXT_V2
, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
844 {ARM_EXT_V2S
, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
845 {ARM_EXT_V3M
, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
846 {ARM_EXT_V3M
, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
848 /* Virtualization Extension instructions. */
849 {ARM_EXT_VIRT
, 0x0160006e, 0x0fffffff, "eret%c"},
850 {ARM_EXT_VIRT
, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
852 /* Integer Divide Extension instructions. */
853 {ARM_EXT_ADIV
, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
854 {ARM_EXT_ADIV
, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
856 /* MP Extension instructions. */
857 {ARM_EXT_MP
, 0xf410f000, 0xfc70f000, "pldw\t%a"},
859 /* V7 instructions. */
860 {ARM_EXT_V7
, 0xf450f000, 0xfd70f000, "pli\t%P"},
861 {ARM_EXT_V7
, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
862 {ARM_EXT_V7
, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
863 {ARM_EXT_V7
, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
864 {ARM_EXT_V7
, 0xf57ff060, 0xfffffff0, "isb\t%U"},
866 /* ARM V6T2 instructions. */
867 {ARM_EXT_V6T2
, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
868 {ARM_EXT_V6T2
, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
869 {ARM_EXT_V6T2
, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
870 {ARM_EXT_V6T2
, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
872 {ARM_EXT_V6T2
, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION
},
873 {ARM_EXT_V6T2
, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
875 {ARM_EXT_V6T2
, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
876 {ARM_EXT_V6T2
, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
877 {ARM_EXT_V6T2
, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
878 {ARM_EXT_V6T2
, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
880 /* ARM Security extension instructions. */
881 {ARM_EXT_SEC
, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
883 /* ARM V6K instructions. */
884 {ARM_EXT_V6K
, 0xf57ff01f, 0xffffffff, "clrex"},
885 {ARM_EXT_V6K
, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
886 {ARM_EXT_V6K
, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
887 {ARM_EXT_V6K
, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
888 {ARM_EXT_V6K
, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
889 {ARM_EXT_V6K
, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
890 {ARM_EXT_V6K
, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
892 /* ARM V6K NOP hints. */
893 {ARM_EXT_V6K
, 0x0320f001, 0x0fffffff, "yield%c"},
894 {ARM_EXT_V6K
, 0x0320f002, 0x0fffffff, "wfe%c"},
895 {ARM_EXT_V6K
, 0x0320f003, 0x0fffffff, "wfi%c"},
896 {ARM_EXT_V6K
, 0x0320f004, 0x0fffffff, "sev%c"},
897 {ARM_EXT_V6K
, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
899 /* ARM V6 instructions. */
900 {ARM_EXT_V6
, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
901 {ARM_EXT_V6
, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
902 {ARM_EXT_V6
, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
903 {ARM_EXT_V6
, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
904 {ARM_EXT_V6
, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
905 {ARM_EXT_V6
, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
906 {ARM_EXT_V6
, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
907 {ARM_EXT_V6
, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
908 {ARM_EXT_V6
, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
909 {ARM_EXT_V6
, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
910 {ARM_EXT_V6
, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
911 {ARM_EXT_V6
, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6
, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6
, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6
, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6
, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6
, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6
, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6
, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6
, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
920 {ARM_EXT_V6
, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
921 {ARM_EXT_V6
, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
922 {ARM_EXT_V6
, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
923 {ARM_EXT_V6
, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
924 {ARM_EXT_V6
, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
925 {ARM_EXT_V6
, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
926 {ARM_EXT_V6
, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
927 {ARM_EXT_V6
, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
928 {ARM_EXT_V6
, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
929 {ARM_EXT_V6
, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
930 {ARM_EXT_V6
, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
931 {ARM_EXT_V6
, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
932 {ARM_EXT_V6
, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
933 {ARM_EXT_V6
, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
934 {ARM_EXT_V6
, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
935 {ARM_EXT_V6
, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
936 {ARM_EXT_V6
, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
937 {ARM_EXT_V6
, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
938 {ARM_EXT_V6
, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
939 {ARM_EXT_V6
, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
940 {ARM_EXT_V6
, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
941 {ARM_EXT_V6
, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
942 {ARM_EXT_V6
, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
943 {ARM_EXT_V6
, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
944 {ARM_EXT_V6
, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
945 {ARM_EXT_V6
, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
946 {ARM_EXT_V6
, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
947 {ARM_EXT_V6
, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
948 {ARM_EXT_V6
, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
949 {ARM_EXT_V6
, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
950 {ARM_EXT_V6
, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
951 {ARM_EXT_V6
, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
952 {ARM_EXT_V6
, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
953 {ARM_EXT_V6
, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
954 {ARM_EXT_V6
, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
955 {ARM_EXT_V6
, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
956 {ARM_EXT_V6
, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
957 {ARM_EXT_V6
, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
958 {ARM_EXT_V6
, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
959 {ARM_EXT_V6
, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
960 {ARM_EXT_V6
, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
961 {ARM_EXT_V6
, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
962 {ARM_EXT_V6
, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
963 {ARM_EXT_V6
, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
964 {ARM_EXT_V6
, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
965 {ARM_EXT_V6
, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
966 {ARM_EXT_V6
, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
967 {ARM_EXT_V6
, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
968 {ARM_EXT_V6
, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
969 {ARM_EXT_V6
, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
970 {ARM_EXT_V6
, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
971 {ARM_EXT_V6
, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
972 {ARM_EXT_V6
, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
973 {ARM_EXT_V6
, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
974 {ARM_EXT_V6
, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
975 {ARM_EXT_V6
, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
976 {ARM_EXT_V6
, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
977 {ARM_EXT_V6
, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
978 {ARM_EXT_V6
, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
979 {ARM_EXT_V6
, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
980 {ARM_EXT_V6
, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
981 {ARM_EXT_V6
, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
982 {ARM_EXT_V6
, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
983 {ARM_EXT_V6
, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
984 {ARM_EXT_V6
, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
985 {ARM_EXT_V6
, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
986 {ARM_EXT_V6
, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
987 {ARM_EXT_V6
, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
988 {ARM_EXT_V6
, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
989 {ARM_EXT_V6
, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
990 {ARM_EXT_V6
, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
991 {ARM_EXT_V6
, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
992 {ARM_EXT_V6
, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
993 {ARM_EXT_V6
, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
994 {ARM_EXT_V6
, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
995 {ARM_EXT_V6
, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
996 {ARM_EXT_V6
, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
997 {ARM_EXT_V6
, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
998 {ARM_EXT_V6
, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
999 {ARM_EXT_V6
, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
1000 {ARM_EXT_V6
, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
1001 {ARM_EXT_V6
, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
1002 {ARM_EXT_V6
, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1003 {ARM_EXT_V6
, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1004 {ARM_EXT_V6
, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1005 {ARM_EXT_V6
, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1006 {ARM_EXT_V6
, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
1007 {ARM_EXT_V6
, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1008 {ARM_EXT_V6
, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1009 {ARM_EXT_V6
, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
1010 {ARM_EXT_V6
, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
1011 {ARM_EXT_V6
, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
1012 {ARM_EXT_V6
, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
1013 {ARM_EXT_V6
, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
1014 {ARM_EXT_V6
, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1015 {ARM_EXT_V6
, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1016 {ARM_EXT_V6
, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1017 {ARM_EXT_V6
, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1018 {ARM_EXT_V6
, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1019 {ARM_EXT_V6
, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1020 {ARM_EXT_V6
, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1021 {ARM_EXT_V6
, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1023 /* V5J instruction. */
1024 {ARM_EXT_V5J
, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1026 /* V5 Instructions. */
1027 {ARM_EXT_V5
, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1028 {ARM_EXT_V5
, 0xfa000000, 0xfe000000, "blx\t%B"},
1029 {ARM_EXT_V5
, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1030 {ARM_EXT_V5
, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1032 /* V5E "El Segundo" Instructions. */
1033 {ARM_EXT_V5E
, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1034 {ARM_EXT_V5E
, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1035 {ARM_EXT_V5E
, 0xf450f000, 0xfc70f000, "pld\t%a"},
1036 {ARM_EXT_V5ExP
, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1037 {ARM_EXT_V5ExP
, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1038 {ARM_EXT_V5ExP
, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1039 {ARM_EXT_V5ExP
, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1041 {ARM_EXT_V5ExP
, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1042 {ARM_EXT_V5ExP
, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1044 {ARM_EXT_V5ExP
, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1045 {ARM_EXT_V5ExP
, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1046 {ARM_EXT_V5ExP
, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1047 {ARM_EXT_V5ExP
, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1049 {ARM_EXT_V5ExP
, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1050 {ARM_EXT_V5ExP
, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1051 {ARM_EXT_V5ExP
, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1052 {ARM_EXT_V5ExP
, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1054 {ARM_EXT_V5ExP
, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1055 {ARM_EXT_V5ExP
, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1057 {ARM_EXT_V5ExP
, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1058 {ARM_EXT_V5ExP
, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1059 {ARM_EXT_V5ExP
, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1060 {ARM_EXT_V5ExP
, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1062 /* ARM Instructions. */
1063 {ARM_EXT_V1
, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1065 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1066 {ARM_EXT_V1
, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1067 {ARM_EXT_V1
, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1068 {ARM_EXT_V1
, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1069 {ARM_EXT_V1
, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1070 {ARM_EXT_V1
, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1072 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1073 {ARM_EXT_V1
, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1074 {ARM_EXT_V1
, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1075 {ARM_EXT_V1
, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1077 {ARM_EXT_V1
, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION
},
1078 {ARM_EXT_V1
, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1079 {ARM_EXT_V1
, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION
},
1080 {ARM_EXT_V1
, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1082 {ARM_EXT_V1
, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1083 {ARM_EXT_V1
, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1
, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1086 {ARM_EXT_V1
, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1087 {ARM_EXT_V1
, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1
, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1090 {ARM_EXT_V1
, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1091 {ARM_EXT_V1
, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1
, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1094 {ARM_EXT_V1
, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1095 {ARM_EXT_V1
, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1096 {ARM_EXT_V1
, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1098 {ARM_EXT_V1
, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1099 {ARM_EXT_V1
, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1100 {ARM_EXT_V1
, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1102 {ARM_EXT_V1
, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1103 {ARM_EXT_V1
, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1104 {ARM_EXT_V1
, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1106 {ARM_EXT_V1
, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1107 {ARM_EXT_V1
, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1108 {ARM_EXT_V1
, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1110 {ARM_EXT_V1
, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1111 {ARM_EXT_V1
, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1112 {ARM_EXT_V1
, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1114 {ARM_EXT_VIRT
, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1115 {ARM_EXT_V3
, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1116 {ARM_EXT_V3
, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1118 {ARM_EXT_V1
, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1119 {ARM_EXT_V1
, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1120 {ARM_EXT_V1
, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1122 {ARM_EXT_V1
, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1123 {ARM_EXT_V1
, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1124 {ARM_EXT_V1
, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1126 {ARM_EXT_V1
, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1127 {ARM_EXT_V1
, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1128 {ARM_EXT_V1
, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1130 {ARM_EXT_V1
, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1131 {ARM_EXT_V1
, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1132 {ARM_EXT_V1
, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1134 {ARM_EXT_V1
, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1135 {ARM_EXT_V1
, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1136 {ARM_EXT_V1
, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1138 {ARM_EXT_V1
, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1139 {ARM_EXT_V1
, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1140 {ARM_EXT_V1
, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1141 {ARM_EXT_V1
, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1142 {ARM_EXT_V1
, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1143 {ARM_EXT_V1
, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1144 {ARM_EXT_V1
, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1146 {ARM_EXT_V1
, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1147 {ARM_EXT_V1
, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1148 {ARM_EXT_V1
, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1150 {ARM_EXT_V1
, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1151 {ARM_EXT_V1
, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1152 {ARM_EXT_V1
, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1154 {ARM_EXT_V1
, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION
},
1155 {ARM_EXT_V1
, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1157 {ARM_EXT_V1
, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1159 {ARM_EXT_V1
, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1160 {ARM_EXT_V1
, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1162 {ARM_EXT_V1
, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1163 {ARM_EXT_V1
, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1164 {ARM_EXT_V1
, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1165 {ARM_EXT_V1
, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1166 {ARM_EXT_V1
, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1167 {ARM_EXT_V1
, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1168 {ARM_EXT_V1
, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1169 {ARM_EXT_V1
, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1172 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1173 {0, 0x00000000, 0x00000000, 0}
1176 /* print_insn_thumb16 recognizes the following format control codes:
1178 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1179 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1180 %<bitfield>I print bitfield as a signed decimal
1181 (top bit of range being the sign bit)
1182 %N print Thumb register mask (with LR)
1183 %O print Thumb register mask (with PC)
1184 %M print Thumb register mask
1185 %b print CZB's 6-bit unsigned branch destination
1186 %s print Thumb right-shift immediate (6..10; 0 == 32).
1187 %c print the condition code
1188 %C print the condition code, or "s" if not conditional
1189 %x print warning if conditional an not at end of IT block"
1190 %X print "\t; unpredictable <IT:code>" if conditional
1191 %I print IT instruction suffix and operands
1192 %W print Thumb Writeback indicator for LDMIA
1193 %<bitfield>r print bitfield as an ARM register
1194 %<bitfield>d print bitfield as a decimal
1195 %<bitfield>H print (bitfield * 2) as a decimal
1196 %<bitfield>W print (bitfield * 4) as a decimal
1197 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1198 %<bitfield>B print Thumb branch destination (signed displacement)
1199 %<bitfield>c print bitfield as a condition code
1200 %<bitnum>'c print specified char iff bit is one
1201 %<bitnum>?ab print a if bit is one else print b. */
1203 static const struct opcode16 thumb_opcodes
[] =
1205 /* Thumb instructions. */
1207 /* ARM V6K no-argument instructions. */
1208 {ARM_EXT_V6K
, 0xbf00, 0xffff, "nop%c"},
1209 {ARM_EXT_V6K
, 0xbf10, 0xffff, "yield%c"},
1210 {ARM_EXT_V6K
, 0xbf20, 0xffff, "wfe%c"},
1211 {ARM_EXT_V6K
, 0xbf30, 0xffff, "wfi%c"},
1212 {ARM_EXT_V6K
, 0xbf40, 0xffff, "sev%c"},
1213 {ARM_EXT_V6K
, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1215 /* ARM V6T2 instructions. */
1216 {ARM_EXT_V6T2
, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1217 {ARM_EXT_V6T2
, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1218 {ARM_EXT_V6T2
, 0xbf00, 0xff00, "it%I%X"},
1221 {ARM_EXT_V6
, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1222 {ARM_EXT_V6
, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1223 {ARM_EXT_V6
, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1224 {ARM_EXT_V6
, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1225 {ARM_EXT_V6
, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1226 {ARM_EXT_V6
, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1227 {ARM_EXT_V6
, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1228 {ARM_EXT_V6
, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1229 {ARM_EXT_V6
, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1230 {ARM_EXT_V6
, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1231 {ARM_EXT_V6
, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1233 /* ARM V5 ISA extends Thumb. */
1234 {ARM_EXT_V5T
, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1235 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1236 {ARM_EXT_V5T
, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1237 /* ARM V4T ISA (Thumb v1). */
1238 {ARM_EXT_V4T
, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1240 {ARM_EXT_V4T
, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1241 {ARM_EXT_V4T
, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1242 {ARM_EXT_V4T
, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1243 {ARM_EXT_V4T
, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1244 {ARM_EXT_V4T
, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1245 {ARM_EXT_V4T
, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1246 {ARM_EXT_V4T
, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1247 {ARM_EXT_V4T
, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1248 {ARM_EXT_V4T
, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1249 {ARM_EXT_V4T
, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1250 {ARM_EXT_V4T
, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1251 {ARM_EXT_V4T
, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1252 {ARM_EXT_V4T
, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1253 {ARM_EXT_V4T
, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1254 {ARM_EXT_V4T
, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1255 {ARM_EXT_V4T
, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1257 {ARM_EXT_V4T
, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1258 {ARM_EXT_V4T
, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1260 {ARM_EXT_V4T
, 0x4700, 0xFF80, "bx%c\t%S%x"},
1261 {ARM_EXT_V4T
, 0x4400, 0xFF00, "add%c\t%D, %S"},
1262 {ARM_EXT_V4T
, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1263 {ARM_EXT_V4T
, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1265 {ARM_EXT_V4T
, 0xB400, 0xFE00, "push%c\t%N"},
1266 {ARM_EXT_V4T
, 0xBC00, 0xFE00, "pop%c\t%O"},
1268 {ARM_EXT_V4T
, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1269 {ARM_EXT_V4T
, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1270 {ARM_EXT_V4T
, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1271 {ARM_EXT_V4T
, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1273 {ARM_EXT_V4T
, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1274 {ARM_EXT_V4T
, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1275 {ARM_EXT_V4T
, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1277 {ARM_EXT_V4T
, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1278 {ARM_EXT_V4T
, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1280 {ARM_EXT_V4T
, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1281 {ARM_EXT_V4T
, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1282 {ARM_EXT_V4T
, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1283 {ARM_EXT_V4T
, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1285 {ARM_EXT_V4T
, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1286 {ARM_EXT_V4T
, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1287 {ARM_EXT_V4T
, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1288 {ARM_EXT_V4T
, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1290 {ARM_EXT_V4T
, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1292 {ARM_EXT_V4T
, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1293 {ARM_EXT_V4T
, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1294 {ARM_EXT_V4T
, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1295 {ARM_EXT_V4T
, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1297 {ARM_EXT_V4T
, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1298 {ARM_EXT_V4T
, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1300 {ARM_EXT_V4T
, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1301 {ARM_EXT_V4T
, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1303 {ARM_EXT_V4T
, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1304 {ARM_EXT_V4T
, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1306 {ARM_EXT_V4T
, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1307 {ARM_EXT_V4T
, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1309 {ARM_EXT_V4T
, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1311 {ARM_EXT_V4T
, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION
},
1312 {ARM_EXT_V4T
, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1314 {ARM_EXT_V4T
, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1316 /* The E800 .. FFFF range is unconditionally redirected to the
1317 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1318 are processed via that table. Thus, we can never encounter a
1319 bare "second half of BL/BLX(1)" instruction here. */
1320 {ARM_EXT_V1
, 0x0000, 0x0000, UNDEFINED_INSTRUCTION
},
1324 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1325 We adopt the convention that hw1 is the high 16 bits of .value and
1326 .mask, hw2 the low 16 bits.
1328 print_insn_thumb32 recognizes the following format control codes:
1332 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1333 %M print a modified 12-bit immediate (same location)
1334 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1335 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1336 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1337 %S print a possibly-shifted Rm
1339 %L print address for a ldrd/strd instruction
1340 %a print the address of a plain load/store
1341 %w print the width and signedness of a core load/store
1342 %m print register mask for ldm/stm
1344 %E print the lsb and width fields of a bfc/bfi instruction
1345 %F print the lsb and width fields of a sbfx/ubfx instruction
1346 %b print a conditional branch offset
1347 %B print an unconditional branch offset
1348 %s print the shift field of an SSAT instruction
1349 %R print the rotation field of an SXT instruction
1350 %U print barrier type.
1351 %P print address for pli instruction.
1352 %c print the condition code
1353 %x print warning if conditional an not at end of IT block"
1354 %X print "\t; unpredictable <IT:code>" if conditional
1356 %<bitfield>d print bitfield in decimal
1357 %<bitfield>W print bitfield*4 in decimal
1358 %<bitfield>r print bitfield as an ARM register
1359 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1360 %<bitfield>c print bitfield as a condition code
1362 %<bitfield>'c print specified char iff bitfield is all ones
1363 %<bitfield>`c print specified char iff bitfield is all zeroes
1364 %<bitfield>?ab... select from array of values in big endian order
1366 With one exception at the bottom (done because BL and BLX(1) need
1367 to come dead last), this table was machine-sorted first in
1368 decreasing order of number of bits set in the mask, then in
1369 increasing numeric order of mask, then in increasing numeric order
1370 of opcode. This order is not the clearest for a human reader, but
1371 is guaranteed never to catch a special-case bit pattern with a more
1372 general mask, which is important, because this instruction encoding
1373 makes heavy use of special-case bit patterns. */
1374 static const struct opcode32 thumb32_opcodes
[] =
1376 /* V7 instructions. */
1377 {ARM_EXT_V7
, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1378 {ARM_EXT_V7
, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1379 {ARM_EXT_V7
, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1380 {ARM_EXT_V7
, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1381 {ARM_EXT_V7
, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1382 {ARM_EXT_DIV
, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_DIV
, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1385 /* Virtualization Extension instructions. */
1386 {ARM_EXT_VIRT
, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1387 /* We skip ERET as that is SUBS pc, lr, #0. */
1389 /* MP Extension instructions. */
1390 {ARM_EXT_MP
, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1392 /* Security extension instructions. */
1393 {ARM_EXT_SEC
, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1395 /* Instructions defined in the basic V6T2 set. */
1396 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffffff, "nop%c.w"},
1397 {ARM_EXT_V6T2
, 0xf3af8001, 0xffffffff, "yield%c.w"},
1398 {ARM_EXT_V6T2
, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1399 {ARM_EXT_V6T2
, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1400 {ARM_EXT_V6T2
, 0xf3af8004, 0xffffffff, "sev%c.w"},
1401 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1403 {ARM_EXT_V6T2
, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1404 {ARM_EXT_V6T2
, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1405 {ARM_EXT_V6T2
, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1406 {ARM_EXT_V6T2
, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1407 {ARM_EXT_V6T2
, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1408 {ARM_EXT_V6T2
, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1409 {ARM_EXT_V6T2
, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1410 {ARM_EXT_V6T2
, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1411 {ARM_EXT_V6T2
, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1412 {ARM_EXT_V6T2
, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1413 {ARM_EXT_V6T2
, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1414 {ARM_EXT_V6T2
, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1415 {ARM_EXT_V6T2
, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1416 {ARM_EXT_V6T2
, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1417 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1418 {ARM_EXT_V6T2
, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1419 {ARM_EXT_V6T2
, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1420 {ARM_EXT_V6T2
, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1421 {ARM_EXT_V6T2
, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1422 {ARM_EXT_V6T2
, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1423 {ARM_EXT_V6T2
, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1424 {ARM_EXT_V6T2
, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1425 {ARM_EXT_V6T2
, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1426 {ARM_EXT_V6T2
, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1427 {ARM_EXT_V6T2
, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1428 {ARM_EXT_V6T2
, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1429 {ARM_EXT_V6T2
, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1430 {ARM_EXT_V6T2
, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1431 {ARM_EXT_V6T2
, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1432 {ARM_EXT_V6T2
, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1433 {ARM_EXT_V6T2
, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1434 {ARM_EXT_V6T2
, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2
, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1436 {ARM_EXT_V6T2
, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1437 {ARM_EXT_V6T2
, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1438 {ARM_EXT_V6T2
, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1439 {ARM_EXT_V6T2
, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1440 {ARM_EXT_V6T2
, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1441 {ARM_EXT_V6T2
, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1442 {ARM_EXT_V6T2
, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1443 {ARM_EXT_V6T2
, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1444 {ARM_EXT_V6T2
, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1445 {ARM_EXT_V6T2
, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1446 {ARM_EXT_V6T2
, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1447 {ARM_EXT_V6T2
, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1448 {ARM_EXT_V6T2
, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1449 {ARM_EXT_V6T2
, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2
, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2
, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1452 {ARM_EXT_V6T2
, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1453 {ARM_EXT_V6T2
, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1454 {ARM_EXT_V6T2
, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1455 {ARM_EXT_V6T2
, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1456 {ARM_EXT_V6T2
, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1457 {ARM_EXT_V6T2
, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2
, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1459 {ARM_EXT_V6T2
, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1460 {ARM_EXT_V6T2
, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1461 {ARM_EXT_V6T2
, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1462 {ARM_EXT_V6T2
, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1463 {ARM_EXT_V6T2
, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1464 {ARM_EXT_V6T2
, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2
, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1466 {ARM_EXT_V6T2
, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1467 {ARM_EXT_V6T2
, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1468 {ARM_EXT_V6T2
, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1469 {ARM_EXT_V6T2
, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1470 {ARM_EXT_V6T2
, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1471 {ARM_EXT_V6T2
, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1472 {ARM_EXT_V6T2
, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1473 {ARM_EXT_V6T2
, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1474 {ARM_EXT_V6T2
, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1475 {ARM_EXT_V6T2
, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1476 {ARM_EXT_V6T2
, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1477 {ARM_EXT_V6T2
, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1478 {ARM_EXT_V6T2
, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1479 {ARM_EXT_V6T2
, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1480 {ARM_EXT_V6T2
, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1481 {ARM_EXT_V6T2
, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1482 {ARM_EXT_V6T2
, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1483 {ARM_EXT_V6T2
, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1484 {ARM_EXT_V6T2
, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1485 {ARM_EXT_V6T2
, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1486 {ARM_EXT_V6T2
, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1487 {ARM_EXT_V6T2
, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1488 {ARM_EXT_V6T2
, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1489 {ARM_EXT_V6T2
, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1490 {ARM_EXT_V6T2
, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1491 {ARM_EXT_V6T2
, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1492 {ARM_EXT_V6T2
, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1493 {ARM_EXT_V6T2
, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1494 {ARM_EXT_V6T2
, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1495 {ARM_EXT_V6T2
, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1496 {ARM_EXT_V6T2
, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1497 {ARM_EXT_V6T2
, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1498 {ARM_EXT_V6T2
, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1499 {ARM_EXT_V6T2
, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1500 {ARM_EXT_V6T2
, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1501 {ARM_EXT_V6T2
, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1502 {ARM_EXT_V6T2
, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1503 {ARM_EXT_V6T2
, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1504 {ARM_EXT_V6T2
, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1505 {ARM_EXT_V6T2
, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1506 {ARM_EXT_V6T2
, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1507 {ARM_EXT_V6T2
, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1508 {ARM_EXT_V6T2
, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1509 {ARM_EXT_V6T2
, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1510 {ARM_EXT_V6T2
, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1511 {ARM_EXT_V6T2
, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1512 {ARM_EXT_V6T2
, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1513 {ARM_EXT_V6T2
, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1514 {ARM_EXT_V6T2
, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1515 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1516 {ARM_EXT_V6T2
, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1517 {ARM_EXT_V6T2
, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1518 {ARM_EXT_V6T2
, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1519 {ARM_EXT_V6T2
, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1520 {ARM_EXT_V6T2
, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1521 {ARM_EXT_V6T2
, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1522 {ARM_EXT_V6T2
, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1523 {ARM_EXT_V6T2
, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1524 {ARM_EXT_V6T2
, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1525 {ARM_EXT_V6T2
, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1526 {ARM_EXT_V6T2
, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1527 {ARM_EXT_V6T2
, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1528 {ARM_EXT_V6T2
, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1529 {ARM_EXT_V6T2
, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1530 {ARM_EXT_V6T2
, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1531 {ARM_EXT_V6T2
, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1532 {ARM_EXT_V6T2
, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1533 {ARM_EXT_V6T2
, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1534 {ARM_EXT_V6T2
, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1535 {ARM_EXT_V6T2
, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1536 {ARM_EXT_V6T2
, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1537 {ARM_EXT_V6T2
, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1538 {ARM_EXT_V6T2
, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1539 {ARM_EXT_V6T2
, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1540 {ARM_EXT_V6T2
, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1541 {ARM_EXT_V6T2
, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1542 {ARM_EXT_V6T2
, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1543 {ARM_EXT_V6T2
, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1544 {ARM_EXT_V6T2
, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1545 {ARM_EXT_V6T2
, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1546 {ARM_EXT_V6T2
, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1547 {ARM_EXT_V6T2
, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1548 {ARM_EXT_V6T2
, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1549 {ARM_EXT_V6T2
, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1550 {ARM_EXT_V6T2
, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1551 {ARM_EXT_V6T2
, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1552 {ARM_EXT_V6T2
, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1553 {ARM_EXT_V6T2
, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1554 {ARM_EXT_V6T2
, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1555 {ARM_EXT_V6T2
, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1556 {ARM_EXT_V6T2
, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1557 {ARM_EXT_V6T2
, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1558 {ARM_EXT_V6T2
, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1559 {ARM_EXT_V6T2
, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1560 {ARM_EXT_V6T2
, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1561 {ARM_EXT_V6T2
, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1562 {ARM_EXT_V6T2
, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1563 {ARM_EXT_V6T2
, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1564 {ARM_EXT_V6T2
, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1565 {ARM_EXT_V6T2
, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1566 {ARM_EXT_V6T2
, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1567 {ARM_EXT_V6T2
, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1568 {ARM_EXT_V6T2
, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1569 {ARM_EXT_V6T2
, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!%L"},
1570 {ARM_EXT_V6T2
, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1571 {ARM_EXT_V6T2
, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W%L"},
1572 {ARM_EXT_V6T2
, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1573 {ARM_EXT_V6T2
, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1575 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1576 {ARM_EXT_V6T2
, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1577 {ARM_EXT_V6T2
, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1578 {ARM_EXT_V6T2
, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1579 {ARM_EXT_V6T2
, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1581 /* These have been 32-bit since the invention of Thumb. */
1582 {ARM_EXT_V4T
, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1583 {ARM_EXT_V4T
, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1586 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1590 static const char *const arm_conditional
[] =
1591 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1592 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1594 static const char *const arm_fp_const
[] =
1595 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1597 static const char *const arm_shift
[] =
1598 {"lsl", "lsr", "asr", "ror"};
1603 const char *description
;
1604 const char *reg_names
[16];
1608 static const arm_regname regnames
[] =
1610 { "raw" , "Select raw register names",
1611 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1612 { "gcc", "Select register names used by GCC",
1613 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1614 { "std", "Select register names used in ARM's ISA documentation",
1615 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1616 { "apcs", "Select register names used in the APCS",
1617 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1618 { "atpcs", "Select register names used in the ATPCS",
1619 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1620 { "special-atpcs", "Select special register names used in the ATPCS",
1621 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1624 static const char *const iwmmxt_wwnames
[] =
1625 {"b", "h", "w", "d"};
1627 static const char *const iwmmxt_wwssnames
[] =
1628 {"b", "bus", "bc", "bss",
1629 "h", "hus", "hc", "hss",
1630 "w", "wus", "wc", "wss",
1631 "d", "dus", "dc", "dss"
1634 static const char *const iwmmxt_regnames
[] =
1635 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1636 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1639 static const char *const iwmmxt_cregnames
[] =
1640 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1641 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1644 /* Default to GCC register name set. */
1645 static unsigned int regname_selected
= 1;
1647 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1648 #define arm_regnames regnames[regname_selected].reg_names
1650 static bfd_boolean force_thumb
= FALSE
;
1652 /* Current IT instruction state. This contains the same state as the IT
1653 bits in the CPSR. */
1654 static unsigned int ifthen_state
;
1655 /* IT state for the next instruction. */
1656 static unsigned int ifthen_next_state
;
1657 /* The address of the insn for which the IT state is valid. */
1658 static bfd_vma ifthen_address
;
1659 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1664 get_arm_regname_num_options (void)
1666 return NUM_ARM_REGNAMES
;
1670 set_arm_regname_option (int option
)
1672 int old
= regname_selected
;
1673 regname_selected
= option
;
1678 get_arm_regnames (int option
,
1679 const char **setname
,
1680 const char **setdescription
,
1681 const char *const **register_names
)
1683 *setname
= regnames
[option
].name
;
1684 *setdescription
= regnames
[option
].description
;
1685 *register_names
= regnames
[option
].reg_names
;
1689 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1690 Returns pointer to following character of the format string and
1691 fills in *VALUEP and *WIDTHP with the extracted value and number of
1692 bits extracted. WIDTHP can be NULL. */
1695 arm_decode_bitfield (const char *ptr
,
1697 unsigned long *valuep
,
1700 unsigned long value
= 0;
1708 for (start
= 0; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1709 start
= start
* 10 + *ptr
- '0';
1711 for (end
= 0, ptr
++; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1712 end
= end
* 10 + *ptr
- '0';
1718 value
|= ((insn
>> start
) & ((2ul << bits
) - 1)) << width
;
1721 while (*ptr
++ == ',');
1729 arm_decode_shift (long given
, fprintf_ftype func
, void *stream
,
1730 bfd_boolean print_shift
)
1732 func (stream
, "%s", arm_regnames
[given
& 0xf]);
1734 if ((given
& 0xff0) != 0)
1736 if ((given
& 0x10) == 0)
1738 int amount
= (given
& 0xf80) >> 7;
1739 int shift
= (given
& 0x60) >> 5;
1745 func (stream
, ", rrx");
1753 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
1755 func (stream
, ", #%d", amount
);
1757 else if ((given
& 0x80) == 0x80)
1758 func (stream
, "\t; <illegal shifter operand>");
1759 else if (print_shift
)
1760 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
1761 arm_regnames
[(given
& 0xf00) >> 8]);
1763 func (stream
, ", %s", arm_regnames
[(given
& 0xf00) >> 8]);
1772 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1773 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1774 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1775 #define PRE_BIT_SET (given & (1 << P_BIT))
1777 /* Print one coprocessor instruction on INFO->STREAM.
1778 Return TRUE if the instuction matched, FALSE if this is not a
1779 recognised coprocessor instruction. */
1782 print_insn_coprocessor (bfd_vma pc
,
1783 struct disassemble_info
*info
,
1787 const struct opcode32
*insn
;
1788 void *stream
= info
->stream
;
1789 fprintf_ftype func
= info
->fprintf_func
;
1791 unsigned long value
= 0;
1792 struct arm_private_data
*private_data
= info
->private_data
;
1793 unsigned long allowed_arches
= private_data
->features
.coproc
;
1796 for (insn
= coprocessor_opcodes
; insn
->assembler
; insn
++)
1798 unsigned long u_reg
= 16;
1799 bfd_boolean is_unpredictable
= FALSE
;
1800 signed long value_in_comment
= 0;
1803 if (insn
->arch
== 0)
1804 switch (insn
->value
)
1806 case SENTINEL_IWMMXT_START
:
1807 if (info
->mach
!= bfd_mach_arm_XScale
1808 && info
->mach
!= bfd_mach_arm_iWMMXt
1809 && info
->mach
!= bfd_mach_arm_iWMMXt2
)
1812 while (insn
->arch
!= 0 && insn
->value
!= SENTINEL_IWMMXT_END
);
1815 case SENTINEL_IWMMXT_END
:
1818 case SENTINEL_GENERIC_START
:
1819 allowed_arches
= private_data
->features
.core
;
1827 value
= insn
->value
;
1830 /* The high 4 bits are 0xe for Arm conditional instructions, and
1831 0xe for arm unconditional instructions. The rest of the
1832 encoding is the same. */
1834 value
|= 0xe0000000;
1842 /* Only match unconditional instuctions against unconditional
1844 if ((given
& 0xf0000000) == 0xf0000000)
1851 cond
= (given
>> 28) & 0xf;
1857 if ((given
& mask
) != value
)
1860 if ((insn
->arch
& allowed_arches
) == 0)
1863 for (c
= insn
->assembler
; *c
; c
++)
1870 func (stream
, "%%");
1875 int rn
= (given
>> 16) & 0xf;
1876 bfd_vma offset
= given
& 0xff;
1878 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
1880 if (PRE_BIT_SET
|| WRITEBACK_BIT_SET
)
1882 /* Not unindexed. The offset is scaled. */
1883 offset
= offset
* 4;
1884 if (NEGATIVE_BIT_SET
)
1887 value_in_comment
= offset
;
1893 func (stream
, ", #%d]%s",
1895 WRITEBACK_BIT_SET
? "!" : "");
1896 else if (NEGATIVE_BIT_SET
)
1897 func (stream
, ", #-0]");
1905 if (WRITEBACK_BIT_SET
)
1908 func (stream
, ", #%d", offset
);
1909 else if (NEGATIVE_BIT_SET
)
1910 func (stream
, ", #-0");
1914 func (stream
, ", {%s%d}",
1915 (NEGATIVE_BIT_SET
&& !offset
) ? "-" : "",
1917 value_in_comment
= offset
;
1920 if (rn
== 15 && (PRE_BIT_SET
|| WRITEBACK_BIT_SET
))
1922 func (stream
, "\t; ");
1923 /* For unaligned PCs, apply off-by-alignment
1925 info
->print_address_func (offset
+ pc
1926 + info
->bytes_per_chunk
* 2
1935 int regno
= ((given
>> 12) & 0xf) | ((given
>> (22 - 4)) & 0x10);
1936 int offset
= (given
>> 1) & 0x3f;
1939 func (stream
, "{d%d}", regno
);
1940 else if (regno
+ offset
> 32)
1941 func (stream
, "{d%d-<overflow reg d%d>}", regno
, regno
+ offset
- 1);
1943 func (stream
, "{d%d-d%d}", regno
, regno
+ offset
- 1);
1948 func (stream
, "%s", arm_conditional
[cond
]);
1952 /* Print a Cirrus/DSP shift immediate. */
1953 /* Immediates are 7bit signed ints with bits 0..3 in
1954 bits 0..3 of opcode and bits 4..6 in bits 5..7
1959 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
1961 /* Is ``imm'' a negative number? */
1965 func (stream
, "%d", imm
);
1971 switch (given
& 0x00408000)
1988 switch (given
& 0x00080080)
2000 func (stream
, _("<illegal precision>"));
2006 switch (given
& 0x00408000)
2024 switch (given
& 0x60)
2040 case '0': case '1': case '2': case '3': case '4':
2041 case '5': case '6': case '7': case '8': case '9':
2045 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2051 is_unpredictable
= TRUE
;
2056 /* Eat the 'u' character. */
2060 is_unpredictable
= TRUE
;
2063 func (stream
, "%s", arm_regnames
[value
]);
2066 func (stream
, "d%ld", value
);
2070 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2072 func (stream
, "q%ld", value
>> 1);
2075 func (stream
, "%ld", value
);
2076 value_in_comment
= value
;
2080 int from
= (given
& (1 << 7)) ? 32 : 16;
2081 func (stream
, "%ld", from
- value
);
2087 func (stream
, "#%s", arm_fp_const
[value
& 7]);
2089 func (stream
, "f%ld", value
);
2094 func (stream
, "%s", iwmmxt_wwnames
[value
]);
2096 func (stream
, "%s", iwmmxt_wwssnames
[value
]);
2100 func (stream
, "%s", iwmmxt_regnames
[value
]);
2103 func (stream
, "%s", iwmmxt_cregnames
[value
]);
2107 func (stream
, "0x%lx", (value
& 0xffffffffUL
));
2113 func (stream
, "%c", *c
);
2117 if (value
== ((1ul << width
) - 1))
2118 func (stream
, "%c", *c
);
2121 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2132 int single
= *c
++ == 'y';
2137 case '4': /* Sm pair */
2138 case '0': /* Sm, Dm */
2139 regno
= given
& 0x0000000f;
2143 regno
+= (given
>> 5) & 1;
2146 regno
+= ((given
>> 5) & 1) << 4;
2149 case '1': /* Sd, Dd */
2150 regno
= (given
>> 12) & 0x0000000f;
2154 regno
+= (given
>> 22) & 1;
2157 regno
+= ((given
>> 22) & 1) << 4;
2160 case '2': /* Sn, Dn */
2161 regno
= (given
>> 16) & 0x0000000f;
2165 regno
+= (given
>> 7) & 1;
2168 regno
+= ((given
>> 7) & 1) << 4;
2171 case '3': /* List */
2173 regno
= (given
>> 12) & 0x0000000f;
2177 regno
+= (given
>> 22) & 1;
2180 regno
+= ((given
>> 22) & 1) << 4;
2187 func (stream
, "%c%d", single
? 's' : 'd', regno
);
2191 int count
= given
& 0xff;
2198 func (stream
, "-%c%d",
2206 func (stream
, ", %c%d", single
? 's' : 'd',
2212 switch (given
& 0x00400100)
2214 case 0x00000000: func (stream
, "b"); break;
2215 case 0x00400000: func (stream
, "h"); break;
2216 case 0x00000100: func (stream
, "w"); break;
2217 case 0x00400100: func (stream
, "d"); break;
2225 /* given (20, 23) | given (0, 3) */
2226 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
2227 func (stream
, "%d", value
);
2232 /* This is like the 'A' operator, except that if
2233 the width field "M" is zero, then the offset is
2234 *not* multiplied by four. */
2236 int offset
= given
& 0xff;
2237 int multiplier
= (given
& 0x00000100) ? 4 : 1;
2239 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2243 value_in_comment
= offset
* multiplier
;
2244 if (NEGATIVE_BIT_SET
)
2245 value_in_comment
= - value_in_comment
;
2251 func (stream
, ", #%s%d]%s",
2252 NEGATIVE_BIT_SET
? "-" : "",
2253 offset
* multiplier
,
2254 WRITEBACK_BIT_SET
? "!" : "");
2256 func (stream
, "], #%s%d",
2257 NEGATIVE_BIT_SET
? "-" : "",
2258 offset
* multiplier
);
2267 int imm4
= (given
>> 4) & 0xf;
2268 int puw_bits
= ((given
>> 22) & 6) | ((given
>> W_BIT
) & 1);
2269 int ubit
= ! NEGATIVE_BIT_SET
;
2270 const char *rm
= arm_regnames
[given
& 0xf];
2271 const char *rn
= arm_regnames
[(given
>> 16) & 0xf];
2277 func (stream
, "[%s], %c%s", rn
, ubit
? '+' : '-', rm
);
2279 func (stream
, ", lsl #%d", imm4
);
2286 func (stream
, "[%s, %c%s", rn
, ubit
? '+' : '-', rm
);
2288 func (stream
, ", lsl #%d", imm4
);
2290 if (puw_bits
== 5 || puw_bits
== 7)
2295 func (stream
, "INVALID");
2303 imm5
= ((given
& 0x100) >> 4) | (given
& 0xf);
2304 func (stream
, "%ld", (imm5
== 0) ? 32 : imm5
);
2314 func (stream
, "%c", *c
);
2317 if (value_in_comment
> 32 || value_in_comment
< -16)
2318 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
2320 if (is_unpredictable
)
2321 func (stream
, UNPREDICTABLE_INSTRUCTION
);
2328 /* Decodes and prints ARM addressing modes. Returns the offset
2329 used in the address, if any, if it is worthwhile printing the
2330 offset as a hexadecimal value in a comment at the end of the
2331 line of disassembly. */
2334 print_arm_address (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2336 void *stream
= info
->stream
;
2337 fprintf_ftype func
= info
->fprintf_func
;
2340 if (((given
& 0x000f0000) == 0x000f0000)
2341 && ((given
& 0x02000000) == 0))
2343 offset
= given
& 0xfff;
2345 func (stream
, "[pc");
2349 /* Pre-indexed. Elide offset of positive zero when
2351 if (WRITEBACK_BIT_SET
|| NEGATIVE_BIT_SET
|| offset
)
2352 func (stream
, ", #%s%d", NEGATIVE_BIT_SET
? "-" : "", offset
);
2354 if (NEGATIVE_BIT_SET
)
2359 /* Cope with the possibility of write-back
2360 being used. Probably a very dangerous thing
2361 for the programmer to do, but who are we to
2363 func (stream
, "]%s", WRITEBACK_BIT_SET
? "!" : "");
2365 else /* Post indexed. */
2367 func (stream
, "], #%s%d", NEGATIVE_BIT_SET
? "-" : "", offset
);
2369 /* Ie ignore the offset. */
2373 func (stream
, "\t; ");
2374 info
->print_address_func (offset
, info
);
2379 func (stream
, "[%s",
2380 arm_regnames
[(given
>> 16) & 0xf]);
2384 if ((given
& 0x02000000) == 0)
2386 /* Elide offset of positive zero when non-writeback. */
2387 offset
= given
& 0xfff;
2388 if (WRITEBACK_BIT_SET
|| NEGATIVE_BIT_SET
|| offset
)
2389 func (stream
, ", #%s%d", NEGATIVE_BIT_SET
? "-" : "", offset
);
2393 func (stream
, ", %s", NEGATIVE_BIT_SET
? "-" : "");
2394 arm_decode_shift (given
, func
, stream
, TRUE
);
2397 func (stream
, "]%s",
2398 WRITEBACK_BIT_SET
? "!" : "");
2402 if ((given
& 0x02000000) == 0)
2404 /* Always show offset. */
2405 offset
= given
& 0xfff;
2406 func (stream
, "], #%s%d",
2407 NEGATIVE_BIT_SET
? "-" : "", offset
);
2411 func (stream
, "], %s",
2412 NEGATIVE_BIT_SET
? "-" : "");
2413 arm_decode_shift (given
, func
, stream
, TRUE
);
2418 return (signed long) offset
;
2421 /* Print one neon instruction on INFO->STREAM.
2422 Return TRUE if the instuction matched, FALSE if this is not a
2423 recognised neon instruction. */
2426 print_insn_neon (struct disassemble_info
*info
, long given
, bfd_boolean thumb
)
2428 const struct opcode32
*insn
;
2429 void *stream
= info
->stream
;
2430 fprintf_ftype func
= info
->fprintf_func
;
2434 if ((given
& 0xef000000) == 0xef000000)
2436 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2437 unsigned long bit28
= given
& (1 << 28);
2439 given
&= 0x00ffffff;
2441 given
|= 0xf3000000;
2443 given
|= 0xf2000000;
2445 else if ((given
& 0xff000000) == 0xf9000000)
2446 given
^= 0xf9000000 ^ 0xf4000000;
2451 for (insn
= neon_opcodes
; insn
->assembler
; insn
++)
2453 if ((given
& insn
->mask
) == insn
->value
)
2455 signed long value_in_comment
= 0;
2458 for (c
= insn
->assembler
; *c
; c
++)
2465 func (stream
, "%%");
2469 if (thumb
&& ifthen_state
)
2470 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
2475 static const unsigned char enc
[16] =
2477 0x4, 0x14, /* st4 0,1 */
2489 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2490 int rn
= ((given
>> 16) & 0xf);
2491 int rm
= ((given
>> 0) & 0xf);
2492 int align
= ((given
>> 4) & 0x3);
2493 int type
= ((given
>> 8) & 0xf);
2494 int n
= enc
[type
] & 0xf;
2495 int stride
= (enc
[type
] >> 4) + 1;
2500 for (ix
= 0; ix
!= n
; ix
++)
2501 func (stream
, "%sd%d", ix
? "," : "", rd
+ ix
* stride
);
2503 func (stream
, "d%d", rd
);
2505 func (stream
, "d%d-d%d", rd
, rd
+ n
- 1);
2506 func (stream
, "}, [%s", arm_regnames
[rn
]);
2508 func (stream
, " :%d", 32 << align
);
2513 func (stream
, ", %s", arm_regnames
[rm
]);
2519 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2520 int rn
= ((given
>> 16) & 0xf);
2521 int rm
= ((given
>> 0) & 0xf);
2522 int idx_align
= ((given
>> 4) & 0xf);
2524 int size
= ((given
>> 10) & 0x3);
2525 int idx
= idx_align
>> (size
+ 1);
2526 int length
= ((given
>> 8) & 3) + 1;
2530 if (length
> 1 && size
> 0)
2531 stride
= (idx_align
& (1 << size
)) ? 2 : 1;
2537 int amask
= (1 << size
) - 1;
2538 if ((idx_align
& (1 << size
)) != 0)
2542 if ((idx_align
& amask
) == amask
)
2544 else if ((idx_align
& amask
) != 0)
2551 if (size
== 2 && (idx_align
& 2) != 0)
2553 align
= (idx_align
& 1) ? 16 << size
: 0;
2557 if ((size
== 2 && (idx_align
& 3) != 0)
2558 || (idx_align
& 1) != 0)
2565 if ((idx_align
& 3) == 3)
2567 align
= (idx_align
& 3) * 64;
2570 align
= (idx_align
& 1) ? 32 << size
: 0;
2578 for (i
= 0; i
< length
; i
++)
2579 func (stream
, "%sd%d[%d]", (i
== 0) ? "" : ",",
2580 rd
+ i
* stride
, idx
);
2581 func (stream
, "}, [%s", arm_regnames
[rn
]);
2583 func (stream
, " :%d", align
);
2588 func (stream
, ", %s", arm_regnames
[rm
]);
2594 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2595 int rn
= ((given
>> 16) & 0xf);
2596 int rm
= ((given
>> 0) & 0xf);
2597 int align
= ((given
>> 4) & 0x1);
2598 int size
= ((given
>> 6) & 0x3);
2599 int type
= ((given
>> 8) & 0x3);
2601 int stride
= ((given
>> 5) & 0x1);
2604 if (stride
&& (n
== 1))
2611 for (ix
= 0; ix
!= n
; ix
++)
2612 func (stream
, "%sd%d[]", ix
? "," : "", rd
+ ix
* stride
);
2614 func (stream
, "d%d[]", rd
);
2616 func (stream
, "d%d[]-d%d[]", rd
, rd
+ n
- 1);
2617 func (stream
, "}, [%s", arm_regnames
[rn
]);
2620 align
= (8 * (type
+ 1)) << size
;
2622 align
= (size
> 1) ? align
>> 1 : align
;
2623 if (type
== 2 || (type
== 0 && !size
))
2624 func (stream
, " :<bad align %d>", align
);
2626 func (stream
, " :%d", align
);
2632 func (stream
, ", %s", arm_regnames
[rm
]);
2638 int raw_reg
= (given
& 0xf) | ((given
>> 1) & 0x10);
2639 int size
= (given
>> 20) & 3;
2640 int reg
= raw_reg
& ((4 << size
) - 1);
2641 int ix
= raw_reg
>> size
>> 2;
2643 func (stream
, "d%d[%d]", reg
, ix
);
2648 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2651 int cmode
= (given
>> 8) & 0xf;
2652 int op
= (given
>> 5) & 0x1;
2653 unsigned long value
= 0, hival
= 0;
2658 bits
|= ((given
>> 24) & 1) << 7;
2659 bits
|= ((given
>> 16) & 7) << 4;
2660 bits
|= ((given
>> 0) & 15) << 0;
2664 shift
= (cmode
>> 1) & 3;
2665 value
= (unsigned long) bits
<< (8 * shift
);
2668 else if (cmode
< 12)
2670 shift
= (cmode
>> 1) & 1;
2671 value
= (unsigned long) bits
<< (8 * shift
);
2674 else if (cmode
< 14)
2676 shift
= (cmode
& 1) + 1;
2677 value
= (unsigned long) bits
<< (8 * shift
);
2678 value
|= (1ul << (8 * shift
)) - 1;
2681 else if (cmode
== 14)
2685 /* Bit replication into bytes. */
2691 for (ix
= 7; ix
>= 0; ix
--)
2693 mask
= ((bits
>> ix
) & 1) ? 0xff : 0;
2695 value
= (value
<< 8) | mask
;
2697 hival
= (hival
<< 8) | mask
;
2703 /* Byte replication. */
2704 value
= (unsigned long) bits
;
2710 /* Floating point encoding. */
2713 value
= (unsigned long) (bits
& 0x7f) << 19;
2714 value
|= (unsigned long) (bits
& 0x80) << 24;
2715 tmp
= bits
& 0x40 ? 0x3c : 0x40;
2716 value
|= (unsigned long) tmp
<< 24;
2722 func (stream
, "<illegal constant %.8x:%x:%x>",
2730 func (stream
, "#%ld\t; 0x%.2lx", value
, value
);
2734 func (stream
, "#%ld\t; 0x%.4lx", value
, value
);
2740 unsigned char valbytes
[4];
2743 /* Do this a byte at a time so we don't have to
2744 worry about the host's endianness. */
2745 valbytes
[0] = value
& 0xff;
2746 valbytes
[1] = (value
>> 8) & 0xff;
2747 valbytes
[2] = (value
>> 16) & 0xff;
2748 valbytes
[3] = (value
>> 24) & 0xff;
2750 floatformat_to_double
2751 (& floatformat_ieee_single_little
, valbytes
,
2754 func (stream
, "#%.7g\t; 0x%.8lx", fvalue
,
2758 func (stream
, "#%ld\t; 0x%.8lx",
2759 (long) (((value
& 0x80000000L
) != 0)
2760 ? value
| ~0xffffffffL
: value
),
2765 func (stream
, "#0x%.8lx%.8lx", hival
, value
);
2776 int regno
= ((given
>> 16) & 0xf) | ((given
>> (7 - 4)) & 0x10);
2777 int num
= (given
>> 8) & 0x3;
2780 func (stream
, "{d%d}", regno
);
2781 else if (num
+ regno
>= 32)
2782 func (stream
, "{d%d-<overflow reg d%d}", regno
, regno
+ num
);
2784 func (stream
, "{d%d-d%d}", regno
, regno
+ num
);
2789 case '0': case '1': case '2': case '3': case '4':
2790 case '5': case '6': case '7': case '8': case '9':
2793 unsigned long value
;
2795 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2800 func (stream
, "%s", arm_regnames
[value
]);
2803 func (stream
, "%ld", value
);
2804 value_in_comment
= value
;
2807 func (stream
, "%ld", (1ul << width
) - value
);
2813 /* Various width encodings. */
2815 int base
= 8 << (*c
- 'S'); /* 8,16 or 32 */
2820 if (*c
>= '0' && *c
<= '9')
2822 else if (*c
>= 'a' && *c
<= 'f')
2823 limit
= *c
- 'a' + 10;
2829 if (value
< low
|| value
> high
)
2830 func (stream
, "<illegal width %d>", base
<< value
);
2832 func (stream
, "%d", base
<< value
);
2836 if (given
& (1 << 6))
2840 func (stream
, "d%ld", value
);
2845 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2847 func (stream
, "q%ld", value
>> 1);
2853 func (stream
, "%c", *c
);
2857 if (value
== ((1ul << width
) - 1))
2858 func (stream
, "%c", *c
);
2861 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2875 func (stream
, "%c", *c
);
2878 if (value_in_comment
> 32 || value_in_comment
< -16)
2879 func (stream
, "\t; 0x%lx", value_in_comment
);
2887 /* Return the name of a v7A special register. */
2890 banked_regname (unsigned reg
)
2894 case 15: return "CPSR";
2895 case 32: return "R8_usr";
2896 case 33: return "R9_usr";
2897 case 34: return "R10_usr";
2898 case 35: return "R11_usr";
2899 case 36: return "R12_usr";
2900 case 37: return "SP_usr";
2901 case 38: return "LR_usr";
2902 case 40: return "R8_fiq";
2903 case 41: return "R9_fiq";
2904 case 42: return "R10_fiq";
2905 case 43: return "R11_fiq";
2906 case 44: return "R12_fiq";
2907 case 45: return "SP_fiq";
2908 case 46: return "LR_fiq";
2909 case 48: return "LR_irq";
2910 case 49: return "SP_irq";
2911 case 50: return "LR_svc";
2912 case 51: return "SP_svc";
2913 case 52: return "LR_abt";
2914 case 53: return "SP_abt";
2915 case 54: return "LR_und";
2916 case 55: return "SP_und";
2917 case 60: return "LR_mon";
2918 case 61: return "SP_mon";
2919 case 62: return "ELR_hyp";
2920 case 63: return "SP_hyp";
2921 case 79: return "SPSR";
2922 case 110: return "SPSR_fiq";
2923 case 112: return "SPSR_irq";
2924 case 114: return "SPSR_svc";
2925 case 116: return "SPSR_abt";
2926 case 118: return "SPSR_und";
2927 case 124: return "SPSR_mon";
2928 case 126: return "SPSR_hyp";
2929 default: return NULL
;
2933 /* Print one ARM instruction from PC on INFO->STREAM. */
2936 print_insn_arm (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2938 const struct opcode32
*insn
;
2939 void *stream
= info
->stream
;
2940 fprintf_ftype func
= info
->fprintf_func
;
2941 struct arm_private_data
*private_data
= info
->private_data
;
2943 if (print_insn_coprocessor (pc
, info
, given
, FALSE
))
2946 if (print_insn_neon (info
, given
, FALSE
))
2949 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
2951 if ((given
& insn
->mask
) != insn
->value
)
2954 if ((insn
->arch
& private_data
->features
.core
) == 0)
2957 /* Special case: an instruction with all bits set in the condition field
2958 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2959 or by the catchall at the end of the table. */
2960 if ((given
& 0xF0000000) != 0xF0000000
2961 || (insn
->mask
& 0xF0000000) == 0xF0000000
2962 || (insn
->mask
== 0 && insn
->value
== 0))
2964 unsigned long u_reg
= 16;
2965 unsigned long U_reg
= 16;
2966 bfd_boolean is_unpredictable
= FALSE
;
2967 signed long value_in_comment
= 0;
2970 for (c
= insn
->assembler
; *c
; c
++)
2974 bfd_boolean allow_unpredictable
= FALSE
;
2979 func (stream
, "%%");
2983 value_in_comment
= print_arm_address (pc
, info
, given
);
2987 /* Set P address bit and use normal address
2988 printing routine. */
2989 value_in_comment
= print_arm_address (pc
, info
, given
| (1 << P_BIT
));
2993 allow_unpredictable
= TRUE
;
2995 if ((given
& 0x004f0000) == 0x004f0000)
2997 /* PC relative with immediate offset. */
2998 bfd_vma offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
3002 /* Elide positive zero offset. */
3003 if (offset
|| NEGATIVE_BIT_SET
)
3004 func (stream
, "[pc, #%s%d]\t; ",
3005 NEGATIVE_BIT_SET
? "-" : "", offset
);
3007 func (stream
, "[pc]\t; ");
3008 if (NEGATIVE_BIT_SET
)
3010 info
->print_address_func (offset
+ pc
+ 8, info
);
3014 /* Always show the offset. */
3015 func (stream
, "[pc], #%s%d",
3016 NEGATIVE_BIT_SET
? "-" : "", offset
);
3017 if (! allow_unpredictable
)
3018 is_unpredictable
= TRUE
;
3023 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
3025 func (stream
, "[%s",
3026 arm_regnames
[(given
>> 16) & 0xf]);
3030 if (IMMEDIATE_BIT_SET
)
3032 /* Elide offset for non-writeback
3034 if (WRITEBACK_BIT_SET
|| NEGATIVE_BIT_SET
3036 func (stream
, ", #%s%d",
3037 NEGATIVE_BIT_SET
? "-" : "", offset
);
3039 if (NEGATIVE_BIT_SET
)
3042 value_in_comment
= offset
;
3046 /* Register Offset or Register Pre-Indexed. */
3047 func (stream
, ", %s%s",
3048 NEGATIVE_BIT_SET
? "-" : "",
3049 arm_regnames
[given
& 0xf]);
3051 /* Writing back to the register that is the source/
3052 destination of the load/store is unpredictable. */
3053 if (! allow_unpredictable
3054 && WRITEBACK_BIT_SET
3055 && ((given
& 0xf) == ((given
>> 12) & 0xf)))
3056 is_unpredictable
= TRUE
;
3059 func (stream
, "]%s",
3060 WRITEBACK_BIT_SET
? "!" : "");
3064 if (IMMEDIATE_BIT_SET
)
3066 /* Immediate Post-indexed. */
3067 /* PR 10924: Offset must be printed, even if it is zero. */
3068 func (stream
, "], #%s%d",
3069 NEGATIVE_BIT_SET
? "-" : "", offset
);
3070 if (NEGATIVE_BIT_SET
)
3072 value_in_comment
= offset
;
3076 /* Register Post-indexed. */
3077 func (stream
, "], %s%s",
3078 NEGATIVE_BIT_SET
? "-" : "",
3079 arm_regnames
[given
& 0xf]);
3081 /* Writing back to the register that is the source/
3082 destination of the load/store is unpredictable. */
3083 if (! allow_unpredictable
3084 && (given
& 0xf) == ((given
>> 12) & 0xf))
3085 is_unpredictable
= TRUE
;
3088 if (! allow_unpredictable
)
3090 /* Writeback is automatically implied by post- addressing.
3091 Setting the W bit is unnecessary and ARM specify it as
3092 being unpredictable. */
3093 if (WRITEBACK_BIT_SET
3094 /* Specifying the PC register as the post-indexed
3095 registers is also unpredictable. */
3096 || (! IMMEDIATE_BIT_SET
&& ((given
& 0xf) == 0xf)))
3097 is_unpredictable
= TRUE
;
3105 bfd_vma disp
= (((given
& 0xffffff) ^ 0x800000) - 0x800000);
3106 info
->print_address_func (disp
* 4 + pc
+ 8, info
);
3111 if (((given
>> 28) & 0xf) != 0xe)
3113 arm_conditional
[(given
>> 28) & 0xf]);
3122 for (reg
= 0; reg
< 16; reg
++)
3123 if ((given
& (1 << reg
)) != 0)
3126 func (stream
, ", ");
3128 func (stream
, "%s", arm_regnames
[reg
]);
3132 is_unpredictable
= TRUE
;
3137 arm_decode_shift (given
, func
, stream
, FALSE
);
3141 if ((given
& 0x02000000) != 0)
3143 int rotate
= (given
& 0xf00) >> 7;
3144 int immed
= (given
& 0xff);
3146 immed
= (((immed
<< (32 - rotate
))
3147 | (immed
>> rotate
)) & 0xffffffff);
3148 func (stream
, "#%d", immed
);
3149 value_in_comment
= immed
;
3152 arm_decode_shift (given
, func
, stream
, TRUE
);
3156 if ((given
& 0x0000f000) == 0x0000f000)
3158 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3159 mechanism for setting PSR flag bits. They are
3160 obsolete in V6 onwards. */
3161 if ((private_data
->features
.core
& ARM_EXT_V6
) == 0)
3167 if ((given
& 0x01200000) == 0x00200000)
3173 int offset
= given
& 0xff;
3175 value_in_comment
= offset
* 4;
3176 if (NEGATIVE_BIT_SET
)
3177 value_in_comment
= - value_in_comment
;
3179 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3184 func (stream
, ", #%d]%s",
3186 WRITEBACK_BIT_SET
? "!" : "");
3194 if (WRITEBACK_BIT_SET
)
3197 func (stream
, ", #%d", value_in_comment
);
3201 func (stream
, ", {%d}", offset
);
3202 value_in_comment
= offset
;
3209 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3214 if (! NEGATIVE_BIT_SET
)
3215 /* Is signed, hi bits should be ones. */
3216 offset
= (-1) ^ 0x00ffffff;
3218 /* Offset is (SignExtend(offset field)<<2). */
3219 offset
+= given
& 0x00ffffff;
3221 address
= offset
+ pc
+ 8;
3223 if (given
& 0x01000000)
3224 /* H bit allows addressing to 2-byte boundaries. */
3227 info
->print_address_func (address
, info
);
3232 if ((given
& 0x02000200) == 0x200)
3235 unsigned sysm
= (given
& 0x004f0000) >> 16;
3237 sysm
|= (given
& 0x300) >> 4;
3238 name
= banked_regname (sysm
);
3241 func (stream
, "%s", name
);
3243 func (stream
, "(UNDEF: %lu)", sysm
);
3247 func (stream
, "%cPSR_",
3248 (given
& 0x00400000) ? 'S' : 'C');
3249 if (given
& 0x80000)
3251 if (given
& 0x40000)
3253 if (given
& 0x20000)
3255 if (given
& 0x10000)
3261 if ((given
& 0xf0) == 0x60)
3263 switch (given
& 0xf)
3265 case 0xf: func (stream
, "sy"); break;
3267 func (stream
, "#%d", (int) given
& 0xf);
3273 switch (given
& 0xf)
3275 case 0xf: func (stream
, "sy"); break;
3276 case 0x7: func (stream
, "un"); break;
3277 case 0xe: func (stream
, "st"); break;
3278 case 0x6: func (stream
, "unst"); break;
3279 case 0xb: func (stream
, "ish"); break;
3280 case 0xa: func (stream
, "ishst"); break;
3281 case 0x3: func (stream
, "osh"); break;
3282 case 0x2: func (stream
, "oshst"); break;
3284 func (stream
, "#%d", (int) given
& 0xf);
3290 case '0': case '1': case '2': case '3': case '4':
3291 case '5': case '6': case '7': case '8': case '9':
3294 unsigned long value
;
3296 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3302 is_unpredictable
= TRUE
;
3307 /* Eat the 'u' character. */
3311 is_unpredictable
= TRUE
;
3316 /* Eat the 'U' character. */
3320 is_unpredictable
= TRUE
;
3323 func (stream
, "%s", arm_regnames
[value
]);
3326 func (stream
, "%ld", value
);
3327 value_in_comment
= value
;
3330 func (stream
, "%ld", value
* 8);
3331 value_in_comment
= value
* 8;
3334 func (stream
, "%ld", value
+ 1);
3335 value_in_comment
= value
+ 1;
3338 func (stream
, "0x%08lx", value
);
3340 /* Some SWI instructions have special
3342 if ((given
& 0x0fffffff) == 0x0FF00000)
3343 func (stream
, "\t; IMB");
3344 else if ((given
& 0x0fffffff) == 0x0FF00001)
3345 func (stream
, "\t; IMBRange");
3348 func (stream
, "%01lx", value
& 0xf);
3349 value_in_comment
= value
;
3354 func (stream
, "%c", *c
);
3358 if (value
== ((1ul << width
) - 1))
3359 func (stream
, "%c", *c
);
3362 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
3374 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3375 func (stream
, "%d", imm
);
3376 value_in_comment
= imm
;
3381 /* LSB and WIDTH fields of BFI or BFC. The machine-
3382 language instruction encodes LSB and MSB. */
3384 long msb
= (given
& 0x001f0000) >> 16;
3385 long lsb
= (given
& 0x00000f80) >> 7;
3386 long w
= msb
- lsb
+ 1;
3389 func (stream
, "#%lu, #%lu", lsb
, w
);
3391 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
3396 /* Get the PSR/banked register name. */
3399 unsigned sysm
= (given
& 0x004f0000) >> 16;
3401 sysm
|= (given
& 0x300) >> 4;
3402 name
= banked_regname (sysm
);
3405 func (stream
, "%s", name
);
3407 func (stream
, "(UNDEF: %lu)", sysm
);
3412 /* 16-bit unsigned immediate from a MOVT or MOVW
3413 instruction, encoded in bits 0:11 and 15:19. */
3415 long hi
= (given
& 0x000f0000) >> 4;
3416 long lo
= (given
& 0x00000fff);
3417 long imm16
= hi
| lo
;
3419 func (stream
, "#%lu", imm16
);
3420 value_in_comment
= imm16
;
3430 func (stream
, "%c", *c
);
3433 if (value_in_comment
> 32 || value_in_comment
< -16)
3434 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
3436 if (is_unpredictable
)
3437 func (stream
, UNPREDICTABLE_INSTRUCTION
);
3445 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3448 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3450 const struct opcode16
*insn
;
3451 void *stream
= info
->stream
;
3452 fprintf_ftype func
= info
->fprintf_func
;
3454 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
3455 if ((given
& insn
->mask
) == insn
->value
)
3457 signed long value_in_comment
= 0;
3458 const char *c
= insn
->assembler
;
3467 func (stream
, "%c", *c
);
3474 func (stream
, "%%");
3479 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3484 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3493 ifthen_next_state
= given
& 0xff;
3494 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
3495 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
3496 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
3501 if (ifthen_next_state
)
3502 func (stream
, "\t; unpredictable branch in IT block\n");
3507 func (stream
, "\t; unpredictable <IT:%s>",
3508 arm_conditional
[IFTHEN_COND
]);
3515 reg
= (given
>> 3) & 0x7;
3516 if (given
& (1 << 6))
3519 func (stream
, "%s", arm_regnames
[reg
]);
3528 if (given
& (1 << 7))
3531 func (stream
, "%s", arm_regnames
[reg
]);
3536 if (given
& (1 << 8))
3540 if (*c
== 'O' && (given
& (1 << 8)))
3550 /* It would be nice if we could spot
3551 ranges, and generate the rS-rE format: */
3552 for (reg
= 0; (reg
< 8); reg
++)
3553 if ((given
& (1 << reg
)) != 0)
3556 func (stream
, ", ");
3558 func (stream
, "%s", arm_regnames
[reg
]);
3564 func (stream
, ", ");
3566 func (stream
, arm_regnames
[14] /* "lr" */);
3572 func (stream
, ", ");
3573 func (stream
, arm_regnames
[15] /* "pc" */);
3581 /* Print writeback indicator for a LDMIA. We are doing a
3582 writeback if the base register is not in the register
3584 if ((given
& (1 << ((given
& 0x0700) >> 8))) == 0)
3589 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3591 bfd_vma address
= (pc
+ 4
3592 + ((given
& 0x00f8) >> 2)
3593 + ((given
& 0x0200) >> 3));
3594 info
->print_address_func (address
, info
);
3599 /* Right shift immediate -- bits 6..10; 1-31 print
3600 as themselves, 0 prints as 32. */
3602 long imm
= (given
& 0x07c0) >> 6;
3605 func (stream
, "#%ld", imm
);
3609 case '0': case '1': case '2': case '3': case '4':
3610 case '5': case '6': case '7': case '8': case '9':
3612 int bitstart
= *c
++ - '0';
3615 while (*c
>= '0' && *c
<= '9')
3616 bitstart
= (bitstart
* 10) + *c
++ - '0';
3625 while (*c
>= '0' && *c
<= '9')
3626 bitend
= (bitend
* 10) + *c
++ - '0';
3629 reg
= given
>> bitstart
;
3630 reg
&= (2 << (bitend
- bitstart
)) - 1;
3635 func (stream
, "%s", arm_regnames
[reg
]);
3639 func (stream
, "%ld", reg
);
3640 value_in_comment
= reg
;
3644 func (stream
, "%ld", reg
<< 1);
3645 value_in_comment
= reg
<< 1;
3649 func (stream
, "%ld", reg
<< 2);
3650 value_in_comment
= reg
<< 2;
3654 /* PC-relative address -- the bottom two
3655 bits of the address are dropped
3656 before the calculation. */
3657 info
->print_address_func
3658 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
3659 value_in_comment
= 0;
3663 func (stream
, "0x%04lx", reg
);
3667 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
3668 info
->print_address_func (reg
* 2 + pc
+ 4, info
);
3669 value_in_comment
= 0;
3673 func (stream
, "%s", arm_conditional
[reg
]);
3684 if ((given
& (1 << bitstart
)) != 0)
3685 func (stream
, "%c", *c
);
3690 if ((given
& (1 << bitstart
)) != 0)
3691 func (stream
, "%c", *c
++);
3693 func (stream
, "%c", *++c
);
3707 if (value_in_comment
> 32 || value_in_comment
< -16)
3708 func (stream
, "\t; 0x%lx", value_in_comment
);
3716 /* Return the name of an V7M special register. */
3719 psr_name (int regno
)
3723 case 0: return "APSR";
3724 case 1: return "IAPSR";
3725 case 2: return "EAPSR";
3726 case 3: return "PSR";
3727 case 5: return "IPSR";
3728 case 6: return "EPSR";
3729 case 7: return "IEPSR";
3730 case 8: return "MSP";
3731 case 9: return "PSP";
3732 case 16: return "PRIMASK";
3733 case 17: return "BASEPRI";
3734 case 18: return "BASEPRI_MAX";
3735 case 19: return "FAULTMASK";
3736 case 20: return "CONTROL";
3737 default: return "<unknown>";
3741 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3744 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3746 const struct opcode32
*insn
;
3747 void *stream
= info
->stream
;
3748 fprintf_ftype func
= info
->fprintf_func
;
3750 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
3753 if (print_insn_neon (info
, given
, TRUE
))
3756 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
3757 if ((given
& insn
->mask
) == insn
->value
)
3759 bfd_boolean is_unpredictable
= FALSE
;
3760 signed long value_in_comment
= 0;
3761 const char *c
= insn
->assembler
;
3767 func (stream
, "%c", *c
);
3774 func (stream
, "%%");
3779 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3783 if (ifthen_next_state
)
3784 func (stream
, "\t; unpredictable branch in IT block\n");
3789 func (stream
, "\t; unpredictable <IT:%s>",
3790 arm_conditional
[IFTHEN_COND
]);
3795 unsigned int imm12
= 0;
3797 imm12
|= (given
& 0x000000ffu
);
3798 imm12
|= (given
& 0x00007000u
) >> 4;
3799 imm12
|= (given
& 0x04000000u
) >> 15;
3800 func (stream
, "#%u", imm12
);
3801 value_in_comment
= imm12
;
3807 unsigned int bits
= 0, imm
, imm8
, mod
;
3809 bits
|= (given
& 0x000000ffu
);
3810 bits
|= (given
& 0x00007000u
) >> 4;
3811 bits
|= (given
& 0x04000000u
) >> 15;
3812 imm8
= (bits
& 0x0ff);
3813 mod
= (bits
& 0xf00) >> 8;
3816 case 0: imm
= imm8
; break;
3817 case 1: imm
= ((imm8
<< 16) | imm8
); break;
3818 case 2: imm
= ((imm8
<< 24) | (imm8
<< 8)); break;
3819 case 3: imm
= ((imm8
<< 24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
3821 mod
= (bits
& 0xf80) >> 7;
3822 imm8
= (bits
& 0x07f) | 0x80;
3823 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
3825 func (stream
, "#%u", imm
);
3826 value_in_comment
= imm
;
3832 unsigned int imm
= 0;
3834 imm
|= (given
& 0x000000ffu
);
3835 imm
|= (given
& 0x00007000u
) >> 4;
3836 imm
|= (given
& 0x04000000u
) >> 15;
3837 imm
|= (given
& 0x000f0000u
) >> 4;
3838 func (stream
, "#%u", imm
);
3839 value_in_comment
= imm
;
3845 unsigned int imm
= 0;
3847 imm
|= (given
& 0x000f0000u
) >> 16;
3848 imm
|= (given
& 0x00000ff0u
) >> 0;
3849 imm
|= (given
& 0x0000000fu
) << 12;
3850 func (stream
, "#%u", imm
);
3851 value_in_comment
= imm
;
3857 unsigned int imm
= 0;
3859 imm
|= (given
& 0x00000fffu
);
3860 imm
|= (given
& 0x000f0000u
) >> 4;
3861 func (stream
, "#%u", imm
);
3862 value_in_comment
= imm
;
3868 unsigned int reg
= (given
& 0x0000000fu
);
3869 unsigned int stp
= (given
& 0x00000030u
) >> 4;
3870 unsigned int imm
= 0;
3871 imm
|= (given
& 0x000000c0u
) >> 6;
3872 imm
|= (given
& 0x00007000u
) >> 10;
3874 func (stream
, "%s", arm_regnames
[reg
]);
3879 func (stream
, ", lsl #%u", imm
);
3885 func (stream
, ", lsr #%u", imm
);
3891 func (stream
, ", asr #%u", imm
);
3896 func (stream
, ", rrx");
3898 func (stream
, ", ror #%u", imm
);
3905 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3906 unsigned int U
= ! NEGATIVE_BIT_SET
;
3907 unsigned int op
= (given
& 0x00000f00) >> 8;
3908 unsigned int i12
= (given
& 0x00000fff);
3909 unsigned int i8
= (given
& 0x000000ff);
3910 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
3913 func (stream
, "[%s", arm_regnames
[Rn
]);
3914 if (U
) /* 12-bit positive immediate offset. */
3918 value_in_comment
= offset
;
3920 else if (Rn
== 15) /* 12-bit negative immediate offset. */
3921 offset
= - (int) i12
;
3922 else if (op
== 0x0) /* Shifted register offset. */
3924 unsigned int Rm
= (i8
& 0x0f);
3925 unsigned int sh
= (i8
& 0x30) >> 4;
3927 func (stream
, ", %s", arm_regnames
[Rm
]);
3929 func (stream
, ", lsl #%u", sh
);
3935 case 0xE: /* 8-bit positive immediate offset. */
3939 case 0xC: /* 8-bit negative immediate offset. */
3943 case 0xF: /* 8-bit + preindex with wb. */
3948 case 0xD: /* 8-bit - preindex with wb. */
3953 case 0xB: /* 8-bit + postindex. */
3958 case 0x9: /* 8-bit - postindex. */
3964 func (stream
, ", <undefined>]");
3969 func (stream
, "], #%d", offset
);
3973 func (stream
, ", #%d", offset
);
3974 func (stream
, writeback
? "]!" : "]");
3979 func (stream
, "\t; ");
3980 info
->print_address_func (((pc
+ 4) & ~3) + offset
, info
);
3988 unsigned int U
= ! NEGATIVE_BIT_SET
;
3989 unsigned int W
= WRITEBACK_BIT_SET
;
3990 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3991 unsigned int off
= (given
& 0x000000ff);
3993 func (stream
, "[%s", arm_regnames
[Rn
]);
3999 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
4000 value_in_comment
= off
* 4 * U
? 1 : -1;
4008 func (stream
, "], ");
4011 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
4012 value_in_comment
= off
* 4 * U
? 1 : -1;
4016 func (stream
, "{%u}", off
);
4017 value_in_comment
= off
;
4025 unsigned int Sbit
= (given
& 0x01000000) >> 24;
4026 unsigned int type
= (given
& 0x00600000) >> 21;
4030 case 0: func (stream
, Sbit
? "sb" : "b"); break;
4031 case 1: func (stream
, Sbit
? "sh" : "h"); break;
4034 func (stream
, "??");
4037 func (stream
, "??");
4049 for (reg
= 0; reg
< 16; reg
++)
4050 if ((given
& (1 << reg
)) != 0)
4053 func (stream
, ", ");
4055 func (stream
, "%s", arm_regnames
[reg
]);
4063 unsigned int msb
= (given
& 0x0000001f);
4064 unsigned int lsb
= 0;
4066 lsb
|= (given
& 0x000000c0u
) >> 6;
4067 lsb
|= (given
& 0x00007000u
) >> 10;
4068 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
4074 unsigned int width
= (given
& 0x0000001f) + 1;
4075 unsigned int lsb
= 0;
4077 lsb
|= (given
& 0x000000c0u
) >> 6;
4078 lsb
|= (given
& 0x00007000u
) >> 10;
4079 func (stream
, "#%u, #%u", lsb
, width
);
4085 unsigned int S
= (given
& 0x04000000u
) >> 26;
4086 unsigned int J1
= (given
& 0x00002000u
) >> 13;
4087 unsigned int J2
= (given
& 0x00000800u
) >> 11;
4093 offset
|= (given
& 0x003f0000) >> 4;
4094 offset
|= (given
& 0x000007ff) << 1;
4095 offset
-= (1 << 20);
4097 info
->print_address_func (pc
+ 4 + offset
, info
);
4103 unsigned int S
= (given
& 0x04000000u
) >> 26;
4104 unsigned int I1
= (given
& 0x00002000u
) >> 13;
4105 unsigned int I2
= (given
& 0x00000800u
) >> 11;
4109 offset
|= !(I1
^ S
) << 23;
4110 offset
|= !(I2
^ S
) << 22;
4111 offset
|= (given
& 0x03ff0000u
) >> 4;
4112 offset
|= (given
& 0x000007ffu
) << 1;
4113 offset
-= (1 << 24);
4116 /* BLX target addresses are always word aligned. */
4117 if ((given
& 0x00001000u
) == 0)
4120 info
->print_address_func (offset
, info
);
4126 unsigned int shift
= 0;
4128 shift
|= (given
& 0x000000c0u
) >> 6;
4129 shift
|= (given
& 0x00007000u
) >> 10;
4130 if (WRITEBACK_BIT_SET
)
4131 func (stream
, ", asr #%u", shift
);
4133 func (stream
, ", lsl #%u", shift
);
4134 /* else print nothing - lsl #0 */
4140 unsigned int rot
= (given
& 0x00000030) >> 4;
4143 func (stream
, ", ror #%u", rot
* 8);
4148 if ((given
& 0xf0) == 0x60)
4150 switch (given
& 0xf)
4152 case 0xf: func (stream
, "sy"); break;
4154 func (stream
, "#%d", (int) given
& 0xf);
4160 switch (given
& 0xf)
4162 case 0xf: func (stream
, "sy"); break;
4163 case 0x7: func (stream
, "un"); break;
4164 case 0xe: func (stream
, "st"); break;
4165 case 0x6: func (stream
, "unst"); break;
4166 case 0xb: func (stream
, "ish"); break;
4167 case 0xa: func (stream
, "ishst"); break;
4168 case 0x3: func (stream
, "osh"); break;
4169 case 0x2: func (stream
, "oshst"); break;
4171 func (stream
, "#%d", (int) given
& 0xf);
4178 if ((given
& 0xff) == 0)
4180 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
4190 else if ((given
& 0x20) == 0x20)
4193 unsigned sysm
= (given
& 0xf00) >> 8;
4195 sysm
|= (given
& 0x30);
4196 sysm
|= (given
& 0x00100000) >> 14;
4197 name
= banked_regname (sysm
);
4200 func (stream
, "%s", name
);
4202 func (stream
, "(UNDEF: %lu)", sysm
);
4206 func (stream
, psr_name (given
& 0xff));
4211 if (((given
& 0xff) == 0)
4212 || ((given
& 0x20) == 0x20))
4215 unsigned sm
= (given
& 0xf0000) >> 16;
4217 sm
|= (given
& 0x30);
4218 sm
|= (given
& 0x00100000) >> 14;
4219 name
= banked_regname (sm
);
4222 func (stream
, "%s", name
);
4224 func (stream
, "(UNDEF: %lu)", sm
);
4227 func (stream
, psr_name (given
& 0xff));
4230 case '0': case '1': case '2': case '3': case '4':
4231 case '5': case '6': case '7': case '8': case '9':
4236 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
4241 func (stream
, "%lu", val
);
4242 value_in_comment
= val
;
4246 func (stream
, "%lu", val
* 4);
4247 value_in_comment
= val
* 4;
4252 is_unpredictable
= TRUE
;
4255 func (stream
, "%s", arm_regnames
[val
]);
4259 func (stream
, "%s", arm_conditional
[val
]);
4264 if (val
== ((1ul << width
) - 1))
4265 func (stream
, "%c", *c
);
4271 func (stream
, "%c", *c
);
4275 func (stream
, "%c", c
[(1 << width
) - (int) val
]);
4280 func (stream
, "0x%lx", val
& 0xffffffffUL
);
4290 /* PR binutils/12534
4291 If we have a PC relative offset in an LDRD or STRD
4292 instructions then display the decoded address. */
4293 if (((given
>> 16) & 0xf) == 0xf)
4295 bfd_vma offset
= (given
& 0xff) * 4;
4297 if ((given
& (1 << 23)) == 0)
4299 func (stream
, "\t; ");
4300 info
->print_address_func ((pc
& ~3) + 4 + offset
, info
);
4309 if (value_in_comment
> 32 || value_in_comment
< -16)
4310 func (stream
, "\t; 0x%lx", value_in_comment
);
4312 if (is_unpredictable
)
4313 func (stream
, UNPREDICTABLE_INSTRUCTION
);
4322 /* Print data bytes on INFO->STREAM. */
4325 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
4326 struct disassemble_info
*info
,
4329 switch (info
->bytes_per_chunk
)
4332 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
4335 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
4338 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
4345 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4346 being displayed in symbol relative addresses. */
4349 arm_symbol_is_valid (asymbol
* sym
,
4350 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
4357 name
= bfd_asymbol_name (sym
);
4359 return (name
&& *name
!= '$');
4362 /* Parse an individual disassembler option. */
4365 parse_arm_disassembler_option (char *option
)
4370 if (CONST_STRNEQ (option
, "reg-names-"))
4376 for (i
= NUM_ARM_REGNAMES
; i
--;)
4377 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
4379 regname_selected
= i
;
4384 /* XXX - should break 'option' at following delimiter. */
4385 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
4387 else if (CONST_STRNEQ (option
, "force-thumb"))
4389 else if (CONST_STRNEQ (option
, "no-force-thumb"))
4392 /* XXX - should break 'option' at following delimiter. */
4393 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
4398 /* Parse the string of disassembler options, spliting it at whitespaces
4399 or commas. (Whitespace separators supported for backwards compatibility). */
4402 parse_disassembler_options (char *options
)
4404 if (options
== NULL
)
4409 parse_arm_disassembler_option (options
);
4411 /* Skip forward to next seperator. */
4412 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
4414 /* Skip forward past seperators. */
4415 while (ISSPACE (*options
) || (*options
== ','))
4420 /* Search back through the insn stream to determine if this instruction is
4421 conditionally executed. */
4424 find_ifthen_state (bfd_vma pc
,
4425 struct disassemble_info
*info
,
4431 /* COUNT is twice the number of instructions seen. It will be odd if we
4432 just crossed an instruction boundary. */
4435 unsigned int seen_it
;
4438 ifthen_address
= pc
;
4445 /* Scan backwards looking for IT instructions, keeping track of where
4446 instruction boundaries are. We don't know if something is actually an
4447 IT instruction until we find a definite instruction boundary. */
4450 if (addr
== 0 || info
->symbol_at_address_func (addr
, info
))
4452 /* A symbol must be on an instruction boundary, and will not
4453 be within an IT block. */
4454 if (seen_it
&& (count
& 1))
4460 status
= info
->read_memory_func (addr
, (bfd_byte
*) b
, 2, info
);
4465 insn
= (b
[0]) | (b
[1] << 8);
4467 insn
= (b
[1]) | (b
[0] << 8);
4470 if ((insn
& 0xf800) < 0xe800)
4472 /* Addr + 2 is an instruction boundary. See if this matches
4473 the expected boundary based on the position of the last
4480 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4482 /* This could be an IT instruction. */
4484 it_count
= count
>> 1;
4486 if ((insn
& 0xf800) >= 0xe800)
4489 count
= (count
+ 2) | 1;
4490 /* IT blocks contain at most 4 instructions. */
4491 if (count
>= 8 && !seen_it
)
4494 /* We found an IT instruction. */
4495 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4496 if ((ifthen_state
& 0xf) == 0)
4500 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4504 is_mapping_symbol (struct disassemble_info
*info
, int n
,
4505 enum map_type
*map_type
)
4509 name
= bfd_asymbol_name (info
->symtab
[n
]);
4510 if (name
[0] == '$' && (name
[1] == 'a' || name
[1] == 't' || name
[1] == 'd')
4511 && (name
[2] == 0 || name
[2] == '.'))
4513 *map_type
= ((name
[1] == 'a') ? MAP_ARM
4514 : (name
[1] == 't') ? MAP_THUMB
4522 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4523 Returns nonzero if *MAP_TYPE was set. */
4526 get_map_sym_type (struct disassemble_info
*info
,
4528 enum map_type
*map_type
)
4530 /* If the symbol is in a different section, ignore it. */
4531 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4534 return is_mapping_symbol (info
, n
, map_type
);
4537 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4538 Returns nonzero if *MAP_TYPE was set. */
4541 get_sym_code_type (struct disassemble_info
*info
,
4543 enum map_type
*map_type
)
4545 elf_symbol_type
*es
;
4548 /* If the symbol is in a different section, ignore it. */
4549 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4552 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
4553 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4555 /* If the symbol has function type then use that. */
4556 if (type
== STT_FUNC
|| type
== STT_GNU_IFUNC
)
4558 if (ARM_SYM_BRANCH_TYPE (&es
->internal_elf_sym
) == ST_BRANCH_TO_THUMB
)
4559 *map_type
= MAP_THUMB
;
4561 *map_type
= MAP_ARM
;
4568 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4569 of the supplied arm_feature_set structure with bitmasks indicating
4570 the support base architectures and coprocessor extensions.
4572 FIXME: This could more efficiently implemented as a constant array,
4573 although it would also be less robust. */
4576 select_arm_features (unsigned long mach
,
4577 arm_feature_set
* features
)
4580 #define ARM_FEATURE(ARCH,CEXT) \
4581 features->core = (ARCH); \
4582 features->coproc = (CEXT) | FPU_FPA; \
4587 case bfd_mach_arm_2
: ARM_ARCH_V2
;
4588 case bfd_mach_arm_2a
: ARM_ARCH_V2S
;
4589 case bfd_mach_arm_3
: ARM_ARCH_V3
;
4590 case bfd_mach_arm_3M
: ARM_ARCH_V3M
;
4591 case bfd_mach_arm_4
: ARM_ARCH_V4
;
4592 case bfd_mach_arm_4T
: ARM_ARCH_V4T
;
4593 case bfd_mach_arm_5
: ARM_ARCH_V5
;
4594 case bfd_mach_arm_5T
: ARM_ARCH_V5T
;
4595 case bfd_mach_arm_5TE
: ARM_ARCH_V5TE
;
4596 case bfd_mach_arm_XScale
: ARM_ARCH_XSCALE
;
4597 case bfd_mach_arm_ep9312
: ARM_FEATURE (ARM_AEXT_V4T
, ARM_CEXT_MAVERICK
| FPU_MAVERICK
);
4598 case bfd_mach_arm_iWMMXt
: ARM_ARCH_IWMMXT
;
4599 case bfd_mach_arm_iWMMXt2
: ARM_ARCH_IWMMXT2
;
4600 /* If the machine type is unknown allow all
4601 architecture types and all extensions. */
4602 case bfd_mach_arm_unknown
: ARM_FEATURE (-1UL, -1UL);
4609 /* NOTE: There are no checks in these routines that
4610 the relevant number of data bytes exist. */
4613 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4618 int is_thumb
= FALSE
;
4619 int is_data
= FALSE
;
4621 unsigned int size
= 4;
4622 void (*printer
) (bfd_vma
, struct disassemble_info
*, long);
4623 bfd_boolean found
= FALSE
;
4624 struct arm_private_data
*private_data
;
4626 if (info
->disassembler_options
)
4628 parse_disassembler_options (info
->disassembler_options
);
4630 /* To avoid repeated parsing of these options, we remove them here. */
4631 info
->disassembler_options
= NULL
;
4634 /* PR 10288: Control which instructions will be disassembled. */
4635 if (info
->private_data
== NULL
)
4637 static struct arm_private_data
private;
4639 if ((info
->flags
& USER_SPECIFIED_MACHINE_TYPE
) == 0)
4640 /* If the user did not use the -m command line switch then default to
4641 disassembling all types of ARM instruction.
4643 The info->mach value has to be ignored as this will be based on
4644 the default archictecture for the target and/or hints in the notes
4645 section, but it will never be greater than the current largest arm
4646 machine value (iWMMXt2), which is only equivalent to the V5TE
4647 architecture. ARM architectures have advanced beyond the machine
4648 value encoding, and these newer architectures would be ignored if
4649 the machine value was used.
4651 Ie the -m switch is used to restrict which instructions will be
4652 disassembled. If it is necessary to use the -m switch to tell
4653 objdump that an ARM binary is being disassembled, eg because the
4654 input is a raw binary file, but it is also desired to disassemble
4655 all ARM instructions then use "-marm". This will select the
4656 "unknown" arm architecture which is compatible with any ARM
4658 info
->mach
= bfd_mach_arm_unknown
;
4660 /* Compute the architecture bitmask from the machine number.
4661 Note: This assumes that the machine number will not change
4662 during disassembly.... */
4663 select_arm_features (info
->mach
, & private.features
);
4665 private.has_mapping_symbols
= -1;
4666 private.last_mapping_sym
= -1;
4667 private.last_mapping_addr
= 0;
4669 info
->private_data
= & private;
4672 private_data
= info
->private_data
;
4674 /* Decide if our code is going to be little-endian, despite what the
4675 function argument might say. */
4676 little_code
= ((info
->endian_code
== BFD_ENDIAN_LITTLE
) || little
);
4678 /* For ELF, consult the symbol table to determine what kind of code
4680 if (info
->symtab_size
!= 0
4681 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4686 enum map_type type
= MAP_ARM
;
4688 /* Start scanning at the start of the function, or wherever
4689 we finished last time. */
4690 start
= info
->symtab_pos
+ 1;
4691 if (start
< private_data
->last_mapping_sym
)
4692 start
= private_data
->last_mapping_sym
;
4695 /* First, look for mapping symbols. */
4696 if (private_data
->has_mapping_symbols
!= 0)
4698 /* Scan up to the location being disassembled. */
4699 for (n
= start
; n
< info
->symtab_size
; n
++)
4701 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4704 if (get_map_sym_type (info
, n
, &type
))
4713 /* No mapping symbol found at this address. Look backwards
4714 for a preceding one. */
4715 for (n
= start
- 1; n
>= 0; n
--)
4717 if (get_map_sym_type (info
, n
, &type
))
4727 private_data
->has_mapping_symbols
= 1;
4729 /* No mapping symbols were found. A leading $d may be
4730 omitted for sections which start with data; but for
4731 compatibility with legacy and stripped binaries, only
4732 assume the leading $d if there is at least one mapping
4733 symbol in the file. */
4734 if (!found
&& private_data
->has_mapping_symbols
== -1)
4736 /* Look for mapping symbols, in any section. */
4737 for (n
= 0; n
< info
->symtab_size
; n
++)
4738 if (is_mapping_symbol (info
, n
, &type
))
4740 private_data
->has_mapping_symbols
= 1;
4743 if (private_data
->has_mapping_symbols
== -1)
4744 private_data
->has_mapping_symbols
= 0;
4747 if (!found
&& private_data
->has_mapping_symbols
== 1)
4754 /* Next search for function symbols to separate ARM from Thumb
4755 in binaries without mapping symbols. */
4758 /* Scan up to the location being disassembled. */
4759 for (n
= start
; n
< info
->symtab_size
; n
++)
4761 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4764 if (get_sym_code_type (info
, n
, &type
))
4773 /* No mapping symbol found at this address. Look backwards
4774 for a preceding one. */
4775 for (n
= start
- 1; n
>= 0; n
--)
4777 if (get_sym_code_type (info
, n
, &type
))
4787 private_data
->last_mapping_sym
= last_sym
;
4788 private_data
->last_type
= type
;
4789 is_thumb
= (private_data
->last_type
== MAP_THUMB
);
4790 is_data
= (private_data
->last_type
== MAP_DATA
);
4792 /* Look a little bit ahead to see if we should print out
4793 two or four bytes of data. If there's a symbol,
4794 mapping or otherwise, after two bytes then don't
4798 size
= 4 - (pc
& 3);
4799 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4801 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4803 && (info
->section
== NULL
4804 || info
->section
== info
->symtab
[n
]->section
))
4806 if (addr
- pc
< size
)
4811 /* If the next symbol is after three bytes, we need to
4812 print only part of the data, so that we can use either
4815 size
= (pc
& 1) ? 1 : 2;
4819 if (info
->symbols
!= NULL
)
4821 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4823 coff_symbol_type
* cs
;
4825 cs
= coffsymbol (*info
->symbols
);
4826 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4827 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4828 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4829 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4830 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4832 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
4835 /* If no mapping symbol has been found then fall back to the type
4836 of the function symbol. */
4837 elf_symbol_type
* es
;
4840 es
= *(elf_symbol_type
**)(info
->symbols
);
4841 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4843 is_thumb
= ((ARM_SYM_BRANCH_TYPE (&es
->internal_elf_sym
)
4844 == ST_BRANCH_TO_THUMB
)
4845 || type
== STT_ARM_16BIT
);
4853 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4855 info
->display_endian
= little_code
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4857 info
->bytes_per_line
= 4;
4859 /* PR 10263: Disassemble data if requested to do so by the user. */
4860 if (is_data
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
4864 /* Size was already set above. */
4865 info
->bytes_per_chunk
= size
;
4866 printer
= print_insn_data
;
4868 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, size
, info
);
4871 for (i
= size
- 1; i
>= 0; i
--)
4872 given
= b
[i
] | (given
<< 8);
4874 for (i
= 0; i
< (int) size
; i
++)
4875 given
= b
[i
] | (given
<< 8);
4879 /* In ARM mode endianness is a straightforward issue: the instruction
4880 is four bytes long and is either ordered 0123 or 3210. */
4881 printer
= print_insn_arm
;
4882 info
->bytes_per_chunk
= 4;
4885 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 4, info
);
4887 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
4889 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
4893 /* In Thumb mode we have the additional wrinkle of two
4894 instruction lengths. Fortunately, the bits that determine
4895 the length of the current instruction are always to be found
4896 in the first two bytes. */
4897 printer
= print_insn_thumb16
;
4898 info
->bytes_per_chunk
= 2;
4901 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
4903 given
= (b
[0]) | (b
[1] << 8);
4905 given
= (b
[1]) | (b
[0] << 8);
4909 /* These bit patterns signal a four-byte Thumb
4911 if ((given
& 0xF800) == 0xF800
4912 || (given
& 0xF800) == 0xF000
4913 || (given
& 0xF800) == 0xE800)
4915 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) b
, 2, info
);
4917 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
4919 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
4921 printer
= print_insn_thumb32
;
4926 if (ifthen_address
!= pc
)
4927 find_ifthen_state (pc
, info
, little_code
);
4931 if ((ifthen_state
& 0xf) == 0x8)
4932 ifthen_next_state
= 0;
4934 ifthen_next_state
= (ifthen_state
& 0xe0)
4935 | ((ifthen_state
& 0xf) << 1);
4941 info
->memory_error_func (status
, pc
, info
);
4944 if (info
->flags
& INSN_HAS_RELOC
)
4945 /* If the instruction has a reloc associated with it, then
4946 the offset field in the instruction will actually be the
4947 addend for the reloc. (We are using REL type relocs).
4948 In such cases, we can ignore the pc when computing
4949 addresses, since the addend is not currently pc-relative. */
4952 printer (pc
, info
, given
);
4956 ifthen_state
= ifthen_next_state
;
4957 ifthen_address
+= size
;
4963 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
4965 /* Detect BE8-ness and record it in the disassembler info. */
4966 if (info
->flavour
== bfd_target_elf_flavour
4967 && info
->section
!= NULL
4968 && (elf_elfheader (info
->section
->owner
)->e_flags
& EF_ARM_BE8
))
4969 info
->endian_code
= BFD_ENDIAN_LITTLE
;
4971 return print_insn (pc
, info
, FALSE
);
4975 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
4977 return print_insn (pc
, info
, TRUE
);
4981 print_arm_disassembler_options (FILE *stream
)
4985 fprintf (stream
, _("\n\
4986 The following ARM specific disassembler options are supported for use with\n\
4987 the -M switch:\n"));
4989 for (i
= NUM_ARM_REGNAMES
; i
--;)
4990 fprintf (stream
, " reg-names-%s %*c%s\n",
4992 (int)(14 - strlen (regnames
[i
].name
)), ' ',
4993 regnames
[i
].description
);
4995 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
4996 fprintf (stream
, " no-force-thumb Examine preceding label to determine an insn's type\n\n");