1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
27 #include "opcode/arm.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
32 /* FIXME: This shouldn't be done here. */
33 #include "coff/internal.h"
36 #include "elf/internal.h"
39 /* FIXME: Belongs in global header. */
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
48 struct arm_private_data
50 /* The features to use when disassembling optional instructions. */
51 arm_feature_set features
;
53 /* Whether any mapping symbols are present in the provided symbol
54 table. -1 if we do not know yet, otherwise 0 or 1. */
55 int has_mapping_symbols
;
60 unsigned long arch
; /* Architecture defining this insn. */
61 unsigned long value
; /* If arch == 0 then value is a sentinel. */
62 unsigned long mask
; /* Recognise insn if (op & mask) == value. */
63 const char * assembler
; /* How to disassemble this insn. */
68 unsigned long arch
; /* Architecture defining this insn. */
69 unsigned short value
, mask
; /* Recognise insn if (op & mask) == value. */
70 const char *assembler
; /* How to disassemble this insn. */
73 /* print_insn_coprocessor recognizes the following format control codes:
77 %c print condition code (always bits 28-31 in ARM mode)
78 %q print shifter argument
79 %u print condition code (unconditional in ARM mode)
80 %A print address for ldc/stc/ldf/stf instruction
81 %B print vstm/vldm register list
82 %I print cirrus signed shift immediate: bits 0..3|4..6
83 %F print the COUNT field of a LFM/SFM instruction.
84 %P print floating point precision in arithmetic insn
85 %Q print floating point precision in ldf/stf insn
86 %R print floating point rounding mode
88 %<bitfield>r print as an ARM register
89 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
90 %<bitfield>ru as %<>r but each u register must be unique.
91 %<bitfield>d print the bitfield in decimal
92 %<bitfield>k print immediate for VFPv3 conversion instruction
93 %<bitfield>x print the bitfield in hex
94 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
95 %<bitfield>f print a floating point constant if >7 else a
96 floating point register
97 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
98 %<bitfield>g print as an iWMMXt 64-bit register
99 %<bitfield>G print as an iWMMXt general purpose or control register
100 %<bitfield>D print as a NEON D register
101 %<bitfield>Q print as a NEON Q register
103 %y<code> print a single precision VFP reg.
104 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
105 %z<code> print a double precision VFP reg
106 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
108 %<bitfield>'c print specified char iff bitfield is all ones
109 %<bitfield>`c print specified char iff bitfield is all zeroes
110 %<bitfield>?ab... select from array of values in big endian order
112 %L print as an iWMMXt N/M width field.
113 %Z print the Immediate of a WSHUFH instruction.
114 %l like 'A' except use byte offsets for 'B' & 'H'
116 %i print 5-bit immediate in bits 8,3..0
118 %r print register offset address for wldt/wstr instruction. */
120 enum opcode_sentinel_enum
122 SENTINEL_IWMMXT_START
= 1,
124 SENTINEL_GENERIC_START
127 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
128 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
130 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
132 static const struct opcode32 coprocessor_opcodes
[] =
134 /* XScale instructions. */
135 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
136 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
137 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
138 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
139 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
141 /* Intel Wireless MMX technology instructions. */
142 { 0, SENTINEL_IWMMXT_START
, 0, "" },
143 {ARM_CEXT_IWMMXT
, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
144 {ARM_CEXT_XSCALE
, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
145 {ARM_CEXT_XSCALE
, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
146 {ARM_CEXT_XSCALE
, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
147 {ARM_CEXT_XSCALE
, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
148 {ARM_CEXT_XSCALE
, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
149 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
150 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
151 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
152 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
153 {ARM_CEXT_XSCALE
, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
154 {ARM_CEXT_XSCALE
, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
155 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
156 {ARM_CEXT_XSCALE
, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
157 {ARM_CEXT_XSCALE
, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
158 {ARM_CEXT_XSCALE
, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
159 {ARM_CEXT_XSCALE
, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
160 {ARM_CEXT_XSCALE
, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
161 {ARM_CEXT_XSCALE
, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
162 {ARM_CEXT_XSCALE
, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
163 {ARM_CEXT_XSCALE
, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
164 {ARM_CEXT_XSCALE
, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
165 {ARM_CEXT_XSCALE
, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
166 {ARM_CEXT_XSCALE
, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
167 {ARM_CEXT_XSCALE
, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
168 {ARM_CEXT_XSCALE
, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
169 {ARM_CEXT_XSCALE
, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
170 {ARM_CEXT_XSCALE
, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
171 {ARM_CEXT_XSCALE
, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
172 {ARM_CEXT_XSCALE
, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
173 {ARM_CEXT_XSCALE
, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
174 {ARM_CEXT_XSCALE
, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
175 {ARM_CEXT_XSCALE
, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
176 {ARM_CEXT_XSCALE
, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
177 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
178 {ARM_CEXT_XSCALE
, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
179 {ARM_CEXT_XSCALE
, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
180 {ARM_CEXT_XSCALE
, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE
, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE
, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE
, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE
, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE
, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
186 {ARM_CEXT_XSCALE
, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
187 {ARM_CEXT_XSCALE
, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
188 {ARM_CEXT_XSCALE
, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE
, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
190 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
191 {ARM_CEXT_XSCALE
, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
192 {ARM_CEXT_XSCALE
, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
193 {ARM_CEXT_XSCALE
, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
194 {ARM_CEXT_XSCALE
, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE
, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
196 {ARM_CEXT_XSCALE
, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
197 {ARM_CEXT_XSCALE
, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE
, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
199 {ARM_CEXT_XSCALE
, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
200 {ARM_CEXT_XSCALE
, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE
, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
202 {ARM_CEXT_XSCALE
, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
203 {ARM_CEXT_XSCALE
, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE
, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
205 {ARM_CEXT_XSCALE
, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
206 {ARM_CEXT_XSCALE
, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
207 {ARM_CEXT_XSCALE
, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
208 {ARM_CEXT_XSCALE
, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
209 {ARM_CEXT_XSCALE
, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
210 {ARM_CEXT_XSCALE
, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
211 {ARM_CEXT_XSCALE
, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
212 {ARM_CEXT_XSCALE
, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
213 {ARM_CEXT_XSCALE
, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
214 {ARM_CEXT_XSCALE
, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
215 {ARM_CEXT_XSCALE
, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
216 {ARM_CEXT_XSCALE
, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
217 {ARM_CEXT_XSCALE
, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
218 { 0, SENTINEL_IWMMXT_END
, 0, "" },
220 /* Floating point coprocessor (FPA) instructions. */
221 {FPU_FPA_EXT_V1
, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
222 {FPU_FPA_EXT_V1
, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
223 {FPU_FPA_EXT_V1
, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
224 {FPU_FPA_EXT_V1
, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
225 {FPU_FPA_EXT_V1
, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
226 {FPU_FPA_EXT_V1
, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
227 {FPU_FPA_EXT_V1
, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
228 {FPU_FPA_EXT_V1
, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
229 {FPU_FPA_EXT_V1
, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
230 {FPU_FPA_EXT_V1
, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
231 {FPU_FPA_EXT_V1
, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
232 {FPU_FPA_EXT_V1
, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
233 {FPU_FPA_EXT_V1
, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
234 {FPU_FPA_EXT_V1
, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
235 {FPU_FPA_EXT_V1
, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
236 {FPU_FPA_EXT_V1
, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
237 {FPU_FPA_EXT_V1
, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
238 {FPU_FPA_EXT_V1
, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
239 {FPU_FPA_EXT_V1
, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
240 {FPU_FPA_EXT_V1
, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
241 {FPU_FPA_EXT_V1
, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
242 {FPU_FPA_EXT_V1
, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
243 {FPU_FPA_EXT_V1
, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
244 {FPU_FPA_EXT_V1
, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
245 {FPU_FPA_EXT_V1
, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
246 {FPU_FPA_EXT_V1
, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
247 {FPU_FPA_EXT_V1
, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
248 {FPU_FPA_EXT_V1
, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
249 {FPU_FPA_EXT_V1
, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
250 {FPU_FPA_EXT_V1
, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
251 {FPU_FPA_EXT_V1
, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
252 {FPU_FPA_EXT_V1
, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
253 {FPU_FPA_EXT_V1
, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
254 {FPU_FPA_EXT_V1
, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
255 {FPU_FPA_EXT_V1
, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
256 {FPU_FPA_EXT_V1
, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
257 {FPU_FPA_EXT_V1
, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
258 {FPU_FPA_EXT_V1
, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
259 {FPU_FPA_EXT_V1
, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
260 {FPU_FPA_EXT_V1
, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
261 {FPU_FPA_EXT_V1
, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
262 {FPU_FPA_EXT_V2
, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
263 {FPU_FPA_EXT_V2
, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
265 /* Register load/store. */
266 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
267 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
268 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
269 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
270 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
271 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
272 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
273 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
274 {FPU_VFP_EXT_V1xD
, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
275 {FPU_VFP_EXT_V1xD
, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
276 {FPU_VFP_EXT_V1xD
, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
277 {FPU_VFP_EXT_V1xD
, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
278 {FPU_VFP_EXT_V1xD
, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
279 {FPU_VFP_EXT_V1xD
, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
280 {FPU_VFP_EXT_V1xD
, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
281 {FPU_VFP_EXT_V1xD
, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
283 {FPU_VFP_EXT_V1xD
, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
284 {FPU_VFP_EXT_V1xD
, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
285 {FPU_VFP_EXT_V1xD
, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
286 {FPU_VFP_EXT_V1xD
, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
288 /* Data transfer between ARM and NEON registers. */
289 {FPU_NEON_EXT_V1
, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
290 {FPU_NEON_EXT_V1
, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
291 {FPU_NEON_EXT_V1
, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
292 {FPU_NEON_EXT_V1
, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
293 {FPU_NEON_EXT_V1
, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
294 {FPU_NEON_EXT_V1
, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
295 {FPU_NEON_EXT_V1
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
296 {FPU_NEON_EXT_V1
, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
297 {FPU_NEON_EXT_V1
, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
298 {FPU_NEON_EXT_V1
, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
299 {FPU_NEON_EXT_V1
, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
300 {FPU_NEON_EXT_V1
, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
301 {FPU_NEON_EXT_V1
, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
302 {FPU_NEON_EXT_V1
, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
303 /* Half-precision conversion instructions. */
304 {FPU_VFP_EXT_FP16
, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
305 {FPU_VFP_EXT_FP16
, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
307 /* Floating point coprocessor (VFP) instructions. */
308 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
309 {FPU_VFP_EXT_V1xD
, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
310 {FPU_VFP_EXT_V1xD
, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
311 {FPU_VFP_EXT_V1xD
, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
312 {FPU_VFP_EXT_V1xD
, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
313 {FPU_VFP_EXT_V1xD
, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
314 {FPU_VFP_EXT_V1xD
, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
315 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
316 {FPU_VFP_EXT_V1xD
, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
317 {FPU_VFP_EXT_V1xD
, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
318 {FPU_VFP_EXT_V1xD
, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
319 {FPU_VFP_EXT_V1xD
, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
320 {FPU_VFP_EXT_V1xD
, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
321 {FPU_VFP_EXT_V1xD
, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
322 {FPU_VFP_EXT_V1xD
, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
323 {FPU_VFP_EXT_V1
, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
324 {FPU_VFP_EXT_V1
, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
325 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
326 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
327 {FPU_VFP_EXT_V1xD
, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
328 {FPU_VFP_EXT_V1xD
, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
329 {FPU_VFP_EXT_V1xD
, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
330 {FPU_VFP_EXT_V1
, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
331 {FPU_VFP_EXT_V1xD
, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
332 {FPU_VFP_EXT_V1xD
, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
333 {FPU_VFP_EXT_V1
, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
334 {FPU_VFP_EXT_V1
, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
335 {FPU_VFP_EXT_V1xD
, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
336 {FPU_VFP_EXT_V1xD
, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
337 {FPU_VFP_EXT_V1
, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
338 {FPU_VFP_EXT_V1
, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
339 {FPU_VFP_EXT_V1
, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
340 {FPU_VFP_EXT_V1
, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
341 {FPU_VFP_EXT_V1xD
, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
342 {FPU_VFP_EXT_V1
, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
343 {FPU_VFP_EXT_V1xD
, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
344 {FPU_VFP_EXT_V1
, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
345 {FPU_VFP_EXT_V3xD
, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
346 {FPU_VFP_EXT_V3
, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
347 {FPU_VFP_EXT_V1xD
, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
348 {FPU_VFP_EXT_V1
, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
349 {FPU_VFP_EXT_V3xD
, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
350 {FPU_VFP_EXT_V3
, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
351 {FPU_VFP_EXT_V1
, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
352 {FPU_VFP_EXT_V3xD
, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
353 {FPU_VFP_EXT_V3
, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
354 {FPU_VFP_EXT_V2
, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
355 {FPU_VFP_EXT_V2
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
356 {FPU_VFP_EXT_V2
, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
357 {FPU_VFP_EXT_V1xD
, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
358 {FPU_VFP_EXT_V1xD
, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
359 {FPU_VFP_EXT_V1
, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
360 {FPU_VFP_EXT_V1
, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
361 {FPU_VFP_EXT_V1xD
, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
362 {FPU_VFP_EXT_V1xD
, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
363 {FPU_VFP_EXT_V1
, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
364 {FPU_VFP_EXT_V1
, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
365 {FPU_VFP_EXT_V1xD
, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
366 {FPU_VFP_EXT_V1xD
, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
367 {FPU_VFP_EXT_V1
, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
368 {FPU_VFP_EXT_V1
, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
369 {FPU_VFP_EXT_V1xD
, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
370 {FPU_VFP_EXT_V1xD
, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
371 {FPU_VFP_EXT_V1
, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
372 {FPU_VFP_EXT_V1
, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
373 {FPU_VFP_EXT_V1xD
, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
374 {FPU_VFP_EXT_V1
, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
376 /* Cirrus coprocessor instructions. */
377 {ARM_CEXT_MAVERICK
, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
378 {ARM_CEXT_MAVERICK
, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
379 {ARM_CEXT_MAVERICK
, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
380 {ARM_CEXT_MAVERICK
, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
381 {ARM_CEXT_MAVERICK
, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
382 {ARM_CEXT_MAVERICK
, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
383 {ARM_CEXT_MAVERICK
, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
384 {ARM_CEXT_MAVERICK
, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
385 {ARM_CEXT_MAVERICK
, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
386 {ARM_CEXT_MAVERICK
, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
387 {ARM_CEXT_MAVERICK
, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
388 {ARM_CEXT_MAVERICK
, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
389 {ARM_CEXT_MAVERICK
, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
390 {ARM_CEXT_MAVERICK
, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
391 {ARM_CEXT_MAVERICK
, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
392 {ARM_CEXT_MAVERICK
, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
393 {ARM_CEXT_MAVERICK
, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
394 {ARM_CEXT_MAVERICK
, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
395 {ARM_CEXT_MAVERICK
, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
396 {ARM_CEXT_MAVERICK
, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
397 {ARM_CEXT_MAVERICK
, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
398 {ARM_CEXT_MAVERICK
, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
399 {ARM_CEXT_MAVERICK
, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
400 {ARM_CEXT_MAVERICK
, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
401 {ARM_CEXT_MAVERICK
, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
402 {ARM_CEXT_MAVERICK
, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
403 {ARM_CEXT_MAVERICK
, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
404 {ARM_CEXT_MAVERICK
, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
405 {ARM_CEXT_MAVERICK
, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
406 {ARM_CEXT_MAVERICK
, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
407 {ARM_CEXT_MAVERICK
, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
408 {ARM_CEXT_MAVERICK
, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
409 {ARM_CEXT_MAVERICK
, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
410 {ARM_CEXT_MAVERICK
, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
411 {ARM_CEXT_MAVERICK
, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
412 {ARM_CEXT_MAVERICK
, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
413 {ARM_CEXT_MAVERICK
, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
414 {ARM_CEXT_MAVERICK
, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
415 {ARM_CEXT_MAVERICK
, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
416 {ARM_CEXT_MAVERICK
, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
417 {ARM_CEXT_MAVERICK
, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
418 {ARM_CEXT_MAVERICK
, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
419 {ARM_CEXT_MAVERICK
, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
420 {ARM_CEXT_MAVERICK
, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
421 {ARM_CEXT_MAVERICK
, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
422 {ARM_CEXT_MAVERICK
, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
423 {ARM_CEXT_MAVERICK
, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
424 {ARM_CEXT_MAVERICK
, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
425 {ARM_CEXT_MAVERICK
, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
426 {ARM_CEXT_MAVERICK
, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
427 {ARM_CEXT_MAVERICK
, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
428 {ARM_CEXT_MAVERICK
, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
429 {ARM_CEXT_MAVERICK
, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
430 {ARM_CEXT_MAVERICK
, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
431 {ARM_CEXT_MAVERICK
, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
432 {ARM_CEXT_MAVERICK
, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
433 {ARM_CEXT_MAVERICK
, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
434 {ARM_CEXT_MAVERICK
, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
435 {ARM_CEXT_MAVERICK
, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
436 {ARM_CEXT_MAVERICK
, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
437 {ARM_CEXT_MAVERICK
, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
438 {ARM_CEXT_MAVERICK
, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
439 {ARM_CEXT_MAVERICK
, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
440 {ARM_CEXT_MAVERICK
, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
441 {ARM_CEXT_MAVERICK
, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
442 {ARM_CEXT_MAVERICK
, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
443 {ARM_CEXT_MAVERICK
, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
444 {ARM_CEXT_MAVERICK
, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
445 {ARM_CEXT_MAVERICK
, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
446 {ARM_CEXT_MAVERICK
, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
447 {ARM_CEXT_MAVERICK
, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
448 {ARM_CEXT_MAVERICK
, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
449 {ARM_CEXT_MAVERICK
, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
450 {ARM_CEXT_MAVERICK
, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
451 {ARM_CEXT_MAVERICK
, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
452 {ARM_CEXT_MAVERICK
, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
453 {ARM_CEXT_MAVERICK
, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
454 {ARM_CEXT_MAVERICK
, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
455 {ARM_CEXT_MAVERICK
, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
456 {ARM_CEXT_MAVERICK
, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
457 {ARM_CEXT_MAVERICK
, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
458 {ARM_CEXT_MAVERICK
, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
459 {ARM_CEXT_MAVERICK
, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
460 {ARM_CEXT_MAVERICK
, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
462 /* VFP Fused multiply add instructions. */
463 {FPU_VFP_EXT_FMA
, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
464 {FPU_VFP_EXT_FMA
, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
465 {FPU_VFP_EXT_FMA
, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
466 {FPU_VFP_EXT_FMA
, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
467 {FPU_VFP_EXT_FMA
, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
468 {FPU_VFP_EXT_FMA
, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
469 {FPU_VFP_EXT_FMA
, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
470 {FPU_VFP_EXT_FMA
, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
472 /* Generic coprocessor instructions. */
473 { 0, SENTINEL_GENERIC_START
, 0, "" },
474 {ARM_EXT_V5E
, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
475 {ARM_EXT_V5E
, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
476 {ARM_EXT_V2
, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
477 {ARM_EXT_V2
, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
478 {ARM_EXT_V2
, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
479 {ARM_EXT_V2
, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
480 {ARM_EXT_V2
, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
481 {ARM_EXT_V2
, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
483 /* V6 coprocessor instructions. */
484 {ARM_EXT_V6
, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
485 {ARM_EXT_V6
, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
487 /* V5 coprocessor instructions. */
488 {ARM_EXT_V5
, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
489 {ARM_EXT_V5
, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
490 {ARM_EXT_V5
, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
491 {ARM_EXT_V5
, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
492 {ARM_EXT_V5
, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
497 /* Neon opcode table: This does not encode the top byte -- that is
498 checked by the print_insn_neon routine, as it depends on whether we are
499 doing thumb32 or arm32 disassembly. */
501 /* print_insn_neon recognizes the following format control codes:
505 %c print condition code
506 %A print v{st,ld}[1234] operands
507 %B print v{st,ld}[1234] any one operands
508 %C print v{st,ld}[1234] single->all operands
510 %E print vmov, vmvn, vorr, vbic encoded constant
511 %F print vtbl,vtbx register list
513 %<bitfield>r print as an ARM register
514 %<bitfield>d print the bitfield in decimal
515 %<bitfield>e print the 2^N - bitfield in decimal
516 %<bitfield>D print as a NEON D register
517 %<bitfield>Q print as a NEON Q register
518 %<bitfield>R print as a NEON D or Q register
519 %<bitfield>Sn print byte scaled width limited by n
520 %<bitfield>Tn print short scaled width limited by n
521 %<bitfield>Un print long scaled width limited by n
523 %<bitfield>'c print specified char iff bitfield is all ones
524 %<bitfield>`c print specified char iff bitfield is all zeroes
525 %<bitfield>?ab... select from array of values in big endian order. */
527 static const struct opcode32 neon_opcodes
[] =
530 {FPU_NEON_EXT_V1
, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
531 {FPU_NEON_EXT_V1
, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
533 /* Move data element to all lanes. */
534 {FPU_NEON_EXT_V1
, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
535 {FPU_NEON_EXT_V1
, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
536 {FPU_NEON_EXT_V1
, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
539 {FPU_NEON_EXT_V1
, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
540 {FPU_NEON_EXT_V1
, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
542 /* Half-precision conversions. */
543 {FPU_VFP_EXT_FP16
, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
544 {FPU_VFP_EXT_FP16
, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
546 /* NEON fused multiply add instructions. */
547 {FPU_NEON_EXT_FMA
, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
548 {FPU_NEON_EXT_FMA
, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
550 /* Two registers, miscellaneous. */
551 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
552 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
553 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
554 {FPU_NEON_EXT_V1
, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
555 {FPU_NEON_EXT_V1
, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
556 {FPU_NEON_EXT_V1
, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
557 {FPU_NEON_EXT_V1
, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
558 {FPU_NEON_EXT_V1
, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
559 {FPU_NEON_EXT_V1
, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
560 {FPU_NEON_EXT_V1
, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
561 {FPU_NEON_EXT_V1
, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
562 {FPU_NEON_EXT_V1
, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
563 {FPU_NEON_EXT_V1
, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
564 {FPU_NEON_EXT_V1
, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
565 {FPU_NEON_EXT_V1
, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
566 {FPU_NEON_EXT_V1
, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
567 {FPU_NEON_EXT_V1
, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
568 {FPU_NEON_EXT_V1
, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
569 {FPU_NEON_EXT_V1
, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
570 {FPU_NEON_EXT_V1
, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
571 {FPU_NEON_EXT_V1
, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
572 {FPU_NEON_EXT_V1
, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
573 {FPU_NEON_EXT_V1
, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
574 {FPU_NEON_EXT_V1
, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
575 {FPU_NEON_EXT_V1
, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
576 {FPU_NEON_EXT_V1
, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
577 {FPU_NEON_EXT_V1
, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
578 {FPU_NEON_EXT_V1
, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
579 {FPU_NEON_EXT_V1
, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
580 {FPU_NEON_EXT_V1
, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
581 {FPU_NEON_EXT_V1
, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
582 {FPU_NEON_EXT_V1
, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
583 {FPU_NEON_EXT_V1
, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
585 /* Three registers of the same length. */
586 {FPU_NEON_EXT_V1
, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
587 {FPU_NEON_EXT_V1
, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
588 {FPU_NEON_EXT_V1
, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
589 {FPU_NEON_EXT_V1
, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
590 {FPU_NEON_EXT_V1
, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
591 {FPU_NEON_EXT_V1
, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
592 {FPU_NEON_EXT_V1
, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
593 {FPU_NEON_EXT_V1
, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
594 {FPU_NEON_EXT_V1
, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
595 {FPU_NEON_EXT_V1
, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
596 {FPU_NEON_EXT_V1
, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
597 {FPU_NEON_EXT_V1
, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
598 {FPU_NEON_EXT_V1
, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
599 {FPU_NEON_EXT_V1
, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
600 {FPU_NEON_EXT_V1
, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
601 {FPU_NEON_EXT_V1
, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
602 {FPU_NEON_EXT_V1
, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1
, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1
, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1
, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1
, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1
, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1
, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1
, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1
, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1
, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1
, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1
, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1
, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1
, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
616 {FPU_NEON_EXT_V1
, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
617 {FPU_NEON_EXT_V1
, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
618 {FPU_NEON_EXT_V1
, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
619 {FPU_NEON_EXT_V1
, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1
, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1
, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1
, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1
, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1
, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
625 {FPU_NEON_EXT_V1
, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
626 {FPU_NEON_EXT_V1
, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
627 {FPU_NEON_EXT_V1
, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
628 {FPU_NEON_EXT_V1
, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
629 {FPU_NEON_EXT_V1
, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
630 {FPU_NEON_EXT_V1
, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
631 {FPU_NEON_EXT_V1
, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
632 {FPU_NEON_EXT_V1
, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
633 {FPU_NEON_EXT_V1
, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
634 {FPU_NEON_EXT_V1
, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635 {FPU_NEON_EXT_V1
, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
636 {FPU_NEON_EXT_V1
, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
637 {FPU_NEON_EXT_V1
, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
638 {FPU_NEON_EXT_V1
, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 /* One register and an immediate value. */
641 {FPU_NEON_EXT_V1
, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
642 {FPU_NEON_EXT_V1
, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
643 {FPU_NEON_EXT_V1
, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
644 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
645 {FPU_NEON_EXT_V1
, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
646 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
647 {FPU_NEON_EXT_V1
, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
648 {FPU_NEON_EXT_V1
, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
649 {FPU_NEON_EXT_V1
, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
650 {FPU_NEON_EXT_V1
, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
651 {FPU_NEON_EXT_V1
, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
652 {FPU_NEON_EXT_V1
, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
653 {FPU_NEON_EXT_V1
, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
655 /* Two registers and a shift amount. */
656 {FPU_NEON_EXT_V1
, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
657 {FPU_NEON_EXT_V1
, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
658 {FPU_NEON_EXT_V1
, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
659 {FPU_NEON_EXT_V1
, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
660 {FPU_NEON_EXT_V1
, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
661 {FPU_NEON_EXT_V1
, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
662 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
663 {FPU_NEON_EXT_V1
, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
664 {FPU_NEON_EXT_V1
, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
665 {FPU_NEON_EXT_V1
, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
666 {FPU_NEON_EXT_V1
, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
667 {FPU_NEON_EXT_V1
, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
668 {FPU_NEON_EXT_V1
, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
669 {FPU_NEON_EXT_V1
, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
670 {FPU_NEON_EXT_V1
, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
671 {FPU_NEON_EXT_V1
, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
672 {FPU_NEON_EXT_V1
, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
673 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
674 {FPU_NEON_EXT_V1
, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
675 {FPU_NEON_EXT_V1
, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
676 {FPU_NEON_EXT_V1
, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
677 {FPU_NEON_EXT_V1
, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
678 {FPU_NEON_EXT_V1
, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
679 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
680 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
681 {FPU_NEON_EXT_V1
, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
682 {FPU_NEON_EXT_V1
, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
683 {FPU_NEON_EXT_V1
, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
684 {FPU_NEON_EXT_V1
, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
685 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
686 {FPU_NEON_EXT_V1
, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
687 {FPU_NEON_EXT_V1
, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
688 {FPU_NEON_EXT_V1
, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
689 {FPU_NEON_EXT_V1
, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
690 {FPU_NEON_EXT_V1
, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
691 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
692 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
693 {FPU_NEON_EXT_V1
, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
694 {FPU_NEON_EXT_V1
, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
695 {FPU_NEON_EXT_V1
, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
696 {FPU_NEON_EXT_V1
, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
697 {FPU_NEON_EXT_V1
, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
698 {FPU_NEON_EXT_V1
, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
699 {FPU_NEON_EXT_V1
, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
700 {FPU_NEON_EXT_V1
, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
701 {FPU_NEON_EXT_V1
, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
702 {FPU_NEON_EXT_V1
, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
703 {FPU_NEON_EXT_V1
, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
704 {FPU_NEON_EXT_V1
, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
705 {FPU_NEON_EXT_V1
, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
706 {FPU_NEON_EXT_V1
, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
707 {FPU_NEON_EXT_V1
, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
708 {FPU_NEON_EXT_V1
, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
709 {FPU_NEON_EXT_V1
, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
710 {FPU_NEON_EXT_V1
, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
711 {FPU_NEON_EXT_V1
, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
712 {FPU_NEON_EXT_V1
, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
713 {FPU_NEON_EXT_V1
, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
715 /* Three registers of different lengths. */
716 {FPU_NEON_EXT_V1
, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
717 {FPU_NEON_EXT_V1
, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
718 {FPU_NEON_EXT_V1
, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
719 {FPU_NEON_EXT_V1
, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
720 {FPU_NEON_EXT_V1
, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
721 {FPU_NEON_EXT_V1
, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
722 {FPU_NEON_EXT_V1
, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
723 {FPU_NEON_EXT_V1
, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
724 {FPU_NEON_EXT_V1
, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
725 {FPU_NEON_EXT_V1
, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
726 {FPU_NEON_EXT_V1
, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
727 {FPU_NEON_EXT_V1
, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
728 {FPU_NEON_EXT_V1
, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
729 {FPU_NEON_EXT_V1
, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
730 {FPU_NEON_EXT_V1
, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
731 {FPU_NEON_EXT_V1
, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
732 {FPU_NEON_EXT_V1
, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
734 /* Two registers and a scalar. */
735 {FPU_NEON_EXT_V1
, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
736 {FPU_NEON_EXT_V1
, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
737 {FPU_NEON_EXT_V1
, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
738 {FPU_NEON_EXT_V1
, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
739 {FPU_NEON_EXT_V1
, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
740 {FPU_NEON_EXT_V1
, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
741 {FPU_NEON_EXT_V1
, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
742 {FPU_NEON_EXT_V1
, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
743 {FPU_NEON_EXT_V1
, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
744 {FPU_NEON_EXT_V1
, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
745 {FPU_NEON_EXT_V1
, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
746 {FPU_NEON_EXT_V1
, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
747 {FPU_NEON_EXT_V1
, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
748 {FPU_NEON_EXT_V1
, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
749 {FPU_NEON_EXT_V1
, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
750 {FPU_NEON_EXT_V1
, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
751 {FPU_NEON_EXT_V1
, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
752 {FPU_NEON_EXT_V1
, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
753 {FPU_NEON_EXT_V1
, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
754 {FPU_NEON_EXT_V1
, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
755 {FPU_NEON_EXT_V1
, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
756 {FPU_NEON_EXT_V1
, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
758 /* Element and structure load/store. */
759 {FPU_NEON_EXT_V1
, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
760 {FPU_NEON_EXT_V1
, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
761 {FPU_NEON_EXT_V1
, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
762 {FPU_NEON_EXT_V1
, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
763 {FPU_NEON_EXT_V1
, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
764 {FPU_NEON_EXT_V1
, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
765 {FPU_NEON_EXT_V1
, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
766 {FPU_NEON_EXT_V1
, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
767 {FPU_NEON_EXT_V1
, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
768 {FPU_NEON_EXT_V1
, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
769 {FPU_NEON_EXT_V1
, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
770 {FPU_NEON_EXT_V1
, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
771 {FPU_NEON_EXT_V1
, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
772 {FPU_NEON_EXT_V1
, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
773 {FPU_NEON_EXT_V1
, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
774 {FPU_NEON_EXT_V1
, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
775 {FPU_NEON_EXT_V1
, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
776 {FPU_NEON_EXT_V1
, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
777 {FPU_NEON_EXT_V1
, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
782 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
783 ordered: they must be searched linearly from the top to obtain a correct
786 /* print_insn_arm recognizes the following format control codes:
790 %a print address for ldr/str instruction
791 %s print address for ldr/str halfword/signextend instruction
792 %S like %s but allow UNPREDICTABLE addressing
793 %b print branch destination
794 %c print condition code (always bits 28-31)
795 %m print register mask for ldm/stm instruction
796 %o print operand2 (immediate or register + shift)
797 %p print 'p' iff bits 12-15 are 15
798 %t print 't' iff bit 21 set and bit 24 clear
799 %B print arm BLX(1) destination
800 %C print the PSR sub type.
801 %U print barrier type.
802 %P print address for pli instruction.
804 %<bitfield>r print as an ARM register
805 %<bitfield>R as %r but r15 is UNPREDICTABLE
806 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
807 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
808 %<bitfield>d print the bitfield in decimal
809 %<bitfield>W print the bitfield plus one in decimal
810 %<bitfield>x print the bitfield in hex
811 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
813 %<bitfield>'c print specified char iff bitfield is all ones
814 %<bitfield>`c print specified char iff bitfield is all zeroes
815 %<bitfield>?ab... select from array of values in big endian order
817 %e print arm SMI operand (bits 0..7,8..19).
818 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
819 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
821 static const struct opcode32 arm_opcodes
[] =
823 /* ARM instructions. */
824 {ARM_EXT_V1
, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
825 {ARM_EXT_V4T
| ARM_EXT_V5
, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
826 {ARM_EXT_V2
, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
827 {ARM_EXT_V2
, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
828 {ARM_EXT_V2S
, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
829 {ARM_EXT_V3M
, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
830 {ARM_EXT_V3M
, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
832 /* MP Extension instructions. */
833 {ARM_EXT_MP
, 0xf410f000, 0xfc70f000, "pldw\t%a"},
835 /* V7 instructions. */
836 {ARM_EXT_V7
, 0xf450f000, 0xfd70f000, "pli\t%P"},
837 {ARM_EXT_V7
, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
838 {ARM_EXT_V7
, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
839 {ARM_EXT_V7
, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
840 {ARM_EXT_V7
, 0xf57ff060, 0xfffffff0, "isb\t%U"},
842 /* ARM V6T2 instructions. */
843 {ARM_EXT_V6T2
, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
844 {ARM_EXT_V6T2
, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
845 {ARM_EXT_V6T2
, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
846 {ARM_EXT_V6T2
, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
848 {ARM_EXT_V6T2
, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION
},
849 {ARM_EXT_V6T2
, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
851 {ARM_EXT_V6T2
, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
852 {ARM_EXT_V6T2
, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
853 {ARM_EXT_V6T2
, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
854 {ARM_EXT_V6T2
, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
856 /* ARM Security extension instructions. */
857 {ARM_EXT_SEC
, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
859 /* ARM V6K instructions. */
860 {ARM_EXT_V6K
, 0xf57ff01f, 0xffffffff, "clrex"},
861 {ARM_EXT_V6K
, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
862 {ARM_EXT_V6K
, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
863 {ARM_EXT_V6K
, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
864 {ARM_EXT_V6K
, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
865 {ARM_EXT_V6K
, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
866 {ARM_EXT_V6K
, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
868 /* ARM V6K NOP hints. */
869 {ARM_EXT_V6K
, 0x0320f001, 0x0fffffff, "yield%c"},
870 {ARM_EXT_V6K
, 0x0320f002, 0x0fffffff, "wfe%c"},
871 {ARM_EXT_V6K
, 0x0320f003, 0x0fffffff, "wfi%c"},
872 {ARM_EXT_V6K
, 0x0320f004, 0x0fffffff, "sev%c"},
873 {ARM_EXT_V6K
, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
875 /* ARM V6 instructions. */
876 {ARM_EXT_V6
, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
877 {ARM_EXT_V6
, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
878 {ARM_EXT_V6
, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
879 {ARM_EXT_V6
, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
880 {ARM_EXT_V6
, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
881 {ARM_EXT_V6
, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
882 {ARM_EXT_V6
, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
883 {ARM_EXT_V6
, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
884 {ARM_EXT_V6
, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
885 {ARM_EXT_V6
, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
886 {ARM_EXT_V6
, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
887 {ARM_EXT_V6
, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
888 {ARM_EXT_V6
, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
889 {ARM_EXT_V6
, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
890 {ARM_EXT_V6
, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
891 {ARM_EXT_V6
, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
892 {ARM_EXT_V6
, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
893 {ARM_EXT_V6
, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
894 {ARM_EXT_V6
, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
895 {ARM_EXT_V6
, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
896 {ARM_EXT_V6
, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
897 {ARM_EXT_V6
, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
898 {ARM_EXT_V6
, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
899 {ARM_EXT_V6
, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
900 {ARM_EXT_V6
, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
901 {ARM_EXT_V6
, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
902 {ARM_EXT_V6
, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
903 {ARM_EXT_V6
, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
904 {ARM_EXT_V6
, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
905 {ARM_EXT_V6
, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
906 {ARM_EXT_V6
, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
907 {ARM_EXT_V6
, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
908 {ARM_EXT_V6
, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
909 {ARM_EXT_V6
, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
910 {ARM_EXT_V6
, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
911 {ARM_EXT_V6
, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6
, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6
, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6
, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6
, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6
, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6
, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6
, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6
, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
920 {ARM_EXT_V6
, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
921 {ARM_EXT_V6
, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
922 {ARM_EXT_V6
, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
923 {ARM_EXT_V6
, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
924 {ARM_EXT_V6
, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
925 {ARM_EXT_V6
, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
926 {ARM_EXT_V6
, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
927 {ARM_EXT_V6
, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
928 {ARM_EXT_V6
, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
929 {ARM_EXT_V6
, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
930 {ARM_EXT_V6
, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
931 {ARM_EXT_V6
, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
932 {ARM_EXT_V6
, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
933 {ARM_EXT_V6
, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
934 {ARM_EXT_V6
, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
935 {ARM_EXT_V6
, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
936 {ARM_EXT_V6
, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
937 {ARM_EXT_V6
, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
938 {ARM_EXT_V6
, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
939 {ARM_EXT_V6
, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
940 {ARM_EXT_V6
, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
941 {ARM_EXT_V6
, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
942 {ARM_EXT_V6
, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
943 {ARM_EXT_V6
, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
944 {ARM_EXT_V6
, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
945 {ARM_EXT_V6
, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
946 {ARM_EXT_V6
, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
947 {ARM_EXT_V6
, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
948 {ARM_EXT_V6
, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
949 {ARM_EXT_V6
, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
950 {ARM_EXT_V6
, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
951 {ARM_EXT_V6
, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
952 {ARM_EXT_V6
, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
953 {ARM_EXT_V6
, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
954 {ARM_EXT_V6
, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
955 {ARM_EXT_V6
, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
956 {ARM_EXT_V6
, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
957 {ARM_EXT_V6
, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
958 {ARM_EXT_V6
, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
959 {ARM_EXT_V6
, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
960 {ARM_EXT_V6
, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
961 {ARM_EXT_V6
, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
962 {ARM_EXT_V6
, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
963 {ARM_EXT_V6
, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
964 {ARM_EXT_V6
, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
965 {ARM_EXT_V6
, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
966 {ARM_EXT_V6
, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
967 {ARM_EXT_V6
, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
968 {ARM_EXT_V6
, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
969 {ARM_EXT_V6
, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
970 {ARM_EXT_V6
, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
971 {ARM_EXT_V6
, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
972 {ARM_EXT_V6
, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
973 {ARM_EXT_V6
, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
974 {ARM_EXT_V6
, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
975 {ARM_EXT_V6
, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
976 {ARM_EXT_V6
, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
977 {ARM_EXT_V6
, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
978 {ARM_EXT_V6
, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
979 {ARM_EXT_V6
, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
980 {ARM_EXT_V6
, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
981 {ARM_EXT_V6
, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
982 {ARM_EXT_V6
, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
983 {ARM_EXT_V6
, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
984 {ARM_EXT_V6
, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
985 {ARM_EXT_V6
, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
986 {ARM_EXT_V6
, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
987 {ARM_EXT_V6
, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
988 {ARM_EXT_V6
, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
989 {ARM_EXT_V6
, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
990 {ARM_EXT_V6
, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
991 {ARM_EXT_V6
, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
992 {ARM_EXT_V6
, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
993 {ARM_EXT_V6
, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
994 {ARM_EXT_V6
, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
995 {ARM_EXT_V6
, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
996 {ARM_EXT_V6
, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
997 {ARM_EXT_V6
, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
999 /* V5J instruction. */
1000 {ARM_EXT_V5J
, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1002 /* V5 Instructions. */
1003 {ARM_EXT_V5
, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1004 {ARM_EXT_V5
, 0xfa000000, 0xfe000000, "blx\t%B"},
1005 {ARM_EXT_V5
, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1006 {ARM_EXT_V5
, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1008 /* V5E "El Segundo" Instructions. */
1009 {ARM_EXT_V5E
, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1010 {ARM_EXT_V5E
, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1011 {ARM_EXT_V5E
, 0xf450f000, 0xfc70f000, "pld\t%a"},
1012 {ARM_EXT_V5ExP
, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1013 {ARM_EXT_V5ExP
, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1014 {ARM_EXT_V5ExP
, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1015 {ARM_EXT_V5ExP
, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1017 {ARM_EXT_V5ExP
, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1018 {ARM_EXT_V5ExP
, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1020 {ARM_EXT_V5ExP
, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1021 {ARM_EXT_V5ExP
, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1022 {ARM_EXT_V5ExP
, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1023 {ARM_EXT_V5ExP
, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1025 {ARM_EXT_V5ExP
, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1026 {ARM_EXT_V5ExP
, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1027 {ARM_EXT_V5ExP
, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1028 {ARM_EXT_V5ExP
, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1030 {ARM_EXT_V5ExP
, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1031 {ARM_EXT_V5ExP
, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1033 {ARM_EXT_V5ExP
, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1034 {ARM_EXT_V5ExP
, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1035 {ARM_EXT_V5ExP
, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1036 {ARM_EXT_V5ExP
, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1038 /* ARM Instructions. */
1039 {ARM_EXT_V1
, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1041 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1042 {ARM_EXT_V1
, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1043 {ARM_EXT_V1
, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1044 {ARM_EXT_V1
, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1045 {ARM_EXT_V1
, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1046 {ARM_EXT_V1
, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1048 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1049 {ARM_EXT_V1
, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1050 {ARM_EXT_V1
, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1051 {ARM_EXT_V1
, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1053 {ARM_EXT_V1
, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION
},
1054 {ARM_EXT_V1
, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1055 {ARM_EXT_V1
, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION
},
1056 {ARM_EXT_V1
, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1058 {ARM_EXT_V1
, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1059 {ARM_EXT_V1
, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1060 {ARM_EXT_V1
, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1062 {ARM_EXT_V1
, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1063 {ARM_EXT_V1
, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1064 {ARM_EXT_V1
, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1066 {ARM_EXT_V1
, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1067 {ARM_EXT_V1
, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1068 {ARM_EXT_V1
, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1070 {ARM_EXT_V1
, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1071 {ARM_EXT_V1
, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1072 {ARM_EXT_V1
, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1074 {ARM_EXT_V1
, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1075 {ARM_EXT_V1
, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1076 {ARM_EXT_V1
, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1078 {ARM_EXT_V1
, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1079 {ARM_EXT_V1
, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1
, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1082 {ARM_EXT_V1
, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1083 {ARM_EXT_V1
, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1
, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1086 {ARM_EXT_V1
, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1087 {ARM_EXT_V1
, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1
, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1090 {ARM_EXT_V3
, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1091 {ARM_EXT_V3
, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15R, %22?SCPSR"},
1093 {ARM_EXT_V1
, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1094 {ARM_EXT_V1
, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1095 {ARM_EXT_V1
, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1097 {ARM_EXT_V1
, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1098 {ARM_EXT_V1
, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1099 {ARM_EXT_V1
, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1101 {ARM_EXT_V1
, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1102 {ARM_EXT_V3
, 0x01400000, 0x0ff00010, "mrs%c\t%12-15R, %22?SCPSR"},
1103 {ARM_EXT_V1
, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1104 {ARM_EXT_V1
, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1106 {ARM_EXT_V1
, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1107 {ARM_EXT_V1
, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1108 {ARM_EXT_V1
, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1110 {ARM_EXT_V1
, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1111 {ARM_EXT_V1
, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1112 {ARM_EXT_V1
, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1114 {ARM_EXT_V1
, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1115 {ARM_EXT_V1
, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1116 {ARM_EXT_V1
, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1117 {ARM_EXT_V1
, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1118 {ARM_EXT_V1
, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1119 {ARM_EXT_V1
, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1120 {ARM_EXT_V1
, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1122 {ARM_EXT_V1
, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1123 {ARM_EXT_V1
, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1124 {ARM_EXT_V1
, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1126 {ARM_EXT_V1
, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1127 {ARM_EXT_V1
, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1128 {ARM_EXT_V1
, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1130 {ARM_EXT_V1
, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION
},
1131 {ARM_EXT_V1
, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1133 {ARM_EXT_V1
, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1135 {ARM_EXT_V1
, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1136 {ARM_EXT_V1
, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1138 {ARM_EXT_V1
, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1139 {ARM_EXT_V1
, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1140 {ARM_EXT_V1
, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1141 {ARM_EXT_V1
, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1142 {ARM_EXT_V1
, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1143 {ARM_EXT_V1
, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1144 {ARM_EXT_V1
, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1145 {ARM_EXT_V1
, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1148 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1149 {0, 0x00000000, 0x00000000, 0}
1152 /* print_insn_thumb16 recognizes the following format control codes:
1154 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1155 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1156 %<bitfield>I print bitfield as a signed decimal
1157 (top bit of range being the sign bit)
1158 %N print Thumb register mask (with LR)
1159 %O print Thumb register mask (with PC)
1160 %M print Thumb register mask
1161 %b print CZB's 6-bit unsigned branch destination
1162 %s print Thumb right-shift immediate (6..10; 0 == 32).
1163 %c print the condition code
1164 %C print the condition code, or "s" if not conditional
1165 %x print warning if conditional an not at end of IT block"
1166 %X print "\t; unpredictable <IT:code>" if conditional
1167 %I print IT instruction suffix and operands
1168 %W print Thumb Writeback indicator for LDMIA
1169 %<bitfield>r print bitfield as an ARM register
1170 %<bitfield>d print bitfield as a decimal
1171 %<bitfield>H print (bitfield * 2) as a decimal
1172 %<bitfield>W print (bitfield * 4) as a decimal
1173 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1174 %<bitfield>B print Thumb branch destination (signed displacement)
1175 %<bitfield>c print bitfield as a condition code
1176 %<bitnum>'c print specified char iff bit is one
1177 %<bitnum>?ab print a if bit is one else print b. */
1179 static const struct opcode16 thumb_opcodes
[] =
1181 /* Thumb instructions. */
1183 /* ARM V6K no-argument instructions. */
1184 {ARM_EXT_V6K
, 0xbf00, 0xffff, "nop%c"},
1185 {ARM_EXT_V6K
, 0xbf10, 0xffff, "yield%c"},
1186 {ARM_EXT_V6K
, 0xbf20, 0xffff, "wfe%c"},
1187 {ARM_EXT_V6K
, 0xbf30, 0xffff, "wfi%c"},
1188 {ARM_EXT_V6K
, 0xbf40, 0xffff, "sev%c"},
1189 {ARM_EXT_V6K
, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1191 /* ARM V6T2 instructions. */
1192 {ARM_EXT_V6T2
, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1193 {ARM_EXT_V6T2
, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1194 {ARM_EXT_V6T2
, 0xbf00, 0xff00, "it%I%X"},
1197 {ARM_EXT_V6
, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1198 {ARM_EXT_V6
, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1199 {ARM_EXT_V6
, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1200 {ARM_EXT_V6
, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1201 {ARM_EXT_V6
, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1202 {ARM_EXT_V6
, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1203 {ARM_EXT_V6
, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1204 {ARM_EXT_V6
, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1205 {ARM_EXT_V6
, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1206 {ARM_EXT_V6
, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1207 {ARM_EXT_V6
, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1209 /* ARM V5 ISA extends Thumb. */
1210 {ARM_EXT_V5T
, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1211 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1212 {ARM_EXT_V5T
, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1213 /* ARM V4T ISA (Thumb v1). */
1214 {ARM_EXT_V4T
, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1216 {ARM_EXT_V4T
, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1217 {ARM_EXT_V4T
, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1218 {ARM_EXT_V4T
, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1219 {ARM_EXT_V4T
, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1220 {ARM_EXT_V4T
, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1221 {ARM_EXT_V4T
, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1222 {ARM_EXT_V4T
, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1223 {ARM_EXT_V4T
, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1224 {ARM_EXT_V4T
, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1225 {ARM_EXT_V4T
, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1226 {ARM_EXT_V4T
, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1227 {ARM_EXT_V4T
, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1228 {ARM_EXT_V4T
, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1229 {ARM_EXT_V4T
, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1230 {ARM_EXT_V4T
, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1231 {ARM_EXT_V4T
, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1233 {ARM_EXT_V4T
, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1234 {ARM_EXT_V4T
, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1236 {ARM_EXT_V4T
, 0x4700, 0xFF80, "bx%c\t%S%x"},
1237 {ARM_EXT_V4T
, 0x4400, 0xFF00, "add%c\t%D, %S"},
1238 {ARM_EXT_V4T
, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1239 {ARM_EXT_V4T
, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1241 {ARM_EXT_V4T
, 0xB400, 0xFE00, "push%c\t%N"},
1242 {ARM_EXT_V4T
, 0xBC00, 0xFE00, "pop%c\t%O"},
1244 {ARM_EXT_V4T
, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1245 {ARM_EXT_V4T
, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1246 {ARM_EXT_V4T
, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1247 {ARM_EXT_V4T
, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1249 {ARM_EXT_V4T
, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1250 {ARM_EXT_V4T
, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1251 {ARM_EXT_V4T
, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1253 {ARM_EXT_V4T
, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1254 {ARM_EXT_V4T
, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1256 {ARM_EXT_V4T
, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1257 {ARM_EXT_V4T
, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1258 {ARM_EXT_V4T
, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1259 {ARM_EXT_V4T
, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1261 {ARM_EXT_V4T
, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1262 {ARM_EXT_V4T
, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1263 {ARM_EXT_V4T
, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1264 {ARM_EXT_V4T
, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1266 {ARM_EXT_V4T
, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1268 {ARM_EXT_V4T
, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1269 {ARM_EXT_V4T
, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1270 {ARM_EXT_V4T
, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1271 {ARM_EXT_V4T
, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1273 {ARM_EXT_V4T
, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1274 {ARM_EXT_V4T
, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1276 {ARM_EXT_V4T
, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1277 {ARM_EXT_V4T
, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1279 {ARM_EXT_V4T
, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1280 {ARM_EXT_V4T
, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1282 {ARM_EXT_V4T
, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1283 {ARM_EXT_V4T
, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1285 {ARM_EXT_V4T
, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1287 {ARM_EXT_V4T
, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION
},
1288 {ARM_EXT_V4T
, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1290 {ARM_EXT_V4T
, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1292 /* The E800 .. FFFF range is unconditionally redirected to the
1293 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1294 are processed via that table. Thus, we can never encounter a
1295 bare "second half of BL/BLX(1)" instruction here. */
1296 {ARM_EXT_V1
, 0x0000, 0x0000, UNDEFINED_INSTRUCTION
},
1300 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1301 We adopt the convention that hw1 is the high 16 bits of .value and
1302 .mask, hw2 the low 16 bits.
1304 print_insn_thumb32 recognizes the following format control codes:
1308 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1309 %M print a modified 12-bit immediate (same location)
1310 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1311 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1312 %S print a possibly-shifted Rm
1314 %a print the address of a plain load/store
1315 %w print the width and signedness of a core load/store
1316 %m print register mask for ldm/stm
1318 %E print the lsb and width fields of a bfc/bfi instruction
1319 %F print the lsb and width fields of a sbfx/ubfx instruction
1320 %b print a conditional branch offset
1321 %B print an unconditional branch offset
1322 %s print the shift field of an SSAT instruction
1323 %R print the rotation field of an SXT instruction
1324 %U print barrier type.
1325 %P print address for pli instruction.
1326 %c print the condition code
1327 %x print warning if conditional an not at end of IT block"
1328 %X print "\t; unpredictable <IT:code>" if conditional
1330 %<bitfield>d print bitfield in decimal
1331 %<bitfield>W print bitfield*4 in decimal
1332 %<bitfield>r print bitfield as an ARM register
1333 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1334 %<bitfield>c print bitfield as a condition code
1336 %<bitfield>'c print specified char iff bitfield is all ones
1337 %<bitfield>`c print specified char iff bitfield is all zeroes
1338 %<bitfield>?ab... select from array of values in big endian order
1340 With one exception at the bottom (done because BL and BLX(1) need
1341 to come dead last), this table was machine-sorted first in
1342 decreasing order of number of bits set in the mask, then in
1343 increasing numeric order of mask, then in increasing numeric order
1344 of opcode. This order is not the clearest for a human reader, but
1345 is guaranteed never to catch a special-case bit pattern with a more
1346 general mask, which is important, because this instruction encoding
1347 makes heavy use of special-case bit patterns. */
1348 static const struct opcode32 thumb32_opcodes
[] =
1350 /* V7 instructions. */
1351 {ARM_EXT_V7
, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1352 {ARM_EXT_V7
, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1353 {ARM_EXT_V7
, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1354 {ARM_EXT_V7
, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1355 {ARM_EXT_V7
, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1356 {ARM_EXT_DIV
, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_DIV
, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1359 /* MP Extension instructions. */
1360 {ARM_EXT_MP
, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1362 /* Security extension instructions. */
1363 {ARM_EXT_SEC
, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1365 /* Instructions defined in the basic V6T2 set. */
1366 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffffff, "nop%c.w"},
1367 {ARM_EXT_V6T2
, 0xf3af8001, 0xffffffff, "yield%c.w"},
1368 {ARM_EXT_V6T2
, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1369 {ARM_EXT_V6T2
, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1370 {ARM_EXT_V6T2
, 0xf3af8004, 0xffffffff, "sev%c.w"},
1371 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1373 {ARM_EXT_V6T2
, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1374 {ARM_EXT_V6T2
, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1375 {ARM_EXT_V6T2
, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1376 {ARM_EXT_V6T2
, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1377 {ARM_EXT_V6T2
, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1378 {ARM_EXT_V6T2
, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1379 {ARM_EXT_V6T2
, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1380 {ARM_EXT_V6T2
, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1381 {ARM_EXT_V6T2
, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1382 {ARM_EXT_V6T2
, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1383 {ARM_EXT_V6T2
, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1384 {ARM_EXT_V6T2
, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1385 {ARM_EXT_V6T2
, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1386 {ARM_EXT_V6T2
, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1387 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1388 {ARM_EXT_V6T2
, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1389 {ARM_EXT_V6T2
, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1390 {ARM_EXT_V6T2
, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1391 {ARM_EXT_V6T2
, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1392 {ARM_EXT_V6T2
, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1393 {ARM_EXT_V6T2
, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1394 {ARM_EXT_V6T2
, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1395 {ARM_EXT_V6T2
, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1396 {ARM_EXT_V6T2
, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1397 {ARM_EXT_V6T2
, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1398 {ARM_EXT_V6T2
, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1399 {ARM_EXT_V6T2
, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1400 {ARM_EXT_V6T2
, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2
, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2
, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2
, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2
, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2
, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1406 {ARM_EXT_V6T2
, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1407 {ARM_EXT_V6T2
, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1408 {ARM_EXT_V6T2
, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1409 {ARM_EXT_V6T2
, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1410 {ARM_EXT_V6T2
, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2
, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2
, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1413 {ARM_EXT_V6T2
, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1414 {ARM_EXT_V6T2
, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1415 {ARM_EXT_V6T2
, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1416 {ARM_EXT_V6T2
, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1417 {ARM_EXT_V6T2
, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1418 {ARM_EXT_V6T2
, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1419 {ARM_EXT_V6T2
, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1420 {ARM_EXT_V6T2
, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1421 {ARM_EXT_V6T2
, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1422 {ARM_EXT_V6T2
, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1423 {ARM_EXT_V6T2
, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1424 {ARM_EXT_V6T2
, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1425 {ARM_EXT_V6T2
, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1426 {ARM_EXT_V6T2
, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1427 {ARM_EXT_V6T2
, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1428 {ARM_EXT_V6T2
, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1429 {ARM_EXT_V6T2
, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1430 {ARM_EXT_V6T2
, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1431 {ARM_EXT_V6T2
, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1432 {ARM_EXT_V6T2
, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1433 {ARM_EXT_V6T2
, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1434 {ARM_EXT_V6T2
, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2
, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2
, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2
, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2
, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2
, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1440 {ARM_EXT_V6T2
, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1441 {ARM_EXT_V6T2
, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1442 {ARM_EXT_V6T2
, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1443 {ARM_EXT_V6T2
, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1444 {ARM_EXT_V6T2
, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1445 {ARM_EXT_V6T2
, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1446 {ARM_EXT_V6T2
, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1447 {ARM_EXT_V6T2
, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1448 {ARM_EXT_V6T2
, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1449 {ARM_EXT_V6T2
, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1450 {ARM_EXT_V6T2
, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2
, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1452 {ARM_EXT_V6T2
, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1453 {ARM_EXT_V6T2
, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1454 {ARM_EXT_V6T2
, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1455 {ARM_EXT_V6T2
, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1456 {ARM_EXT_V6T2
, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1457 {ARM_EXT_V6T2
, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2
, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1459 {ARM_EXT_V6T2
, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1460 {ARM_EXT_V6T2
, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1461 {ARM_EXT_V6T2
, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1462 {ARM_EXT_V6T2
, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1463 {ARM_EXT_V6T2
, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1464 {ARM_EXT_V6T2
, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2
, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1466 {ARM_EXT_V6T2
, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1467 {ARM_EXT_V6T2
, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1468 {ARM_EXT_V6T2
, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1469 {ARM_EXT_V6T2
, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1470 {ARM_EXT_V6T2
, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1471 {ARM_EXT_V6T2
, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1472 {ARM_EXT_V6T2
, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1473 {ARM_EXT_V6T2
, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1474 {ARM_EXT_V6T2
, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1475 {ARM_EXT_V6T2
, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1476 {ARM_EXT_V6T2
, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1477 {ARM_EXT_V6T2
, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1478 {ARM_EXT_V6T2
, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1479 {ARM_EXT_V6T2
, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1480 {ARM_EXT_V6T2
, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1481 {ARM_EXT_V6T2
, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1482 {ARM_EXT_V6T2
, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1483 {ARM_EXT_V6T2
, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1484 {ARM_EXT_V6T2
, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1485 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1486 {ARM_EXT_V6T2
, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1487 {ARM_EXT_V6T2
, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1488 {ARM_EXT_V6T2
, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1489 {ARM_EXT_V6T2
, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1490 {ARM_EXT_V6T2
, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1491 {ARM_EXT_V6T2
, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1492 {ARM_EXT_V6T2
, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1493 {ARM_EXT_V6T2
, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1494 {ARM_EXT_V6T2
, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1495 {ARM_EXT_V6T2
, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1496 {ARM_EXT_V6T2
, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1497 {ARM_EXT_V6T2
, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1498 {ARM_EXT_V6T2
, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1499 {ARM_EXT_V6T2
, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1500 {ARM_EXT_V6T2
, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1501 {ARM_EXT_V6T2
, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1502 {ARM_EXT_V6T2
, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1503 {ARM_EXT_V6T2
, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1504 {ARM_EXT_V6T2
, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1505 {ARM_EXT_V6T2
, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1506 {ARM_EXT_V6T2
, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1507 {ARM_EXT_V6T2
, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1508 {ARM_EXT_V6T2
, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1509 {ARM_EXT_V6T2
, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1510 {ARM_EXT_V6T2
, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1511 {ARM_EXT_V6T2
, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1512 {ARM_EXT_V6T2
, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1513 {ARM_EXT_V6T2
, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1514 {ARM_EXT_V6T2
, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1515 {ARM_EXT_V6T2
, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1516 {ARM_EXT_V6T2
, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1517 {ARM_EXT_V6T2
, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1518 {ARM_EXT_V6T2
, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1519 {ARM_EXT_V6T2
, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1520 {ARM_EXT_V6T2
, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1521 {ARM_EXT_V6T2
, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1522 {ARM_EXT_V6T2
, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1523 {ARM_EXT_V6T2
, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1524 {ARM_EXT_V6T2
, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1525 {ARM_EXT_V6T2
, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1526 {ARM_EXT_V6T2
, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1527 {ARM_EXT_V6T2
, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1528 {ARM_EXT_V6T2
, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1529 {ARM_EXT_V6T2
, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1530 {ARM_EXT_V6T2
, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1531 {ARM_EXT_V6T2
, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1532 {ARM_EXT_V6T2
, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1533 {ARM_EXT_V6T2
, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1534 {ARM_EXT_V6T2
, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1535 {ARM_EXT_V6T2
, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1536 {ARM_EXT_V6T2
, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1537 {ARM_EXT_V6T2
, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1538 {ARM_EXT_V6T2
, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1539 {ARM_EXT_V6T2
, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1540 {ARM_EXT_V6T2
, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1541 {ARM_EXT_V6T2
, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1542 {ARM_EXT_V6T2
, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1543 {ARM_EXT_V6T2
, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1545 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1546 {ARM_EXT_V6T2
, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1547 {ARM_EXT_V6T2
, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1548 {ARM_EXT_V6T2
, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1549 {ARM_EXT_V6T2
, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1551 /* These have been 32-bit since the invention of Thumb. */
1552 {ARM_EXT_V4T
, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1553 {ARM_EXT_V4T
, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1556 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1560 static const char *const arm_conditional
[] =
1561 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1562 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1564 static const char *const arm_fp_const
[] =
1565 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1567 static const char *const arm_shift
[] =
1568 {"lsl", "lsr", "asr", "ror"};
1573 const char *description
;
1574 const char *reg_names
[16];
1578 static const arm_regname regnames
[] =
1580 { "raw" , "Select raw register names",
1581 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1582 { "gcc", "Select register names used by GCC",
1583 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1584 { "std", "Select register names used in ARM's ISA documentation",
1585 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1586 { "apcs", "Select register names used in the APCS",
1587 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1588 { "atpcs", "Select register names used in the ATPCS",
1589 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1590 { "special-atpcs", "Select special register names used in the ATPCS",
1591 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1594 static const char *const iwmmxt_wwnames
[] =
1595 {"b", "h", "w", "d"};
1597 static const char *const iwmmxt_wwssnames
[] =
1598 {"b", "bus", "bc", "bss",
1599 "h", "hus", "hc", "hss",
1600 "w", "wus", "wc", "wss",
1601 "d", "dus", "dc", "dss"
1604 static const char *const iwmmxt_regnames
[] =
1605 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1606 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1609 static const char *const iwmmxt_cregnames
[] =
1610 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1611 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1614 /* Default to GCC register name set. */
1615 static unsigned int regname_selected
= 1;
1617 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1618 #define arm_regnames regnames[regname_selected].reg_names
1620 static bfd_boolean force_thumb
= FALSE
;
1622 /* Current IT instruction state. This contains the same state as the IT
1623 bits in the CPSR. */
1624 static unsigned int ifthen_state
;
1625 /* IT state for the next instruction. */
1626 static unsigned int ifthen_next_state
;
1627 /* The address of the insn for which the IT state is valid. */
1628 static bfd_vma ifthen_address
;
1629 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1631 /* Cached mapping symbol state. */
1639 enum map_type last_type
;
1640 int last_mapping_sym
= -1;
1641 bfd_vma last_mapping_addr
= 0;
1646 get_arm_regname_num_options (void)
1648 return NUM_ARM_REGNAMES
;
1652 set_arm_regname_option (int option
)
1654 int old
= regname_selected
;
1655 regname_selected
= option
;
1660 get_arm_regnames (int option
,
1661 const char **setname
,
1662 const char **setdescription
,
1663 const char *const **register_names
)
1665 *setname
= regnames
[option
].name
;
1666 *setdescription
= regnames
[option
].description
;
1667 *register_names
= regnames
[option
].reg_names
;
1671 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1672 Returns pointer to following character of the format string and
1673 fills in *VALUEP and *WIDTHP with the extracted value and number of
1674 bits extracted. WIDTHP can be NULL. */
1677 arm_decode_bitfield (const char *ptr
,
1679 unsigned long *valuep
,
1682 unsigned long value
= 0;
1690 for (start
= 0; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1691 start
= start
* 10 + *ptr
- '0';
1693 for (end
= 0, ptr
++; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1694 end
= end
* 10 + *ptr
- '0';
1700 value
|= ((insn
>> start
) & ((2ul << bits
) - 1)) << width
;
1703 while (*ptr
++ == ',');
1711 arm_decode_shift (long given
, fprintf_ftype func
, void *stream
,
1712 bfd_boolean print_shift
)
1714 func (stream
, "%s", arm_regnames
[given
& 0xf]);
1716 if ((given
& 0xff0) != 0)
1718 if ((given
& 0x10) == 0)
1720 int amount
= (given
& 0xf80) >> 7;
1721 int shift
= (given
& 0x60) >> 5;
1727 func (stream
, ", rrx");
1735 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
1737 func (stream
, ", #%d", amount
);
1739 else if ((given
& 0x80) == 0x80)
1740 func (stream
, "\t; <illegal shifter operand>");
1741 else if (print_shift
)
1742 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
1743 arm_regnames
[(given
& 0xf00) >> 8]);
1745 func (stream
, ", %s", arm_regnames
[(given
& 0xf00) >> 8]);
1754 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1755 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1756 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1757 #define PRE_BIT_SET (given & (1 << P_BIT))
1759 /* Print one coprocessor instruction on INFO->STREAM.
1760 Return TRUE if the instuction matched, FALSE if this is not a
1761 recognised coprocessor instruction. */
1764 print_insn_coprocessor (bfd_vma pc
,
1765 struct disassemble_info
*info
,
1769 const struct opcode32
*insn
;
1770 void *stream
= info
->stream
;
1771 fprintf_ftype func
= info
->fprintf_func
;
1773 unsigned long value
= 0;
1774 struct arm_private_data
*private_data
= info
->private_data
;
1775 unsigned long allowed_arches
= private_data
->features
.coproc
;
1778 for (insn
= coprocessor_opcodes
; insn
->assembler
; insn
++)
1780 unsigned long u_reg
= 16;
1781 bfd_boolean is_unpredictable
= FALSE
;
1782 signed long value_in_comment
= 0;
1785 if (insn
->arch
== 0)
1786 switch (insn
->value
)
1788 case SENTINEL_IWMMXT_START
:
1789 if (info
->mach
!= bfd_mach_arm_XScale
1790 && info
->mach
!= bfd_mach_arm_iWMMXt
1791 && info
->mach
!= bfd_mach_arm_iWMMXt2
)
1794 while (insn
->arch
!= 0 && insn
->value
!= SENTINEL_IWMMXT_END
);
1797 case SENTINEL_IWMMXT_END
:
1800 case SENTINEL_GENERIC_START
:
1801 allowed_arches
= private_data
->features
.core
;
1809 value
= insn
->value
;
1812 /* The high 4 bits are 0xe for Arm conditional instructions, and
1813 0xe for arm unconditional instructions. The rest of the
1814 encoding is the same. */
1816 value
|= 0xe0000000;
1824 /* Only match unconditional instuctions against unconditional
1826 if ((given
& 0xf0000000) == 0xf0000000)
1833 cond
= (given
>> 28) & 0xf;
1839 if ((given
& mask
) != value
)
1842 if ((insn
->arch
& allowed_arches
) == 0)
1845 for (c
= insn
->assembler
; *c
; c
++)
1852 func (stream
, "%%");
1857 int rn
= (given
>> 16) & 0xf;
1858 int offset
= given
& 0xff;
1860 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
1862 if (PRE_BIT_SET
|| WRITEBACK_BIT_SET
)
1864 /* Not unindexed. The offset is scaled. */
1865 offset
= offset
* 4;
1866 if (NEGATIVE_BIT_SET
)
1869 value_in_comment
= offset
;
1875 func (stream
, ", #%d]%s",
1877 WRITEBACK_BIT_SET
? "!" : "");
1885 if (WRITEBACK_BIT_SET
)
1888 func (stream
, ", #%d", offset
);
1892 func (stream
, ", {%d}", offset
);
1893 value_in_comment
= offset
;
1896 if (rn
== 15 && (PRE_BIT_SET
|| WRITEBACK_BIT_SET
))
1898 func (stream
, "\t; ");
1899 info
->print_address_func (offset
+ pc
1900 + info
->bytes_per_chunk
* 2, info
);
1907 int regno
= ((given
>> 12) & 0xf) | ((given
>> (22 - 4)) & 0x10);
1908 int offset
= (given
>> 1) & 0x3f;
1911 func (stream
, "{d%d}", regno
);
1912 else if (regno
+ offset
> 32)
1913 func (stream
, "{d%d-<overflow reg d%d>}", regno
, regno
+ offset
- 1);
1915 func (stream
, "{d%d-d%d}", regno
, regno
+ offset
- 1);
1920 func (stream
, "%s", arm_conditional
[cond
]);
1924 /* Print a Cirrus/DSP shift immediate. */
1925 /* Immediates are 7bit signed ints with bits 0..3 in
1926 bits 0..3 of opcode and bits 4..6 in bits 5..7
1931 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
1933 /* Is ``imm'' a negative number? */
1937 func (stream
, "%d", imm
);
1943 switch (given
& 0x00408000)
1960 switch (given
& 0x00080080)
1972 func (stream
, _("<illegal precision>"));
1978 switch (given
& 0x00408000)
1996 switch (given
& 0x60)
2012 case '0': case '1': case '2': case '3': case '4':
2013 case '5': case '6': case '7': case '8': case '9':
2017 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2023 is_unpredictable
= TRUE
;
2028 /* Eat the 'u' character. */
2032 is_unpredictable
= TRUE
;
2035 func (stream
, "%s", arm_regnames
[value
]);
2038 func (stream
, "d%ld", value
);
2042 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2044 func (stream
, "q%ld", value
>> 1);
2047 func (stream
, "%ld", value
);
2048 value_in_comment
= value
;
2052 int from
= (given
& (1 << 7)) ? 32 : 16;
2053 func (stream
, "%ld", from
- value
);
2059 func (stream
, "#%s", arm_fp_const
[value
& 7]);
2061 func (stream
, "f%ld", value
);
2066 func (stream
, "%s", iwmmxt_wwnames
[value
]);
2068 func (stream
, "%s", iwmmxt_wwssnames
[value
]);
2072 func (stream
, "%s", iwmmxt_regnames
[value
]);
2075 func (stream
, "%s", iwmmxt_cregnames
[value
]);
2079 func (stream
, "0x%lx", (value
& 0xffffffffUL
));
2085 func (stream
, "%c", *c
);
2089 if (value
== ((1ul << width
) - 1))
2090 func (stream
, "%c", *c
);
2093 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2104 int single
= *c
++ == 'y';
2109 case '4': /* Sm pair */
2110 case '0': /* Sm, Dm */
2111 regno
= given
& 0x0000000f;
2115 regno
+= (given
>> 5) & 1;
2118 regno
+= ((given
>> 5) & 1) << 4;
2121 case '1': /* Sd, Dd */
2122 regno
= (given
>> 12) & 0x0000000f;
2126 regno
+= (given
>> 22) & 1;
2129 regno
+= ((given
>> 22) & 1) << 4;
2132 case '2': /* Sn, Dn */
2133 regno
= (given
>> 16) & 0x0000000f;
2137 regno
+= (given
>> 7) & 1;
2140 regno
+= ((given
>> 7) & 1) << 4;
2143 case '3': /* List */
2145 regno
= (given
>> 12) & 0x0000000f;
2149 regno
+= (given
>> 22) & 1;
2152 regno
+= ((given
>> 22) & 1) << 4;
2159 func (stream
, "%c%d", single
? 's' : 'd', regno
);
2163 int count
= given
& 0xff;
2170 func (stream
, "-%c%d",
2178 func (stream
, ", %c%d", single
? 's' : 'd',
2184 switch (given
& 0x00400100)
2186 case 0x00000000: func (stream
, "b"); break;
2187 case 0x00400000: func (stream
, "h"); break;
2188 case 0x00000100: func (stream
, "w"); break;
2189 case 0x00400100: func (stream
, "d"); break;
2197 /* given (20, 23) | given (0, 3) */
2198 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
2199 func (stream
, "%d", value
);
2204 /* This is like the 'A' operator, except that if
2205 the width field "M" is zero, then the offset is
2206 *not* multiplied by four. */
2208 int offset
= given
& 0xff;
2209 int multiplier
= (given
& 0x00000100) ? 4 : 1;
2211 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2215 value_in_comment
= offset
* multiplier
;
2216 if (NEGATIVE_BIT_SET
)
2217 value_in_comment
= - value_in_comment
;
2223 func (stream
, ", #%s%d]%s",
2224 NEGATIVE_BIT_SET
? "-" : "",
2225 offset
* multiplier
,
2226 WRITEBACK_BIT_SET
? "!" : "");
2228 func (stream
, "], #%s%d",
2229 NEGATIVE_BIT_SET
? "-" : "",
2230 offset
* multiplier
);
2239 int imm4
= (given
>> 4) & 0xf;
2240 int puw_bits
= ((given
>> 22) & 6) | ((given
>> W_BIT
) & 1);
2241 int ubit
= ! NEGATIVE_BIT_SET
;
2242 const char *rm
= arm_regnames
[given
& 0xf];
2243 const char *rn
= arm_regnames
[(given
>> 16) & 0xf];
2249 func (stream
, "[%s], %c%s", rn
, ubit
? '+' : '-', rm
);
2251 func (stream
, ", lsl #%d", imm4
);
2258 func (stream
, "[%s, %c%s", rn
, ubit
? '+' : '-', rm
);
2260 func (stream
, ", lsl #%d", imm4
);
2262 if (puw_bits
== 5 || puw_bits
== 7)
2267 func (stream
, "INVALID");
2275 imm5
= ((given
& 0x100) >> 4) | (given
& 0xf);
2276 func (stream
, "%ld", (imm5
== 0) ? 32 : imm5
);
2286 func (stream
, "%c", *c
);
2289 if (value_in_comment
> 32 || value_in_comment
< -16)
2290 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
2292 if (is_unpredictable
)
2293 func (stream
, UNPREDICTABLE_INSTRUCTION
);
2300 /* Decodes and prints ARM addressing modes. Returns the offset
2301 used in the address, if any, if it is worthwhile printing the
2302 offset as a hexadecimal value in a comment at the end of the
2303 line of disassembly. */
2306 print_arm_address (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2308 void *stream
= info
->stream
;
2309 fprintf_ftype func
= info
->fprintf_func
;
2312 if (((given
& 0x000f0000) == 0x000f0000)
2313 && ((given
& 0x02000000) == 0))
2315 offset
= given
& 0xfff;
2317 func (stream
, "[pc");
2319 if (NEGATIVE_BIT_SET
)
2325 func (stream
, ", #%d]", offset
);
2329 /* Cope with the possibility of write-back
2330 being used. Probably a very dangerous thing
2331 for the programmer to do, but who are we to
2333 if (WRITEBACK_BIT_SET
)
2336 else /* Post indexed. */
2338 func (stream
, "], #%d", offset
);
2340 /* Ie ignore the offset. */
2344 func (stream
, "\t; ");
2345 info
->print_address_func (offset
, info
);
2350 func (stream
, "[%s",
2351 arm_regnames
[(given
>> 16) & 0xf]);
2355 if ((given
& 0x02000000) == 0)
2357 offset
= given
& 0xfff;
2359 func (stream
, ", #%s%d",
2360 NEGATIVE_BIT_SET
? "-" : "", offset
);
2364 func (stream
, ", %s",
2365 NEGATIVE_BIT_SET
? "-" : "");
2366 arm_decode_shift (given
, func
, stream
, TRUE
);
2369 func (stream
, "]%s",
2370 WRITEBACK_BIT_SET
? "!" : "");
2374 if ((given
& 0x02000000) == 0)
2376 offset
= given
& 0xfff;
2378 func (stream
, "], #%s%d",
2379 NEGATIVE_BIT_SET
? "-" : "", offset
);
2385 func (stream
, "], %s",
2386 NEGATIVE_BIT_SET
? "-" : "");
2387 arm_decode_shift (given
, func
, stream
, TRUE
);
2392 return (signed long) offset
;
2395 /* Print one neon instruction on INFO->STREAM.
2396 Return TRUE if the instuction matched, FALSE if this is not a
2397 recognised neon instruction. */
2400 print_insn_neon (struct disassemble_info
*info
, long given
, bfd_boolean thumb
)
2402 const struct opcode32
*insn
;
2403 void *stream
= info
->stream
;
2404 fprintf_ftype func
= info
->fprintf_func
;
2408 if ((given
& 0xef000000) == 0xef000000)
2410 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2411 unsigned long bit28
= given
& (1 << 28);
2413 given
&= 0x00ffffff;
2415 given
|= 0xf3000000;
2417 given
|= 0xf2000000;
2419 else if ((given
& 0xff000000) == 0xf9000000)
2420 given
^= 0xf9000000 ^ 0xf4000000;
2425 for (insn
= neon_opcodes
; insn
->assembler
; insn
++)
2427 if ((given
& insn
->mask
) == insn
->value
)
2429 signed long value_in_comment
= 0;
2432 for (c
= insn
->assembler
; *c
; c
++)
2439 func (stream
, "%%");
2443 if (thumb
&& ifthen_state
)
2444 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
2449 static const unsigned char enc
[16] =
2451 0x4, 0x14, /* st4 0,1 */
2463 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2464 int rn
= ((given
>> 16) & 0xf);
2465 int rm
= ((given
>> 0) & 0xf);
2466 int align
= ((given
>> 4) & 0x3);
2467 int type
= ((given
>> 8) & 0xf);
2468 int n
= enc
[type
] & 0xf;
2469 int stride
= (enc
[type
] >> 4) + 1;
2474 for (ix
= 0; ix
!= n
; ix
++)
2475 func (stream
, "%sd%d", ix
? "," : "", rd
+ ix
* stride
);
2477 func (stream
, "d%d", rd
);
2479 func (stream
, "d%d-d%d", rd
, rd
+ n
- 1);
2480 func (stream
, "}, [%s", arm_regnames
[rn
]);
2482 func (stream
, " :%d", 32 << align
);
2487 func (stream
, ", %s", arm_regnames
[rm
]);
2493 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2494 int rn
= ((given
>> 16) & 0xf);
2495 int rm
= ((given
>> 0) & 0xf);
2496 int idx_align
= ((given
>> 4) & 0xf);
2498 int size
= ((given
>> 10) & 0x3);
2499 int idx
= idx_align
>> (size
+ 1);
2500 int length
= ((given
>> 8) & 3) + 1;
2504 if (length
> 1 && size
> 0)
2505 stride
= (idx_align
& (1 << size
)) ? 2 : 1;
2511 int amask
= (1 << size
) - 1;
2512 if ((idx_align
& (1 << size
)) != 0)
2516 if ((idx_align
& amask
) == amask
)
2518 else if ((idx_align
& amask
) != 0)
2525 if (size
== 2 && (idx_align
& 2) != 0)
2527 align
= (idx_align
& 1) ? 16 << size
: 0;
2531 if ((size
== 2 && (idx_align
& 3) != 0)
2532 || (idx_align
& 1) != 0)
2539 if ((idx_align
& 3) == 3)
2541 align
= (idx_align
& 3) * 64;
2544 align
= (idx_align
& 1) ? 32 << size
: 0;
2552 for (i
= 0; i
< length
; i
++)
2553 func (stream
, "%sd%d[%d]", (i
== 0) ? "" : ",",
2554 rd
+ i
* stride
, idx
);
2555 func (stream
, "}, [%s", arm_regnames
[rn
]);
2557 func (stream
, " :%d", align
);
2562 func (stream
, ", %s", arm_regnames
[rm
]);
2568 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2569 int rn
= ((given
>> 16) & 0xf);
2570 int rm
= ((given
>> 0) & 0xf);
2571 int align
= ((given
>> 4) & 0x1);
2572 int size
= ((given
>> 6) & 0x3);
2573 int type
= ((given
>> 8) & 0x3);
2575 int stride
= ((given
>> 5) & 0x1);
2578 if (stride
&& (n
== 1))
2585 for (ix
= 0; ix
!= n
; ix
++)
2586 func (stream
, "%sd%d[]", ix
? "," : "", rd
+ ix
* stride
);
2588 func (stream
, "d%d[]", rd
);
2590 func (stream
, "d%d[]-d%d[]", rd
, rd
+ n
- 1);
2591 func (stream
, "}, [%s", arm_regnames
[rn
]);
2594 align
= (8 * (type
+ 1)) << size
;
2596 align
= (size
> 1) ? align
>> 1 : align
;
2597 if (type
== 2 || (type
== 0 && !size
))
2598 func (stream
, " :<bad align %d>", align
);
2600 func (stream
, " :%d", align
);
2606 func (stream
, ", %s", arm_regnames
[rm
]);
2612 int raw_reg
= (given
& 0xf) | ((given
>> 1) & 0x10);
2613 int size
= (given
>> 20) & 3;
2614 int reg
= raw_reg
& ((4 << size
) - 1);
2615 int ix
= raw_reg
>> size
>> 2;
2617 func (stream
, "d%d[%d]", reg
, ix
);
2622 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2625 int cmode
= (given
>> 8) & 0xf;
2626 int op
= (given
>> 5) & 0x1;
2627 unsigned long value
= 0, hival
= 0;
2632 bits
|= ((given
>> 24) & 1) << 7;
2633 bits
|= ((given
>> 16) & 7) << 4;
2634 bits
|= ((given
>> 0) & 15) << 0;
2638 shift
= (cmode
>> 1) & 3;
2639 value
= (unsigned long) bits
<< (8 * shift
);
2642 else if (cmode
< 12)
2644 shift
= (cmode
>> 1) & 1;
2645 value
= (unsigned long) bits
<< (8 * shift
);
2648 else if (cmode
< 14)
2650 shift
= (cmode
& 1) + 1;
2651 value
= (unsigned long) bits
<< (8 * shift
);
2652 value
|= (1ul << (8 * shift
)) - 1;
2655 else if (cmode
== 14)
2659 /* Bit replication into bytes. */
2665 for (ix
= 7; ix
>= 0; ix
--)
2667 mask
= ((bits
>> ix
) & 1) ? 0xff : 0;
2669 value
= (value
<< 8) | mask
;
2671 hival
= (hival
<< 8) | mask
;
2677 /* Byte replication. */
2678 value
= (unsigned long) bits
;
2684 /* Floating point encoding. */
2687 value
= (unsigned long) (bits
& 0x7f) << 19;
2688 value
|= (unsigned long) (bits
& 0x80) << 24;
2689 tmp
= bits
& 0x40 ? 0x3c : 0x40;
2690 value
|= (unsigned long) tmp
<< 24;
2696 func (stream
, "<illegal constant %.8x:%x:%x>",
2704 func (stream
, "#%ld\t; 0x%.2lx", value
, value
);
2708 func (stream
, "#%ld\t; 0x%.4lx", value
, value
);
2714 unsigned char valbytes
[4];
2717 /* Do this a byte at a time so we don't have to
2718 worry about the host's endianness. */
2719 valbytes
[0] = value
& 0xff;
2720 valbytes
[1] = (value
>> 8) & 0xff;
2721 valbytes
[2] = (value
>> 16) & 0xff;
2722 valbytes
[3] = (value
>> 24) & 0xff;
2724 floatformat_to_double
2725 (& floatformat_ieee_single_little
, valbytes
,
2728 func (stream
, "#%.7g\t; 0x%.8lx", fvalue
,
2732 func (stream
, "#%ld\t; 0x%.8lx",
2733 (long) (((value
& 0x80000000L
) != 0)
2734 ? value
| ~0xffffffffL
: value
),
2739 func (stream
, "#0x%.8lx%.8lx", hival
, value
);
2750 int regno
= ((given
>> 16) & 0xf) | ((given
>> (7 - 4)) & 0x10);
2751 int num
= (given
>> 8) & 0x3;
2754 func (stream
, "{d%d}", regno
);
2755 else if (num
+ regno
>= 32)
2756 func (stream
, "{d%d-<overflow reg d%d}", regno
, regno
+ num
);
2758 func (stream
, "{d%d-d%d}", regno
, regno
+ num
);
2763 case '0': case '1': case '2': case '3': case '4':
2764 case '5': case '6': case '7': case '8': case '9':
2767 unsigned long value
;
2769 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2774 func (stream
, "%s", arm_regnames
[value
]);
2777 func (stream
, "%ld", value
);
2778 value_in_comment
= value
;
2781 func (stream
, "%ld", (1ul << width
) - value
);
2787 /* Various width encodings. */
2789 int base
= 8 << (*c
- 'S'); /* 8,16 or 32 */
2794 if (*c
>= '0' && *c
<= '9')
2796 else if (*c
>= 'a' && *c
<= 'f')
2797 limit
= *c
- 'a' + 10;
2803 if (value
< low
|| value
> high
)
2804 func (stream
, "<illegal width %d>", base
<< value
);
2806 func (stream
, "%d", base
<< value
);
2810 if (given
& (1 << 6))
2814 func (stream
, "d%ld", value
);
2819 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2821 func (stream
, "q%ld", value
>> 1);
2827 func (stream
, "%c", *c
);
2831 if (value
== ((1ul << width
) - 1))
2832 func (stream
, "%c", *c
);
2835 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2849 func (stream
, "%c", *c
);
2852 if (value_in_comment
> 32 || value_in_comment
< -16)
2853 func (stream
, "\t; 0x%lx", value_in_comment
);
2861 /* Print one ARM instruction from PC on INFO->STREAM. */
2864 print_insn_arm (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2866 const struct opcode32
*insn
;
2867 void *stream
= info
->stream
;
2868 fprintf_ftype func
= info
->fprintf_func
;
2869 struct arm_private_data
*private_data
= info
->private_data
;
2871 if (print_insn_coprocessor (pc
, info
, given
, FALSE
))
2874 if (print_insn_neon (info
, given
, FALSE
))
2877 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
2879 if ((given
& insn
->mask
) != insn
->value
)
2882 if ((insn
->arch
& private_data
->features
.core
) == 0)
2885 /* Special case: an instruction with all bits set in the condition field
2886 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2887 or by the catchall at the end of the table. */
2888 if ((given
& 0xF0000000) != 0xF0000000
2889 || (insn
->mask
& 0xF0000000) == 0xF0000000
2890 || (insn
->mask
== 0 && insn
->value
== 0))
2892 unsigned long u_reg
= 16;
2893 unsigned long U_reg
= 16;
2894 bfd_boolean is_unpredictable
= FALSE
;
2895 signed long value_in_comment
= 0;
2898 for (c
= insn
->assembler
; *c
; c
++)
2902 bfd_boolean allow_unpredictable
= FALSE
;
2907 func (stream
, "%%");
2911 value_in_comment
= print_arm_address (pc
, info
, given
);
2915 /* Set P address bit and use normal address
2916 printing routine. */
2917 value_in_comment
= print_arm_address (pc
, info
, given
| (1 << P_BIT
));
2921 allow_unpredictable
= TRUE
;
2923 if ((given
& 0x004f0000) == 0x004f0000)
2925 /* PC relative with immediate offset. */
2926 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2928 if (NEGATIVE_BIT_SET
)
2934 func (stream
, "[pc, #%d]\t; ", offset
);
2936 func (stream
, "[pc]\t; ");
2937 info
->print_address_func (offset
+ pc
+ 8, info
);
2941 func (stream
, "[pc], #%d", offset
);
2942 if (! allow_unpredictable
)
2943 is_unpredictable
= TRUE
;
2948 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2950 if (NEGATIVE_BIT_SET
)
2953 func (stream
, "[%s",
2954 arm_regnames
[(given
>> 16) & 0xf]);
2958 if (IMMEDIATE_BIT_SET
)
2960 if (WRITEBACK_BIT_SET
)
2961 /* Immediate Pre-indexed. */
2962 /* PR 10924: Offset must be printed, even if it is zero. */
2963 func (stream
, ", #%d", offset
);
2965 /* Immediate Offset: printing zero offset is optional. */
2966 func (stream
, ", #%d", offset
);
2968 value_in_comment
= offset
;
2972 /* Register Offset or Register Pre-Indexed. */
2973 func (stream
, ", %s%s",
2974 NEGATIVE_BIT_SET
? "-" : "",
2975 arm_regnames
[given
& 0xf]);
2977 /* Writing back to the register that is the source/
2978 destination of the load/store is unpredictable. */
2979 if (! allow_unpredictable
2980 && WRITEBACK_BIT_SET
2981 && ((given
& 0xf) == ((given
>> 12) & 0xf)))
2982 is_unpredictable
= TRUE
;
2985 func (stream
, "]%s",
2986 WRITEBACK_BIT_SET
? "!" : "");
2990 if (IMMEDIATE_BIT_SET
)
2992 /* Immediate Post-indexed. */
2993 /* PR 10924: Offset must be printed, even if it is zero. */
2994 func (stream
, "], #%d", offset
);
2995 value_in_comment
= offset
;
2999 /* Register Post-indexed. */
3000 func (stream
, "], %s%s",
3001 NEGATIVE_BIT_SET
? "-" : "",
3002 arm_regnames
[given
& 0xf]);
3004 /* Writing back to the register that is the source/
3005 destination of the load/store is unpredictable. */
3006 if (! allow_unpredictable
3007 && (given
& 0xf) == ((given
>> 12) & 0xf))
3008 is_unpredictable
= TRUE
;
3011 if (! allow_unpredictable
)
3013 /* Writeback is automatically implied by post- addressing.
3014 Setting the W bit is unnecessary and ARM specify it as
3015 being unpredictable. */
3016 if (WRITEBACK_BIT_SET
3017 /* Specifying the PC register as the post-indexed
3018 registers is also unpredictable. */
3019 || (! IMMEDIATE_BIT_SET
&& ((given
& 0xf) == 0xf)))
3020 is_unpredictable
= TRUE
;
3028 int disp
= (((given
& 0xffffff) ^ 0x800000) - 0x800000);
3029 info
->print_address_func (disp
* 4 + pc
+ 8, info
);
3034 if (((given
>> 28) & 0xf) != 0xe)
3036 arm_conditional
[(given
>> 28) & 0xf]);
3045 for (reg
= 0; reg
< 16; reg
++)
3046 if ((given
& (1 << reg
)) != 0)
3049 func (stream
, ", ");
3051 func (stream
, "%s", arm_regnames
[reg
]);
3055 is_unpredictable
= TRUE
;
3060 arm_decode_shift (given
, func
, stream
, FALSE
);
3064 if ((given
& 0x02000000) != 0)
3066 int rotate
= (given
& 0xf00) >> 7;
3067 int immed
= (given
& 0xff);
3069 immed
= (((immed
<< (32 - rotate
))
3070 | (immed
>> rotate
)) & 0xffffffff);
3071 func (stream
, "#%d", immed
);
3072 value_in_comment
= immed
;
3075 arm_decode_shift (given
, func
, stream
, TRUE
);
3079 if ((given
& 0x0000f000) == 0x0000f000)
3081 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3082 mechanism for setting PSR flag bits. They are
3083 obsolete in V6 onwards. */
3084 if ((private_data
->features
.core
& ARM_EXT_V6
) == 0)
3090 if ((given
& 0x01200000) == 0x00200000)
3096 int offset
= given
& 0xff;
3098 value_in_comment
= offset
* 4;
3099 if (NEGATIVE_BIT_SET
)
3100 value_in_comment
= - value_in_comment
;
3102 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3107 func (stream
, ", #%d]%s",
3109 WRITEBACK_BIT_SET
? "!" : "");
3117 if (WRITEBACK_BIT_SET
)
3120 func (stream
, ", #%d", value_in_comment
);
3124 func (stream
, ", {%d}", offset
);
3125 value_in_comment
= offset
;
3132 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3137 if (! NEGATIVE_BIT_SET
)
3138 /* Is signed, hi bits should be ones. */
3139 offset
= (-1) ^ 0x00ffffff;
3141 /* Offset is (SignExtend(offset field)<<2). */
3142 offset
+= given
& 0x00ffffff;
3144 address
= offset
+ pc
+ 8;
3146 if (given
& 0x01000000)
3147 /* H bit allows addressing to 2-byte boundaries. */
3150 info
->print_address_func (address
, info
);
3156 if (given
& 0x80000)
3158 if (given
& 0x40000)
3160 if (given
& 0x20000)
3162 if (given
& 0x10000)
3167 if ((given
& 0xf0) == 0x60)
3169 switch (given
& 0xf)
3171 case 0xf: func (stream
, "sy"); break;
3173 func (stream
, "#%d", (int) given
& 0xf);
3179 switch (given
& 0xf)
3181 case 0xf: func (stream
, "sy"); break;
3182 case 0x7: func (stream
, "un"); break;
3183 case 0xe: func (stream
, "st"); break;
3184 case 0x6: func (stream
, "unst"); break;
3185 case 0xb: func (stream
, "ish"); break;
3186 case 0xa: func (stream
, "ishst"); break;
3187 case 0x3: func (stream
, "osh"); break;
3188 case 0x2: func (stream
, "oshst"); break;
3190 func (stream
, "#%d", (int) given
& 0xf);
3196 case '0': case '1': case '2': case '3': case '4':
3197 case '5': case '6': case '7': case '8': case '9':
3200 unsigned long value
;
3202 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3208 is_unpredictable
= TRUE
;
3213 /* Eat the 'u' character. */
3217 is_unpredictable
= TRUE
;
3222 /* Eat the 'U' character. */
3226 is_unpredictable
= TRUE
;
3229 func (stream
, "%s", arm_regnames
[value
]);
3232 func (stream
, "%ld", value
);
3233 value_in_comment
= value
;
3236 func (stream
, "%ld", value
* 8);
3237 value_in_comment
= value
* 8;
3240 func (stream
, "%ld", value
+ 1);
3241 value_in_comment
= value
+ 1;
3244 func (stream
, "0x%08lx", value
);
3246 /* Some SWI instructions have special
3248 if ((given
& 0x0fffffff) == 0x0FF00000)
3249 func (stream
, "\t; IMB");
3250 else if ((given
& 0x0fffffff) == 0x0FF00001)
3251 func (stream
, "\t; IMBRange");
3254 func (stream
, "%01lx", value
& 0xf);
3255 value_in_comment
= value
;
3260 func (stream
, "%c", *c
);
3264 if (value
== ((1ul << width
) - 1))
3265 func (stream
, "%c", *c
);
3268 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
3280 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3281 func (stream
, "%d", imm
);
3282 value_in_comment
= imm
;
3287 /* LSB and WIDTH fields of BFI or BFC. The machine-
3288 language instruction encodes LSB and MSB. */
3290 long msb
= (given
& 0x001f0000) >> 16;
3291 long lsb
= (given
& 0x00000f80) >> 7;
3292 long w
= msb
- lsb
+ 1;
3295 func (stream
, "#%lu, #%lu", lsb
, w
);
3297 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
3302 /* 16-bit unsigned immediate from a MOVT or MOVW
3303 instruction, encoded in bits 0:11 and 15:19. */
3305 long hi
= (given
& 0x000f0000) >> 4;
3306 long lo
= (given
& 0x00000fff);
3307 long imm16
= hi
| lo
;
3309 func (stream
, "#%lu", imm16
);
3310 value_in_comment
= imm16
;
3320 func (stream
, "%c", *c
);
3323 if (value_in_comment
> 32 || value_in_comment
< -16)
3324 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
3326 if (is_unpredictable
)
3327 func (stream
, UNPREDICTABLE_INSTRUCTION
);
3335 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3338 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3340 const struct opcode16
*insn
;
3341 void *stream
= info
->stream
;
3342 fprintf_ftype func
= info
->fprintf_func
;
3344 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
3345 if ((given
& insn
->mask
) == insn
->value
)
3347 signed long value_in_comment
= 0;
3348 const char *c
= insn
->assembler
;
3357 func (stream
, "%c", *c
);
3364 func (stream
, "%%");
3369 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3374 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3383 ifthen_next_state
= given
& 0xff;
3384 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
3385 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
3386 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
3391 if (ifthen_next_state
)
3392 func (stream
, "\t; unpredictable branch in IT block\n");
3397 func (stream
, "\t; unpredictable <IT:%s>",
3398 arm_conditional
[IFTHEN_COND
]);
3405 reg
= (given
>> 3) & 0x7;
3406 if (given
& (1 << 6))
3409 func (stream
, "%s", arm_regnames
[reg
]);
3418 if (given
& (1 << 7))
3421 func (stream
, "%s", arm_regnames
[reg
]);
3426 if (given
& (1 << 8))
3430 if (*c
== 'O' && (given
& (1 << 8)))
3440 /* It would be nice if we could spot
3441 ranges, and generate the rS-rE format: */
3442 for (reg
= 0; (reg
< 8); reg
++)
3443 if ((given
& (1 << reg
)) != 0)
3446 func (stream
, ", ");
3448 func (stream
, "%s", arm_regnames
[reg
]);
3454 func (stream
, ", ");
3456 func (stream
, arm_regnames
[14] /* "lr" */);
3462 func (stream
, ", ");
3463 func (stream
, arm_regnames
[15] /* "pc" */);
3471 /* Print writeback indicator for a LDMIA. We are doing a
3472 writeback if the base register is not in the register
3474 if ((given
& (1 << ((given
& 0x0700) >> 8))) == 0)
3479 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3481 bfd_vma address
= (pc
+ 4
3482 + ((given
& 0x00f8) >> 2)
3483 + ((given
& 0x0200) >> 3));
3484 info
->print_address_func (address
, info
);
3489 /* Right shift immediate -- bits 6..10; 1-31 print
3490 as themselves, 0 prints as 32. */
3492 long imm
= (given
& 0x07c0) >> 6;
3495 func (stream
, "#%ld", imm
);
3499 case '0': case '1': case '2': case '3': case '4':
3500 case '5': case '6': case '7': case '8': case '9':
3502 int bitstart
= *c
++ - '0';
3505 while (*c
>= '0' && *c
<= '9')
3506 bitstart
= (bitstart
* 10) + *c
++ - '0';
3515 while (*c
>= '0' && *c
<= '9')
3516 bitend
= (bitend
* 10) + *c
++ - '0';
3519 reg
= given
>> bitstart
;
3520 reg
&= (2 << (bitend
- bitstart
)) - 1;
3525 func (stream
, "%s", arm_regnames
[reg
]);
3529 func (stream
, "%ld", reg
);
3530 value_in_comment
= reg
;
3534 func (stream
, "%ld", reg
<< 1);
3535 value_in_comment
= reg
<< 1;
3539 func (stream
, "%ld", reg
<< 2);
3540 value_in_comment
= reg
<< 2;
3544 /* PC-relative address -- the bottom two
3545 bits of the address are dropped
3546 before the calculation. */
3547 info
->print_address_func
3548 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
3549 value_in_comment
= 0;
3553 func (stream
, "0x%04lx", reg
);
3557 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
3558 info
->print_address_func (reg
* 2 + pc
+ 4, info
);
3559 value_in_comment
= 0;
3563 func (stream
, "%s", arm_conditional
[reg
]);
3574 if ((given
& (1 << bitstart
)) != 0)
3575 func (stream
, "%c", *c
);
3580 if ((given
& (1 << bitstart
)) != 0)
3581 func (stream
, "%c", *c
++);
3583 func (stream
, "%c", *++c
);
3597 if (value_in_comment
> 32 || value_in_comment
< -16)
3598 func (stream
, "\t; 0x%lx", value_in_comment
);
3606 /* Return the name of an V7M special register. */
3609 psr_name (int regno
)
3613 case 0: return "APSR";
3614 case 1: return "IAPSR";
3615 case 2: return "EAPSR";
3616 case 3: return "PSR";
3617 case 5: return "IPSR";
3618 case 6: return "EPSR";
3619 case 7: return "IEPSR";
3620 case 8: return "MSP";
3621 case 9: return "PSP";
3622 case 16: return "PRIMASK";
3623 case 17: return "BASEPRI";
3624 case 18: return "BASEPRI_MASK";
3625 case 19: return "FAULTMASK";
3626 case 20: return "CONTROL";
3627 default: return "<unknown>";
3631 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3634 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3636 const struct opcode32
*insn
;
3637 void *stream
= info
->stream
;
3638 fprintf_ftype func
= info
->fprintf_func
;
3640 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
3643 if (print_insn_neon (info
, given
, TRUE
))
3646 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
3647 if ((given
& insn
->mask
) == insn
->value
)
3649 bfd_boolean is_unpredictable
= FALSE
;
3650 signed long value_in_comment
= 0;
3651 const char *c
= insn
->assembler
;
3657 func (stream
, "%c", *c
);
3664 func (stream
, "%%");
3669 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3673 if (ifthen_next_state
)
3674 func (stream
, "\t; unpredictable branch in IT block\n");
3679 func (stream
, "\t; unpredictable <IT:%s>",
3680 arm_conditional
[IFTHEN_COND
]);
3685 unsigned int imm12
= 0;
3687 imm12
|= (given
& 0x000000ffu
);
3688 imm12
|= (given
& 0x00007000u
) >> 4;
3689 imm12
|= (given
& 0x04000000u
) >> 15;
3690 func (stream
, "#%u", imm12
);
3691 value_in_comment
= imm12
;
3697 unsigned int bits
= 0, imm
, imm8
, mod
;
3699 bits
|= (given
& 0x000000ffu
);
3700 bits
|= (given
& 0x00007000u
) >> 4;
3701 bits
|= (given
& 0x04000000u
) >> 15;
3702 imm8
= (bits
& 0x0ff);
3703 mod
= (bits
& 0xf00) >> 8;
3706 case 0: imm
= imm8
; break;
3707 case 1: imm
= ((imm8
<< 16) | imm8
); break;
3708 case 2: imm
= ((imm8
<< 24) | (imm8
<< 8)); break;
3709 case 3: imm
= ((imm8
<< 24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
3711 mod
= (bits
& 0xf80) >> 7;
3712 imm8
= (bits
& 0x07f) | 0x80;
3713 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
3715 func (stream
, "#%u", imm
);
3716 value_in_comment
= imm
;
3722 unsigned int imm
= 0;
3724 imm
|= (given
& 0x000000ffu
);
3725 imm
|= (given
& 0x00007000u
) >> 4;
3726 imm
|= (given
& 0x04000000u
) >> 15;
3727 imm
|= (given
& 0x000f0000u
) >> 4;
3728 func (stream
, "#%u", imm
);
3729 value_in_comment
= imm
;
3735 unsigned int imm
= 0;
3737 imm
|= (given
& 0x000f0000u
) >> 16;
3738 imm
|= (given
& 0x00000ff0u
) >> 0;
3739 imm
|= (given
& 0x0000000fu
) << 12;
3740 func (stream
, "#%u", imm
);
3741 value_in_comment
= imm
;
3747 unsigned int reg
= (given
& 0x0000000fu
);
3748 unsigned int stp
= (given
& 0x00000030u
) >> 4;
3749 unsigned int imm
= 0;
3750 imm
|= (given
& 0x000000c0u
) >> 6;
3751 imm
|= (given
& 0x00007000u
) >> 10;
3753 func (stream
, "%s", arm_regnames
[reg
]);
3758 func (stream
, ", lsl #%u", imm
);
3764 func (stream
, ", lsr #%u", imm
);
3770 func (stream
, ", asr #%u", imm
);
3775 func (stream
, ", rrx");
3777 func (stream
, ", ror #%u", imm
);
3784 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3785 unsigned int U
= ! NEGATIVE_BIT_SET
;
3786 unsigned int op
= (given
& 0x00000f00) >> 8;
3787 unsigned int i12
= (given
& 0x00000fff);
3788 unsigned int i8
= (given
& 0x000000ff);
3789 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
3792 func (stream
, "[%s", arm_regnames
[Rn
]);
3793 if (U
) /* 12-bit positive immediate offset. */
3797 value_in_comment
= offset
;
3799 else if (Rn
== 15) /* 12-bit negative immediate offset. */
3800 offset
= - (int) i12
;
3801 else if (op
== 0x0) /* Shifted register offset. */
3803 unsigned int Rm
= (i8
& 0x0f);
3804 unsigned int sh
= (i8
& 0x30) >> 4;
3806 func (stream
, ", %s", arm_regnames
[Rm
]);
3808 func (stream
, ", lsl #%u", sh
);
3814 case 0xE: /* 8-bit positive immediate offset. */
3818 case 0xC: /* 8-bit negative immediate offset. */
3822 case 0xF: /* 8-bit + preindex with wb. */
3827 case 0xD: /* 8-bit - preindex with wb. */
3832 case 0xB: /* 8-bit + postindex. */
3837 case 0x9: /* 8-bit - postindex. */
3843 func (stream
, ", <undefined>]");
3848 func (stream
, "], #%d", offset
);
3852 func (stream
, ", #%d", offset
);
3853 func (stream
, writeback
? "]!" : "]");
3858 func (stream
, "\t; ");
3859 info
->print_address_func (((pc
+ 4) & ~3) + offset
, info
);
3867 unsigned int U
= ! NEGATIVE_BIT_SET
;
3868 unsigned int W
= WRITEBACK_BIT_SET
;
3869 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3870 unsigned int off
= (given
& 0x000000ff);
3872 func (stream
, "[%s", arm_regnames
[Rn
]);
3878 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
3879 value_in_comment
= off
* 4 * U
? 1 : -1;
3887 func (stream
, "], ");
3890 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
3891 value_in_comment
= off
* 4 * U
? 1 : -1;
3895 func (stream
, "{%u}", off
);
3896 value_in_comment
= off
;
3904 unsigned int Sbit
= (given
& 0x01000000) >> 24;
3905 unsigned int type
= (given
& 0x00600000) >> 21;
3909 case 0: func (stream
, Sbit
? "sb" : "b"); break;
3910 case 1: func (stream
, Sbit
? "sh" : "h"); break;
3913 func (stream
, "??");
3916 func (stream
, "??");
3928 for (reg
= 0; reg
< 16; reg
++)
3929 if ((given
& (1 << reg
)) != 0)
3932 func (stream
, ", ");
3934 func (stream
, "%s", arm_regnames
[reg
]);
3942 unsigned int msb
= (given
& 0x0000001f);
3943 unsigned int lsb
= 0;
3945 lsb
|= (given
& 0x000000c0u
) >> 6;
3946 lsb
|= (given
& 0x00007000u
) >> 10;
3947 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
3953 unsigned int width
= (given
& 0x0000001f) + 1;
3954 unsigned int lsb
= 0;
3956 lsb
|= (given
& 0x000000c0u
) >> 6;
3957 lsb
|= (given
& 0x00007000u
) >> 10;
3958 func (stream
, "#%u, #%u", lsb
, width
);
3964 unsigned int S
= (given
& 0x04000000u
) >> 26;
3965 unsigned int J1
= (given
& 0x00002000u
) >> 13;
3966 unsigned int J2
= (given
& 0x00000800u
) >> 11;
3972 offset
|= (given
& 0x003f0000) >> 4;
3973 offset
|= (given
& 0x000007ff) << 1;
3974 offset
-= (1 << 20);
3976 info
->print_address_func (pc
+ 4 + offset
, info
);
3982 unsigned int S
= (given
& 0x04000000u
) >> 26;
3983 unsigned int I1
= (given
& 0x00002000u
) >> 13;
3984 unsigned int I2
= (given
& 0x00000800u
) >> 11;
3988 offset
|= !(I1
^ S
) << 23;
3989 offset
|= !(I2
^ S
) << 22;
3990 offset
|= (given
& 0x03ff0000u
) >> 4;
3991 offset
|= (given
& 0x000007ffu
) << 1;
3992 offset
-= (1 << 24);
3995 /* BLX target addresses are always word aligned. */
3996 if ((given
& 0x00001000u
) == 0)
3999 info
->print_address_func (offset
, info
);
4005 unsigned int shift
= 0;
4007 shift
|= (given
& 0x000000c0u
) >> 6;
4008 shift
|= (given
& 0x00007000u
) >> 10;
4009 if (WRITEBACK_BIT_SET
)
4010 func (stream
, ", asr #%u", shift
);
4012 func (stream
, ", lsl #%u", shift
);
4013 /* else print nothing - lsl #0 */
4019 unsigned int rot
= (given
& 0x00000030) >> 4;
4022 func (stream
, ", ror #%u", rot
* 8);
4027 if ((given
& 0xf0) == 0x60)
4029 switch (given
& 0xf)
4031 case 0xf: func (stream
, "sy"); break;
4033 func (stream
, "#%d", (int) given
& 0xf);
4039 switch (given
& 0xf)
4041 case 0xf: func (stream
, "sy"); break;
4042 case 0x7: func (stream
, "un"); break;
4043 case 0xe: func (stream
, "st"); break;
4044 case 0x6: func (stream
, "unst"); break;
4045 case 0xb: func (stream
, "ish"); break;
4046 case 0xa: func (stream
, "ishst"); break;
4047 case 0x3: func (stream
, "osh"); break;
4048 case 0x2: func (stream
, "oshst"); break;
4050 func (stream
, "#%d", (int) given
& 0xf);
4057 if ((given
& 0xff) == 0)
4059 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
4071 func (stream
, psr_name (given
& 0xff));
4076 if ((given
& 0xff) == 0)
4077 func (stream
, "%cPSR", (given
& 0x100000) ? 'S' : 'C');
4079 func (stream
, psr_name (given
& 0xff));
4082 case '0': case '1': case '2': case '3': case '4':
4083 case '5': case '6': case '7': case '8': case '9':
4088 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
4093 func (stream
, "%lu", val
);
4094 value_in_comment
= val
;
4098 func (stream
, "%lu", val
* 4);
4099 value_in_comment
= val
* 4;
4104 is_unpredictable
= TRUE
;
4107 func (stream
, "%s", arm_regnames
[val
]);
4111 func (stream
, "%s", arm_conditional
[val
]);
4116 if (val
== ((1ul << width
) - 1))
4117 func (stream
, "%c", *c
);
4123 func (stream
, "%c", *c
);
4127 func (stream
, "%c", c
[(1 << width
) - (int) val
]);
4132 func (stream
, "0x%lx", val
& 0xffffffffUL
);
4146 if (value_in_comment
> 32 || value_in_comment
< -16)
4147 func (stream
, "\t; 0x%lx", value_in_comment
);
4149 if (is_unpredictable
)
4150 func (stream
, UNPREDICTABLE_INSTRUCTION
);
4159 /* Print data bytes on INFO->STREAM. */
4162 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
4163 struct disassemble_info
*info
,
4166 switch (info
->bytes_per_chunk
)
4169 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
4172 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
4175 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
4182 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4183 being displayed in symbol relative addresses. */
4186 arm_symbol_is_valid (asymbol
* sym
,
4187 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
4194 name
= bfd_asymbol_name (sym
);
4196 return (name
&& *name
!= '$');
4199 /* Parse an individual disassembler option. */
4202 parse_arm_disassembler_option (char *option
)
4207 if (CONST_STRNEQ (option
, "reg-names-"))
4213 for (i
= NUM_ARM_REGNAMES
; i
--;)
4214 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
4216 regname_selected
= i
;
4221 /* XXX - should break 'option' at following delimiter. */
4222 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
4224 else if (CONST_STRNEQ (option
, "force-thumb"))
4226 else if (CONST_STRNEQ (option
, "no-force-thumb"))
4229 /* XXX - should break 'option' at following delimiter. */
4230 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
4235 /* Parse the string of disassembler options, spliting it at whitespaces
4236 or commas. (Whitespace separators supported for backwards compatibility). */
4239 parse_disassembler_options (char *options
)
4241 if (options
== NULL
)
4246 parse_arm_disassembler_option (options
);
4248 /* Skip forward to next seperator. */
4249 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
4251 /* Skip forward past seperators. */
4252 while (ISSPACE (*options
) || (*options
== ','))
4257 /* Search back through the insn stream to determine if this instruction is
4258 conditionally executed. */
4261 find_ifthen_state (bfd_vma pc
,
4262 struct disassemble_info
*info
,
4268 /* COUNT is twice the number of instructions seen. It will be odd if we
4269 just crossed an instruction boundary. */
4272 unsigned int seen_it
;
4275 ifthen_address
= pc
;
4282 /* Scan backwards looking for IT instructions, keeping track of where
4283 instruction boundaries are. We don't know if something is actually an
4284 IT instruction until we find a definite instruction boundary. */
4287 if (addr
== 0 || info
->symbol_at_address_func (addr
, info
))
4289 /* A symbol must be on an instruction boundary, and will not
4290 be within an IT block. */
4291 if (seen_it
&& (count
& 1))
4297 status
= info
->read_memory_func (addr
, (bfd_byte
*) b
, 2, info
);
4302 insn
= (b
[0]) | (b
[1] << 8);
4304 insn
= (b
[1]) | (b
[0] << 8);
4307 if ((insn
& 0xf800) < 0xe800)
4309 /* Addr + 2 is an instruction boundary. See if this matches
4310 the expected boundary based on the position of the last
4317 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4319 /* This could be an IT instruction. */
4321 it_count
= count
>> 1;
4323 if ((insn
& 0xf800) >= 0xe800)
4326 count
= (count
+ 2) | 1;
4327 /* IT blocks contain at most 4 instructions. */
4328 if (count
>= 8 && !seen_it
)
4331 /* We found an IT instruction. */
4332 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4333 if ((ifthen_state
& 0xf) == 0)
4337 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4341 is_mapping_symbol (struct disassemble_info
*info
, int n
,
4342 enum map_type
*map_type
)
4346 name
= bfd_asymbol_name (info
->symtab
[n
]);
4347 if (name
[0] == '$' && (name
[1] == 'a' || name
[1] == 't' || name
[1] == 'd')
4348 && (name
[2] == 0 || name
[2] == '.'))
4350 *map_type
= ((name
[1] == 'a') ? MAP_ARM
4351 : (name
[1] == 't') ? MAP_THUMB
4359 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4360 Returns nonzero if *MAP_TYPE was set. */
4363 get_map_sym_type (struct disassemble_info
*info
,
4365 enum map_type
*map_type
)
4367 /* If the symbol is in a different section, ignore it. */
4368 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4371 return is_mapping_symbol (info
, n
, map_type
);
4374 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4375 Returns nonzero if *MAP_TYPE was set. */
4378 get_sym_code_type (struct disassemble_info
*info
,
4380 enum map_type
*map_type
)
4382 elf_symbol_type
*es
;
4385 /* If the symbol is in a different section, ignore it. */
4386 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4389 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
4390 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4392 /* If the symbol has function type then use that. */
4393 if (type
== STT_FUNC
|| type
== STT_ARM_TFUNC
)
4395 *map_type
= (type
== STT_ARM_TFUNC
) ? MAP_THUMB
: MAP_ARM
;
4402 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4403 of the supplied arm_feature_set structure with bitmasks indicating
4404 the support base architectures and coprocessor extensions.
4406 FIXME: This could more efficiently implemented as a constant array,
4407 although it would also be less robust. */
4410 select_arm_features (unsigned long mach
,
4411 arm_feature_set
* features
)
4414 #define ARM_FEATURE(ARCH,CEXT) \
4415 features->core = (ARCH); \
4416 features->coproc = (CEXT) | FPU_FPA; \
4421 case bfd_mach_arm_2
: ARM_ARCH_V2
;
4422 case bfd_mach_arm_2a
: ARM_ARCH_V2S
;
4423 case bfd_mach_arm_3
: ARM_ARCH_V3
;
4424 case bfd_mach_arm_3M
: ARM_ARCH_V3M
;
4425 case bfd_mach_arm_4
: ARM_ARCH_V4
;
4426 case bfd_mach_arm_4T
: ARM_ARCH_V4T
;
4427 case bfd_mach_arm_5
: ARM_ARCH_V5
;
4428 case bfd_mach_arm_5T
: ARM_ARCH_V5T
;
4429 case bfd_mach_arm_5TE
: ARM_ARCH_V5TE
;
4430 case bfd_mach_arm_XScale
: ARM_ARCH_XSCALE
;
4431 case bfd_mach_arm_ep9312
: ARM_FEATURE (ARM_AEXT_V4T
, ARM_CEXT_MAVERICK
| FPU_MAVERICK
);
4432 case bfd_mach_arm_iWMMXt
: ARM_ARCH_IWMMXT
;
4433 case bfd_mach_arm_iWMMXt2
: ARM_ARCH_IWMMXT2
;
4434 /* If the machine type is unknown allow all
4435 architecture types and all extensions. */
4436 case bfd_mach_arm_unknown
: ARM_FEATURE (-1UL, -1UL);
4443 /* NOTE: There are no checks in these routines that
4444 the relevant number of data bytes exist. */
4447 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4452 int is_thumb
= FALSE
;
4453 int is_data
= FALSE
;
4455 unsigned int size
= 4;
4456 void (*printer
) (bfd_vma
, struct disassemble_info
*, long);
4457 bfd_boolean found
= FALSE
;
4458 struct arm_private_data
*private_data
;
4460 if (info
->disassembler_options
)
4462 parse_disassembler_options (info
->disassembler_options
);
4464 /* To avoid repeated parsing of these options, we remove them here. */
4465 info
->disassembler_options
= NULL
;
4468 /* PR 10288: Control which instructions will be disassembled. */
4469 if (info
->private_data
== NULL
)
4471 static struct arm_private_data
private;
4473 if ((info
->flags
& USER_SPECIFIED_MACHINE_TYPE
) == 0)
4474 /* If the user did not use the -m command line switch then default to
4475 disassembling all types of ARM instruction.
4477 The info->mach value has to be ignored as this will be based on
4478 the default archictecture for the target and/or hints in the notes
4479 section, but it will never be greater than the current largest arm
4480 machine value (iWMMXt2), which is only equivalent to the V5TE
4481 architecture. ARM architectures have advanced beyond the machine
4482 value encoding, and these newer architectures would be ignored if
4483 the machine value was used.
4485 Ie the -m switch is used to restrict which instructions will be
4486 disassembled. If it is necessary to use the -m switch to tell
4487 objdump that an ARM binary is being disassembled, eg because the
4488 input is a raw binary file, but it is also desired to disassemble
4489 all ARM instructions then use "-marm". This will select the
4490 "unknown" arm architecture which is compatible with any ARM
4492 info
->mach
= bfd_mach_arm_unknown
;
4494 /* Compute the architecture bitmask from the machine number.
4495 Note: This assumes that the machine number will not change
4496 during disassembly.... */
4497 select_arm_features (info
->mach
, & private.features
);
4499 private.has_mapping_symbols
= -1;
4501 info
->private_data
= & private;
4504 private_data
= info
->private_data
;
4506 /* Decide if our code is going to be little-endian, despite what the
4507 function argument might say. */
4508 little_code
= ((info
->endian_code
== BFD_ENDIAN_LITTLE
) || little
);
4510 /* For ELF, consult the symbol table to determine what kind of code
4512 if (info
->symtab_size
!= 0
4513 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4518 enum map_type type
= MAP_ARM
;
4520 /* Start scanning at the start of the function, or wherever
4521 we finished last time. */
4522 start
= info
->symtab_pos
+ 1;
4523 if (start
< last_mapping_sym
)
4524 start
= last_mapping_sym
;
4527 /* First, look for mapping symbols. */
4528 if (private_data
->has_mapping_symbols
!= 0)
4530 /* Scan up to the location being disassembled. */
4531 for (n
= start
; n
< info
->symtab_size
; n
++)
4533 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4536 if (get_map_sym_type (info
, n
, &type
))
4545 /* No mapping symbol found at this address. Look backwards
4546 for a preceeding one. */
4547 for (n
= start
- 1; n
>= 0; n
--)
4549 if (get_map_sym_type (info
, n
, &type
))
4559 private_data
->has_mapping_symbols
= 1;
4561 /* No mapping symbols were found. A leading $d may be
4562 omitted for sections which start with data; but for
4563 compatibility with legacy and stripped binaries, only
4564 assume the leading $d if there is at least one mapping
4565 symbol in the file. */
4566 if (!found
&& private_data
->has_mapping_symbols
== -1)
4568 /* Look for mapping symbols, in any section. */
4569 for (n
= 0; n
< info
->symtab_size
; n
++)
4570 if (is_mapping_symbol (info
, n
, &type
))
4572 private_data
->has_mapping_symbols
= 1;
4575 if (private_data
->has_mapping_symbols
== -1)
4576 private_data
->has_mapping_symbols
= 0;
4579 if (!found
&& private_data
->has_mapping_symbols
== 1)
4586 /* Next search for function symbols to separate ARM from Thumb
4587 in binaries without mapping symbols. */
4590 /* Scan up to the location being disassembled. */
4591 for (n
= start
; n
< info
->symtab_size
; n
++)
4593 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4596 if (get_sym_code_type (info
, n
, &type
))
4605 /* No mapping symbol found at this address. Look backwards
4606 for a preceeding one. */
4607 for (n
= start
- 1; n
>= 0; n
--)
4609 if (get_sym_code_type (info
, n
, &type
))
4619 last_mapping_sym
= last_sym
;
4621 is_thumb
= (last_type
== MAP_THUMB
);
4622 is_data
= (last_type
== MAP_DATA
);
4624 /* Look a little bit ahead to see if we should print out
4625 two or four bytes of data. If there's a symbol,
4626 mapping or otherwise, after two bytes then don't
4630 size
= 4 - (pc
& 3);
4631 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4633 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4635 && (info
->section
== NULL
4636 || info
->section
== info
->symtab
[n
]->section
))
4638 if (addr
- pc
< size
)
4643 /* If the next symbol is after three bytes, we need to
4644 print only part of the data, so that we can use either
4647 size
= (pc
& 1) ? 1 : 2;
4651 if (info
->symbols
!= NULL
)
4653 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4655 coff_symbol_type
* cs
;
4657 cs
= coffsymbol (*info
->symbols
);
4658 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4659 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4660 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4661 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4662 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4664 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
4667 /* If no mapping symbol has been found then fall back to the type
4668 of the function symbol. */
4669 elf_symbol_type
* es
;
4672 es
= *(elf_symbol_type
**)(info
->symbols
);
4673 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4675 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
4683 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4685 info
->display_endian
= little_code
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4687 info
->bytes_per_line
= 4;
4689 /* PR 10263: Disassemble data if requested to do so by the user. */
4690 if (is_data
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
4694 /* Size was already set above. */
4695 info
->bytes_per_chunk
= size
;
4696 printer
= print_insn_data
;
4698 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, size
, info
);
4701 for (i
= size
- 1; i
>= 0; i
--)
4702 given
= b
[i
] | (given
<< 8);
4704 for (i
= 0; i
< (int) size
; i
++)
4705 given
= b
[i
] | (given
<< 8);
4709 /* In ARM mode endianness is a straightforward issue: the instruction
4710 is four bytes long and is either ordered 0123 or 3210. */
4711 printer
= print_insn_arm
;
4712 info
->bytes_per_chunk
= 4;
4715 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 4, info
);
4717 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
4719 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
4723 /* In Thumb mode we have the additional wrinkle of two
4724 instruction lengths. Fortunately, the bits that determine
4725 the length of the current instruction are always to be found
4726 in the first two bytes. */
4727 printer
= print_insn_thumb16
;
4728 info
->bytes_per_chunk
= 2;
4731 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
4733 given
= (b
[0]) | (b
[1] << 8);
4735 given
= (b
[1]) | (b
[0] << 8);
4739 /* These bit patterns signal a four-byte Thumb
4741 if ((given
& 0xF800) == 0xF800
4742 || (given
& 0xF800) == 0xF000
4743 || (given
& 0xF800) == 0xE800)
4745 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) b
, 2, info
);
4747 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
4749 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
4751 printer
= print_insn_thumb32
;
4756 if (ifthen_address
!= pc
)
4757 find_ifthen_state (pc
, info
, little_code
);
4761 if ((ifthen_state
& 0xf) == 0x8)
4762 ifthen_next_state
= 0;
4764 ifthen_next_state
= (ifthen_state
& 0xe0)
4765 | ((ifthen_state
& 0xf) << 1);
4771 info
->memory_error_func (status
, pc
, info
);
4774 if (info
->flags
& INSN_HAS_RELOC
)
4775 /* If the instruction has a reloc associated with it, then
4776 the offset field in the instruction will actually be the
4777 addend for the reloc. (We are using REL type relocs).
4778 In such cases, we can ignore the pc when computing
4779 addresses, since the addend is not currently pc-relative. */
4782 printer (pc
, info
, given
);
4786 ifthen_state
= ifthen_next_state
;
4787 ifthen_address
+= size
;
4793 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
4795 /* Detect BE8-ness and record it in the disassembler info. */
4796 if (info
->flavour
== bfd_target_elf_flavour
4797 && info
->section
!= NULL
4798 && (elf_elfheader (info
->section
->owner
)->e_flags
& EF_ARM_BE8
))
4799 info
->endian_code
= BFD_ENDIAN_LITTLE
;
4801 return print_insn (pc
, info
, FALSE
);
4805 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
4807 return print_insn (pc
, info
, TRUE
);
4811 print_arm_disassembler_options (FILE *stream
)
4815 fprintf (stream
, _("\n\
4816 The following ARM specific disassembler options are supported for use with\n\
4817 the -M switch:\n"));
4819 for (i
= NUM_ARM_REGNAMES
; i
--;)
4820 fprintf (stream
, " reg-names-%s %*c%s\n",
4822 (int)(14 - strlen (regnames
[i
].name
)), ' ',
4823 regnames
[i
].description
);
4825 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
4826 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");