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 unsigned int rotate
= (given
& 0xf00) >> 7;
3144 unsigned int immed
= (given
& 0xff);
3147 a
= (((immed
<< (32 - rotate
))
3148 | (immed
>> rotate
)) & 0xffffffff);
3149 /* If there is another encoding with smaller rotate,
3150 the rotate should be specified directly. */
3151 for (i
= 0; i
< 32; i
+= 2)
3152 if ((a
<< i
| a
>> (32 - i
)) <= 0xff)
3156 func (stream
, "#%d, %d", immed
, rotate
);
3158 func (stream
, "#%d", a
);
3159 value_in_comment
= a
;
3162 arm_decode_shift (given
, func
, stream
, TRUE
);
3166 if ((given
& 0x0000f000) == 0x0000f000)
3168 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3169 mechanism for setting PSR flag bits. They are
3170 obsolete in V6 onwards. */
3171 if ((private_data
->features
.core
& ARM_EXT_V6
) == 0)
3177 if ((given
& 0x01200000) == 0x00200000)
3183 int offset
= given
& 0xff;
3185 value_in_comment
= offset
* 4;
3186 if (NEGATIVE_BIT_SET
)
3187 value_in_comment
= - value_in_comment
;
3189 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3194 func (stream
, ", #%d]%s",
3196 WRITEBACK_BIT_SET
? "!" : "");
3204 if (WRITEBACK_BIT_SET
)
3207 func (stream
, ", #%d", value_in_comment
);
3211 func (stream
, ", {%d}", offset
);
3212 value_in_comment
= offset
;
3219 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3224 if (! NEGATIVE_BIT_SET
)
3225 /* Is signed, hi bits should be ones. */
3226 offset
= (-1) ^ 0x00ffffff;
3228 /* Offset is (SignExtend(offset field)<<2). */
3229 offset
+= given
& 0x00ffffff;
3231 address
= offset
+ pc
+ 8;
3233 if (given
& 0x01000000)
3234 /* H bit allows addressing to 2-byte boundaries. */
3237 info
->print_address_func (address
, info
);
3242 if ((given
& 0x02000200) == 0x200)
3245 unsigned sysm
= (given
& 0x004f0000) >> 16;
3247 sysm
|= (given
& 0x300) >> 4;
3248 name
= banked_regname (sysm
);
3251 func (stream
, "%s", name
);
3253 func (stream
, "(UNDEF: %lu)", sysm
);
3257 func (stream
, "%cPSR_",
3258 (given
& 0x00400000) ? 'S' : 'C');
3259 if (given
& 0x80000)
3261 if (given
& 0x40000)
3263 if (given
& 0x20000)
3265 if (given
& 0x10000)
3271 if ((given
& 0xf0) == 0x60)
3273 switch (given
& 0xf)
3275 case 0xf: func (stream
, "sy"); break;
3277 func (stream
, "#%d", (int) given
& 0xf);
3283 switch (given
& 0xf)
3285 case 0xf: func (stream
, "sy"); break;
3286 case 0x7: func (stream
, "un"); break;
3287 case 0xe: func (stream
, "st"); break;
3288 case 0x6: func (stream
, "unst"); break;
3289 case 0xb: func (stream
, "ish"); break;
3290 case 0xa: func (stream
, "ishst"); break;
3291 case 0x3: func (stream
, "osh"); break;
3292 case 0x2: func (stream
, "oshst"); break;
3294 func (stream
, "#%d", (int) given
& 0xf);
3300 case '0': case '1': case '2': case '3': case '4':
3301 case '5': case '6': case '7': case '8': case '9':
3304 unsigned long value
;
3306 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3312 is_unpredictable
= TRUE
;
3317 /* Eat the 'u' character. */
3321 is_unpredictable
= TRUE
;
3326 /* Eat the 'U' character. */
3330 is_unpredictable
= TRUE
;
3333 func (stream
, "%s", arm_regnames
[value
]);
3336 func (stream
, "%ld", value
);
3337 value_in_comment
= value
;
3340 func (stream
, "%ld", value
* 8);
3341 value_in_comment
= value
* 8;
3344 func (stream
, "%ld", value
+ 1);
3345 value_in_comment
= value
+ 1;
3348 func (stream
, "0x%08lx", value
);
3350 /* Some SWI instructions have special
3352 if ((given
& 0x0fffffff) == 0x0FF00000)
3353 func (stream
, "\t; IMB");
3354 else if ((given
& 0x0fffffff) == 0x0FF00001)
3355 func (stream
, "\t; IMBRange");
3358 func (stream
, "%01lx", value
& 0xf);
3359 value_in_comment
= value
;
3364 func (stream
, "%c", *c
);
3368 if (value
== ((1ul << width
) - 1))
3369 func (stream
, "%c", *c
);
3372 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
3384 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3385 func (stream
, "%d", imm
);
3386 value_in_comment
= imm
;
3391 /* LSB and WIDTH fields of BFI or BFC. The machine-
3392 language instruction encodes LSB and MSB. */
3394 long msb
= (given
& 0x001f0000) >> 16;
3395 long lsb
= (given
& 0x00000f80) >> 7;
3396 long w
= msb
- lsb
+ 1;
3399 func (stream
, "#%lu, #%lu", lsb
, w
);
3401 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
3406 /* Get the PSR/banked register name. */
3409 unsigned sysm
= (given
& 0x004f0000) >> 16;
3411 sysm
|= (given
& 0x300) >> 4;
3412 name
= banked_regname (sysm
);
3415 func (stream
, "%s", name
);
3417 func (stream
, "(UNDEF: %lu)", sysm
);
3422 /* 16-bit unsigned immediate from a MOVT or MOVW
3423 instruction, encoded in bits 0:11 and 15:19. */
3425 long hi
= (given
& 0x000f0000) >> 4;
3426 long lo
= (given
& 0x00000fff);
3427 long imm16
= hi
| lo
;
3429 func (stream
, "#%lu", imm16
);
3430 value_in_comment
= imm16
;
3440 func (stream
, "%c", *c
);
3443 if (value_in_comment
> 32 || value_in_comment
< -16)
3444 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
3446 if (is_unpredictable
)
3447 func (stream
, UNPREDICTABLE_INSTRUCTION
);
3455 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3458 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3460 const struct opcode16
*insn
;
3461 void *stream
= info
->stream
;
3462 fprintf_ftype func
= info
->fprintf_func
;
3464 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
3465 if ((given
& insn
->mask
) == insn
->value
)
3467 signed long value_in_comment
= 0;
3468 const char *c
= insn
->assembler
;
3477 func (stream
, "%c", *c
);
3484 func (stream
, "%%");
3489 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3494 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3503 ifthen_next_state
= given
& 0xff;
3504 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
3505 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
3506 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
3511 if (ifthen_next_state
)
3512 func (stream
, "\t; unpredictable branch in IT block\n");
3517 func (stream
, "\t; unpredictable <IT:%s>",
3518 arm_conditional
[IFTHEN_COND
]);
3525 reg
= (given
>> 3) & 0x7;
3526 if (given
& (1 << 6))
3529 func (stream
, "%s", arm_regnames
[reg
]);
3538 if (given
& (1 << 7))
3541 func (stream
, "%s", arm_regnames
[reg
]);
3546 if (given
& (1 << 8))
3550 if (*c
== 'O' && (given
& (1 << 8)))
3560 /* It would be nice if we could spot
3561 ranges, and generate the rS-rE format: */
3562 for (reg
= 0; (reg
< 8); reg
++)
3563 if ((given
& (1 << reg
)) != 0)
3566 func (stream
, ", ");
3568 func (stream
, "%s", arm_regnames
[reg
]);
3574 func (stream
, ", ");
3576 func (stream
, arm_regnames
[14] /* "lr" */);
3582 func (stream
, ", ");
3583 func (stream
, arm_regnames
[15] /* "pc" */);
3591 /* Print writeback indicator for a LDMIA. We are doing a
3592 writeback if the base register is not in the register
3594 if ((given
& (1 << ((given
& 0x0700) >> 8))) == 0)
3599 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3601 bfd_vma address
= (pc
+ 4
3602 + ((given
& 0x00f8) >> 2)
3603 + ((given
& 0x0200) >> 3));
3604 info
->print_address_func (address
, info
);
3609 /* Right shift immediate -- bits 6..10; 1-31 print
3610 as themselves, 0 prints as 32. */
3612 long imm
= (given
& 0x07c0) >> 6;
3615 func (stream
, "#%ld", imm
);
3619 case '0': case '1': case '2': case '3': case '4':
3620 case '5': case '6': case '7': case '8': case '9':
3622 int bitstart
= *c
++ - '0';
3625 while (*c
>= '0' && *c
<= '9')
3626 bitstart
= (bitstart
* 10) + *c
++ - '0';
3635 while (*c
>= '0' && *c
<= '9')
3636 bitend
= (bitend
* 10) + *c
++ - '0';
3639 reg
= given
>> bitstart
;
3640 reg
&= (2 << (bitend
- bitstart
)) - 1;
3645 func (stream
, "%s", arm_regnames
[reg
]);
3649 func (stream
, "%ld", reg
);
3650 value_in_comment
= reg
;
3654 func (stream
, "%ld", reg
<< 1);
3655 value_in_comment
= reg
<< 1;
3659 func (stream
, "%ld", reg
<< 2);
3660 value_in_comment
= reg
<< 2;
3664 /* PC-relative address -- the bottom two
3665 bits of the address are dropped
3666 before the calculation. */
3667 info
->print_address_func
3668 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
3669 value_in_comment
= 0;
3673 func (stream
, "0x%04lx", reg
);
3677 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
3678 info
->print_address_func (reg
* 2 + pc
+ 4, info
);
3679 value_in_comment
= 0;
3683 func (stream
, "%s", arm_conditional
[reg
]);
3694 if ((given
& (1 << bitstart
)) != 0)
3695 func (stream
, "%c", *c
);
3700 if ((given
& (1 << bitstart
)) != 0)
3701 func (stream
, "%c", *c
++);
3703 func (stream
, "%c", *++c
);
3717 if (value_in_comment
> 32 || value_in_comment
< -16)
3718 func (stream
, "\t; 0x%lx", value_in_comment
);
3726 /* Return the name of an V7M special register. */
3729 psr_name (int regno
)
3733 case 0: return "APSR";
3734 case 1: return "IAPSR";
3735 case 2: return "EAPSR";
3736 case 3: return "PSR";
3737 case 5: return "IPSR";
3738 case 6: return "EPSR";
3739 case 7: return "IEPSR";
3740 case 8: return "MSP";
3741 case 9: return "PSP";
3742 case 16: return "PRIMASK";
3743 case 17: return "BASEPRI";
3744 case 18: return "BASEPRI_MAX";
3745 case 19: return "FAULTMASK";
3746 case 20: return "CONTROL";
3747 default: return "<unknown>";
3751 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3754 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3756 const struct opcode32
*insn
;
3757 void *stream
= info
->stream
;
3758 fprintf_ftype func
= info
->fprintf_func
;
3760 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
3763 if (print_insn_neon (info
, given
, TRUE
))
3766 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
3767 if ((given
& insn
->mask
) == insn
->value
)
3769 bfd_boolean is_unpredictable
= FALSE
;
3770 signed long value_in_comment
= 0;
3771 const char *c
= insn
->assembler
;
3777 func (stream
, "%c", *c
);
3784 func (stream
, "%%");
3789 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3793 if (ifthen_next_state
)
3794 func (stream
, "\t; unpredictable branch in IT block\n");
3799 func (stream
, "\t; unpredictable <IT:%s>",
3800 arm_conditional
[IFTHEN_COND
]);
3805 unsigned int imm12
= 0;
3807 imm12
|= (given
& 0x000000ffu
);
3808 imm12
|= (given
& 0x00007000u
) >> 4;
3809 imm12
|= (given
& 0x04000000u
) >> 15;
3810 func (stream
, "#%u", imm12
);
3811 value_in_comment
= imm12
;
3817 unsigned int bits
= 0, imm
, imm8
, mod
;
3819 bits
|= (given
& 0x000000ffu
);
3820 bits
|= (given
& 0x00007000u
) >> 4;
3821 bits
|= (given
& 0x04000000u
) >> 15;
3822 imm8
= (bits
& 0x0ff);
3823 mod
= (bits
& 0xf00) >> 8;
3826 case 0: imm
= imm8
; break;
3827 case 1: imm
= ((imm8
<< 16) | imm8
); break;
3828 case 2: imm
= ((imm8
<< 24) | (imm8
<< 8)); break;
3829 case 3: imm
= ((imm8
<< 24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
3831 mod
= (bits
& 0xf80) >> 7;
3832 imm8
= (bits
& 0x07f) | 0x80;
3833 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
3835 func (stream
, "#%u", imm
);
3836 value_in_comment
= imm
;
3842 unsigned int imm
= 0;
3844 imm
|= (given
& 0x000000ffu
);
3845 imm
|= (given
& 0x00007000u
) >> 4;
3846 imm
|= (given
& 0x04000000u
) >> 15;
3847 imm
|= (given
& 0x000f0000u
) >> 4;
3848 func (stream
, "#%u", imm
);
3849 value_in_comment
= imm
;
3855 unsigned int imm
= 0;
3857 imm
|= (given
& 0x000f0000u
) >> 16;
3858 imm
|= (given
& 0x00000ff0u
) >> 0;
3859 imm
|= (given
& 0x0000000fu
) << 12;
3860 func (stream
, "#%u", imm
);
3861 value_in_comment
= imm
;
3867 unsigned int imm
= 0;
3869 imm
|= (given
& 0x00000fffu
);
3870 imm
|= (given
& 0x000f0000u
) >> 4;
3871 func (stream
, "#%u", imm
);
3872 value_in_comment
= imm
;
3878 unsigned int reg
= (given
& 0x0000000fu
);
3879 unsigned int stp
= (given
& 0x00000030u
) >> 4;
3880 unsigned int imm
= 0;
3881 imm
|= (given
& 0x000000c0u
) >> 6;
3882 imm
|= (given
& 0x00007000u
) >> 10;
3884 func (stream
, "%s", arm_regnames
[reg
]);
3889 func (stream
, ", lsl #%u", imm
);
3895 func (stream
, ", lsr #%u", imm
);
3901 func (stream
, ", asr #%u", imm
);
3906 func (stream
, ", rrx");
3908 func (stream
, ", ror #%u", imm
);
3915 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3916 unsigned int U
= ! NEGATIVE_BIT_SET
;
3917 unsigned int op
= (given
& 0x00000f00) >> 8;
3918 unsigned int i12
= (given
& 0x00000fff);
3919 unsigned int i8
= (given
& 0x000000ff);
3920 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
3923 func (stream
, "[%s", arm_regnames
[Rn
]);
3924 if (U
) /* 12-bit positive immediate offset. */
3928 value_in_comment
= offset
;
3930 else if (Rn
== 15) /* 12-bit negative immediate offset. */
3931 offset
= - (int) i12
;
3932 else if (op
== 0x0) /* Shifted register offset. */
3934 unsigned int Rm
= (i8
& 0x0f);
3935 unsigned int sh
= (i8
& 0x30) >> 4;
3937 func (stream
, ", %s", arm_regnames
[Rm
]);
3939 func (stream
, ", lsl #%u", sh
);
3945 case 0xE: /* 8-bit positive immediate offset. */
3949 case 0xC: /* 8-bit negative immediate offset. */
3953 case 0xF: /* 8-bit + preindex with wb. */
3958 case 0xD: /* 8-bit - preindex with wb. */
3963 case 0xB: /* 8-bit + postindex. */
3968 case 0x9: /* 8-bit - postindex. */
3974 func (stream
, ", <undefined>]");
3979 func (stream
, "], #%d", offset
);
3983 func (stream
, ", #%d", offset
);
3984 func (stream
, writeback
? "]!" : "]");
3989 func (stream
, "\t; ");
3990 info
->print_address_func (((pc
+ 4) & ~3) + offset
, info
);
3998 unsigned int U
= ! NEGATIVE_BIT_SET
;
3999 unsigned int W
= WRITEBACK_BIT_SET
;
4000 unsigned int Rn
= (given
& 0x000f0000) >> 16;
4001 unsigned int off
= (given
& 0x000000ff);
4003 func (stream
, "[%s", arm_regnames
[Rn
]);
4009 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
4010 value_in_comment
= off
* 4 * U
? 1 : -1;
4018 func (stream
, "], ");
4021 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
4022 value_in_comment
= off
* 4 * U
? 1 : -1;
4026 func (stream
, "{%u}", off
);
4027 value_in_comment
= off
;
4035 unsigned int Sbit
= (given
& 0x01000000) >> 24;
4036 unsigned int type
= (given
& 0x00600000) >> 21;
4040 case 0: func (stream
, Sbit
? "sb" : "b"); break;
4041 case 1: func (stream
, Sbit
? "sh" : "h"); break;
4044 func (stream
, "??");
4047 func (stream
, "??");
4059 for (reg
= 0; reg
< 16; reg
++)
4060 if ((given
& (1 << reg
)) != 0)
4063 func (stream
, ", ");
4065 func (stream
, "%s", arm_regnames
[reg
]);
4073 unsigned int msb
= (given
& 0x0000001f);
4074 unsigned int lsb
= 0;
4076 lsb
|= (given
& 0x000000c0u
) >> 6;
4077 lsb
|= (given
& 0x00007000u
) >> 10;
4078 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
4084 unsigned int width
= (given
& 0x0000001f) + 1;
4085 unsigned int lsb
= 0;
4087 lsb
|= (given
& 0x000000c0u
) >> 6;
4088 lsb
|= (given
& 0x00007000u
) >> 10;
4089 func (stream
, "#%u, #%u", lsb
, width
);
4095 unsigned int S
= (given
& 0x04000000u
) >> 26;
4096 unsigned int J1
= (given
& 0x00002000u
) >> 13;
4097 unsigned int J2
= (given
& 0x00000800u
) >> 11;
4103 offset
|= (given
& 0x003f0000) >> 4;
4104 offset
|= (given
& 0x000007ff) << 1;
4105 offset
-= (1 << 20);
4107 info
->print_address_func (pc
+ 4 + offset
, info
);
4113 unsigned int S
= (given
& 0x04000000u
) >> 26;
4114 unsigned int I1
= (given
& 0x00002000u
) >> 13;
4115 unsigned int I2
= (given
& 0x00000800u
) >> 11;
4119 offset
|= !(I1
^ S
) << 23;
4120 offset
|= !(I2
^ S
) << 22;
4121 offset
|= (given
& 0x03ff0000u
) >> 4;
4122 offset
|= (given
& 0x000007ffu
) << 1;
4123 offset
-= (1 << 24);
4126 /* BLX target addresses are always word aligned. */
4127 if ((given
& 0x00001000u
) == 0)
4130 info
->print_address_func (offset
, info
);
4136 unsigned int shift
= 0;
4138 shift
|= (given
& 0x000000c0u
) >> 6;
4139 shift
|= (given
& 0x00007000u
) >> 10;
4140 if (WRITEBACK_BIT_SET
)
4141 func (stream
, ", asr #%u", shift
);
4143 func (stream
, ", lsl #%u", shift
);
4144 /* else print nothing - lsl #0 */
4150 unsigned int rot
= (given
& 0x00000030) >> 4;
4153 func (stream
, ", ror #%u", rot
* 8);
4158 if ((given
& 0xf0) == 0x60)
4160 switch (given
& 0xf)
4162 case 0xf: func (stream
, "sy"); break;
4164 func (stream
, "#%d", (int) given
& 0xf);
4170 switch (given
& 0xf)
4172 case 0xf: func (stream
, "sy"); break;
4173 case 0x7: func (stream
, "un"); break;
4174 case 0xe: func (stream
, "st"); break;
4175 case 0x6: func (stream
, "unst"); break;
4176 case 0xb: func (stream
, "ish"); break;
4177 case 0xa: func (stream
, "ishst"); break;
4178 case 0x3: func (stream
, "osh"); break;
4179 case 0x2: func (stream
, "oshst"); break;
4181 func (stream
, "#%d", (int) given
& 0xf);
4188 if ((given
& 0xff) == 0)
4190 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
4200 else if ((given
& 0x20) == 0x20)
4203 unsigned sysm
= (given
& 0xf00) >> 8;
4205 sysm
|= (given
& 0x30);
4206 sysm
|= (given
& 0x00100000) >> 14;
4207 name
= banked_regname (sysm
);
4210 func (stream
, "%s", name
);
4212 func (stream
, "(UNDEF: %lu)", sysm
);
4216 func (stream
, psr_name (given
& 0xff));
4221 if (((given
& 0xff) == 0)
4222 || ((given
& 0x20) == 0x20))
4225 unsigned sm
= (given
& 0xf0000) >> 16;
4227 sm
|= (given
& 0x30);
4228 sm
|= (given
& 0x00100000) >> 14;
4229 name
= banked_regname (sm
);
4232 func (stream
, "%s", name
);
4234 func (stream
, "(UNDEF: %lu)", sm
);
4237 func (stream
, psr_name (given
& 0xff));
4240 case '0': case '1': case '2': case '3': case '4':
4241 case '5': case '6': case '7': case '8': case '9':
4246 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
4251 func (stream
, "%lu", val
);
4252 value_in_comment
= val
;
4256 func (stream
, "%lu", val
* 4);
4257 value_in_comment
= val
* 4;
4262 is_unpredictable
= TRUE
;
4265 func (stream
, "%s", arm_regnames
[val
]);
4269 func (stream
, "%s", arm_conditional
[val
]);
4274 if (val
== ((1ul << width
) - 1))
4275 func (stream
, "%c", *c
);
4281 func (stream
, "%c", *c
);
4285 func (stream
, "%c", c
[(1 << width
) - (int) val
]);
4290 func (stream
, "0x%lx", val
& 0xffffffffUL
);
4300 /* PR binutils/12534
4301 If we have a PC relative offset in an LDRD or STRD
4302 instructions then display the decoded address. */
4303 if (((given
>> 16) & 0xf) == 0xf)
4305 bfd_vma offset
= (given
& 0xff) * 4;
4307 if ((given
& (1 << 23)) == 0)
4309 func (stream
, "\t; ");
4310 info
->print_address_func ((pc
& ~3) + 4 + offset
, info
);
4319 if (value_in_comment
> 32 || value_in_comment
< -16)
4320 func (stream
, "\t; 0x%lx", value_in_comment
);
4322 if (is_unpredictable
)
4323 func (stream
, UNPREDICTABLE_INSTRUCTION
);
4332 /* Print data bytes on INFO->STREAM. */
4335 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
4336 struct disassemble_info
*info
,
4339 switch (info
->bytes_per_chunk
)
4342 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
4345 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
4348 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
4355 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4356 being displayed in symbol relative addresses. */
4359 arm_symbol_is_valid (asymbol
* sym
,
4360 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
4367 name
= bfd_asymbol_name (sym
);
4369 return (name
&& *name
!= '$');
4372 /* Parse an individual disassembler option. */
4375 parse_arm_disassembler_option (char *option
)
4380 if (CONST_STRNEQ (option
, "reg-names-"))
4386 for (i
= NUM_ARM_REGNAMES
; i
--;)
4387 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
4389 regname_selected
= i
;
4394 /* XXX - should break 'option' at following delimiter. */
4395 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
4397 else if (CONST_STRNEQ (option
, "force-thumb"))
4399 else if (CONST_STRNEQ (option
, "no-force-thumb"))
4402 /* XXX - should break 'option' at following delimiter. */
4403 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
4408 /* Parse the string of disassembler options, spliting it at whitespaces
4409 or commas. (Whitespace separators supported for backwards compatibility). */
4412 parse_disassembler_options (char *options
)
4414 if (options
== NULL
)
4419 parse_arm_disassembler_option (options
);
4421 /* Skip forward to next seperator. */
4422 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
4424 /* Skip forward past seperators. */
4425 while (ISSPACE (*options
) || (*options
== ','))
4430 /* Search back through the insn stream to determine if this instruction is
4431 conditionally executed. */
4434 find_ifthen_state (bfd_vma pc
,
4435 struct disassemble_info
*info
,
4441 /* COUNT is twice the number of instructions seen. It will be odd if we
4442 just crossed an instruction boundary. */
4445 unsigned int seen_it
;
4448 ifthen_address
= pc
;
4455 /* Scan backwards looking for IT instructions, keeping track of where
4456 instruction boundaries are. We don't know if something is actually an
4457 IT instruction until we find a definite instruction boundary. */
4460 if (addr
== 0 || info
->symbol_at_address_func (addr
, info
))
4462 /* A symbol must be on an instruction boundary, and will not
4463 be within an IT block. */
4464 if (seen_it
&& (count
& 1))
4470 status
= info
->read_memory_func (addr
, (bfd_byte
*) b
, 2, info
);
4475 insn
= (b
[0]) | (b
[1] << 8);
4477 insn
= (b
[1]) | (b
[0] << 8);
4480 if ((insn
& 0xf800) < 0xe800)
4482 /* Addr + 2 is an instruction boundary. See if this matches
4483 the expected boundary based on the position of the last
4490 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4492 /* This could be an IT instruction. */
4494 it_count
= count
>> 1;
4496 if ((insn
& 0xf800) >= 0xe800)
4499 count
= (count
+ 2) | 1;
4500 /* IT blocks contain at most 4 instructions. */
4501 if (count
>= 8 && !seen_it
)
4504 /* We found an IT instruction. */
4505 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4506 if ((ifthen_state
& 0xf) == 0)
4510 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4514 is_mapping_symbol (struct disassemble_info
*info
, int n
,
4515 enum map_type
*map_type
)
4519 name
= bfd_asymbol_name (info
->symtab
[n
]);
4520 if (name
[0] == '$' && (name
[1] == 'a' || name
[1] == 't' || name
[1] == 'd')
4521 && (name
[2] == 0 || name
[2] == '.'))
4523 *map_type
= ((name
[1] == 'a') ? MAP_ARM
4524 : (name
[1] == 't') ? MAP_THUMB
4532 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4533 Returns nonzero if *MAP_TYPE was set. */
4536 get_map_sym_type (struct disassemble_info
*info
,
4538 enum map_type
*map_type
)
4540 /* If the symbol is in a different section, ignore it. */
4541 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4544 return is_mapping_symbol (info
, n
, map_type
);
4547 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4548 Returns nonzero if *MAP_TYPE was set. */
4551 get_sym_code_type (struct disassemble_info
*info
,
4553 enum map_type
*map_type
)
4555 elf_symbol_type
*es
;
4558 /* If the symbol is in a different section, ignore it. */
4559 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4562 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
4563 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4565 /* If the symbol has function type then use that. */
4566 if (type
== STT_FUNC
|| type
== STT_GNU_IFUNC
)
4568 if (ARM_SYM_BRANCH_TYPE (&es
->internal_elf_sym
) == ST_BRANCH_TO_THUMB
)
4569 *map_type
= MAP_THUMB
;
4571 *map_type
= MAP_ARM
;
4578 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4579 of the supplied arm_feature_set structure with bitmasks indicating
4580 the support base architectures and coprocessor extensions.
4582 FIXME: This could more efficiently implemented as a constant array,
4583 although it would also be less robust. */
4586 select_arm_features (unsigned long mach
,
4587 arm_feature_set
* features
)
4590 #define ARM_FEATURE(ARCH,CEXT) \
4591 features->core = (ARCH); \
4592 features->coproc = (CEXT) | FPU_FPA; \
4597 case bfd_mach_arm_2
: ARM_ARCH_V2
;
4598 case bfd_mach_arm_2a
: ARM_ARCH_V2S
;
4599 case bfd_mach_arm_3
: ARM_ARCH_V3
;
4600 case bfd_mach_arm_3M
: ARM_ARCH_V3M
;
4601 case bfd_mach_arm_4
: ARM_ARCH_V4
;
4602 case bfd_mach_arm_4T
: ARM_ARCH_V4T
;
4603 case bfd_mach_arm_5
: ARM_ARCH_V5
;
4604 case bfd_mach_arm_5T
: ARM_ARCH_V5T
;
4605 case bfd_mach_arm_5TE
: ARM_ARCH_V5TE
;
4606 case bfd_mach_arm_XScale
: ARM_ARCH_XSCALE
;
4607 case bfd_mach_arm_ep9312
: ARM_FEATURE (ARM_AEXT_V4T
, ARM_CEXT_MAVERICK
| FPU_MAVERICK
);
4608 case bfd_mach_arm_iWMMXt
: ARM_ARCH_IWMMXT
;
4609 case bfd_mach_arm_iWMMXt2
: ARM_ARCH_IWMMXT2
;
4610 /* If the machine type is unknown allow all
4611 architecture types and all extensions. */
4612 case bfd_mach_arm_unknown
: ARM_FEATURE (-1UL, -1UL);
4619 /* NOTE: There are no checks in these routines that
4620 the relevant number of data bytes exist. */
4623 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4628 int is_thumb
= FALSE
;
4629 int is_data
= FALSE
;
4631 unsigned int size
= 4;
4632 void (*printer
) (bfd_vma
, struct disassemble_info
*, long);
4633 bfd_boolean found
= FALSE
;
4634 struct arm_private_data
*private_data
;
4636 if (info
->disassembler_options
)
4638 parse_disassembler_options (info
->disassembler_options
);
4640 /* To avoid repeated parsing of these options, we remove them here. */
4641 info
->disassembler_options
= NULL
;
4644 /* PR 10288: Control which instructions will be disassembled. */
4645 if (info
->private_data
== NULL
)
4647 static struct arm_private_data
private;
4649 if ((info
->flags
& USER_SPECIFIED_MACHINE_TYPE
) == 0)
4650 /* If the user did not use the -m command line switch then default to
4651 disassembling all types of ARM instruction.
4653 The info->mach value has to be ignored as this will be based on
4654 the default archictecture for the target and/or hints in the notes
4655 section, but it will never be greater than the current largest arm
4656 machine value (iWMMXt2), which is only equivalent to the V5TE
4657 architecture. ARM architectures have advanced beyond the machine
4658 value encoding, and these newer architectures would be ignored if
4659 the machine value was used.
4661 Ie the -m switch is used to restrict which instructions will be
4662 disassembled. If it is necessary to use the -m switch to tell
4663 objdump that an ARM binary is being disassembled, eg because the
4664 input is a raw binary file, but it is also desired to disassemble
4665 all ARM instructions then use "-marm". This will select the
4666 "unknown" arm architecture which is compatible with any ARM
4668 info
->mach
= bfd_mach_arm_unknown
;
4670 /* Compute the architecture bitmask from the machine number.
4671 Note: This assumes that the machine number will not change
4672 during disassembly.... */
4673 select_arm_features (info
->mach
, & private.features
);
4675 private.has_mapping_symbols
= -1;
4676 private.last_mapping_sym
= -1;
4677 private.last_mapping_addr
= 0;
4679 info
->private_data
= & private;
4682 private_data
= info
->private_data
;
4684 /* Decide if our code is going to be little-endian, despite what the
4685 function argument might say. */
4686 little_code
= ((info
->endian_code
== BFD_ENDIAN_LITTLE
) || little
);
4688 /* For ELF, consult the symbol table to determine what kind of code
4690 if (info
->symtab_size
!= 0
4691 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4696 enum map_type type
= MAP_ARM
;
4698 /* Start scanning at the start of the function, or wherever
4699 we finished last time. */
4700 start
= info
->symtab_pos
+ 1;
4701 if (start
< private_data
->last_mapping_sym
)
4702 start
= private_data
->last_mapping_sym
;
4705 /* First, look for mapping symbols. */
4706 if (private_data
->has_mapping_symbols
!= 0)
4708 /* Scan up to the location being disassembled. */
4709 for (n
= start
; n
< info
->symtab_size
; n
++)
4711 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4714 if (get_map_sym_type (info
, n
, &type
))
4723 /* No mapping symbol found at this address. Look backwards
4724 for a preceding one. */
4725 for (n
= start
- 1; n
>= 0; n
--)
4727 if (get_map_sym_type (info
, n
, &type
))
4737 private_data
->has_mapping_symbols
= 1;
4739 /* No mapping symbols were found. A leading $d may be
4740 omitted for sections which start with data; but for
4741 compatibility with legacy and stripped binaries, only
4742 assume the leading $d if there is at least one mapping
4743 symbol in the file. */
4744 if (!found
&& private_data
->has_mapping_symbols
== -1)
4746 /* Look for mapping symbols, in any section. */
4747 for (n
= 0; n
< info
->symtab_size
; n
++)
4748 if (is_mapping_symbol (info
, n
, &type
))
4750 private_data
->has_mapping_symbols
= 1;
4753 if (private_data
->has_mapping_symbols
== -1)
4754 private_data
->has_mapping_symbols
= 0;
4757 if (!found
&& private_data
->has_mapping_symbols
== 1)
4764 /* Next search for function symbols to separate ARM from Thumb
4765 in binaries without mapping symbols. */
4768 /* Scan up to the location being disassembled. */
4769 for (n
= start
; n
< info
->symtab_size
; n
++)
4771 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4774 if (get_sym_code_type (info
, n
, &type
))
4783 /* No mapping symbol found at this address. Look backwards
4784 for a preceding one. */
4785 for (n
= start
- 1; n
>= 0; n
--)
4787 if (get_sym_code_type (info
, n
, &type
))
4797 private_data
->last_mapping_sym
= last_sym
;
4798 private_data
->last_type
= type
;
4799 is_thumb
= (private_data
->last_type
== MAP_THUMB
);
4800 is_data
= (private_data
->last_type
== MAP_DATA
);
4802 /* Look a little bit ahead to see if we should print out
4803 two or four bytes of data. If there's a symbol,
4804 mapping or otherwise, after two bytes then don't
4808 size
= 4 - (pc
& 3);
4809 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4811 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4813 && (info
->section
== NULL
4814 || info
->section
== info
->symtab
[n
]->section
))
4816 if (addr
- pc
< size
)
4821 /* If the next symbol is after three bytes, we need to
4822 print only part of the data, so that we can use either
4825 size
= (pc
& 1) ? 1 : 2;
4829 if (info
->symbols
!= NULL
)
4831 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4833 coff_symbol_type
* cs
;
4835 cs
= coffsymbol (*info
->symbols
);
4836 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4837 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4838 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4839 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4840 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4842 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
4845 /* If no mapping symbol has been found then fall back to the type
4846 of the function symbol. */
4847 elf_symbol_type
* es
;
4850 es
= *(elf_symbol_type
**)(info
->symbols
);
4851 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4853 is_thumb
= ((ARM_SYM_BRANCH_TYPE (&es
->internal_elf_sym
)
4854 == ST_BRANCH_TO_THUMB
)
4855 || type
== STT_ARM_16BIT
);
4863 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4865 info
->display_endian
= little_code
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4867 info
->bytes_per_line
= 4;
4869 /* PR 10263: Disassemble data if requested to do so by the user. */
4870 if (is_data
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
4874 /* Size was already set above. */
4875 info
->bytes_per_chunk
= size
;
4876 printer
= print_insn_data
;
4878 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, size
, info
);
4881 for (i
= size
- 1; i
>= 0; i
--)
4882 given
= b
[i
] | (given
<< 8);
4884 for (i
= 0; i
< (int) size
; i
++)
4885 given
= b
[i
] | (given
<< 8);
4889 /* In ARM mode endianness is a straightforward issue: the instruction
4890 is four bytes long and is either ordered 0123 or 3210. */
4891 printer
= print_insn_arm
;
4892 info
->bytes_per_chunk
= 4;
4895 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 4, info
);
4897 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
4899 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
4903 /* In Thumb mode we have the additional wrinkle of two
4904 instruction lengths. Fortunately, the bits that determine
4905 the length of the current instruction are always to be found
4906 in the first two bytes. */
4907 printer
= print_insn_thumb16
;
4908 info
->bytes_per_chunk
= 2;
4911 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
4913 given
= (b
[0]) | (b
[1] << 8);
4915 given
= (b
[1]) | (b
[0] << 8);
4919 /* These bit patterns signal a four-byte Thumb
4921 if ((given
& 0xF800) == 0xF800
4922 || (given
& 0xF800) == 0xF000
4923 || (given
& 0xF800) == 0xE800)
4925 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) b
, 2, info
);
4927 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
4929 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
4931 printer
= print_insn_thumb32
;
4936 if (ifthen_address
!= pc
)
4937 find_ifthen_state (pc
, info
, little_code
);
4941 if ((ifthen_state
& 0xf) == 0x8)
4942 ifthen_next_state
= 0;
4944 ifthen_next_state
= (ifthen_state
& 0xe0)
4945 | ((ifthen_state
& 0xf) << 1);
4951 info
->memory_error_func (status
, pc
, info
);
4954 if (info
->flags
& INSN_HAS_RELOC
)
4955 /* If the instruction has a reloc associated with it, then
4956 the offset field in the instruction will actually be the
4957 addend for the reloc. (We are using REL type relocs).
4958 In such cases, we can ignore the pc when computing
4959 addresses, since the addend is not currently pc-relative. */
4962 printer (pc
, info
, given
);
4966 ifthen_state
= ifthen_next_state
;
4967 ifthen_address
+= size
;
4973 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
4975 /* Detect BE8-ness and record it in the disassembler info. */
4976 if (info
->flavour
== bfd_target_elf_flavour
4977 && info
->section
!= NULL
4978 && (elf_elfheader (info
->section
->owner
)->e_flags
& EF_ARM_BE8
))
4979 info
->endian_code
= BFD_ENDIAN_LITTLE
;
4981 return print_insn (pc
, info
, FALSE
);
4985 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
4987 return print_insn (pc
, info
, TRUE
);
4991 print_arm_disassembler_options (FILE *stream
)
4995 fprintf (stream
, _("\n\
4996 The following ARM specific disassembler options are supported for use with\n\
4997 the -M switch:\n"));
4999 for (i
= NUM_ARM_REGNAMES
; i
--;)
5000 fprintf (stream
, " reg-names-%s %*c%s\n",
5002 (int)(14 - strlen (regnames
[i
].name
)), ' ',
5003 regnames
[i
].description
);
5005 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
5006 fprintf (stream
, " no-force-thumb Examine preceding label to determine an insn's type\n\n");