1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
27 #include "opcode/arm.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
32 /* FIXME: This shouldn't be done here. */
33 #include "coff/internal.h"
36 #include "elf/internal.h"
39 /* FIXME: Belongs in global header. */
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
48 struct arm_private_data
50 /* The features to use when disassembling optional instructions. */
51 arm_feature_set features
;
53 /* Whether any mapping symbols are present in the provided symbol
54 table. -1 if we do not know yet, otherwise 0 or 1. */
55 int has_mapping_symbols
;
60 unsigned long arch
; /* Architecture defining this insn. */
61 unsigned long value
; /* If arch == 0 then value is a sentinel. */
62 unsigned long mask
; /* Recognise insn if (op & mask) == value. */
63 const char * assembler
; /* How to disassemble this insn. */
68 unsigned long arch
; /* Architecture defining this insn. */
69 unsigned short value
, mask
; /* Recognise insn if (op & mask) == value. */
70 const char *assembler
; /* How to disassemble this insn. */
73 /* print_insn_coprocessor recognizes the following format control codes:
77 %c print condition code (always bits 28-31 in ARM mode)
78 %q print shifter argument
79 %u print condition code (unconditional in ARM mode)
80 %A print address for ldc/stc/ldf/stf instruction
81 %B print vstm/vldm register list
82 %I print cirrus signed shift immediate: bits 0..3|4..6
83 %F print the COUNT field of a LFM/SFM instruction.
84 %P print floating point precision in arithmetic insn
85 %Q print floating point precision in ldf/stf insn
86 %R print floating point rounding mode
88 %<bitfield>r print as an ARM register
89 %<bitfield>R as %<>r but r15 is UNPREDICTABLE
90 %<bitfield>ru as %<>r but each u register must be unique.
91 %<bitfield>d print the bitfield in decimal
92 %<bitfield>k print immediate for VFPv3 conversion instruction
93 %<bitfield>x print the bitfield in hex
94 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
95 %<bitfield>f print a floating point constant if >7 else a
96 floating point register
97 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
98 %<bitfield>g print as an iWMMXt 64-bit register
99 %<bitfield>G print as an iWMMXt general purpose or control register
100 %<bitfield>D print as a NEON D register
101 %<bitfield>Q print as a NEON Q register
103 %y<code> print a single precision VFP reg.
104 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
105 %z<code> print a double precision VFP reg
106 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
108 %<bitfield>'c print specified char iff bitfield is all ones
109 %<bitfield>`c print specified char iff bitfield is all zeroes
110 %<bitfield>?ab... select from array of values in big endian order
112 %L print as an iWMMXt N/M width field.
113 %Z print the Immediate of a WSHUFH instruction.
114 %l like 'A' except use byte offsets for 'B' & 'H'
116 %i print 5-bit immediate in bits 8,3..0
118 %r print register offset address for wldt/wstr instruction. */
120 enum opcode_sentinel_enum
122 SENTINEL_IWMMXT_START
= 1,
124 SENTINEL_GENERIC_START
127 #define UNDEFINED_INSTRUCTION "\t\t; <UNDEFINED> instruction: %0-31x"
128 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
130 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
132 static const struct opcode32 coprocessor_opcodes
[] =
134 /* XScale instructions. */
135 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
136 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
137 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
138 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
139 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
141 /* Intel Wireless MMX technology instructions. */
142 { 0, SENTINEL_IWMMXT_START
, 0, "" },
143 {ARM_CEXT_IWMMXT
, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
144 {ARM_CEXT_XSCALE
, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
145 {ARM_CEXT_XSCALE
, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
146 {ARM_CEXT_XSCALE
, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
147 {ARM_CEXT_XSCALE
, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
148 {ARM_CEXT_XSCALE
, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
149 {ARM_CEXT_XSCALE
, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
150 {ARM_CEXT_XSCALE
, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
151 {ARM_CEXT_XSCALE
, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
152 {ARM_CEXT_XSCALE
, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
153 {ARM_CEXT_XSCALE
, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
154 {ARM_CEXT_XSCALE
, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
155 {ARM_CEXT_XSCALE
, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
156 {ARM_CEXT_XSCALE
, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
157 {ARM_CEXT_XSCALE
, 0x0e120190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
158 {ARM_CEXT_XSCALE
, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
159 {ARM_CEXT_XSCALE
, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
160 {ARM_CEXT_XSCALE
, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
161 {ARM_CEXT_XSCALE
, 0x0e2001a0, 0x0fb00ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
162 {ARM_CEXT_XSCALE
, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
163 {ARM_CEXT_XSCALE
, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
164 {ARM_CEXT_XSCALE
, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
165 {ARM_CEXT_XSCALE
, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
166 {ARM_CEXT_XSCALE
, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
167 {ARM_CEXT_XSCALE
, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
168 {ARM_CEXT_XSCALE
, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
169 {ARM_CEXT_XSCALE
, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
170 {ARM_CEXT_XSCALE
, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
171 {ARM_CEXT_XSCALE
, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
172 {ARM_CEXT_XSCALE
, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
173 {ARM_CEXT_XSCALE
, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
174 {ARM_CEXT_XSCALE
, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
175 {ARM_CEXT_XSCALE
, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
176 {ARM_CEXT_XSCALE
, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
177 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
178 {ARM_CEXT_XSCALE
, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
179 {ARM_CEXT_XSCALE
, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
180 {ARM_CEXT_XSCALE
, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
181 {ARM_CEXT_XSCALE
, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE
, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
183 {ARM_CEXT_XSCALE
, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
184 {ARM_CEXT_XSCALE
, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
185 {ARM_CEXT_XSCALE
, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
186 {ARM_CEXT_XSCALE
, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
187 {ARM_CEXT_XSCALE
, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
188 {ARM_CEXT_XSCALE
, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE
, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
190 {ARM_CEXT_XSCALE
, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
191 {ARM_CEXT_XSCALE
, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
192 {ARM_CEXT_XSCALE
, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
193 {ARM_CEXT_XSCALE
, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
194 {ARM_CEXT_XSCALE
, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE
, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
196 {ARM_CEXT_XSCALE
, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
197 {ARM_CEXT_XSCALE
, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
198 {ARM_CEXT_XSCALE
, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
199 {ARM_CEXT_XSCALE
, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
200 {ARM_CEXT_XSCALE
, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
201 {ARM_CEXT_XSCALE
, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
202 {ARM_CEXT_XSCALE
, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
203 {ARM_CEXT_XSCALE
, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
204 {ARM_CEXT_XSCALE
, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
205 {ARM_CEXT_XSCALE
, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
206 {ARM_CEXT_XSCALE
, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
207 {ARM_CEXT_XSCALE
, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
208 {ARM_CEXT_XSCALE
, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
209 {ARM_CEXT_XSCALE
, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
210 {ARM_CEXT_XSCALE
, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
211 {ARM_CEXT_XSCALE
, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
212 {ARM_CEXT_XSCALE
, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
213 {ARM_CEXT_XSCALE
, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
214 {ARM_CEXT_XSCALE
, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
215 {ARM_CEXT_XSCALE
, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
216 {ARM_CEXT_XSCALE
, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
217 {ARM_CEXT_XSCALE
, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
218 { 0, SENTINEL_IWMMXT_END
, 0, "" },
220 /* Floating point coprocessor (FPA) instructions. */
221 {FPU_FPA_EXT_V1
, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
222 {FPU_FPA_EXT_V1
, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
223 {FPU_FPA_EXT_V1
, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
224 {FPU_FPA_EXT_V1
, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
225 {FPU_FPA_EXT_V1
, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
226 {FPU_FPA_EXT_V1
, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
227 {FPU_FPA_EXT_V1
, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
228 {FPU_FPA_EXT_V1
, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
229 {FPU_FPA_EXT_V1
, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
230 {FPU_FPA_EXT_V1
, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
231 {FPU_FPA_EXT_V1
, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
232 {FPU_FPA_EXT_V1
, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
233 {FPU_FPA_EXT_V1
, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
234 {FPU_FPA_EXT_V1
, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
235 {FPU_FPA_EXT_V1
, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
236 {FPU_FPA_EXT_V1
, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
237 {FPU_FPA_EXT_V1
, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
238 {FPU_FPA_EXT_V1
, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
239 {FPU_FPA_EXT_V1
, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
240 {FPU_FPA_EXT_V1
, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
241 {FPU_FPA_EXT_V1
, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
242 {FPU_FPA_EXT_V1
, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
243 {FPU_FPA_EXT_V1
, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
244 {FPU_FPA_EXT_V1
, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
245 {FPU_FPA_EXT_V1
, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
246 {FPU_FPA_EXT_V1
, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
247 {FPU_FPA_EXT_V1
, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
248 {FPU_FPA_EXT_V1
, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
249 {FPU_FPA_EXT_V1
, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
250 {FPU_FPA_EXT_V1
, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
251 {FPU_FPA_EXT_V1
, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
252 {FPU_FPA_EXT_V1
, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
253 {FPU_FPA_EXT_V1
, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
254 {FPU_FPA_EXT_V1
, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
255 {FPU_FPA_EXT_V1
, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
256 {FPU_FPA_EXT_V1
, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
257 {FPU_FPA_EXT_V1
, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
258 {FPU_FPA_EXT_V1
, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
259 {FPU_FPA_EXT_V1
, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
260 {FPU_FPA_EXT_V1
, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
261 {FPU_FPA_EXT_V1
, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
262 {FPU_FPA_EXT_V2
, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
263 {FPU_FPA_EXT_V2
, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
265 /* Register load/store. */
266 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d2d0b00, 0x0fbf0f01, "vpush%c\t%B"},
267 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r!, %B"},
268 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r!, %B"},
269 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
270 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0cbd0b00, 0x0fbf0f01, "vpop%c\t%B"},
271 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
272 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %A"},
273 {FPU_VFP_EXT_V1xD
| FPU_NEON_EXT_V1
, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
274 {FPU_VFP_EXT_V1xD
, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
275 {FPU_VFP_EXT_V1xD
, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
276 {FPU_VFP_EXT_V1xD
, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
277 {FPU_VFP_EXT_V1xD
, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
278 {FPU_VFP_EXT_V1xD
, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
279 {FPU_VFP_EXT_V1xD
, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
280 {FPU_VFP_EXT_V1xD
, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
281 {FPU_VFP_EXT_V1xD
, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
283 {FPU_VFP_EXT_V1xD
, 0x0d200b01, 0x0fb00f01, "fstmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
284 {FPU_VFP_EXT_V1xD
, 0x0d300b01, 0x0fb00f01, "fldmdbx%c\t%16-19r!, %z3\t;@ Deprecated"},
285 {FPU_VFP_EXT_V1xD
, 0x0c800b01, 0x0f900f01, "fstmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
286 {FPU_VFP_EXT_V1xD
, 0x0c900b01, 0x0f900f01, "fldmiax%c\t%16-19r%21'!, %z3\t;@ Deprecated"},
288 /* Data transfer between ARM and NEON registers. */
289 {FPU_NEON_EXT_V1
, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
290 {FPU_NEON_EXT_V1
, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
291 {FPU_NEON_EXT_V1
, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
292 {FPU_NEON_EXT_V1
, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
293 {FPU_NEON_EXT_V1
, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
294 {FPU_NEON_EXT_V1
, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
295 {FPU_NEON_EXT_V1
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
296 {FPU_NEON_EXT_V1
, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
297 {FPU_NEON_EXT_V1
, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
298 {FPU_NEON_EXT_V1
, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
299 {FPU_NEON_EXT_V1
, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
300 {FPU_NEON_EXT_V1
, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
301 {FPU_NEON_EXT_V1
, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
302 {FPU_NEON_EXT_V1
, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
303 /* Half-precision conversion instructions. */
304 {FPU_VFP_EXT_FP16
, 0x0eb20a40, 0x0fbf0f50, "vcvt%7?tb%c.f32.f16\t%y1, %y0"},
305 {FPU_VFP_EXT_FP16
, 0x0eb30a40, 0x0fbf0f50, "vcvt%7?tb%c.f16.f32\t%y1, %y0"},
307 /* Floating point coprocessor (VFP) instructions. */
308 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0fff0fff, "vmsr%c\tfpsid, %12-15r"},
309 {FPU_VFP_EXT_V1xD
, 0x0ee10a10, 0x0fff0fff, "vmsr%c\tfpscr, %12-15r"},
310 {FPU_VFP_EXT_V1xD
, 0x0ee60a10, 0x0fff0fff, "vmsr%c\tmvfr1, %12-15r"},
311 {FPU_VFP_EXT_V1xD
, 0x0ee70a10, 0x0fff0fff, "vmsr%c\tmvfr0, %12-15r"},
312 {FPU_VFP_EXT_V1xD
, 0x0ee80a10, 0x0fff0fff, "vmsr%c\tfpexc, %12-15r"},
313 {FPU_VFP_EXT_V1xD
, 0x0ee90a10, 0x0fff0fff, "vmsr%c\tfpinst, %12-15r\t@ Impl def"},
314 {FPU_VFP_EXT_V1xD
, 0x0eea0a10, 0x0fff0fff, "vmsr%c\tfpinst2, %12-15r\t@ Impl def"},
315 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpsid"},
316 {FPU_VFP_EXT_V1xD
, 0x0ef1fa10, 0x0fffffff, "vmrs%c\tAPSR_nzcv, fpscr"},
317 {FPU_VFP_EXT_V1xD
, 0x0ef10a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpscr"},
318 {FPU_VFP_EXT_V1xD
, 0x0ef60a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr1"},
319 {FPU_VFP_EXT_V1xD
, 0x0ef70a10, 0x0fff0fff, "vmrs%c\t%12-15r, mvfr0"},
320 {FPU_VFP_EXT_V1xD
, 0x0ef80a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpexc"},
321 {FPU_VFP_EXT_V1xD
, 0x0ef90a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst\t@ Impl def"},
322 {FPU_VFP_EXT_V1xD
, 0x0efa0a10, 0x0fff0fff, "vmrs%c\t%12-15r, fpinst2\t@ Impl def"},
323 {FPU_VFP_EXT_V1
, 0x0e000b10, 0x0fd00fff, "vmov%c.32\t%z2[%21d], %12-15r"},
324 {FPU_VFP_EXT_V1
, 0x0e100b10, 0x0fd00fff, "vmov%c.32\t%12-15r, %z2[%21d]"},
325 {FPU_VFP_EXT_V1xD
, 0x0ee00a10, 0x0ff00fff, "vmsr%c\t<impl def %16-19x>, %12-15r"},
326 {FPU_VFP_EXT_V1xD
, 0x0ef00a10, 0x0ff00fff, "vmrs%c\t%12-15r, <impl def %16-19x>"},
327 {FPU_VFP_EXT_V1xD
, 0x0e000a10, 0x0ff00f7f, "vmov%c\t%y2, %12-15r"},
328 {FPU_VFP_EXT_V1xD
, 0x0e100a10, 0x0ff00f7f, "vmov%c\t%12-15r, %y2"},
329 {FPU_VFP_EXT_V1xD
, 0x0eb50a40, 0x0fbf0f70, "vcmp%7'e%c.f32\t%y1, #0.0"},
330 {FPU_VFP_EXT_V1
, 0x0eb50b40, 0x0fbf0f70, "vcmp%7'e%c.f64\t%z1, #0.0"},
331 {FPU_VFP_EXT_V1xD
, 0x0eb00a40, 0x0fbf0fd0, "vmov%c.f32\t%y1, %y0"},
332 {FPU_VFP_EXT_V1xD
, 0x0eb00ac0, 0x0fbf0fd0, "vabs%c.f32\t%y1, %y0"},
333 {FPU_VFP_EXT_V1
, 0x0eb00b40, 0x0fbf0fd0, "vmov%c.f64\t%z1, %z0"},
334 {FPU_VFP_EXT_V1
, 0x0eb00bc0, 0x0fbf0fd0, "vabs%c.f64\t%z1, %z0"},
335 {FPU_VFP_EXT_V1xD
, 0x0eb10a40, 0x0fbf0fd0, "vneg%c.f32\t%y1, %y0"},
336 {FPU_VFP_EXT_V1xD
, 0x0eb10ac0, 0x0fbf0fd0, "vsqrt%c.f32\t%y1, %y0"},
337 {FPU_VFP_EXT_V1
, 0x0eb10b40, 0x0fbf0fd0, "vneg%c.f64\t%z1, %z0"},
338 {FPU_VFP_EXT_V1
, 0x0eb10bc0, 0x0fbf0fd0, "vsqrt%c.f64\t%z1, %z0"},
339 {FPU_VFP_EXT_V1
, 0x0eb70ac0, 0x0fbf0fd0, "vcvt%c.f64.f32\t%z1, %y0"},
340 {FPU_VFP_EXT_V1
, 0x0eb70bc0, 0x0fbf0fd0, "vcvt%c.f32.f64\t%y1, %z0"},
341 {FPU_VFP_EXT_V1xD
, 0x0eb80a40, 0x0fbf0f50, "vcvt%c.f32.%7?su32\t%y1, %y0"},
342 {FPU_VFP_EXT_V1
, 0x0eb80b40, 0x0fbf0f50, "vcvt%c.f64.%7?su32\t%z1, %y0"},
343 {FPU_VFP_EXT_V1xD
, 0x0eb40a40, 0x0fbf0f50, "vcmp%7'e%c.f32\t%y1, %y0"},
344 {FPU_VFP_EXT_V1
, 0x0eb40b40, 0x0fbf0f50, "vcmp%7'e%c.f64\t%z1, %z0"},
345 {FPU_VFP_EXT_V3xD
, 0x0eba0a40, 0x0fbe0f50, "vcvt%c.f32.%16?us%7?31%7?26\t%y1, %y1, #%5,0-3k"},
346 {FPU_VFP_EXT_V3
, 0x0eba0b40, 0x0fbe0f50, "vcvt%c.f64.%16?us%7?31%7?26\t%z1, %z1, #%5,0-3k"},
347 {FPU_VFP_EXT_V1xD
, 0x0ebc0a40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f32\t%y1, %y0"},
348 {FPU_VFP_EXT_V1
, 0x0ebc0b40, 0x0fbe0f50, "vcvt%7`r%c.%16?su32.f64\t%y1, %z0"},
349 {FPU_VFP_EXT_V3xD
, 0x0ebe0a40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f32\t%y1, %y1, #%5,0-3k"},
350 {FPU_VFP_EXT_V3
, 0x0ebe0b40, 0x0fbe0f50, "vcvt%c.%16?us%7?31%7?26.f64\t%z1, %z1, #%5,0-3k"},
351 {FPU_VFP_EXT_V1
, 0x0c500b10, 0x0fb00ff0, "vmov%c\t%12-15r, %16-19r, %z0"},
352 {FPU_VFP_EXT_V3xD
, 0x0eb00a00, 0x0fb00ff0, "vmov%c.f32\t%y1, #%0-3,16-19d"},
353 {FPU_VFP_EXT_V3
, 0x0eb00b00, 0x0fb00ff0, "vmov%c.f64\t%z1, #%0-3,16-19d"},
354 {FPU_VFP_EXT_V2
, 0x0c400a10, 0x0ff00fd0, "vmov%c\t%y4, %12-15r, %16-19r"},
355 {FPU_VFP_EXT_V2
, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%z0, %12-15r, %16-19r"},
356 {FPU_VFP_EXT_V2
, 0x0c500a10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %y4"},
357 {FPU_VFP_EXT_V1xD
, 0x0e000a00, 0x0fb00f50, "vmla%c.f32\t%y1, %y2, %y0"},
358 {FPU_VFP_EXT_V1xD
, 0x0e000a40, 0x0fb00f50, "vmls%c.f32\t%y1, %y2, %y0"},
359 {FPU_VFP_EXT_V1
, 0x0e000b00, 0x0fb00f50, "vmla%c.f64\t%z1, %z2, %z0"},
360 {FPU_VFP_EXT_V1
, 0x0e000b40, 0x0fb00f50, "vmls%c.f64\t%z1, %z2, %z0"},
361 {FPU_VFP_EXT_V1xD
, 0x0e100a00, 0x0fb00f50, "vnmls%c.f32\t%y1, %y2, %y0"},
362 {FPU_VFP_EXT_V1xD
, 0x0e100a40, 0x0fb00f50, "vnmla%c.f32\t%y1, %y2, %y0"},
363 {FPU_VFP_EXT_V1
, 0x0e100b00, 0x0fb00f50, "vnmls%c.f64\t%z1, %z2, %z0"},
364 {FPU_VFP_EXT_V1
, 0x0e100b40, 0x0fb00f50, "vnmla%c.f64\t%z1, %z2, %z0"},
365 {FPU_VFP_EXT_V1xD
, 0x0e200a00, 0x0fb00f50, "vmul%c.f32\t%y1, %y2, %y0"},
366 {FPU_VFP_EXT_V1xD
, 0x0e200a40, 0x0fb00f50, "vnmul%c.f32\t%y1, %y2, %y0"},
367 {FPU_VFP_EXT_V1
, 0x0e200b00, 0x0fb00f50, "vmul%c.f64\t%z1, %z2, %z0"},
368 {FPU_VFP_EXT_V1
, 0x0e200b40, 0x0fb00f50, "vnmul%c.f64\t%z1, %z2, %z0"},
369 {FPU_VFP_EXT_V1xD
, 0x0e300a00, 0x0fb00f50, "vadd%c.f32\t%y1, %y2, %y0"},
370 {FPU_VFP_EXT_V1xD
, 0x0e300a40, 0x0fb00f50, "vsub%c.f32\t%y1, %y2, %y0"},
371 {FPU_VFP_EXT_V1
, 0x0e300b00, 0x0fb00f50, "vadd%c.f64\t%z1, %z2, %z0"},
372 {FPU_VFP_EXT_V1
, 0x0e300b40, 0x0fb00f50, "vsub%c.f64\t%z1, %z2, %z0"},
373 {FPU_VFP_EXT_V1xD
, 0x0e800a00, 0x0fb00f50, "vdiv%c.f32\t%y1, %y2, %y0"},
374 {FPU_VFP_EXT_V1
, 0x0e800b00, 0x0fb00f50, "vdiv%c.f64\t%z1, %z2, %z0"},
376 /* Cirrus coprocessor instructions. */
377 {ARM_CEXT_MAVERICK
, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
378 {ARM_CEXT_MAVERICK
, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
379 {ARM_CEXT_MAVERICK
, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
380 {ARM_CEXT_MAVERICK
, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
381 {ARM_CEXT_MAVERICK
, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
382 {ARM_CEXT_MAVERICK
, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
383 {ARM_CEXT_MAVERICK
, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
384 {ARM_CEXT_MAVERICK
, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
385 {ARM_CEXT_MAVERICK
, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
386 {ARM_CEXT_MAVERICK
, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
387 {ARM_CEXT_MAVERICK
, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
388 {ARM_CEXT_MAVERICK
, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
389 {ARM_CEXT_MAVERICK
, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
390 {ARM_CEXT_MAVERICK
, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
391 {ARM_CEXT_MAVERICK
, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
392 {ARM_CEXT_MAVERICK
, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
393 {ARM_CEXT_MAVERICK
, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
394 {ARM_CEXT_MAVERICK
, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
395 {ARM_CEXT_MAVERICK
, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
396 {ARM_CEXT_MAVERICK
, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
397 {ARM_CEXT_MAVERICK
, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
398 {ARM_CEXT_MAVERICK
, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
399 {ARM_CEXT_MAVERICK
, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
400 {ARM_CEXT_MAVERICK
, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
401 {ARM_CEXT_MAVERICK
, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
402 {ARM_CEXT_MAVERICK
, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
403 {ARM_CEXT_MAVERICK
, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
404 {ARM_CEXT_MAVERICK
, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
405 {ARM_CEXT_MAVERICK
, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
406 {ARM_CEXT_MAVERICK
, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
407 {ARM_CEXT_MAVERICK
, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
408 {ARM_CEXT_MAVERICK
, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
409 {ARM_CEXT_MAVERICK
, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
410 {ARM_CEXT_MAVERICK
, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
411 {ARM_CEXT_MAVERICK
, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
412 {ARM_CEXT_MAVERICK
, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
413 {ARM_CEXT_MAVERICK
, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
414 {ARM_CEXT_MAVERICK
, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
415 {ARM_CEXT_MAVERICK
, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
416 {ARM_CEXT_MAVERICK
, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
417 {ARM_CEXT_MAVERICK
, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
418 {ARM_CEXT_MAVERICK
, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
419 {ARM_CEXT_MAVERICK
, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
420 {ARM_CEXT_MAVERICK
, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
421 {ARM_CEXT_MAVERICK
, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
422 {ARM_CEXT_MAVERICK
, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
423 {ARM_CEXT_MAVERICK
, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
424 {ARM_CEXT_MAVERICK
, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
425 {ARM_CEXT_MAVERICK
, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
426 {ARM_CEXT_MAVERICK
, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
427 {ARM_CEXT_MAVERICK
, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
428 {ARM_CEXT_MAVERICK
, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
429 {ARM_CEXT_MAVERICK
, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
430 {ARM_CEXT_MAVERICK
, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
431 {ARM_CEXT_MAVERICK
, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
432 {ARM_CEXT_MAVERICK
, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
433 {ARM_CEXT_MAVERICK
, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
434 {ARM_CEXT_MAVERICK
, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
435 {ARM_CEXT_MAVERICK
, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
436 {ARM_CEXT_MAVERICK
, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
437 {ARM_CEXT_MAVERICK
, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
438 {ARM_CEXT_MAVERICK
, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
439 {ARM_CEXT_MAVERICK
, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
440 {ARM_CEXT_MAVERICK
, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
441 {ARM_CEXT_MAVERICK
, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
442 {ARM_CEXT_MAVERICK
, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
443 {ARM_CEXT_MAVERICK
, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
444 {ARM_CEXT_MAVERICK
, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
445 {ARM_CEXT_MAVERICK
, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
446 {ARM_CEXT_MAVERICK
, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
447 {ARM_CEXT_MAVERICK
, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
448 {ARM_CEXT_MAVERICK
, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
449 {ARM_CEXT_MAVERICK
, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
450 {ARM_CEXT_MAVERICK
, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
451 {ARM_CEXT_MAVERICK
, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
452 {ARM_CEXT_MAVERICK
, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
453 {ARM_CEXT_MAVERICK
, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
454 {ARM_CEXT_MAVERICK
, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
455 {ARM_CEXT_MAVERICK
, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
456 {ARM_CEXT_MAVERICK
, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
457 {ARM_CEXT_MAVERICK
, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
458 {ARM_CEXT_MAVERICK
, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
459 {ARM_CEXT_MAVERICK
, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
460 {ARM_CEXT_MAVERICK
, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
462 /* VFP Fused multiply add instructions. */
463 {FPU_VFP_EXT_FMA
, 0x0ea00a00, 0x0fb00f50, "vfma%c.f32\t%y1, %y2, %y0"},
464 {FPU_VFP_EXT_FMA
, 0x0ea00b00, 0x0fb00f50, "vfma%c.f64\t%z1, %z2, %z0"},
465 {FPU_VFP_EXT_FMA
, 0x0ea00a40, 0x0fb00f50, "vfms%c.f32\t%y1, %y2, %y0"},
466 {FPU_VFP_EXT_FMA
, 0x0ea00b40, 0x0fb00f50, "vfms%c.f64\t%z1, %z2, %z0"},
467 {FPU_VFP_EXT_FMA
, 0x0e900a40, 0x0fb00f50, "vfnma%c.f32\t%y1, %y2, %y0"},
468 {FPU_VFP_EXT_FMA
, 0x0e900b40, 0x0fb00f50, "vfnma%c.f64\t%z1, %z2, %z0"},
469 {FPU_VFP_EXT_FMA
, 0x0e900a00, 0x0fb00f50, "vfnms%c.f32\t%y1, %y2, %y0"},
470 {FPU_VFP_EXT_FMA
, 0x0e900b00, 0x0fb00f50, "vfnms%c.f64\t%z1, %z2, %z0"},
472 /* Generic coprocessor instructions. */
473 { 0, SENTINEL_GENERIC_START
, 0, "" },
474 {ARM_EXT_V5E
, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15R, %16-19r, cr%0-3d"},
475 {ARM_EXT_V5E
, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
476 {ARM_EXT_V2
, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
477 {ARM_EXT_V2
, 0x0e10f010, 0x0f10f010, "mrc%c\t%8-11d, %21-23d, APSR_nzcv, cr%16-19d, cr%0-3d, {%5-7d}"},
478 {ARM_EXT_V2
, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
479 {ARM_EXT_V2
, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
480 {ARM_EXT_V2
, 0x0c000000, 0x0e100000, "stc%22'l%c\t%8-11d, cr%12-15d, %A"},
481 {ARM_EXT_V2
, 0x0c100000, 0x0e100000, "ldc%22'l%c\t%8-11d, cr%12-15d, %A"},
483 /* V6 coprocessor instructions. */
484 {ARM_EXT_V6
, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15Ru, %16-19Ru, cr%0-3d"},
485 {ARM_EXT_V6
, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15R, %16-19R, cr%0-3d"},
487 /* V5 coprocessor instructions. */
488 {ARM_EXT_V5
, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
489 {ARM_EXT_V5
, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
490 {ARM_EXT_V5
, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
491 {ARM_EXT_V5
, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15R, cr%16-19d, cr%0-3d, {%5-7d}"},
492 {ARM_EXT_V5
, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
497 /* Neon opcode table: This does not encode the top byte -- that is
498 checked by the print_insn_neon routine, as it depends on whether we are
499 doing thumb32 or arm32 disassembly. */
501 /* print_insn_neon recognizes the following format control codes:
505 %c print condition code
506 %A print v{st,ld}[1234] operands
507 %B print v{st,ld}[1234] any one operands
508 %C print v{st,ld}[1234] single->all operands
510 %E print vmov, vmvn, vorr, vbic encoded constant
511 %F print vtbl,vtbx register list
513 %<bitfield>r print as an ARM register
514 %<bitfield>d print the bitfield in decimal
515 %<bitfield>e print the 2^N - bitfield in decimal
516 %<bitfield>D print as a NEON D register
517 %<bitfield>Q print as a NEON Q register
518 %<bitfield>R print as a NEON D or Q register
519 %<bitfield>Sn print byte scaled width limited by n
520 %<bitfield>Tn print short scaled width limited by n
521 %<bitfield>Un print long scaled width limited by n
523 %<bitfield>'c print specified char iff bitfield is all ones
524 %<bitfield>`c print specified char iff bitfield is all zeroes
525 %<bitfield>?ab... select from array of values in big endian order. */
527 static const struct opcode32 neon_opcodes
[] =
530 {FPU_NEON_EXT_V1
, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
531 {FPU_NEON_EXT_V1
, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
533 /* Move data element to all lanes. */
534 {FPU_NEON_EXT_V1
, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
535 {FPU_NEON_EXT_V1
, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
536 {FPU_NEON_EXT_V1
, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
539 {FPU_NEON_EXT_V1
, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
540 {FPU_NEON_EXT_V1
, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
542 /* Half-precision conversions. */
543 {FPU_VFP_EXT_FP16
, 0xf3b60600, 0xffbf0fd0, "vcvt%c.f16.f32\t%12-15,22D, %0-3,5Q"},
544 {FPU_VFP_EXT_FP16
, 0xf3b60700, 0xffbf0fd0, "vcvt%c.f32.f16\t%12-15,22Q, %0-3,5D"},
546 /* NEON fused multiply add instructions. */
547 {FPU_NEON_EXT_FMA
, 0xf2000c10, 0xffa00f10, "vfma%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
548 {FPU_NEON_EXT_FMA
, 0xf2200c10, 0xffa00f10, "vfms%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
550 /* Two registers, miscellaneous. */
551 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
552 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
553 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
554 {FPU_NEON_EXT_V1
, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
555 {FPU_NEON_EXT_V1
, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
556 {FPU_NEON_EXT_V1
, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
557 {FPU_NEON_EXT_V1
, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
558 {FPU_NEON_EXT_V1
, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
559 {FPU_NEON_EXT_V1
, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
560 {FPU_NEON_EXT_V1
, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
561 {FPU_NEON_EXT_V1
, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
562 {FPU_NEON_EXT_V1
, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
563 {FPU_NEON_EXT_V1
, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
564 {FPU_NEON_EXT_V1
, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
565 {FPU_NEON_EXT_V1
, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
566 {FPU_NEON_EXT_V1
, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
567 {FPU_NEON_EXT_V1
, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
568 {FPU_NEON_EXT_V1
, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
569 {FPU_NEON_EXT_V1
, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
570 {FPU_NEON_EXT_V1
, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
571 {FPU_NEON_EXT_V1
, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
572 {FPU_NEON_EXT_V1
, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
573 {FPU_NEON_EXT_V1
, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
574 {FPU_NEON_EXT_V1
, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
575 {FPU_NEON_EXT_V1
, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
576 {FPU_NEON_EXT_V1
, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
577 {FPU_NEON_EXT_V1
, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
578 {FPU_NEON_EXT_V1
, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
579 {FPU_NEON_EXT_V1
, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
580 {FPU_NEON_EXT_V1
, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
581 {FPU_NEON_EXT_V1
, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
582 {FPU_NEON_EXT_V1
, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
583 {FPU_NEON_EXT_V1
, 0xf3b30600, 0xffb30e10, "vcvt%c.%7-8?usff%18-19Sa.%7-8?ffus%18-19Sa\t%12-15,22R, %0-3,5R"},
585 /* Three registers of the same length. */
586 {FPU_NEON_EXT_V1
, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
587 {FPU_NEON_EXT_V1
, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
588 {FPU_NEON_EXT_V1
, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
589 {FPU_NEON_EXT_V1
, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
590 {FPU_NEON_EXT_V1
, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
591 {FPU_NEON_EXT_V1
, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
592 {FPU_NEON_EXT_V1
, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
593 {FPU_NEON_EXT_V1
, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
594 {FPU_NEON_EXT_V1
, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
595 {FPU_NEON_EXT_V1
, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
596 {FPU_NEON_EXT_V1
, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
597 {FPU_NEON_EXT_V1
, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
598 {FPU_NEON_EXT_V1
, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
599 {FPU_NEON_EXT_V1
, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
600 {FPU_NEON_EXT_V1
, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
601 {FPU_NEON_EXT_V1
, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
602 {FPU_NEON_EXT_V1
, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
603 {FPU_NEON_EXT_V1
, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
604 {FPU_NEON_EXT_V1
, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
605 {FPU_NEON_EXT_V1
, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
606 {FPU_NEON_EXT_V1
, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
607 {FPU_NEON_EXT_V1
, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
608 {FPU_NEON_EXT_V1
, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
609 {FPU_NEON_EXT_V1
, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
610 {FPU_NEON_EXT_V1
, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
611 {FPU_NEON_EXT_V1
, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
612 {FPU_NEON_EXT_V1
, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
613 {FPU_NEON_EXT_V1
, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
614 {FPU_NEON_EXT_V1
, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
615 {FPU_NEON_EXT_V1
, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
616 {FPU_NEON_EXT_V1
, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
617 {FPU_NEON_EXT_V1
, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
618 {FPU_NEON_EXT_V1
, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
619 {FPU_NEON_EXT_V1
, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
620 {FPU_NEON_EXT_V1
, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
621 {FPU_NEON_EXT_V1
, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
622 {FPU_NEON_EXT_V1
, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
623 {FPU_NEON_EXT_V1
, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
624 {FPU_NEON_EXT_V1
, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
625 {FPU_NEON_EXT_V1
, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
626 {FPU_NEON_EXT_V1
, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
627 {FPU_NEON_EXT_V1
, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
628 {FPU_NEON_EXT_V1
, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
629 {FPU_NEON_EXT_V1
, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
630 {FPU_NEON_EXT_V1
, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
631 {FPU_NEON_EXT_V1
, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %0-3,5R, %16-19,7R"},
632 {FPU_NEON_EXT_V1
, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
633 {FPU_NEON_EXT_V1
, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
634 {FPU_NEON_EXT_V1
, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
635 {FPU_NEON_EXT_V1
, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
636 {FPU_NEON_EXT_V1
, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
637 {FPU_NEON_EXT_V1
, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
638 {FPU_NEON_EXT_V1
, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
640 /* One register and an immediate value. */
641 {FPU_NEON_EXT_V1
, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
642 {FPU_NEON_EXT_V1
, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
643 {FPU_NEON_EXT_V1
, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
644 {FPU_NEON_EXT_V1
, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
645 {FPU_NEON_EXT_V1
, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
646 {FPU_NEON_EXT_V1
, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
647 {FPU_NEON_EXT_V1
, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
648 {FPU_NEON_EXT_V1
, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
649 {FPU_NEON_EXT_V1
, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
650 {FPU_NEON_EXT_V1
, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
651 {FPU_NEON_EXT_V1
, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
652 {FPU_NEON_EXT_V1
, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
653 {FPU_NEON_EXT_V1
, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
655 /* Two registers and a shift amount. */
656 {FPU_NEON_EXT_V1
, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
657 {FPU_NEON_EXT_V1
, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
658 {FPU_NEON_EXT_V1
, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
659 {FPU_NEON_EXT_V1
, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
660 {FPU_NEON_EXT_V1
, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
661 {FPU_NEON_EXT_V1
, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
662 {FPU_NEON_EXT_V1
, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
663 {FPU_NEON_EXT_V1
, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
664 {FPU_NEON_EXT_V1
, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
665 {FPU_NEON_EXT_V1
, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
666 {FPU_NEON_EXT_V1
, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
667 {FPU_NEON_EXT_V1
, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
668 {FPU_NEON_EXT_V1
, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
669 {FPU_NEON_EXT_V1
, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
670 {FPU_NEON_EXT_V1
, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
671 {FPU_NEON_EXT_V1
, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
672 {FPU_NEON_EXT_V1
, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
673 {FPU_NEON_EXT_V1
, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
674 {FPU_NEON_EXT_V1
, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
675 {FPU_NEON_EXT_V1
, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
676 {FPU_NEON_EXT_V1
, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
677 {FPU_NEON_EXT_V1
, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
678 {FPU_NEON_EXT_V1
, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
679 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
680 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
681 {FPU_NEON_EXT_V1
, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
682 {FPU_NEON_EXT_V1
, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
683 {FPU_NEON_EXT_V1
, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
684 {FPU_NEON_EXT_V1
, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
685 {FPU_NEON_EXT_V1
, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
686 {FPU_NEON_EXT_V1
, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
687 {FPU_NEON_EXT_V1
, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
688 {FPU_NEON_EXT_V1
, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
689 {FPU_NEON_EXT_V1
, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
690 {FPU_NEON_EXT_V1
, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
691 {FPU_NEON_EXT_V1
, 0xf2a00810, 0xfea00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
692 {FPU_NEON_EXT_V1
, 0xf2a00850, 0xfea00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
693 {FPU_NEON_EXT_V1
, 0xf2a00910, 0xfea00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
694 {FPU_NEON_EXT_V1
, 0xf2a00950, 0xfea00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
695 {FPU_NEON_EXT_V1
, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
696 {FPU_NEON_EXT_V1
, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
697 {FPU_NEON_EXT_V1
, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
698 {FPU_NEON_EXT_V1
, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
699 {FPU_NEON_EXT_V1
, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
700 {FPU_NEON_EXT_V1
, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
701 {FPU_NEON_EXT_V1
, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
702 {FPU_NEON_EXT_V1
, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
703 {FPU_NEON_EXT_V1
, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
704 {FPU_NEON_EXT_V1
, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
705 {FPU_NEON_EXT_V1
, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
706 {FPU_NEON_EXT_V1
, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
707 {FPU_NEON_EXT_V1
, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
708 {FPU_NEON_EXT_V1
, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
709 {FPU_NEON_EXT_V1
, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
710 {FPU_NEON_EXT_V1
, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
711 {FPU_NEON_EXT_V1
, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
712 {FPU_NEON_EXT_V1
, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
713 {FPU_NEON_EXT_V1
, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
715 /* Three registers of different lengths. */
716 {FPU_NEON_EXT_V1
, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
717 {FPU_NEON_EXT_V1
, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
718 {FPU_NEON_EXT_V1
, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
719 {FPU_NEON_EXT_V1
, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
720 {FPU_NEON_EXT_V1
, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
721 {FPU_NEON_EXT_V1
, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
722 {FPU_NEON_EXT_V1
, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
723 {FPU_NEON_EXT_V1
, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
724 {FPU_NEON_EXT_V1
, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
725 {FPU_NEON_EXT_V1
, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
726 {FPU_NEON_EXT_V1
, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
727 {FPU_NEON_EXT_V1
, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
728 {FPU_NEON_EXT_V1
, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
729 {FPU_NEON_EXT_V1
, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
730 {FPU_NEON_EXT_V1
, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
731 {FPU_NEON_EXT_V1
, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
732 {FPU_NEON_EXT_V1
, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
734 /* Two registers and a scalar. */
735 {FPU_NEON_EXT_V1
, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
736 {FPU_NEON_EXT_V1
, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
737 {FPU_NEON_EXT_V1
, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
738 {FPU_NEON_EXT_V1
, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
739 {FPU_NEON_EXT_V1
, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
740 {FPU_NEON_EXT_V1
, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
741 {FPU_NEON_EXT_V1
, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
742 {FPU_NEON_EXT_V1
, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
743 {FPU_NEON_EXT_V1
, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
744 {FPU_NEON_EXT_V1
, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
745 {FPU_NEON_EXT_V1
, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
746 {FPU_NEON_EXT_V1
, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
747 {FPU_NEON_EXT_V1
, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
748 {FPU_NEON_EXT_V1
, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
749 {FPU_NEON_EXT_V1
, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
750 {FPU_NEON_EXT_V1
, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
751 {FPU_NEON_EXT_V1
, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
752 {FPU_NEON_EXT_V1
, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
753 {FPU_NEON_EXT_V1
, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
754 {FPU_NEON_EXT_V1
, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
755 {FPU_NEON_EXT_V1
, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
756 {FPU_NEON_EXT_V1
, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
758 /* Element and structure load/store. */
759 {FPU_NEON_EXT_V1
, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
760 {FPU_NEON_EXT_V1
, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
761 {FPU_NEON_EXT_V1
, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
762 {FPU_NEON_EXT_V1
, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
763 {FPU_NEON_EXT_V1
, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
764 {FPU_NEON_EXT_V1
, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
765 {FPU_NEON_EXT_V1
, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
766 {FPU_NEON_EXT_V1
, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
767 {FPU_NEON_EXT_V1
, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
768 {FPU_NEON_EXT_V1
, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
769 {FPU_NEON_EXT_V1
, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
770 {FPU_NEON_EXT_V1
, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
771 {FPU_NEON_EXT_V1
, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
772 {FPU_NEON_EXT_V1
, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
773 {FPU_NEON_EXT_V1
, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
774 {FPU_NEON_EXT_V1
, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
775 {FPU_NEON_EXT_V1
, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
776 {FPU_NEON_EXT_V1
, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
777 {FPU_NEON_EXT_V1
, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
782 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
783 ordered: they must be searched linearly from the top to obtain a correct
786 /* print_insn_arm recognizes the following format control codes:
790 %a print address for ldr/str instruction
791 %s print address for ldr/str halfword/signextend instruction
792 %S like %s but allow UNPREDICTABLE addressing
793 %b print branch destination
794 %c print condition code (always bits 28-31)
795 %m print register mask for ldm/stm instruction
796 %o print operand2 (immediate or register + shift)
797 %p print 'p' iff bits 12-15 are 15
798 %t print 't' iff bit 21 set and bit 24 clear
799 %B print arm BLX(1) destination
800 %C print the PSR sub type.
801 %U print barrier type.
802 %P print address for pli instruction.
804 %<bitfield>r print as an ARM register
805 %<bitfield>R as %r but r15 is UNPREDICTABLE
806 %<bitfield>{r|R}u as %{r|R} but if matches the other %u field then is UNPREDICTABLE
807 %<bitfield>{r|R}U as %{r|R} but if matches the other %U field then is UNPREDICTABLE
808 %<bitfield>d print the bitfield in decimal
809 %<bitfield>W print the bitfield plus one in decimal
810 %<bitfield>x print the bitfield in hex
811 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
813 %<bitfield>'c print specified char iff bitfield is all ones
814 %<bitfield>`c print specified char iff bitfield is all zeroes
815 %<bitfield>?ab... select from array of values in big endian order
817 %e print arm SMI operand (bits 0..7,8..19).
818 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
819 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
820 %R print the SPSR/CPSR or banked register of an MRS. */
822 static const struct opcode32 arm_opcodes
[] =
824 /* ARM instructions. */
825 {ARM_EXT_V1
, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
826 {ARM_EXT_V4T
| ARM_EXT_V5
, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
827 {ARM_EXT_V2
, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19R, %0-3R, %8-11R"},
828 {ARM_EXT_V2
, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
829 {ARM_EXT_V2S
, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15RU, %0-3Ru, [%16-19RuU]"},
830 {ARM_EXT_V3M
, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
831 {ARM_EXT_V3M
, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
833 /* Virtualization Extension instructions. */
834 {ARM_EXT_VIRT
, 0x0160006e, 0x0fffffff, "eret%c"},
835 {ARM_EXT_VIRT
, 0x01400070, 0x0ff000f0, "hvc%c\t%e"},
837 /* Integer Divide Extension instructions. */
838 {ARM_EXT_ADIV
, 0x0710f010, 0x0ff0f0f0, "sdiv%c\t%16-19r, %0-3r, %8-11r"},
839 {ARM_EXT_ADIV
, 0x0730f010, 0x0ff0f0f0, "udiv%c\t%16-19r, %0-3r, %8-11r"},
841 /* MP Extension instructions. */
842 {ARM_EXT_MP
, 0xf410f000, 0xfc70f000, "pldw\t%a"},
844 /* V7 instructions. */
845 {ARM_EXT_V7
, 0xf450f000, 0xfd70f000, "pli\t%P"},
846 {ARM_EXT_V7
, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
847 {ARM_EXT_V7
, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
848 {ARM_EXT_V7
, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
849 {ARM_EXT_V7
, 0xf57ff060, 0xfffffff0, "isb\t%U"},
851 /* ARM V6T2 instructions. */
852 {ARM_EXT_V6T2
, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15R, %E"},
853 {ARM_EXT_V6T2
, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15R, %0-3r, %E"},
854 {ARM_EXT_V6T2
, 0x00600090, 0x0ff000f0, "mls%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
855 {ARM_EXT_V6T2
, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15R, %S"},
857 {ARM_EXT_V6T2
, 0x00300090, 0x0f3000f0, UNDEFINED_INSTRUCTION
},
858 {ARM_EXT_V6T2
, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15R, %S"},
860 {ARM_EXT_V6T2
, 0x03000000, 0x0ff00000, "movw%c\t%12-15R, %V"},
861 {ARM_EXT_V6T2
, 0x03400000, 0x0ff00000, "movt%c\t%12-15R, %V"},
862 {ARM_EXT_V6T2
, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15R, %0-3R"},
863 {ARM_EXT_V6T2
, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
865 /* ARM Security extension instructions. */
866 {ARM_EXT_SEC
, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
868 /* ARM V6K instructions. */
869 {ARM_EXT_V6K
, 0xf57ff01f, 0xffffffff, "clrex"},
870 {ARM_EXT_V6K
, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15R, [%16-19R]"},
871 {ARM_EXT_V6K
, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19R]"},
872 {ARM_EXT_V6K
, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15R, [%16-19R]"},
873 {ARM_EXT_V6K
, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15R, %0-3R, [%16-19R]"},
874 {ARM_EXT_V6K
, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15R, %0-3r, [%16-19R]"},
875 {ARM_EXT_V6K
, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15R, %0-3R, [%16-19R]"},
877 /* ARM V6K NOP hints. */
878 {ARM_EXT_V6K
, 0x0320f001, 0x0fffffff, "yield%c"},
879 {ARM_EXT_V6K
, 0x0320f002, 0x0fffffff, "wfe%c"},
880 {ARM_EXT_V6K
, 0x0320f003, 0x0fffffff, "wfi%c"},
881 {ARM_EXT_V6K
, 0x0320f004, 0x0fffffff, "sev%c"},
882 {ARM_EXT_V6K
, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
884 /* ARM V6 instructions. */
885 {ARM_EXT_V6
, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
886 {ARM_EXT_V6
, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
887 {ARM_EXT_V6
, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
888 {ARM_EXT_V6
, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
889 {ARM_EXT_V6
, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
890 {ARM_EXT_V6
, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15R, %16-19R, %0-3R"},
891 {ARM_EXT_V6
, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15R, %16-19R, %0-3R, lsl #%7-11d"},
892 {ARM_EXT_V6
, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #32"},
893 {ARM_EXT_V6
, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15R, %16-19R, %0-3R, asr #%7-11d"},
894 {ARM_EXT_V6
, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19R]"},
895 {ARM_EXT_V6
, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15R, %16-19R, %0-3R"},
896 {ARM_EXT_V6
, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15R, %16-19R, %0-3R"},
897 {ARM_EXT_V6
, 0x06200f30, 0x0ff00ff0, "qasx%c\t%12-15R, %16-19R, %0-3R"},
898 {ARM_EXT_V6
, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15R, %16-19R, %0-3R"},
899 {ARM_EXT_V6
, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15R, %16-19R, %0-3R"},
900 {ARM_EXT_V6
, 0x06200f50, 0x0ff00ff0, "qsax%c\t%12-15R, %16-19R, %0-3R"},
901 {ARM_EXT_V6
, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15R, %16-19R, %0-3R"},
902 {ARM_EXT_V6
, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15R, %16-19R, %0-3R"},
903 {ARM_EXT_V6
, 0x06100f30, 0x0ff00ff0, "sasx%c\t%12-15R, %16-19R, %0-3R"},
904 {ARM_EXT_V6
, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15R, %16-19R, %0-3R"},
905 {ARM_EXT_V6
, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15R, %16-19R, %0-3R"},
906 {ARM_EXT_V6
, 0x06300f30, 0x0ff00ff0, "shasx%c\t%12-15R, %16-19R, %0-3R"},
907 {ARM_EXT_V6
, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15R, %16-19R, %0-3R"},
908 {ARM_EXT_V6
, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15R, %16-19R, %0-3R"},
909 {ARM_EXT_V6
, 0x06300f50, 0x0ff00ff0, "shsax%c\t%12-15R, %16-19R, %0-3R"},
910 {ARM_EXT_V6
, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15R, %16-19R, %0-3R"},
911 {ARM_EXT_V6
, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15R, %16-19R, %0-3R"},
912 {ARM_EXT_V6
, 0x06100f50, 0x0ff00ff0, "ssax%c\t%12-15R, %16-19R, %0-3R"},
913 {ARM_EXT_V6
, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15R, %16-19R, %0-3R"},
914 {ARM_EXT_V6
, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15R, %16-19R, %0-3R"},
915 {ARM_EXT_V6
, 0x06500f30, 0x0ff00ff0, "uasx%c\t%12-15R, %16-19R, %0-3R"},
916 {ARM_EXT_V6
, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15R, %16-19R, %0-3R"},
917 {ARM_EXT_V6
, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15R, %16-19R, %0-3R"},
918 {ARM_EXT_V6
, 0x06700f30, 0x0ff00ff0, "uhasx%c\t%12-15R, %16-19R, %0-3R"},
919 {ARM_EXT_V6
, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15R, %16-19R, %0-3R"},
920 {ARM_EXT_V6
, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15R, %16-19R, %0-3R"},
921 {ARM_EXT_V6
, 0x06700f50, 0x0ff00ff0, "uhsax%c\t%12-15R, %16-19R, %0-3R"},
922 {ARM_EXT_V6
, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15R, %16-19R, %0-3R"},
923 {ARM_EXT_V6
, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15R, %16-19R, %0-3R"},
924 {ARM_EXT_V6
, 0x06600f30, 0x0ff00ff0, "uqasx%c\t%12-15R, %16-19R, %0-3R"},
925 {ARM_EXT_V6
, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15R, %16-19R, %0-3R"},
926 {ARM_EXT_V6
, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15R, %16-19R, %0-3R"},
927 {ARM_EXT_V6
, 0x06600f50, 0x0ff00ff0, "uqsax%c\t%12-15R, %16-19R, %0-3R"},
928 {ARM_EXT_V6
, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15R, %16-19R, %0-3R"},
929 {ARM_EXT_V6
, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15R, %16-19R, %0-3R"},
930 {ARM_EXT_V6
, 0x06500f50, 0x0ff00ff0, "usax%c\t%12-15R, %16-19R, %0-3R"},
931 {ARM_EXT_V6
, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15R, %0-3R"},
932 {ARM_EXT_V6
, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15R, %0-3R"},
933 {ARM_EXT_V6
, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15R, %0-3R"},
934 {ARM_EXT_V6
, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
935 {ARM_EXT_V6
, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R"},
936 {ARM_EXT_V6
, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #8"},
937 {ARM_EXT_V6
, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #16"},
938 {ARM_EXT_V6
, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15R, %0-3R, ror #24"},
939 {ARM_EXT_V6
, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R"},
940 {ARM_EXT_V6
, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #8"},
941 {ARM_EXT_V6
, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #16"},
942 {ARM_EXT_V6
, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15R, %0-3R, ror #24"},
943 {ARM_EXT_V6
, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R"},
944 {ARM_EXT_V6
, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #8"},
945 {ARM_EXT_V6
, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #16"},
946 {ARM_EXT_V6
, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15R, %0-3R, ror #24"},
947 {ARM_EXT_V6
, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R"},
948 {ARM_EXT_V6
, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #8"},
949 {ARM_EXT_V6
, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #16"},
950 {ARM_EXT_V6
, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15R, %0-3R, ror #24"},
951 {ARM_EXT_V6
, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R"},
952 {ARM_EXT_V6
, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #8"},
953 {ARM_EXT_V6
, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #16"},
954 {ARM_EXT_V6
, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15R, %0-3R, ror #24"},
955 {ARM_EXT_V6
, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R"},
956 {ARM_EXT_V6
, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #8"},
957 {ARM_EXT_V6
, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #16"},
958 {ARM_EXT_V6
, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15R, %0-3R, ror #24"},
959 {ARM_EXT_V6
, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R"},
960 {ARM_EXT_V6
, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
961 {ARM_EXT_V6
, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
962 {ARM_EXT_V6
, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
963 {ARM_EXT_V6
, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R"},
964 {ARM_EXT_V6
, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
965 {ARM_EXT_V6
, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
966 {ARM_EXT_V6
, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15R, %16-19r, %0-3R, ror #24"},
967 {ARM_EXT_V6
, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R"},
968 {ARM_EXT_V6
, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
969 {ARM_EXT_V6
, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
970 {ARM_EXT_V6
, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
971 {ARM_EXT_V6
, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R"},
972 {ARM_EXT_V6
, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #8"},
973 {ARM_EXT_V6
, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #16"},
974 {ARM_EXT_V6
, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15R, %16-19r, %0-3R, ror #24"},
975 {ARM_EXT_V6
, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R"},
976 {ARM_EXT_V6
, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #8"},
977 {ARM_EXT_V6
, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ror #16"},
978 {ARM_EXT_V6
, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15R, %16-19r, %0-3R, ROR #24"},
979 {ARM_EXT_V6
, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R"},
980 {ARM_EXT_V6
, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #8"},
981 {ARM_EXT_V6
, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #16"},
982 {ARM_EXT_V6
, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15R, %16-19r, %0-3R, ror #24"},
983 {ARM_EXT_V6
, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15R, %16-19R, %0-3R"},
984 {ARM_EXT_V6
, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
985 {ARM_EXT_V6
, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19R, %0-3R, %8-11R"},
986 {ARM_EXT_V6
, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19R, %0-3R, %8-11R"},
987 {ARM_EXT_V6
, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
988 {ARM_EXT_V6
, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
989 {ARM_EXT_V6
, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
990 {ARM_EXT_V6
, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
991 {ARM_EXT_V6
, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19R, %0-3R, %8-11R"},
992 {ARM_EXT_V6
, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
993 {ARM_EXT_V6
, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
994 {ARM_EXT_V6
, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
995 {ARM_EXT_V6
, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15R, #%16-20W, %0-3R"},
996 {ARM_EXT_V6
, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, lsl #%7-11d"},
997 {ARM_EXT_V6
, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15R, #%16-20W, %0-3R, asr #%7-11d"},
998 {ARM_EXT_V6
, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
999 {ARM_EXT_V6
, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15R, %0-3R, [%16-19R]"},
1000 {ARM_EXT_V6
, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15R, %16-19R, %0-3R, %8-11R"},
1001 {ARM_EXT_V6
, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19R, %0-3R, %8-11R"},
1002 {ARM_EXT_V6
, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1003 {ARM_EXT_V6
, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15R, #%16-20d, %0-3R"},
1004 {ARM_EXT_V6
, 0x06e00010, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, lsl #%7-11d"},
1005 {ARM_EXT_V6
, 0x06e00050, 0x0fe00070, "usat%c\t%12-15R, #%16-20d, %0-3R, asr #%7-11d"},
1006 {ARM_EXT_V6
, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15R, #%16-19d, %0-3R"},
1008 /* V5J instruction. */
1009 {ARM_EXT_V5J
, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3R"},
1011 /* V5 Instructions. */
1012 {ARM_EXT_V5
, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
1013 {ARM_EXT_V5
, 0xfa000000, 0xfe000000, "blx\t%B"},
1014 {ARM_EXT_V5
, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3R"},
1015 {ARM_EXT_V5
, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15R, %0-3R"},
1017 /* V5E "El Segundo" Instructions. */
1018 {ARM_EXT_V5E
, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
1019 {ARM_EXT_V5E
, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
1020 {ARM_EXT_V5E
, 0xf450f000, 0xfc70f000, "pld\t%a"},
1021 {ARM_EXT_V5ExP
, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1022 {ARM_EXT_V5ExP
, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1023 {ARM_EXT_V5ExP
, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1024 {ARM_EXT_V5ExP
, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11R, %12-15R"},
1026 {ARM_EXT_V5ExP
, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19R, %0-3R, %8-11R, %12-15R"},
1027 {ARM_EXT_V5ExP
, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19R, %0-3r, %8-11R, %12-15R"},
1029 {ARM_EXT_V5ExP
, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1030 {ARM_EXT_V5ExP
, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1031 {ARM_EXT_V5ExP
, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1032 {ARM_EXT_V5ExP
, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15Ru, %16-19Ru, %0-3R, %8-11R"},
1034 {ARM_EXT_V5ExP
, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19R, %0-3R, %8-11R"},
1035 {ARM_EXT_V5ExP
, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19R, %0-3R, %8-11R"},
1036 {ARM_EXT_V5ExP
, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19R, %0-3R, %8-11R"},
1037 {ARM_EXT_V5ExP
, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19R, %0-3R, %8-11R"},
1039 {ARM_EXT_V5ExP
, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19R, %0-3R, %8-11R"},
1040 {ARM_EXT_V5ExP
, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19R, %0-3R, %8-11R"},
1042 {ARM_EXT_V5ExP
, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15R, %0-3R, %16-19R"},
1043 {ARM_EXT_V5ExP
, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15R, %0-3R, %16-19R"},
1044 {ARM_EXT_V5ExP
, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15R, %0-3R, %16-19R"},
1045 {ARM_EXT_V5ExP
, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15R, %0-3R, %16-19R"},
1047 /* ARM Instructions. */
1048 {ARM_EXT_V1
, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1050 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%t%c\t%12-15R, %a"},
1051 {ARM_EXT_V1
, 0x04000000, 0x0e500000, "str%t%c\t%12-15r, %a"},
1052 {ARM_EXT_V1
, 0x06400000, 0x0e500ff0, "strb%t%c\t%12-15R, %a"},
1053 {ARM_EXT_V1
, 0x06000000, 0x0e500ff0, "str%t%c\t%12-15r, %a"},
1054 {ARM_EXT_V1
, 0x04400000, 0x0c500010, "strb%t%c\t%12-15R, %a"},
1055 {ARM_EXT_V1
, 0x04000000, 0x0c500010, "str%t%c\t%12-15r, %a"},
1057 {ARM_EXT_V1
, 0x04400000, 0x0e500000, "strb%c\t%12-15R, %a"},
1058 {ARM_EXT_V1
, 0x06400000, 0x0e500010, "strb%c\t%12-15R, %a"},
1059 {ARM_EXT_V1
, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15R, %s"},
1060 {ARM_EXT_V1
, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15R, %s"},
1062 {ARM_EXT_V1
, 0x00500090, 0x0e5000f0, UNDEFINED_INSTRUCTION
},
1063 {ARM_EXT_V1
, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15R, %s"},
1064 {ARM_EXT_V1
, 0x00100090, 0x0e500ff0, UNDEFINED_INSTRUCTION
},
1065 {ARM_EXT_V1
, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15R, %s"},
1067 {ARM_EXT_V1
, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1068 {ARM_EXT_V1
, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1069 {ARM_EXT_V1
, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15R, %16-19R, %o"},
1071 {ARM_EXT_V1
, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1072 {ARM_EXT_V1
, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1073 {ARM_EXT_V1
, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15R, %16-19R, %o"},
1075 {ARM_EXT_V1
, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1076 {ARM_EXT_V1
, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1077 {ARM_EXT_V1
, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15R, %16-19R, %o"},
1079 {ARM_EXT_V1
, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1
, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1081 {ARM_EXT_V1
, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15R, %16-19R, %o"},
1083 {ARM_EXT_V1
, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1084 {ARM_EXT_V1
, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1085 {ARM_EXT_V1
, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15R, %16-19R, %o"},
1087 {ARM_EXT_V1
, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1088 {ARM_EXT_V1
, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1089 {ARM_EXT_V1
, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15R, %16-19R, %o"},
1091 {ARM_EXT_V1
, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1
, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1093 {ARM_EXT_V1
, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15R, %16-19R, %o"},
1095 {ARM_EXT_V1
, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1096 {ARM_EXT_V1
, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1097 {ARM_EXT_V1
, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15R, %16-19R, %o"},
1099 {ARM_EXT_VIRT
, 0x0120f200, 0x0fb0f200, "msr%c\t%C, %0-3r"},
1100 {ARM_EXT_V3
, 0x0120f000, 0x0db0f000, "msr%c\t%C, %o"},
1101 {ARM_EXT_V3
, 0x01000000, 0x0fb00cff, "mrs%c\t%12-15R, %R"},
1103 {ARM_EXT_V1
, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1104 {ARM_EXT_V1
, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1105 {ARM_EXT_V1
, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19R, %o"},
1107 {ARM_EXT_V1
, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1108 {ARM_EXT_V1
, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1109 {ARM_EXT_V1
, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19R, %o"},
1111 {ARM_EXT_V1
, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1112 {ARM_EXT_V1
, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1113 {ARM_EXT_V1
, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19R, %o"},
1115 {ARM_EXT_V1
, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1116 {ARM_EXT_V1
, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1117 {ARM_EXT_V1
, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19R, %o"},
1119 {ARM_EXT_V1
, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1120 {ARM_EXT_V1
, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1121 {ARM_EXT_V1
, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15R, %16-19R, %o"},
1123 {ARM_EXT_V1
, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1124 {ARM_EXT_V1
, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1125 {ARM_EXT_V1
, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15R, %q"},
1126 {ARM_EXT_V1
, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15R, %q"},
1127 {ARM_EXT_V1
, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15R, %q"},
1128 {ARM_EXT_V1
, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1129 {ARM_EXT_V1
, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15R, %q"},
1131 {ARM_EXT_V1
, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1132 {ARM_EXT_V1
, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1133 {ARM_EXT_V1
, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15R, %16-19R, %o"},
1135 {ARM_EXT_V1
, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1136 {ARM_EXT_V1
, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1137 {ARM_EXT_V1
, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15R, %o"},
1139 {ARM_EXT_V1
, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION
},
1140 {ARM_EXT_V1
, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1142 {ARM_EXT_V1
, 0x04500000, 0x0c500000, "ldrb%t%c\t%12-15R, %a"},
1144 {ARM_EXT_V1
, 0x04300000, 0x0d700000, "ldrt%c\t%12-15R, %a"},
1145 {ARM_EXT_V1
, 0x04100000, 0x0c500000, "ldr%c\t%12-15r, %a"},
1147 {ARM_EXT_V1
, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1148 {ARM_EXT_V1
, 0x08800000, 0x0ff00000, "stm%c\t%16-19R%21'!, %m%22'^"},
1149 {ARM_EXT_V1
, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1150 {ARM_EXT_V1
, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1151 {ARM_EXT_V1
, 0x08900000, 0x0f900000, "ldm%c\t%16-19R%21'!, %m%22'^"},
1152 {ARM_EXT_V1
, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19R%21'!, %m%22'^"},
1153 {ARM_EXT_V1
, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1154 {ARM_EXT_V1
, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1157 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1158 {0, 0x00000000, 0x00000000, 0}
1161 /* print_insn_thumb16 recognizes the following format control codes:
1163 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1164 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1165 %<bitfield>I print bitfield as a signed decimal
1166 (top bit of range being the sign bit)
1167 %N print Thumb register mask (with LR)
1168 %O print Thumb register mask (with PC)
1169 %M print Thumb register mask
1170 %b print CZB's 6-bit unsigned branch destination
1171 %s print Thumb right-shift immediate (6..10; 0 == 32).
1172 %c print the condition code
1173 %C print the condition code, or "s" if not conditional
1174 %x print warning if conditional an not at end of IT block"
1175 %X print "\t; unpredictable <IT:code>" if conditional
1176 %I print IT instruction suffix and operands
1177 %W print Thumb Writeback indicator for LDMIA
1178 %<bitfield>r print bitfield as an ARM register
1179 %<bitfield>d print bitfield as a decimal
1180 %<bitfield>H print (bitfield * 2) as a decimal
1181 %<bitfield>W print (bitfield * 4) as a decimal
1182 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1183 %<bitfield>B print Thumb branch destination (signed displacement)
1184 %<bitfield>c print bitfield as a condition code
1185 %<bitnum>'c print specified char iff bit is one
1186 %<bitnum>?ab print a if bit is one else print b. */
1188 static const struct opcode16 thumb_opcodes
[] =
1190 /* Thumb instructions. */
1192 /* ARM V6K no-argument instructions. */
1193 {ARM_EXT_V6K
, 0xbf00, 0xffff, "nop%c"},
1194 {ARM_EXT_V6K
, 0xbf10, 0xffff, "yield%c"},
1195 {ARM_EXT_V6K
, 0xbf20, 0xffff, "wfe%c"},
1196 {ARM_EXT_V6K
, 0xbf30, 0xffff, "wfi%c"},
1197 {ARM_EXT_V6K
, 0xbf40, 0xffff, "sev%c"},
1198 {ARM_EXT_V6K
, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1200 /* ARM V6T2 instructions. */
1201 {ARM_EXT_V6T2
, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1202 {ARM_EXT_V6T2
, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1203 {ARM_EXT_V6T2
, 0xbf00, 0xff00, "it%I%X"},
1206 {ARM_EXT_V6
, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1207 {ARM_EXT_V6
, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1208 {ARM_EXT_V6
, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1209 {ARM_EXT_V6
, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1210 {ARM_EXT_V6
, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1211 {ARM_EXT_V6
, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1212 {ARM_EXT_V6
, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1213 {ARM_EXT_V6
, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1214 {ARM_EXT_V6
, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1215 {ARM_EXT_V6
, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1216 {ARM_EXT_V6
, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1218 /* ARM V5 ISA extends Thumb. */
1219 {ARM_EXT_V5T
, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1220 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1221 {ARM_EXT_V5T
, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1222 /* ARM V4T ISA (Thumb v1). */
1223 {ARM_EXT_V4T
, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1225 {ARM_EXT_V4T
, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1226 {ARM_EXT_V4T
, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1227 {ARM_EXT_V4T
, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1228 {ARM_EXT_V4T
, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1229 {ARM_EXT_V4T
, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1230 {ARM_EXT_V4T
, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1231 {ARM_EXT_V4T
, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1232 {ARM_EXT_V4T
, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1233 {ARM_EXT_V4T
, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1234 {ARM_EXT_V4T
, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1235 {ARM_EXT_V4T
, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1236 {ARM_EXT_V4T
, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1237 {ARM_EXT_V4T
, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1238 {ARM_EXT_V4T
, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1239 {ARM_EXT_V4T
, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1240 {ARM_EXT_V4T
, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1242 {ARM_EXT_V4T
, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1243 {ARM_EXT_V4T
, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1245 {ARM_EXT_V4T
, 0x4700, 0xFF80, "bx%c\t%S%x"},
1246 {ARM_EXT_V4T
, 0x4400, 0xFF00, "add%c\t%D, %S"},
1247 {ARM_EXT_V4T
, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1248 {ARM_EXT_V4T
, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1250 {ARM_EXT_V4T
, 0xB400, 0xFE00, "push%c\t%N"},
1251 {ARM_EXT_V4T
, 0xBC00, 0xFE00, "pop%c\t%O"},
1253 {ARM_EXT_V4T
, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1254 {ARM_EXT_V4T
, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1255 {ARM_EXT_V4T
, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1256 {ARM_EXT_V4T
, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1258 {ARM_EXT_V4T
, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1259 {ARM_EXT_V4T
, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1260 {ARM_EXT_V4T
, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1262 {ARM_EXT_V4T
, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1263 {ARM_EXT_V4T
, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1265 {ARM_EXT_V4T
, 0x0000, 0xFFC0, "mov%C\t%0-2r, %3-5r"},
1266 {ARM_EXT_V4T
, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1267 {ARM_EXT_V4T
, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1268 {ARM_EXT_V4T
, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1270 {ARM_EXT_V4T
, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1271 {ARM_EXT_V4T
, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1272 {ARM_EXT_V4T
, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1273 {ARM_EXT_V4T
, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1275 {ARM_EXT_V4T
, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1277 {ARM_EXT_V4T
, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1278 {ARM_EXT_V4T
, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1279 {ARM_EXT_V4T
, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1280 {ARM_EXT_V4T
, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1282 {ARM_EXT_V4T
, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1283 {ARM_EXT_V4T
, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1285 {ARM_EXT_V4T
, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1286 {ARM_EXT_V4T
, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1288 {ARM_EXT_V4T
, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1289 {ARM_EXT_V4T
, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1291 {ARM_EXT_V4T
, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1292 {ARM_EXT_V4T
, 0xC800, 0xF800, "ldmia%c\t%8-10r%W, %M"},
1294 {ARM_EXT_V4T
, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1296 {ARM_EXT_V4T
, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION
},
1297 {ARM_EXT_V4T
, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1299 {ARM_EXT_V4T
, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1301 /* The E800 .. FFFF range is unconditionally redirected to the
1302 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1303 are processed via that table. Thus, we can never encounter a
1304 bare "second half of BL/BLX(1)" instruction here. */
1305 {ARM_EXT_V1
, 0x0000, 0x0000, UNDEFINED_INSTRUCTION
},
1309 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1310 We adopt the convention that hw1 is the high 16 bits of .value and
1311 .mask, hw2 the low 16 bits.
1313 print_insn_thumb32 recognizes the following format control codes:
1317 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1318 %M print a modified 12-bit immediate (same location)
1319 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1320 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1321 %H print a 16-bit immediate from hw2[3:0],hw1[11:0]
1322 %S print a possibly-shifted Rm
1324 %a print the address of a plain load/store
1325 %w print the width and signedness of a core load/store
1326 %m print register mask for ldm/stm
1328 %E print the lsb and width fields of a bfc/bfi instruction
1329 %F print the lsb and width fields of a sbfx/ubfx instruction
1330 %b print a conditional branch offset
1331 %B print an unconditional branch offset
1332 %s print the shift field of an SSAT instruction
1333 %R print the rotation field of an SXT instruction
1334 %U print barrier type.
1335 %P print address for pli instruction.
1336 %c print the condition code
1337 %x print warning if conditional an not at end of IT block"
1338 %X print "\t; unpredictable <IT:code>" if conditional
1340 %<bitfield>d print bitfield in decimal
1341 %<bitfield>W print bitfield*4 in decimal
1342 %<bitfield>r print bitfield as an ARM register
1343 %<bitfield>R as %<>r bit r15 is UNPREDICTABLE
1344 %<bitfield>c print bitfield as a condition code
1346 %<bitfield>'c print specified char iff bitfield is all ones
1347 %<bitfield>`c print specified char iff bitfield is all zeroes
1348 %<bitfield>?ab... select from array of values in big endian order
1350 With one exception at the bottom (done because BL and BLX(1) need
1351 to come dead last), this table was machine-sorted first in
1352 decreasing order of number of bits set in the mask, then in
1353 increasing numeric order of mask, then in increasing numeric order
1354 of opcode. This order is not the clearest for a human reader, but
1355 is guaranteed never to catch a special-case bit pattern with a more
1356 general mask, which is important, because this instruction encoding
1357 makes heavy use of special-case bit patterns. */
1358 static const struct opcode32 thumb32_opcodes
[] =
1360 /* V7 instructions. */
1361 {ARM_EXT_V7
, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1362 {ARM_EXT_V7
, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1363 {ARM_EXT_V7
, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1364 {ARM_EXT_V7
, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1365 {ARM_EXT_V7
, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1366 {ARM_EXT_DIV
, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_DIV
, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1369 /* Virtualization Extension instructions. */
1370 {ARM_EXT_VIRT
, 0xf7e08000, 0xfff0f000, "hvc%c\t%V"},
1371 /* We skip ERET as that is SUBS pc, lr, #0. */
1373 /* MP Extension instructions. */
1374 {ARM_EXT_MP
, 0xf830f000, 0xff70f000, "pldw%c\t%a"},
1376 /* Security extension instructions. */
1377 {ARM_EXT_SEC
, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1379 /* Instructions defined in the basic V6T2 set. */
1380 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffffff, "nop%c.w"},
1381 {ARM_EXT_V6T2
, 0xf3af8001, 0xffffffff, "yield%c.w"},
1382 {ARM_EXT_V6T2
, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1383 {ARM_EXT_V6T2
, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1384 {ARM_EXT_V6T2
, 0xf3af8004, 0xffffffff, "sev%c.w"},
1385 {ARM_EXT_V6T2
, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1387 {ARM_EXT_V6T2
, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1388 {ARM_EXT_V6T2
, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1389 {ARM_EXT_V6T2
, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1390 {ARM_EXT_V6T2
, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1391 {ARM_EXT_V6T2
, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1392 {ARM_EXT_V6T2
, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1393 {ARM_EXT_V6T2
, 0xf3e08000, 0xffe0f000, "mrs%c\t%8-11r, %D"},
1394 {ARM_EXT_V6T2
, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1395 {ARM_EXT_V6T2
, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1396 {ARM_EXT_V6T2
, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1397 {ARM_EXT_V6T2
, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1398 {ARM_EXT_V6T2
, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1399 {ARM_EXT_V6T2
, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1400 {ARM_EXT_V6T2
, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1401 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1402 {ARM_EXT_V6T2
, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1403 {ARM_EXT_V6T2
, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1404 {ARM_EXT_V6T2
, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1405 {ARM_EXT_V6T2
, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1406 {ARM_EXT_V6T2
, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1407 {ARM_EXT_V6T2
, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1408 {ARM_EXT_V6T2
, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1409 {ARM_EXT_V6T2
, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1410 {ARM_EXT_V6T2
, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1411 {ARM_EXT_V6T2
, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1412 {ARM_EXT_V6T2
, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1413 {ARM_EXT_V6T2
, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1414 {ARM_EXT_V6T2
, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1415 {ARM_EXT_V6T2
, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1416 {ARM_EXT_V6T2
, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1417 {ARM_EXT_V6T2
, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1418 {ARM_EXT_V6T2
, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2
, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1420 {ARM_EXT_V6T2
, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1421 {ARM_EXT_V6T2
, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1422 {ARM_EXT_V6T2
, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1423 {ARM_EXT_V6T2
, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1424 {ARM_EXT_V6T2
, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1425 {ARM_EXT_V6T2
, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1426 {ARM_EXT_V6T2
, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1427 {ARM_EXT_V6T2
, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1428 {ARM_EXT_V6T2
, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1429 {ARM_EXT_V6T2
, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1430 {ARM_EXT_V6T2
, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1431 {ARM_EXT_V6T2
, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1432 {ARM_EXT_V6T2
, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1433 {ARM_EXT_V6T2
, 0xfaa0f000, 0xfff0f0f0, "sasx%c\t%8-11r, %16-19r, %0-3r"},
1434 {ARM_EXT_V6T2
, 0xfaa0f010, 0xfff0f0f0, "qasx%c\t%8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2
, 0xfaa0f020, 0xfff0f0f0, "shasx%c\t%8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2
, 0xfaa0f040, 0xfff0f0f0, "uasx%c\t%8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2
, 0xfaa0f050, 0xfff0f0f0, "uqasx%c\t%8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2
, 0xfaa0f060, 0xfff0f0f0, "uhasx%c\t%8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2
, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1440 {ARM_EXT_V6T2
, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1441 {ARM_EXT_V6T2
, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1442 {ARM_EXT_V6T2
, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1443 {ARM_EXT_V6T2
, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1444 {ARM_EXT_V6T2
, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1445 {ARM_EXT_V6T2
, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1446 {ARM_EXT_V6T2
, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1447 {ARM_EXT_V6T2
, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1448 {ARM_EXT_V6T2
, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1449 {ARM_EXT_V6T2
, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2
, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2
, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1452 {ARM_EXT_V6T2
, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1453 {ARM_EXT_V6T2
, 0xfae0f000, 0xfff0f0f0, "ssax%c\t%8-11r, %16-19r, %0-3r"},
1454 {ARM_EXT_V6T2
, 0xfae0f010, 0xfff0f0f0, "qsax%c\t%8-11r, %16-19r, %0-3r"},
1455 {ARM_EXT_V6T2
, 0xfae0f020, 0xfff0f0f0, "shsax%c\t%8-11r, %16-19r, %0-3r"},
1456 {ARM_EXT_V6T2
, 0xfae0f040, 0xfff0f0f0, "usax%c\t%8-11r, %16-19r, %0-3r"},
1457 {ARM_EXT_V6T2
, 0xfae0f050, 0xfff0f0f0, "uqsax%c\t%8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2
, 0xfae0f060, 0xfff0f0f0, "uhsax%c\t%8-11r, %16-19r, %0-3r"},
1459 {ARM_EXT_V6T2
, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1460 {ARM_EXT_V6T2
, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1461 {ARM_EXT_V6T2
, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1462 {ARM_EXT_V6T2
, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1463 {ARM_EXT_V6T2
, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11R, %16-19R, %0-3R"},
1464 {ARM_EXT_V6T2
, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1465 {ARM_EXT_V6T2
, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1466 {ARM_EXT_V6T2
, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1467 {ARM_EXT_V6T2
, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1468 {ARM_EXT_V6T2
, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1469 {ARM_EXT_V6T2
, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1470 {ARM_EXT_V6T2
, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1471 {ARM_EXT_V6T2
, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1472 {ARM_EXT_V6T2
, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1473 {ARM_EXT_V6T2
, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1474 {ARM_EXT_V6T2
, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1475 {ARM_EXT_V6T2
, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1476 {ARM_EXT_V6T2
, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1477 {ARM_EXT_V6T2
, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1478 {ARM_EXT_V6T2
, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1479 {ARM_EXT_V6T2
, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1480 {ARM_EXT_V6T2
, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1481 {ARM_EXT_V6T2
, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1482 {ARM_EXT_V6T2
, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1483 {ARM_EXT_V6T2
, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1484 {ARM_EXT_V6T2
, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1485 {ARM_EXT_V6T2
, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1486 {ARM_EXT_V6T2
, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1487 {ARM_EXT_V6T2
, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1488 {ARM_EXT_V6T2
, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1489 {ARM_EXT_V6T2
, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1490 {ARM_EXT_V6T2
, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1491 {ARM_EXT_V6T2
, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1492 {ARM_EXT_V6T2
, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1493 {ARM_EXT_V6T2
, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1494 {ARM_EXT_V6T2
, 0xfb800000, 0xfff000f0, "smull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1495 {ARM_EXT_V6T2
, 0xfba00000, 0xfff000f0, "umull%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1496 {ARM_EXT_V6T2
, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1497 {ARM_EXT_V6T2
, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1498 {ARM_EXT_V6T2
, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1499 {ARM_EXT_V6T2
, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1500 {ARM_EXT_V6T2
, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1501 {ARM_EXT_V6T2
, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1502 {ARM_EXT_V6T2
, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1503 {ARM_EXT_V6T2
, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1504 {ARM_EXT_V6T2
, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1505 {ARM_EXT_V6T2
, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1506 {ARM_EXT_V6T2
, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1507 {ARM_EXT_V6T2
, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11R, %16-19R, %0-3R, %12-15R"},
1508 {ARM_EXT_V6T2
, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1509 {ARM_EXT_V6T2
, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15R, %8-11R, %16-19R, %0-3R"},
1510 {ARM_EXT_V6T2
, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1511 {ARM_EXT_V6T2
, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1512 {ARM_EXT_V6T2
, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1513 {ARM_EXT_V6T2
, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1514 {ARM_EXT_V6T2
, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1515 {ARM_EXT_V6T2
, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1516 {ARM_EXT_V6T2
, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1517 {ARM_EXT_V6T2
, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1518 {ARM_EXT_V6T2
, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1519 {ARM_EXT_V6T2
, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1520 {ARM_EXT_V6T2
, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1521 {ARM_EXT_V6T2
, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1522 {ARM_EXT_V6T2
, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1523 {ARM_EXT_V6T2
, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1524 {ARM_EXT_V6T2
, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1525 {ARM_EXT_V6T2
, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1526 {ARM_EXT_V6T2
, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1527 {ARM_EXT_V6T2
, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1528 {ARM_EXT_V6T2
, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1529 {ARM_EXT_V6T2
, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1530 {ARM_EXT_V6T2
, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1531 {ARM_EXT_V6T2
, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1532 {ARM_EXT_V6T2
, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1533 {ARM_EXT_V6T2
, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1534 {ARM_EXT_V6T2
, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1535 {ARM_EXT_V6T2
, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1536 {ARM_EXT_V6T2
, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1537 {ARM_EXT_V6T2
, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1538 {ARM_EXT_V6T2
, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1539 {ARM_EXT_V6T2
, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1540 {ARM_EXT_V6T2
, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1541 {ARM_EXT_V6T2
, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1542 {ARM_EXT_V6T2
, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1543 {ARM_EXT_V6T2
, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1544 {ARM_EXT_V6T2
, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1545 {ARM_EXT_V6T2
, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1546 {ARM_EXT_V6T2
, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1547 {ARM_EXT_V6T2
, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1548 {ARM_EXT_V6T2
, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1549 {ARM_EXT_V6T2
, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1550 {ARM_EXT_V6T2
, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1551 {ARM_EXT_V6T2
, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1552 {ARM_EXT_V6T2
, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1553 {ARM_EXT_V6T2
, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1554 {ARM_EXT_V6T2
, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1555 {ARM_EXT_V6T2
, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1556 {ARM_EXT_V6T2
, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1557 {ARM_EXT_V6T2
, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1559 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1560 {ARM_EXT_V6T2
, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1561 {ARM_EXT_V6T2
, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1562 {ARM_EXT_V6T2
, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1563 {ARM_EXT_V6T2
, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1565 /* These have been 32-bit since the invention of Thumb. */
1566 {ARM_EXT_V4T
, 0xf000c000, 0xf800d001, "blx%c\t%B%x"},
1567 {ARM_EXT_V4T
, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1570 {ARM_EXT_V1
, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION
},
1574 static const char *const arm_conditional
[] =
1575 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1576 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1578 static const char *const arm_fp_const
[] =
1579 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1581 static const char *const arm_shift
[] =
1582 {"lsl", "lsr", "asr", "ror"};
1587 const char *description
;
1588 const char *reg_names
[16];
1592 static const arm_regname regnames
[] =
1594 { "raw" , "Select raw register names",
1595 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1596 { "gcc", "Select register names used by GCC",
1597 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1598 { "std", "Select register names used in ARM's ISA documentation",
1599 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1600 { "apcs", "Select register names used in the APCS",
1601 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1602 { "atpcs", "Select register names used in the ATPCS",
1603 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1604 { "special-atpcs", "Select special register names used in the ATPCS",
1605 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1608 static const char *const iwmmxt_wwnames
[] =
1609 {"b", "h", "w", "d"};
1611 static const char *const iwmmxt_wwssnames
[] =
1612 {"b", "bus", "bc", "bss",
1613 "h", "hus", "hc", "hss",
1614 "w", "wus", "wc", "wss",
1615 "d", "dus", "dc", "dss"
1618 static const char *const iwmmxt_regnames
[] =
1619 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1620 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1623 static const char *const iwmmxt_cregnames
[] =
1624 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1625 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1628 /* Default to GCC register name set. */
1629 static unsigned int regname_selected
= 1;
1631 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1632 #define arm_regnames regnames[regname_selected].reg_names
1634 static bfd_boolean force_thumb
= FALSE
;
1636 /* Current IT instruction state. This contains the same state as the IT
1637 bits in the CPSR. */
1638 static unsigned int ifthen_state
;
1639 /* IT state for the next instruction. */
1640 static unsigned int ifthen_next_state
;
1641 /* The address of the insn for which the IT state is valid. */
1642 static bfd_vma ifthen_address
;
1643 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1645 /* Cached mapping symbol state. */
1653 enum map_type last_type
;
1654 int last_mapping_sym
= -1;
1655 bfd_vma last_mapping_addr
= 0;
1660 get_arm_regname_num_options (void)
1662 return NUM_ARM_REGNAMES
;
1666 set_arm_regname_option (int option
)
1668 int old
= regname_selected
;
1669 regname_selected
= option
;
1674 get_arm_regnames (int option
,
1675 const char **setname
,
1676 const char **setdescription
,
1677 const char *const **register_names
)
1679 *setname
= regnames
[option
].name
;
1680 *setdescription
= regnames
[option
].description
;
1681 *register_names
= regnames
[option
].reg_names
;
1685 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1686 Returns pointer to following character of the format string and
1687 fills in *VALUEP and *WIDTHP with the extracted value and number of
1688 bits extracted. WIDTHP can be NULL. */
1691 arm_decode_bitfield (const char *ptr
,
1693 unsigned long *valuep
,
1696 unsigned long value
= 0;
1704 for (start
= 0; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1705 start
= start
* 10 + *ptr
- '0';
1707 for (end
= 0, ptr
++; *ptr
>= '0' && *ptr
<= '9'; ptr
++)
1708 end
= end
* 10 + *ptr
- '0';
1714 value
|= ((insn
>> start
) & ((2ul << bits
) - 1)) << width
;
1717 while (*ptr
++ == ',');
1725 arm_decode_shift (long given
, fprintf_ftype func
, void *stream
,
1726 bfd_boolean print_shift
)
1728 func (stream
, "%s", arm_regnames
[given
& 0xf]);
1730 if ((given
& 0xff0) != 0)
1732 if ((given
& 0x10) == 0)
1734 int amount
= (given
& 0xf80) >> 7;
1735 int shift
= (given
& 0x60) >> 5;
1741 func (stream
, ", rrx");
1749 func (stream
, ", %s #%d", arm_shift
[shift
], amount
);
1751 func (stream
, ", #%d", amount
);
1753 else if ((given
& 0x80) == 0x80)
1754 func (stream
, "\t; <illegal shifter operand>");
1755 else if (print_shift
)
1756 func (stream
, ", %s %s", arm_shift
[(given
& 0x60) >> 5],
1757 arm_regnames
[(given
& 0xf00) >> 8]);
1759 func (stream
, ", %s", arm_regnames
[(given
& 0xf00) >> 8]);
1768 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1769 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1770 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1771 #define PRE_BIT_SET (given & (1 << P_BIT))
1773 /* Print one coprocessor instruction on INFO->STREAM.
1774 Return TRUE if the instuction matched, FALSE if this is not a
1775 recognised coprocessor instruction. */
1778 print_insn_coprocessor (bfd_vma pc
,
1779 struct disassemble_info
*info
,
1783 const struct opcode32
*insn
;
1784 void *stream
= info
->stream
;
1785 fprintf_ftype func
= info
->fprintf_func
;
1787 unsigned long value
= 0;
1788 struct arm_private_data
*private_data
= info
->private_data
;
1789 unsigned long allowed_arches
= private_data
->features
.coproc
;
1792 for (insn
= coprocessor_opcodes
; insn
->assembler
; insn
++)
1794 unsigned long u_reg
= 16;
1795 bfd_boolean is_unpredictable
= FALSE
;
1796 signed long value_in_comment
= 0;
1799 if (insn
->arch
== 0)
1800 switch (insn
->value
)
1802 case SENTINEL_IWMMXT_START
:
1803 if (info
->mach
!= bfd_mach_arm_XScale
1804 && info
->mach
!= bfd_mach_arm_iWMMXt
1805 && info
->mach
!= bfd_mach_arm_iWMMXt2
)
1808 while (insn
->arch
!= 0 && insn
->value
!= SENTINEL_IWMMXT_END
);
1811 case SENTINEL_IWMMXT_END
:
1814 case SENTINEL_GENERIC_START
:
1815 allowed_arches
= private_data
->features
.core
;
1823 value
= insn
->value
;
1826 /* The high 4 bits are 0xe for Arm conditional instructions, and
1827 0xe for arm unconditional instructions. The rest of the
1828 encoding is the same. */
1830 value
|= 0xe0000000;
1838 /* Only match unconditional instuctions against unconditional
1840 if ((given
& 0xf0000000) == 0xf0000000)
1847 cond
= (given
>> 28) & 0xf;
1853 if ((given
& mask
) != value
)
1856 if ((insn
->arch
& allowed_arches
) == 0)
1859 for (c
= insn
->assembler
; *c
; c
++)
1866 func (stream
, "%%");
1871 int rn
= (given
>> 16) & 0xf;
1872 int offset
= given
& 0xff;
1874 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
1876 if (PRE_BIT_SET
|| WRITEBACK_BIT_SET
)
1878 /* Not unindexed. The offset is scaled. */
1879 offset
= offset
* 4;
1880 if (NEGATIVE_BIT_SET
)
1883 value_in_comment
= offset
;
1889 func (stream
, ", #%d]%s",
1891 WRITEBACK_BIT_SET
? "!" : "");
1899 if (WRITEBACK_BIT_SET
)
1902 func (stream
, ", #%d", offset
);
1906 func (stream
, ", {%d}", offset
);
1907 value_in_comment
= offset
;
1910 if (rn
== 15 && (PRE_BIT_SET
|| WRITEBACK_BIT_SET
))
1912 func (stream
, "\t; ");
1913 /* For unaligned PCs, apply off-by-alignment
1915 info
->print_address_func (offset
+ pc
1916 + info
->bytes_per_chunk
* 2
1925 int regno
= ((given
>> 12) & 0xf) | ((given
>> (22 - 4)) & 0x10);
1926 int offset
= (given
>> 1) & 0x3f;
1929 func (stream
, "{d%d}", regno
);
1930 else if (regno
+ offset
> 32)
1931 func (stream
, "{d%d-<overflow reg d%d>}", regno
, regno
+ offset
- 1);
1933 func (stream
, "{d%d-d%d}", regno
, regno
+ offset
- 1);
1938 func (stream
, "%s", arm_conditional
[cond
]);
1942 /* Print a Cirrus/DSP shift immediate. */
1943 /* Immediates are 7bit signed ints with bits 0..3 in
1944 bits 0..3 of opcode and bits 4..6 in bits 5..7
1949 imm
= (given
& 0xf) | ((given
& 0xe0) >> 1);
1951 /* Is ``imm'' a negative number? */
1955 func (stream
, "%d", imm
);
1961 switch (given
& 0x00408000)
1978 switch (given
& 0x00080080)
1990 func (stream
, _("<illegal precision>"));
1996 switch (given
& 0x00408000)
2014 switch (given
& 0x60)
2030 case '0': case '1': case '2': case '3': case '4':
2031 case '5': case '6': case '7': case '8': case '9':
2035 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2041 is_unpredictable
= TRUE
;
2046 /* Eat the 'u' character. */
2050 is_unpredictable
= TRUE
;
2053 func (stream
, "%s", arm_regnames
[value
]);
2056 func (stream
, "d%ld", value
);
2060 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2062 func (stream
, "q%ld", value
>> 1);
2065 func (stream
, "%ld", value
);
2066 value_in_comment
= value
;
2070 int from
= (given
& (1 << 7)) ? 32 : 16;
2071 func (stream
, "%ld", from
- value
);
2077 func (stream
, "#%s", arm_fp_const
[value
& 7]);
2079 func (stream
, "f%ld", value
);
2084 func (stream
, "%s", iwmmxt_wwnames
[value
]);
2086 func (stream
, "%s", iwmmxt_wwssnames
[value
]);
2090 func (stream
, "%s", iwmmxt_regnames
[value
]);
2093 func (stream
, "%s", iwmmxt_cregnames
[value
]);
2097 func (stream
, "0x%lx", (value
& 0xffffffffUL
));
2103 func (stream
, "%c", *c
);
2107 if (value
== ((1ul << width
) - 1))
2108 func (stream
, "%c", *c
);
2111 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2122 int single
= *c
++ == 'y';
2127 case '4': /* Sm pair */
2128 case '0': /* Sm, Dm */
2129 regno
= given
& 0x0000000f;
2133 regno
+= (given
>> 5) & 1;
2136 regno
+= ((given
>> 5) & 1) << 4;
2139 case '1': /* Sd, Dd */
2140 regno
= (given
>> 12) & 0x0000000f;
2144 regno
+= (given
>> 22) & 1;
2147 regno
+= ((given
>> 22) & 1) << 4;
2150 case '2': /* Sn, Dn */
2151 regno
= (given
>> 16) & 0x0000000f;
2155 regno
+= (given
>> 7) & 1;
2158 regno
+= ((given
>> 7) & 1) << 4;
2161 case '3': /* List */
2163 regno
= (given
>> 12) & 0x0000000f;
2167 regno
+= (given
>> 22) & 1;
2170 regno
+= ((given
>> 22) & 1) << 4;
2177 func (stream
, "%c%d", single
? 's' : 'd', regno
);
2181 int count
= given
& 0xff;
2188 func (stream
, "-%c%d",
2196 func (stream
, ", %c%d", single
? 's' : 'd',
2202 switch (given
& 0x00400100)
2204 case 0x00000000: func (stream
, "b"); break;
2205 case 0x00400000: func (stream
, "h"); break;
2206 case 0x00000100: func (stream
, "w"); break;
2207 case 0x00400100: func (stream
, "d"); break;
2215 /* given (20, 23) | given (0, 3) */
2216 value
= ((given
>> 16) & 0xf0) | (given
& 0xf);
2217 func (stream
, "%d", value
);
2222 /* This is like the 'A' operator, except that if
2223 the width field "M" is zero, then the offset is
2224 *not* multiplied by four. */
2226 int offset
= given
& 0xff;
2227 int multiplier
= (given
& 0x00000100) ? 4 : 1;
2229 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
2233 value_in_comment
= offset
* multiplier
;
2234 if (NEGATIVE_BIT_SET
)
2235 value_in_comment
= - value_in_comment
;
2241 func (stream
, ", #%s%d]%s",
2242 NEGATIVE_BIT_SET
? "-" : "",
2243 offset
* multiplier
,
2244 WRITEBACK_BIT_SET
? "!" : "");
2246 func (stream
, "], #%s%d",
2247 NEGATIVE_BIT_SET
? "-" : "",
2248 offset
* multiplier
);
2257 int imm4
= (given
>> 4) & 0xf;
2258 int puw_bits
= ((given
>> 22) & 6) | ((given
>> W_BIT
) & 1);
2259 int ubit
= ! NEGATIVE_BIT_SET
;
2260 const char *rm
= arm_regnames
[given
& 0xf];
2261 const char *rn
= arm_regnames
[(given
>> 16) & 0xf];
2267 func (stream
, "[%s], %c%s", rn
, ubit
? '+' : '-', rm
);
2269 func (stream
, ", lsl #%d", imm4
);
2276 func (stream
, "[%s, %c%s", rn
, ubit
? '+' : '-', rm
);
2278 func (stream
, ", lsl #%d", imm4
);
2280 if (puw_bits
== 5 || puw_bits
== 7)
2285 func (stream
, "INVALID");
2293 imm5
= ((given
& 0x100) >> 4) | (given
& 0xf);
2294 func (stream
, "%ld", (imm5
== 0) ? 32 : imm5
);
2304 func (stream
, "%c", *c
);
2307 if (value_in_comment
> 32 || value_in_comment
< -16)
2308 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
2310 if (is_unpredictable
)
2311 func (stream
, UNPREDICTABLE_INSTRUCTION
);
2318 /* Decodes and prints ARM addressing modes. Returns the offset
2319 used in the address, if any, if it is worthwhile printing the
2320 offset as a hexadecimal value in a comment at the end of the
2321 line of disassembly. */
2324 print_arm_address (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2326 void *stream
= info
->stream
;
2327 fprintf_ftype func
= info
->fprintf_func
;
2330 if (((given
& 0x000f0000) == 0x000f0000)
2331 && ((given
& 0x02000000) == 0))
2333 offset
= given
& 0xfff;
2335 func (stream
, "[pc");
2337 if (NEGATIVE_BIT_SET
)
2343 func (stream
, ", #%d]", offset
);
2347 /* Cope with the possibility of write-back
2348 being used. Probably a very dangerous thing
2349 for the programmer to do, but who are we to
2351 if (WRITEBACK_BIT_SET
)
2354 else /* Post indexed. */
2356 func (stream
, "], #%d", offset
);
2358 /* Ie ignore the offset. */
2362 func (stream
, "\t; ");
2363 info
->print_address_func (offset
, info
);
2368 func (stream
, "[%s",
2369 arm_regnames
[(given
>> 16) & 0xf]);
2373 if ((given
& 0x02000000) == 0)
2375 offset
= given
& 0xfff;
2377 func (stream
, ", #%s%d",
2378 NEGATIVE_BIT_SET
? "-" : "", offset
);
2382 func (stream
, ", %s",
2383 NEGATIVE_BIT_SET
? "-" : "");
2384 arm_decode_shift (given
, func
, stream
, TRUE
);
2387 func (stream
, "]%s",
2388 WRITEBACK_BIT_SET
? "!" : "");
2392 if ((given
& 0x02000000) == 0)
2394 offset
= given
& 0xfff;
2396 func (stream
, "], #%s%d",
2397 NEGATIVE_BIT_SET
? "-" : "", offset
);
2403 func (stream
, "], %s",
2404 NEGATIVE_BIT_SET
? "-" : "");
2405 arm_decode_shift (given
, func
, stream
, TRUE
);
2410 return (signed long) offset
;
2413 /* Print one neon instruction on INFO->STREAM.
2414 Return TRUE if the instuction matched, FALSE if this is not a
2415 recognised neon instruction. */
2418 print_insn_neon (struct disassemble_info
*info
, long given
, bfd_boolean thumb
)
2420 const struct opcode32
*insn
;
2421 void *stream
= info
->stream
;
2422 fprintf_ftype func
= info
->fprintf_func
;
2426 if ((given
& 0xef000000) == 0xef000000)
2428 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2429 unsigned long bit28
= given
& (1 << 28);
2431 given
&= 0x00ffffff;
2433 given
|= 0xf3000000;
2435 given
|= 0xf2000000;
2437 else if ((given
& 0xff000000) == 0xf9000000)
2438 given
^= 0xf9000000 ^ 0xf4000000;
2443 for (insn
= neon_opcodes
; insn
->assembler
; insn
++)
2445 if ((given
& insn
->mask
) == insn
->value
)
2447 signed long value_in_comment
= 0;
2450 for (c
= insn
->assembler
; *c
; c
++)
2457 func (stream
, "%%");
2461 if (thumb
&& ifthen_state
)
2462 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
2467 static const unsigned char enc
[16] =
2469 0x4, 0x14, /* st4 0,1 */
2481 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2482 int rn
= ((given
>> 16) & 0xf);
2483 int rm
= ((given
>> 0) & 0xf);
2484 int align
= ((given
>> 4) & 0x3);
2485 int type
= ((given
>> 8) & 0xf);
2486 int n
= enc
[type
] & 0xf;
2487 int stride
= (enc
[type
] >> 4) + 1;
2492 for (ix
= 0; ix
!= n
; ix
++)
2493 func (stream
, "%sd%d", ix
? "," : "", rd
+ ix
* stride
);
2495 func (stream
, "d%d", rd
);
2497 func (stream
, "d%d-d%d", rd
, rd
+ n
- 1);
2498 func (stream
, "}, [%s", arm_regnames
[rn
]);
2500 func (stream
, " :%d", 32 << align
);
2505 func (stream
, ", %s", arm_regnames
[rm
]);
2511 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2512 int rn
= ((given
>> 16) & 0xf);
2513 int rm
= ((given
>> 0) & 0xf);
2514 int idx_align
= ((given
>> 4) & 0xf);
2516 int size
= ((given
>> 10) & 0x3);
2517 int idx
= idx_align
>> (size
+ 1);
2518 int length
= ((given
>> 8) & 3) + 1;
2522 if (length
> 1 && size
> 0)
2523 stride
= (idx_align
& (1 << size
)) ? 2 : 1;
2529 int amask
= (1 << size
) - 1;
2530 if ((idx_align
& (1 << size
)) != 0)
2534 if ((idx_align
& amask
) == amask
)
2536 else if ((idx_align
& amask
) != 0)
2543 if (size
== 2 && (idx_align
& 2) != 0)
2545 align
= (idx_align
& 1) ? 16 << size
: 0;
2549 if ((size
== 2 && (idx_align
& 3) != 0)
2550 || (idx_align
& 1) != 0)
2557 if ((idx_align
& 3) == 3)
2559 align
= (idx_align
& 3) * 64;
2562 align
= (idx_align
& 1) ? 32 << size
: 0;
2570 for (i
= 0; i
< length
; i
++)
2571 func (stream
, "%sd%d[%d]", (i
== 0) ? "" : ",",
2572 rd
+ i
* stride
, idx
);
2573 func (stream
, "}, [%s", arm_regnames
[rn
]);
2575 func (stream
, " :%d", align
);
2580 func (stream
, ", %s", arm_regnames
[rm
]);
2586 int rd
= ((given
>> 12) & 0xf) | (((given
>> 22) & 1) << 4);
2587 int rn
= ((given
>> 16) & 0xf);
2588 int rm
= ((given
>> 0) & 0xf);
2589 int align
= ((given
>> 4) & 0x1);
2590 int size
= ((given
>> 6) & 0x3);
2591 int type
= ((given
>> 8) & 0x3);
2593 int stride
= ((given
>> 5) & 0x1);
2596 if (stride
&& (n
== 1))
2603 for (ix
= 0; ix
!= n
; ix
++)
2604 func (stream
, "%sd%d[]", ix
? "," : "", rd
+ ix
* stride
);
2606 func (stream
, "d%d[]", rd
);
2608 func (stream
, "d%d[]-d%d[]", rd
, rd
+ n
- 1);
2609 func (stream
, "}, [%s", arm_regnames
[rn
]);
2612 align
= (8 * (type
+ 1)) << size
;
2614 align
= (size
> 1) ? align
>> 1 : align
;
2615 if (type
== 2 || (type
== 0 && !size
))
2616 func (stream
, " :<bad align %d>", align
);
2618 func (stream
, " :%d", align
);
2624 func (stream
, ", %s", arm_regnames
[rm
]);
2630 int raw_reg
= (given
& 0xf) | ((given
>> 1) & 0x10);
2631 int size
= (given
>> 20) & 3;
2632 int reg
= raw_reg
& ((4 << size
) - 1);
2633 int ix
= raw_reg
>> size
>> 2;
2635 func (stream
, "d%d[%d]", reg
, ix
);
2640 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2643 int cmode
= (given
>> 8) & 0xf;
2644 int op
= (given
>> 5) & 0x1;
2645 unsigned long value
= 0, hival
= 0;
2650 bits
|= ((given
>> 24) & 1) << 7;
2651 bits
|= ((given
>> 16) & 7) << 4;
2652 bits
|= ((given
>> 0) & 15) << 0;
2656 shift
= (cmode
>> 1) & 3;
2657 value
= (unsigned long) bits
<< (8 * shift
);
2660 else if (cmode
< 12)
2662 shift
= (cmode
>> 1) & 1;
2663 value
= (unsigned long) bits
<< (8 * shift
);
2666 else if (cmode
< 14)
2668 shift
= (cmode
& 1) + 1;
2669 value
= (unsigned long) bits
<< (8 * shift
);
2670 value
|= (1ul << (8 * shift
)) - 1;
2673 else if (cmode
== 14)
2677 /* Bit replication into bytes. */
2683 for (ix
= 7; ix
>= 0; ix
--)
2685 mask
= ((bits
>> ix
) & 1) ? 0xff : 0;
2687 value
= (value
<< 8) | mask
;
2689 hival
= (hival
<< 8) | mask
;
2695 /* Byte replication. */
2696 value
= (unsigned long) bits
;
2702 /* Floating point encoding. */
2705 value
= (unsigned long) (bits
& 0x7f) << 19;
2706 value
|= (unsigned long) (bits
& 0x80) << 24;
2707 tmp
= bits
& 0x40 ? 0x3c : 0x40;
2708 value
|= (unsigned long) tmp
<< 24;
2714 func (stream
, "<illegal constant %.8x:%x:%x>",
2722 func (stream
, "#%ld\t; 0x%.2lx", value
, value
);
2726 func (stream
, "#%ld\t; 0x%.4lx", value
, value
);
2732 unsigned char valbytes
[4];
2735 /* Do this a byte at a time so we don't have to
2736 worry about the host's endianness. */
2737 valbytes
[0] = value
& 0xff;
2738 valbytes
[1] = (value
>> 8) & 0xff;
2739 valbytes
[2] = (value
>> 16) & 0xff;
2740 valbytes
[3] = (value
>> 24) & 0xff;
2742 floatformat_to_double
2743 (& floatformat_ieee_single_little
, valbytes
,
2746 func (stream
, "#%.7g\t; 0x%.8lx", fvalue
,
2750 func (stream
, "#%ld\t; 0x%.8lx",
2751 (long) (((value
& 0x80000000L
) != 0)
2752 ? value
| ~0xffffffffL
: value
),
2757 func (stream
, "#0x%.8lx%.8lx", hival
, value
);
2768 int regno
= ((given
>> 16) & 0xf) | ((given
>> (7 - 4)) & 0x10);
2769 int num
= (given
>> 8) & 0x3;
2772 func (stream
, "{d%d}", regno
);
2773 else if (num
+ regno
>= 32)
2774 func (stream
, "{d%d-<overflow reg d%d}", regno
, regno
+ num
);
2776 func (stream
, "{d%d-d%d}", regno
, regno
+ num
);
2781 case '0': case '1': case '2': case '3': case '4':
2782 case '5': case '6': case '7': case '8': case '9':
2785 unsigned long value
;
2787 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
2792 func (stream
, "%s", arm_regnames
[value
]);
2795 func (stream
, "%ld", value
);
2796 value_in_comment
= value
;
2799 func (stream
, "%ld", (1ul << width
) - value
);
2805 /* Various width encodings. */
2807 int base
= 8 << (*c
- 'S'); /* 8,16 or 32 */
2812 if (*c
>= '0' && *c
<= '9')
2814 else if (*c
>= 'a' && *c
<= 'f')
2815 limit
= *c
- 'a' + 10;
2821 if (value
< low
|| value
> high
)
2822 func (stream
, "<illegal width %d>", base
<< value
);
2824 func (stream
, "%d", base
<< value
);
2828 if (given
& (1 << 6))
2832 func (stream
, "d%ld", value
);
2837 func (stream
, "<illegal reg q%ld.5>", value
>> 1);
2839 func (stream
, "q%ld", value
>> 1);
2845 func (stream
, "%c", *c
);
2849 if (value
== ((1ul << width
) - 1))
2850 func (stream
, "%c", *c
);
2853 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
2867 func (stream
, "%c", *c
);
2870 if (value_in_comment
> 32 || value_in_comment
< -16)
2871 func (stream
, "\t; 0x%lx", value_in_comment
);
2879 /* Return the name of a v7A special register. */
2882 banked_regname (unsigned reg
)
2886 case 15: return "CPSR";
2887 case 32: return "R8_usr";
2888 case 33: return "R9_usr";
2889 case 34: return "R10_usr";
2890 case 35: return "R11_usr";
2891 case 36: return "R12_usr";
2892 case 37: return "SP_usr";
2893 case 38: return "LR_usr";
2894 case 40: return "R8_fiq";
2895 case 41: return "R9_fiq";
2896 case 42: return "R10_fiq";
2897 case 43: return "R11_fiq";
2898 case 44: return "R12_fiq";
2899 case 45: return "SP_fiq";
2900 case 46: return "LR_fiq";
2901 case 48: return "LR_irq";
2902 case 49: return "SP_irq";
2903 case 50: return "LR_svc";
2904 case 51: return "SP_svc";
2905 case 52: return "LR_abt";
2906 case 53: return "SP_abt";
2907 case 54: return "LR_und";
2908 case 55: return "SP_und";
2909 case 60: return "LR_mon";
2910 case 61: return "SP_mon";
2911 case 62: return "ELR_hyp";
2912 case 63: return "SP_hyp";
2913 case 79: return "SPSR";
2914 case 110: return "SPSR_fiq";
2915 case 112: return "SPSR_irq";
2916 case 114: return "SPSR_svc";
2917 case 116: return "SPSR_abt";
2918 case 118: return "SPSR_und";
2919 case 124: return "SPSR_mon";
2920 case 126: return "SPSR_hyp";
2921 default: return NULL
;
2925 /* Print one ARM instruction from PC on INFO->STREAM. */
2928 print_insn_arm (bfd_vma pc
, struct disassemble_info
*info
, long given
)
2930 const struct opcode32
*insn
;
2931 void *stream
= info
->stream
;
2932 fprintf_ftype func
= info
->fprintf_func
;
2933 struct arm_private_data
*private_data
= info
->private_data
;
2935 if (print_insn_coprocessor (pc
, info
, given
, FALSE
))
2938 if (print_insn_neon (info
, given
, FALSE
))
2941 for (insn
= arm_opcodes
; insn
->assembler
; insn
++)
2943 if ((given
& insn
->mask
) != insn
->value
)
2946 if ((insn
->arch
& private_data
->features
.core
) == 0)
2949 /* Special case: an instruction with all bits set in the condition field
2950 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2951 or by the catchall at the end of the table. */
2952 if ((given
& 0xF0000000) != 0xF0000000
2953 || (insn
->mask
& 0xF0000000) == 0xF0000000
2954 || (insn
->mask
== 0 && insn
->value
== 0))
2956 unsigned long u_reg
= 16;
2957 unsigned long U_reg
= 16;
2958 bfd_boolean is_unpredictable
= FALSE
;
2959 signed long value_in_comment
= 0;
2962 for (c
= insn
->assembler
; *c
; c
++)
2966 bfd_boolean allow_unpredictable
= FALSE
;
2971 func (stream
, "%%");
2975 value_in_comment
= print_arm_address (pc
, info
, given
);
2979 /* Set P address bit and use normal address
2980 printing routine. */
2981 value_in_comment
= print_arm_address (pc
, info
, given
| (1 << P_BIT
));
2985 allow_unpredictable
= TRUE
;
2987 if ((given
& 0x004f0000) == 0x004f0000)
2989 /* PC relative with immediate offset. */
2990 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
2992 if (NEGATIVE_BIT_SET
)
2998 func (stream
, "[pc, #%d]\t; ", offset
);
3000 func (stream
, "[pc]\t; ");
3001 info
->print_address_func (offset
+ pc
+ 8, info
);
3005 func (stream
, "[pc], #%d", offset
);
3006 if (! allow_unpredictable
)
3007 is_unpredictable
= TRUE
;
3012 int offset
= ((given
& 0xf00) >> 4) | (given
& 0xf);
3014 if (NEGATIVE_BIT_SET
)
3017 func (stream
, "[%s",
3018 arm_regnames
[(given
>> 16) & 0xf]);
3022 if (IMMEDIATE_BIT_SET
)
3024 if (WRITEBACK_BIT_SET
)
3025 /* Immediate Pre-indexed. */
3026 /* PR 10924: Offset must be printed, even if it is zero. */
3027 func (stream
, ", #%d", offset
);
3029 /* Immediate Offset: printing zero offset is optional. */
3030 func (stream
, ", #%d", offset
);
3032 value_in_comment
= offset
;
3036 /* Register Offset or Register Pre-Indexed. */
3037 func (stream
, ", %s%s",
3038 NEGATIVE_BIT_SET
? "-" : "",
3039 arm_regnames
[given
& 0xf]);
3041 /* Writing back to the register that is the source/
3042 destination of the load/store is unpredictable. */
3043 if (! allow_unpredictable
3044 && WRITEBACK_BIT_SET
3045 && ((given
& 0xf) == ((given
>> 12) & 0xf)))
3046 is_unpredictable
= TRUE
;
3049 func (stream
, "]%s",
3050 WRITEBACK_BIT_SET
? "!" : "");
3054 if (IMMEDIATE_BIT_SET
)
3056 /* Immediate Post-indexed. */
3057 /* PR 10924: Offset must be printed, even if it is zero. */
3058 func (stream
, "], #%d", offset
);
3059 value_in_comment
= offset
;
3063 /* Register Post-indexed. */
3064 func (stream
, "], %s%s",
3065 NEGATIVE_BIT_SET
? "-" : "",
3066 arm_regnames
[given
& 0xf]);
3068 /* Writing back to the register that is the source/
3069 destination of the load/store is unpredictable. */
3070 if (! allow_unpredictable
3071 && (given
& 0xf) == ((given
>> 12) & 0xf))
3072 is_unpredictable
= TRUE
;
3075 if (! allow_unpredictable
)
3077 /* Writeback is automatically implied by post- addressing.
3078 Setting the W bit is unnecessary and ARM specify it as
3079 being unpredictable. */
3080 if (WRITEBACK_BIT_SET
3081 /* Specifying the PC register as the post-indexed
3082 registers is also unpredictable. */
3083 || (! IMMEDIATE_BIT_SET
&& ((given
& 0xf) == 0xf)))
3084 is_unpredictable
= TRUE
;
3092 int disp
= (((given
& 0xffffff) ^ 0x800000) - 0x800000);
3093 info
->print_address_func (disp
* 4 + pc
+ 8, info
);
3098 if (((given
>> 28) & 0xf) != 0xe)
3100 arm_conditional
[(given
>> 28) & 0xf]);
3109 for (reg
= 0; reg
< 16; reg
++)
3110 if ((given
& (1 << reg
)) != 0)
3113 func (stream
, ", ");
3115 func (stream
, "%s", arm_regnames
[reg
]);
3119 is_unpredictable
= TRUE
;
3124 arm_decode_shift (given
, func
, stream
, FALSE
);
3128 if ((given
& 0x02000000) != 0)
3130 int rotate
= (given
& 0xf00) >> 7;
3131 int immed
= (given
& 0xff);
3133 immed
= (((immed
<< (32 - rotate
))
3134 | (immed
>> rotate
)) & 0xffffffff);
3135 func (stream
, "#%d", immed
);
3136 value_in_comment
= immed
;
3139 arm_decode_shift (given
, func
, stream
, TRUE
);
3143 if ((given
& 0x0000f000) == 0x0000f000)
3145 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3146 mechanism for setting PSR flag bits. They are
3147 obsolete in V6 onwards. */
3148 if ((private_data
->features
.core
& ARM_EXT_V6
) == 0)
3154 if ((given
& 0x01200000) == 0x00200000)
3160 int offset
= given
& 0xff;
3162 value_in_comment
= offset
* 4;
3163 if (NEGATIVE_BIT_SET
)
3164 value_in_comment
= - value_in_comment
;
3166 func (stream
, "[%s", arm_regnames
[(given
>> 16) & 0xf]);
3171 func (stream
, ", #%d]%s",
3173 WRITEBACK_BIT_SET
? "!" : "");
3181 if (WRITEBACK_BIT_SET
)
3184 func (stream
, ", #%d", value_in_comment
);
3188 func (stream
, ", {%d}", offset
);
3189 value_in_comment
= offset
;
3196 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3201 if (! NEGATIVE_BIT_SET
)
3202 /* Is signed, hi bits should be ones. */
3203 offset
= (-1) ^ 0x00ffffff;
3205 /* Offset is (SignExtend(offset field)<<2). */
3206 offset
+= given
& 0x00ffffff;
3208 address
= offset
+ pc
+ 8;
3210 if (given
& 0x01000000)
3211 /* H bit allows addressing to 2-byte boundaries. */
3214 info
->print_address_func (address
, info
);
3219 if ((given
& 0x02000200) == 0x200)
3222 unsigned sysm
= (given
& 0x004f0000) >> 16;
3224 sysm
|= (given
& 0x300) >> 4;
3225 name
= banked_regname (sysm
);
3228 func (stream
, "%s", name
);
3230 func (stream
, "(UNDEF: %lu)", sysm
);
3234 func (stream
, "%cPSR_",
3235 (given
& 0x00400000) ? 'S' : 'C');
3236 if (given
& 0x80000)
3238 if (given
& 0x40000)
3240 if (given
& 0x20000)
3242 if (given
& 0x10000)
3248 if ((given
& 0xf0) == 0x60)
3250 switch (given
& 0xf)
3252 case 0xf: func (stream
, "sy"); break;
3254 func (stream
, "#%d", (int) given
& 0xf);
3260 switch (given
& 0xf)
3262 case 0xf: func (stream
, "sy"); break;
3263 case 0x7: func (stream
, "un"); break;
3264 case 0xe: func (stream
, "st"); break;
3265 case 0x6: func (stream
, "unst"); break;
3266 case 0xb: func (stream
, "ish"); break;
3267 case 0xa: func (stream
, "ishst"); break;
3268 case 0x3: func (stream
, "osh"); break;
3269 case 0x2: func (stream
, "oshst"); break;
3271 func (stream
, "#%d", (int) given
& 0xf);
3277 case '0': case '1': case '2': case '3': case '4':
3278 case '5': case '6': case '7': case '8': case '9':
3281 unsigned long value
;
3283 c
= arm_decode_bitfield (c
, given
, &value
, &width
);
3289 is_unpredictable
= TRUE
;
3294 /* Eat the 'u' character. */
3298 is_unpredictable
= TRUE
;
3303 /* Eat the 'U' character. */
3307 is_unpredictable
= TRUE
;
3310 func (stream
, "%s", arm_regnames
[value
]);
3313 func (stream
, "%ld", value
);
3314 value_in_comment
= value
;
3317 func (stream
, "%ld", value
* 8);
3318 value_in_comment
= value
* 8;
3321 func (stream
, "%ld", value
+ 1);
3322 value_in_comment
= value
+ 1;
3325 func (stream
, "0x%08lx", value
);
3327 /* Some SWI instructions have special
3329 if ((given
& 0x0fffffff) == 0x0FF00000)
3330 func (stream
, "\t; IMB");
3331 else if ((given
& 0x0fffffff) == 0x0FF00001)
3332 func (stream
, "\t; IMBRange");
3335 func (stream
, "%01lx", value
& 0xf);
3336 value_in_comment
= value
;
3341 func (stream
, "%c", *c
);
3345 if (value
== ((1ul << width
) - 1))
3346 func (stream
, "%c", *c
);
3349 func (stream
, "%c", c
[(1 << width
) - (int) value
]);
3361 imm
= (given
& 0xf) | ((given
& 0xfff00) >> 4);
3362 func (stream
, "%d", imm
);
3363 value_in_comment
= imm
;
3368 /* LSB and WIDTH fields of BFI or BFC. The machine-
3369 language instruction encodes LSB and MSB. */
3371 long msb
= (given
& 0x001f0000) >> 16;
3372 long lsb
= (given
& 0x00000f80) >> 7;
3373 long w
= msb
- lsb
+ 1;
3376 func (stream
, "#%lu, #%lu", lsb
, w
);
3378 func (stream
, "(invalid: %lu:%lu)", lsb
, msb
);
3383 /* Get the PSR/banked register name. */
3386 unsigned sysm
= (given
& 0x004f0000) >> 16;
3388 sysm
|= (given
& 0x300) >> 4;
3389 name
= banked_regname (sysm
);
3392 func (stream
, "%s", name
);
3394 func (stream
, "(UNDEF: %lu)", sysm
);
3399 /* 16-bit unsigned immediate from a MOVT or MOVW
3400 instruction, encoded in bits 0:11 and 15:19. */
3402 long hi
= (given
& 0x000f0000) >> 4;
3403 long lo
= (given
& 0x00000fff);
3404 long imm16
= hi
| lo
;
3406 func (stream
, "#%lu", imm16
);
3407 value_in_comment
= imm16
;
3417 func (stream
, "%c", *c
);
3420 if (value_in_comment
> 32 || value_in_comment
< -16)
3421 func (stream
, "\t; 0x%lx", (value_in_comment
& 0xffffffffUL
));
3423 if (is_unpredictable
)
3424 func (stream
, UNPREDICTABLE_INSTRUCTION
);
3432 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3435 print_insn_thumb16 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3437 const struct opcode16
*insn
;
3438 void *stream
= info
->stream
;
3439 fprintf_ftype func
= info
->fprintf_func
;
3441 for (insn
= thumb_opcodes
; insn
->assembler
; insn
++)
3442 if ((given
& insn
->mask
) == insn
->value
)
3444 signed long value_in_comment
= 0;
3445 const char *c
= insn
->assembler
;
3454 func (stream
, "%c", *c
);
3461 func (stream
, "%%");
3466 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3471 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3480 ifthen_next_state
= given
& 0xff;
3481 for (tmp
= given
<< 1; tmp
& 0xf; tmp
<<= 1)
3482 func (stream
, ((given
^ tmp
) & 0x10) ? "e" : "t");
3483 func (stream
, "\t%s", arm_conditional
[(given
>> 4) & 0xf]);
3488 if (ifthen_next_state
)
3489 func (stream
, "\t; unpredictable branch in IT block\n");
3494 func (stream
, "\t; unpredictable <IT:%s>",
3495 arm_conditional
[IFTHEN_COND
]);
3502 reg
= (given
>> 3) & 0x7;
3503 if (given
& (1 << 6))
3506 func (stream
, "%s", arm_regnames
[reg
]);
3515 if (given
& (1 << 7))
3518 func (stream
, "%s", arm_regnames
[reg
]);
3523 if (given
& (1 << 8))
3527 if (*c
== 'O' && (given
& (1 << 8)))
3537 /* It would be nice if we could spot
3538 ranges, and generate the rS-rE format: */
3539 for (reg
= 0; (reg
< 8); reg
++)
3540 if ((given
& (1 << reg
)) != 0)
3543 func (stream
, ", ");
3545 func (stream
, "%s", arm_regnames
[reg
]);
3551 func (stream
, ", ");
3553 func (stream
, arm_regnames
[14] /* "lr" */);
3559 func (stream
, ", ");
3560 func (stream
, arm_regnames
[15] /* "pc" */);
3568 /* Print writeback indicator for a LDMIA. We are doing a
3569 writeback if the base register is not in the register
3571 if ((given
& (1 << ((given
& 0x0700) >> 8))) == 0)
3576 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3578 bfd_vma address
= (pc
+ 4
3579 + ((given
& 0x00f8) >> 2)
3580 + ((given
& 0x0200) >> 3));
3581 info
->print_address_func (address
, info
);
3586 /* Right shift immediate -- bits 6..10; 1-31 print
3587 as themselves, 0 prints as 32. */
3589 long imm
= (given
& 0x07c0) >> 6;
3592 func (stream
, "#%ld", imm
);
3596 case '0': case '1': case '2': case '3': case '4':
3597 case '5': case '6': case '7': case '8': case '9':
3599 int bitstart
= *c
++ - '0';
3602 while (*c
>= '0' && *c
<= '9')
3603 bitstart
= (bitstart
* 10) + *c
++ - '0';
3612 while (*c
>= '0' && *c
<= '9')
3613 bitend
= (bitend
* 10) + *c
++ - '0';
3616 reg
= given
>> bitstart
;
3617 reg
&= (2 << (bitend
- bitstart
)) - 1;
3622 func (stream
, "%s", arm_regnames
[reg
]);
3626 func (stream
, "%ld", reg
);
3627 value_in_comment
= reg
;
3631 func (stream
, "%ld", reg
<< 1);
3632 value_in_comment
= reg
<< 1;
3636 func (stream
, "%ld", reg
<< 2);
3637 value_in_comment
= reg
<< 2;
3641 /* PC-relative address -- the bottom two
3642 bits of the address are dropped
3643 before the calculation. */
3644 info
->print_address_func
3645 (((pc
+ 4) & ~3) + (reg
<< 2), info
);
3646 value_in_comment
= 0;
3650 func (stream
, "0x%04lx", reg
);
3654 reg
= ((reg
^ (1 << bitend
)) - (1 << bitend
));
3655 info
->print_address_func (reg
* 2 + pc
+ 4, info
);
3656 value_in_comment
= 0;
3660 func (stream
, "%s", arm_conditional
[reg
]);
3671 if ((given
& (1 << bitstart
)) != 0)
3672 func (stream
, "%c", *c
);
3677 if ((given
& (1 << bitstart
)) != 0)
3678 func (stream
, "%c", *c
++);
3680 func (stream
, "%c", *++c
);
3694 if (value_in_comment
> 32 || value_in_comment
< -16)
3695 func (stream
, "\t; 0x%lx", value_in_comment
);
3703 /* Return the name of an V7M special register. */
3706 psr_name (int regno
)
3710 case 0: return "APSR";
3711 case 1: return "IAPSR";
3712 case 2: return "EAPSR";
3713 case 3: return "PSR";
3714 case 5: return "IPSR";
3715 case 6: return "EPSR";
3716 case 7: return "IEPSR";
3717 case 8: return "MSP";
3718 case 9: return "PSP";
3719 case 16: return "PRIMASK";
3720 case 17: return "BASEPRI";
3721 case 18: return "BASEPRI_MASK";
3722 case 19: return "FAULTMASK";
3723 case 20: return "CONTROL";
3724 default: return "<unknown>";
3728 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3731 print_insn_thumb32 (bfd_vma pc
, struct disassemble_info
*info
, long given
)
3733 const struct opcode32
*insn
;
3734 void *stream
= info
->stream
;
3735 fprintf_ftype func
= info
->fprintf_func
;
3737 if (print_insn_coprocessor (pc
, info
, given
, TRUE
))
3740 if (print_insn_neon (info
, given
, TRUE
))
3743 for (insn
= thumb32_opcodes
; insn
->assembler
; insn
++)
3744 if ((given
& insn
->mask
) == insn
->value
)
3746 bfd_boolean is_unpredictable
= FALSE
;
3747 signed long value_in_comment
= 0;
3748 const char *c
= insn
->assembler
;
3754 func (stream
, "%c", *c
);
3761 func (stream
, "%%");
3766 func (stream
, "%s", arm_conditional
[IFTHEN_COND
]);
3770 if (ifthen_next_state
)
3771 func (stream
, "\t; unpredictable branch in IT block\n");
3776 func (stream
, "\t; unpredictable <IT:%s>",
3777 arm_conditional
[IFTHEN_COND
]);
3782 unsigned int imm12
= 0;
3784 imm12
|= (given
& 0x000000ffu
);
3785 imm12
|= (given
& 0x00007000u
) >> 4;
3786 imm12
|= (given
& 0x04000000u
) >> 15;
3787 func (stream
, "#%u", imm12
);
3788 value_in_comment
= imm12
;
3794 unsigned int bits
= 0, imm
, imm8
, mod
;
3796 bits
|= (given
& 0x000000ffu
);
3797 bits
|= (given
& 0x00007000u
) >> 4;
3798 bits
|= (given
& 0x04000000u
) >> 15;
3799 imm8
= (bits
& 0x0ff);
3800 mod
= (bits
& 0xf00) >> 8;
3803 case 0: imm
= imm8
; break;
3804 case 1: imm
= ((imm8
<< 16) | imm8
); break;
3805 case 2: imm
= ((imm8
<< 24) | (imm8
<< 8)); break;
3806 case 3: imm
= ((imm8
<< 24) | (imm8
<< 16) | (imm8
<< 8) | imm8
); break;
3808 mod
= (bits
& 0xf80) >> 7;
3809 imm8
= (bits
& 0x07f) | 0x80;
3810 imm
= (((imm8
<< (32 - mod
)) | (imm8
>> mod
)) & 0xffffffff);
3812 func (stream
, "#%u", imm
);
3813 value_in_comment
= imm
;
3819 unsigned int imm
= 0;
3821 imm
|= (given
& 0x000000ffu
);
3822 imm
|= (given
& 0x00007000u
) >> 4;
3823 imm
|= (given
& 0x04000000u
) >> 15;
3824 imm
|= (given
& 0x000f0000u
) >> 4;
3825 func (stream
, "#%u", imm
);
3826 value_in_comment
= imm
;
3832 unsigned int imm
= 0;
3834 imm
|= (given
& 0x000f0000u
) >> 16;
3835 imm
|= (given
& 0x00000ff0u
) >> 0;
3836 imm
|= (given
& 0x0000000fu
) << 12;
3837 func (stream
, "#%u", imm
);
3838 value_in_comment
= imm
;
3844 unsigned int imm
= 0;
3846 imm
|= (given
& 0x00000fffu
);
3847 imm
|= (given
& 0x000f0000u
) >> 4;
3848 func (stream
, "#%u", imm
);
3849 value_in_comment
= imm
;
3855 unsigned int reg
= (given
& 0x0000000fu
);
3856 unsigned int stp
= (given
& 0x00000030u
) >> 4;
3857 unsigned int imm
= 0;
3858 imm
|= (given
& 0x000000c0u
) >> 6;
3859 imm
|= (given
& 0x00007000u
) >> 10;
3861 func (stream
, "%s", arm_regnames
[reg
]);
3866 func (stream
, ", lsl #%u", imm
);
3872 func (stream
, ", lsr #%u", imm
);
3878 func (stream
, ", asr #%u", imm
);
3883 func (stream
, ", rrx");
3885 func (stream
, ", ror #%u", imm
);
3892 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3893 unsigned int U
= ! NEGATIVE_BIT_SET
;
3894 unsigned int op
= (given
& 0x00000f00) >> 8;
3895 unsigned int i12
= (given
& 0x00000fff);
3896 unsigned int i8
= (given
& 0x000000ff);
3897 bfd_boolean writeback
= FALSE
, postind
= FALSE
;
3900 func (stream
, "[%s", arm_regnames
[Rn
]);
3901 if (U
) /* 12-bit positive immediate offset. */
3905 value_in_comment
= offset
;
3907 else if (Rn
== 15) /* 12-bit negative immediate offset. */
3908 offset
= - (int) i12
;
3909 else if (op
== 0x0) /* Shifted register offset. */
3911 unsigned int Rm
= (i8
& 0x0f);
3912 unsigned int sh
= (i8
& 0x30) >> 4;
3914 func (stream
, ", %s", arm_regnames
[Rm
]);
3916 func (stream
, ", lsl #%u", sh
);
3922 case 0xE: /* 8-bit positive immediate offset. */
3926 case 0xC: /* 8-bit negative immediate offset. */
3930 case 0xF: /* 8-bit + preindex with wb. */
3935 case 0xD: /* 8-bit - preindex with wb. */
3940 case 0xB: /* 8-bit + postindex. */
3945 case 0x9: /* 8-bit - postindex. */
3951 func (stream
, ", <undefined>]");
3956 func (stream
, "], #%d", offset
);
3960 func (stream
, ", #%d", offset
);
3961 func (stream
, writeback
? "]!" : "]");
3966 func (stream
, "\t; ");
3967 info
->print_address_func (((pc
+ 4) & ~3) + offset
, info
);
3975 unsigned int U
= ! NEGATIVE_BIT_SET
;
3976 unsigned int W
= WRITEBACK_BIT_SET
;
3977 unsigned int Rn
= (given
& 0x000f0000) >> 16;
3978 unsigned int off
= (given
& 0x000000ff);
3980 func (stream
, "[%s", arm_regnames
[Rn
]);
3986 func (stream
, ", #%c%u", U
? '+' : '-', off
* 4);
3987 value_in_comment
= off
* 4 * U
? 1 : -1;
3995 func (stream
, "], ");
3998 func (stream
, "#%c%u", U
? '+' : '-', off
* 4);
3999 value_in_comment
= off
* 4 * U
? 1 : -1;
4003 func (stream
, "{%u}", off
);
4004 value_in_comment
= off
;
4012 unsigned int Sbit
= (given
& 0x01000000) >> 24;
4013 unsigned int type
= (given
& 0x00600000) >> 21;
4017 case 0: func (stream
, Sbit
? "sb" : "b"); break;
4018 case 1: func (stream
, Sbit
? "sh" : "h"); break;
4021 func (stream
, "??");
4024 func (stream
, "??");
4036 for (reg
= 0; reg
< 16; reg
++)
4037 if ((given
& (1 << reg
)) != 0)
4040 func (stream
, ", ");
4042 func (stream
, "%s", arm_regnames
[reg
]);
4050 unsigned int msb
= (given
& 0x0000001f);
4051 unsigned int lsb
= 0;
4053 lsb
|= (given
& 0x000000c0u
) >> 6;
4054 lsb
|= (given
& 0x00007000u
) >> 10;
4055 func (stream
, "#%u, #%u", lsb
, msb
- lsb
+ 1);
4061 unsigned int width
= (given
& 0x0000001f) + 1;
4062 unsigned int lsb
= 0;
4064 lsb
|= (given
& 0x000000c0u
) >> 6;
4065 lsb
|= (given
& 0x00007000u
) >> 10;
4066 func (stream
, "#%u, #%u", lsb
, width
);
4072 unsigned int S
= (given
& 0x04000000u
) >> 26;
4073 unsigned int J1
= (given
& 0x00002000u
) >> 13;
4074 unsigned int J2
= (given
& 0x00000800u
) >> 11;
4080 offset
|= (given
& 0x003f0000) >> 4;
4081 offset
|= (given
& 0x000007ff) << 1;
4082 offset
-= (1 << 20);
4084 info
->print_address_func (pc
+ 4 + offset
, info
);
4090 unsigned int S
= (given
& 0x04000000u
) >> 26;
4091 unsigned int I1
= (given
& 0x00002000u
) >> 13;
4092 unsigned int I2
= (given
& 0x00000800u
) >> 11;
4096 offset
|= !(I1
^ S
) << 23;
4097 offset
|= !(I2
^ S
) << 22;
4098 offset
|= (given
& 0x03ff0000u
) >> 4;
4099 offset
|= (given
& 0x000007ffu
) << 1;
4100 offset
-= (1 << 24);
4103 /* BLX target addresses are always word aligned. */
4104 if ((given
& 0x00001000u
) == 0)
4107 info
->print_address_func (offset
, info
);
4113 unsigned int shift
= 0;
4115 shift
|= (given
& 0x000000c0u
) >> 6;
4116 shift
|= (given
& 0x00007000u
) >> 10;
4117 if (WRITEBACK_BIT_SET
)
4118 func (stream
, ", asr #%u", shift
);
4120 func (stream
, ", lsl #%u", shift
);
4121 /* else print nothing - lsl #0 */
4127 unsigned int rot
= (given
& 0x00000030) >> 4;
4130 func (stream
, ", ror #%u", rot
* 8);
4135 if ((given
& 0xf0) == 0x60)
4137 switch (given
& 0xf)
4139 case 0xf: func (stream
, "sy"); break;
4141 func (stream
, "#%d", (int) given
& 0xf);
4147 switch (given
& 0xf)
4149 case 0xf: func (stream
, "sy"); break;
4150 case 0x7: func (stream
, "un"); break;
4151 case 0xe: func (stream
, "st"); break;
4152 case 0x6: func (stream
, "unst"); break;
4153 case 0xb: func (stream
, "ish"); break;
4154 case 0xa: func (stream
, "ishst"); break;
4155 case 0x3: func (stream
, "osh"); break;
4156 case 0x2: func (stream
, "oshst"); break;
4158 func (stream
, "#%d", (int) given
& 0xf);
4165 if ((given
& 0xff) == 0)
4167 func (stream
, "%cPSR_", (given
& 0x100000) ? 'S' : 'C');
4177 else if ((given
& 0x20) == 0x20)
4180 unsigned sysm
= (given
& 0xf00) >> 8;
4182 sysm
|= (given
& 0x30);
4183 sysm
|= (given
& 0x00100000) >> 14;
4184 name
= banked_regname (sysm
);
4187 func (stream
, "%s", name
);
4189 func (stream
, "(UNDEF: %lu)", sysm
);
4193 func (stream
, psr_name (given
& 0xff));
4198 if (((given
& 0xff) == 0)
4199 || ((given
& 0x20) == 0x20))
4202 unsigned sm
= (given
& 0xf0000) >> 16;
4204 sm
|= (given
& 0x30);
4205 sm
|= (given
& 0x00100000) >> 14;
4206 name
= banked_regname (sm
);
4209 func (stream
, "%s", name
);
4211 func (stream
, "(UNDEF: %lu)", sm
);
4214 func (stream
, psr_name (given
& 0xff));
4217 case '0': case '1': case '2': case '3': case '4':
4218 case '5': case '6': case '7': case '8': case '9':
4223 c
= arm_decode_bitfield (c
, given
, &val
, &width
);
4228 func (stream
, "%lu", val
);
4229 value_in_comment
= val
;
4233 func (stream
, "%lu", val
* 4);
4234 value_in_comment
= val
* 4;
4239 is_unpredictable
= TRUE
;
4242 func (stream
, "%s", arm_regnames
[val
]);
4246 func (stream
, "%s", arm_conditional
[val
]);
4251 if (val
== ((1ul << width
) - 1))
4252 func (stream
, "%c", *c
);
4258 func (stream
, "%c", *c
);
4262 func (stream
, "%c", c
[(1 << width
) - (int) val
]);
4267 func (stream
, "0x%lx", val
& 0xffffffffUL
);
4281 if (value_in_comment
> 32 || value_in_comment
< -16)
4282 func (stream
, "\t; 0x%lx", value_in_comment
);
4284 if (is_unpredictable
)
4285 func (stream
, UNPREDICTABLE_INSTRUCTION
);
4294 /* Print data bytes on INFO->STREAM. */
4297 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED
,
4298 struct disassemble_info
*info
,
4301 switch (info
->bytes_per_chunk
)
4304 info
->fprintf_func (info
->stream
, ".byte\t0x%02lx", given
);
4307 info
->fprintf_func (info
->stream
, ".short\t0x%04lx", given
);
4310 info
->fprintf_func (info
->stream
, ".word\t0x%08lx", given
);
4317 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4318 being displayed in symbol relative addresses. */
4321 arm_symbol_is_valid (asymbol
* sym
,
4322 struct disassemble_info
* info ATTRIBUTE_UNUSED
)
4329 name
= bfd_asymbol_name (sym
);
4331 return (name
&& *name
!= '$');
4334 /* Parse an individual disassembler option. */
4337 parse_arm_disassembler_option (char *option
)
4342 if (CONST_STRNEQ (option
, "reg-names-"))
4348 for (i
= NUM_ARM_REGNAMES
; i
--;)
4349 if (strneq (option
, regnames
[i
].name
, strlen (regnames
[i
].name
)))
4351 regname_selected
= i
;
4356 /* XXX - should break 'option' at following delimiter. */
4357 fprintf (stderr
, _("Unrecognised register name set: %s\n"), option
);
4359 else if (CONST_STRNEQ (option
, "force-thumb"))
4361 else if (CONST_STRNEQ (option
, "no-force-thumb"))
4364 /* XXX - should break 'option' at following delimiter. */
4365 fprintf (stderr
, _("Unrecognised disassembler option: %s\n"), option
);
4370 /* Parse the string of disassembler options, spliting it at whitespaces
4371 or commas. (Whitespace separators supported for backwards compatibility). */
4374 parse_disassembler_options (char *options
)
4376 if (options
== NULL
)
4381 parse_arm_disassembler_option (options
);
4383 /* Skip forward to next seperator. */
4384 while ((*options
) && (! ISSPACE (*options
)) && (*options
!= ','))
4386 /* Skip forward past seperators. */
4387 while (ISSPACE (*options
) || (*options
== ','))
4392 /* Search back through the insn stream to determine if this instruction is
4393 conditionally executed. */
4396 find_ifthen_state (bfd_vma pc
,
4397 struct disassemble_info
*info
,
4403 /* COUNT is twice the number of instructions seen. It will be odd if we
4404 just crossed an instruction boundary. */
4407 unsigned int seen_it
;
4410 ifthen_address
= pc
;
4417 /* Scan backwards looking for IT instructions, keeping track of where
4418 instruction boundaries are. We don't know if something is actually an
4419 IT instruction until we find a definite instruction boundary. */
4422 if (addr
== 0 || info
->symbol_at_address_func (addr
, info
))
4424 /* A symbol must be on an instruction boundary, and will not
4425 be within an IT block. */
4426 if (seen_it
&& (count
& 1))
4432 status
= info
->read_memory_func (addr
, (bfd_byte
*) b
, 2, info
);
4437 insn
= (b
[0]) | (b
[1] << 8);
4439 insn
= (b
[1]) | (b
[0] << 8);
4442 if ((insn
& 0xf800) < 0xe800)
4444 /* Addr + 2 is an instruction boundary. See if this matches
4445 the expected boundary based on the position of the last
4452 if ((insn
& 0xff00) == 0xbf00 && (insn
& 0xf) != 0)
4454 /* This could be an IT instruction. */
4456 it_count
= count
>> 1;
4458 if ((insn
& 0xf800) >= 0xe800)
4461 count
= (count
+ 2) | 1;
4462 /* IT blocks contain at most 4 instructions. */
4463 if (count
>= 8 && !seen_it
)
4466 /* We found an IT instruction. */
4467 ifthen_state
= (seen_it
& 0xe0) | ((seen_it
<< it_count
) & 0x1f);
4468 if ((ifthen_state
& 0xf) == 0)
4472 /* Returns nonzero and sets *MAP_TYPE if the N'th symbol is a
4476 is_mapping_symbol (struct disassemble_info
*info
, int n
,
4477 enum map_type
*map_type
)
4481 name
= bfd_asymbol_name (info
->symtab
[n
]);
4482 if (name
[0] == '$' && (name
[1] == 'a' || name
[1] == 't' || name
[1] == 'd')
4483 && (name
[2] == 0 || name
[2] == '.'))
4485 *map_type
= ((name
[1] == 'a') ? MAP_ARM
4486 : (name
[1] == 't') ? MAP_THUMB
4494 /* Try to infer the code type (ARM or Thumb) from a mapping symbol.
4495 Returns nonzero if *MAP_TYPE was set. */
4498 get_map_sym_type (struct disassemble_info
*info
,
4500 enum map_type
*map_type
)
4502 /* If the symbol is in a different section, ignore it. */
4503 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4506 return is_mapping_symbol (info
, n
, map_type
);
4509 /* Try to infer the code type (ARM or Thumb) from a non-mapping symbol.
4510 Returns nonzero if *MAP_TYPE was set. */
4513 get_sym_code_type (struct disassemble_info
*info
,
4515 enum map_type
*map_type
)
4517 elf_symbol_type
*es
;
4520 /* If the symbol is in a different section, ignore it. */
4521 if (info
->section
!= NULL
&& info
->section
!= info
->symtab
[n
]->section
)
4524 es
= *(elf_symbol_type
**)(info
->symtab
+ n
);
4525 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4527 /* If the symbol has function type then use that. */
4528 if (type
== STT_FUNC
|| type
== STT_ARM_TFUNC
)
4530 *map_type
= (type
== STT_ARM_TFUNC
) ? MAP_THUMB
: MAP_ARM
;
4537 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4538 of the supplied arm_feature_set structure with bitmasks indicating
4539 the support base architectures and coprocessor extensions.
4541 FIXME: This could more efficiently implemented as a constant array,
4542 although it would also be less robust. */
4545 select_arm_features (unsigned long mach
,
4546 arm_feature_set
* features
)
4549 #define ARM_FEATURE(ARCH,CEXT) \
4550 features->core = (ARCH); \
4551 features->coproc = (CEXT) | FPU_FPA; \
4556 case bfd_mach_arm_2
: ARM_ARCH_V2
;
4557 case bfd_mach_arm_2a
: ARM_ARCH_V2S
;
4558 case bfd_mach_arm_3
: ARM_ARCH_V3
;
4559 case bfd_mach_arm_3M
: ARM_ARCH_V3M
;
4560 case bfd_mach_arm_4
: ARM_ARCH_V4
;
4561 case bfd_mach_arm_4T
: ARM_ARCH_V4T
;
4562 case bfd_mach_arm_5
: ARM_ARCH_V5
;
4563 case bfd_mach_arm_5T
: ARM_ARCH_V5T
;
4564 case bfd_mach_arm_5TE
: ARM_ARCH_V5TE
;
4565 case bfd_mach_arm_XScale
: ARM_ARCH_XSCALE
;
4566 case bfd_mach_arm_ep9312
: ARM_FEATURE (ARM_AEXT_V4T
, ARM_CEXT_MAVERICK
| FPU_MAVERICK
);
4567 case bfd_mach_arm_iWMMXt
: ARM_ARCH_IWMMXT
;
4568 case bfd_mach_arm_iWMMXt2
: ARM_ARCH_IWMMXT2
;
4569 /* If the machine type is unknown allow all
4570 architecture types and all extensions. */
4571 case bfd_mach_arm_unknown
: ARM_FEATURE (-1UL, -1UL);
4578 /* NOTE: There are no checks in these routines that
4579 the relevant number of data bytes exist. */
4582 print_insn (bfd_vma pc
, struct disassemble_info
*info
, bfd_boolean little
)
4587 int is_thumb
= FALSE
;
4588 int is_data
= FALSE
;
4590 unsigned int size
= 4;
4591 void (*printer
) (bfd_vma
, struct disassemble_info
*, long);
4592 bfd_boolean found
= FALSE
;
4593 struct arm_private_data
*private_data
;
4595 if (info
->disassembler_options
)
4597 parse_disassembler_options (info
->disassembler_options
);
4599 /* To avoid repeated parsing of these options, we remove them here. */
4600 info
->disassembler_options
= NULL
;
4603 /* PR 10288: Control which instructions will be disassembled. */
4604 if (info
->private_data
== NULL
)
4606 static struct arm_private_data
private;
4608 if ((info
->flags
& USER_SPECIFIED_MACHINE_TYPE
) == 0)
4609 /* If the user did not use the -m command line switch then default to
4610 disassembling all types of ARM instruction.
4612 The info->mach value has to be ignored as this will be based on
4613 the default archictecture for the target and/or hints in the notes
4614 section, but it will never be greater than the current largest arm
4615 machine value (iWMMXt2), which is only equivalent to the V5TE
4616 architecture. ARM architectures have advanced beyond the machine
4617 value encoding, and these newer architectures would be ignored if
4618 the machine value was used.
4620 Ie the -m switch is used to restrict which instructions will be
4621 disassembled. If it is necessary to use the -m switch to tell
4622 objdump that an ARM binary is being disassembled, eg because the
4623 input is a raw binary file, but it is also desired to disassemble
4624 all ARM instructions then use "-marm". This will select the
4625 "unknown" arm architecture which is compatible with any ARM
4627 info
->mach
= bfd_mach_arm_unknown
;
4629 /* Compute the architecture bitmask from the machine number.
4630 Note: This assumes that the machine number will not change
4631 during disassembly.... */
4632 select_arm_features (info
->mach
, & private.features
);
4634 private.has_mapping_symbols
= -1;
4636 info
->private_data
= & private;
4639 private_data
= info
->private_data
;
4641 /* Decide if our code is going to be little-endian, despite what the
4642 function argument might say. */
4643 little_code
= ((info
->endian_code
== BFD_ENDIAN_LITTLE
) || little
);
4645 /* For ELF, consult the symbol table to determine what kind of code
4647 if (info
->symtab_size
!= 0
4648 && bfd_asymbol_flavour (*info
->symtab
) == bfd_target_elf_flavour
)
4653 enum map_type type
= MAP_ARM
;
4655 /* Start scanning at the start of the function, or wherever
4656 we finished last time. */
4657 start
= info
->symtab_pos
+ 1;
4658 if (start
< last_mapping_sym
)
4659 start
= last_mapping_sym
;
4662 /* First, look for mapping symbols. */
4663 if (private_data
->has_mapping_symbols
!= 0)
4665 /* Scan up to the location being disassembled. */
4666 for (n
= start
; n
< info
->symtab_size
; n
++)
4668 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4671 if (get_map_sym_type (info
, n
, &type
))
4680 /* No mapping symbol found at this address. Look backwards
4681 for a preceeding one. */
4682 for (n
= start
- 1; n
>= 0; n
--)
4684 if (get_map_sym_type (info
, n
, &type
))
4694 private_data
->has_mapping_symbols
= 1;
4696 /* No mapping symbols were found. A leading $d may be
4697 omitted for sections which start with data; but for
4698 compatibility with legacy and stripped binaries, only
4699 assume the leading $d if there is at least one mapping
4700 symbol in the file. */
4701 if (!found
&& private_data
->has_mapping_symbols
== -1)
4703 /* Look for mapping symbols, in any section. */
4704 for (n
= 0; n
< info
->symtab_size
; n
++)
4705 if (is_mapping_symbol (info
, n
, &type
))
4707 private_data
->has_mapping_symbols
= 1;
4710 if (private_data
->has_mapping_symbols
== -1)
4711 private_data
->has_mapping_symbols
= 0;
4714 if (!found
&& private_data
->has_mapping_symbols
== 1)
4721 /* Next search for function symbols to separate ARM from Thumb
4722 in binaries without mapping symbols. */
4725 /* Scan up to the location being disassembled. */
4726 for (n
= start
; n
< info
->symtab_size
; n
++)
4728 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4731 if (get_sym_code_type (info
, n
, &type
))
4740 /* No mapping symbol found at this address. Look backwards
4741 for a preceeding one. */
4742 for (n
= start
- 1; n
>= 0; n
--)
4744 if (get_sym_code_type (info
, n
, &type
))
4754 last_mapping_sym
= last_sym
;
4756 is_thumb
= (last_type
== MAP_THUMB
);
4757 is_data
= (last_type
== MAP_DATA
);
4759 /* Look a little bit ahead to see if we should print out
4760 two or four bytes of data. If there's a symbol,
4761 mapping or otherwise, after two bytes then don't
4765 size
= 4 - (pc
& 3);
4766 for (n
= last_sym
+ 1; n
< info
->symtab_size
; n
++)
4768 addr
= bfd_asymbol_value (info
->symtab
[n
]);
4770 && (info
->section
== NULL
4771 || info
->section
== info
->symtab
[n
]->section
))
4773 if (addr
- pc
< size
)
4778 /* If the next symbol is after three bytes, we need to
4779 print only part of the data, so that we can use either
4782 size
= (pc
& 1) ? 1 : 2;
4786 if (info
->symbols
!= NULL
)
4788 if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_coff_flavour
)
4790 coff_symbol_type
* cs
;
4792 cs
= coffsymbol (*info
->symbols
);
4793 is_thumb
= ( cs
->native
->u
.syment
.n_sclass
== C_THUMBEXT
4794 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTAT
4795 || cs
->native
->u
.syment
.n_sclass
== C_THUMBLABEL
4796 || cs
->native
->u
.syment
.n_sclass
== C_THUMBEXTFUNC
4797 || cs
->native
->u
.syment
.n_sclass
== C_THUMBSTATFUNC
);
4799 else if (bfd_asymbol_flavour (*info
->symbols
) == bfd_target_elf_flavour
4802 /* If no mapping symbol has been found then fall back to the type
4803 of the function symbol. */
4804 elf_symbol_type
* es
;
4807 es
= *(elf_symbol_type
**)(info
->symbols
);
4808 type
= ELF_ST_TYPE (es
->internal_elf_sym
.st_info
);
4810 is_thumb
= (type
== STT_ARM_TFUNC
) || (type
== STT_ARM_16BIT
);
4818 info
->display_endian
= little
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4820 info
->display_endian
= little_code
? BFD_ENDIAN_LITTLE
: BFD_ENDIAN_BIG
;
4822 info
->bytes_per_line
= 4;
4824 /* PR 10263: Disassemble data if requested to do so by the user. */
4825 if (is_data
&& ((info
->flags
& DISASSEMBLE_DATA
) == 0))
4829 /* Size was already set above. */
4830 info
->bytes_per_chunk
= size
;
4831 printer
= print_insn_data
;
4833 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, size
, info
);
4836 for (i
= size
- 1; i
>= 0; i
--)
4837 given
= b
[i
] | (given
<< 8);
4839 for (i
= 0; i
< (int) size
; i
++)
4840 given
= b
[i
] | (given
<< 8);
4844 /* In ARM mode endianness is a straightforward issue: the instruction
4845 is four bytes long and is either ordered 0123 or 3210. */
4846 printer
= print_insn_arm
;
4847 info
->bytes_per_chunk
= 4;
4850 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 4, info
);
4852 given
= (b
[0]) | (b
[1] << 8) | (b
[2] << 16) | (b
[3] << 24);
4854 given
= (b
[3]) | (b
[2] << 8) | (b
[1] << 16) | (b
[0] << 24);
4858 /* In Thumb mode we have the additional wrinkle of two
4859 instruction lengths. Fortunately, the bits that determine
4860 the length of the current instruction are always to be found
4861 in the first two bytes. */
4862 printer
= print_insn_thumb16
;
4863 info
->bytes_per_chunk
= 2;
4866 status
= info
->read_memory_func (pc
, (bfd_byte
*) b
, 2, info
);
4868 given
= (b
[0]) | (b
[1] << 8);
4870 given
= (b
[1]) | (b
[0] << 8);
4874 /* These bit patterns signal a four-byte Thumb
4876 if ((given
& 0xF800) == 0xF800
4877 || (given
& 0xF800) == 0xF000
4878 || (given
& 0xF800) == 0xE800)
4880 status
= info
->read_memory_func (pc
+ 2, (bfd_byte
*) b
, 2, info
);
4882 given
= (b
[0]) | (b
[1] << 8) | (given
<< 16);
4884 given
= (b
[1]) | (b
[0] << 8) | (given
<< 16);
4886 printer
= print_insn_thumb32
;
4891 if (ifthen_address
!= pc
)
4892 find_ifthen_state (pc
, info
, little_code
);
4896 if ((ifthen_state
& 0xf) == 0x8)
4897 ifthen_next_state
= 0;
4899 ifthen_next_state
= (ifthen_state
& 0xe0)
4900 | ((ifthen_state
& 0xf) << 1);
4906 info
->memory_error_func (status
, pc
, info
);
4909 if (info
->flags
& INSN_HAS_RELOC
)
4910 /* If the instruction has a reloc associated with it, then
4911 the offset field in the instruction will actually be the
4912 addend for the reloc. (We are using REL type relocs).
4913 In such cases, we can ignore the pc when computing
4914 addresses, since the addend is not currently pc-relative. */
4917 printer (pc
, info
, given
);
4921 ifthen_state
= ifthen_next_state
;
4922 ifthen_address
+= size
;
4928 print_insn_big_arm (bfd_vma pc
, struct disassemble_info
*info
)
4930 /* Detect BE8-ness and record it in the disassembler info. */
4931 if (info
->flavour
== bfd_target_elf_flavour
4932 && info
->section
!= NULL
4933 && (elf_elfheader (info
->section
->owner
)->e_flags
& EF_ARM_BE8
))
4934 info
->endian_code
= BFD_ENDIAN_LITTLE
;
4936 return print_insn (pc
, info
, FALSE
);
4940 print_insn_little_arm (bfd_vma pc
, struct disassemble_info
*info
)
4942 return print_insn (pc
, info
, TRUE
);
4946 print_arm_disassembler_options (FILE *stream
)
4950 fprintf (stream
, _("\n\
4951 The following ARM specific disassembler options are supported for use with\n\
4952 the -M switch:\n"));
4954 for (i
= NUM_ARM_REGNAMES
; i
--;)
4955 fprintf (stream
, " reg-names-%s %*c%s\n",
4957 (int)(14 - strlen (regnames
[i
].name
)), ' ',
4958 regnames
[i
].description
);
4960 fprintf (stream
, " force-thumb Assume all insns are Thumb insns\n");
4961 fprintf (stream
, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");