bfd/
[binutils.git] / opcodes / arm-dis.c
blob49765d86d4b6b37c88505478094f4e0735e37f1d
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 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 program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 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, MA 02110-1301, USA. */
23 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
29 #include "floatformat.h"
31 /* FIXME: This shouldn't be done here. */
32 #include "coff/internal.h"
33 #include "libcoff.h"
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
38 /* FIXME: Belongs in global header. */
39 #ifndef strneq
40 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
41 #endif
43 #ifndef NUM_ELEM
44 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
45 #endif
47 struct opcode32
49 unsigned long arch; /* Architecture defining this insn. */
50 unsigned long value, mask; /* Recognise insn if (op&mask)==value. */
51 const char *assembler; /* How to disassemble this insn. */
54 struct opcode16
56 unsigned long arch; /* Architecture defining this insn. */
57 unsigned short value, mask; /* Recognise insn if (op&mask)==value. */
58 const char *assembler; /* How to disassemble this insn. */
61 /* print_insn_coprocessor recognizes the following format control codes:
63 %% %
65 %c print condition code (always bits 28-31 in ARM mode)
66 %u print condition code (unconditional in ARM mode)
67 %A print address for ldc/stc/ldf/stf instruction
68 %B print vstm/vldm register list
69 %C print vstr/vldr address operand
70 %I print cirrus signed shift immediate: bits 0..3|4..6
71 %F print the COUNT field of a LFM/SFM instruction.
72 %P print floating point precision in arithmetic insn
73 %Q print floating point precision in ldf/stf insn
74 %R print floating point rounding mode
76 %<bitfield>r print as an ARM register
77 %<bitfield>d print the bitfield in decimal
78 %<bitfield>k print immediate for VFPv3 conversion instruction
79 %<bitfield>x print the bitfield in hex
80 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
81 %<bitfield>f print a floating point constant if >7 else a
82 floating point register
83 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
84 %<bitfield>g print as an iWMMXt 64-bit register
85 %<bitfield>G print as an iWMMXt general purpose or control register
86 %<bitfield>D print as a NEON D register
87 %<bitfield>Q print as a NEON Q register
89 %y<code> print a single precision VFP reg.
90 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
91 %z<code> print a double precision VFP reg
92 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
94 %<bitfield>'c print specified char iff bitfield is all ones
95 %<bitfield>`c print specified char iff bitfield is all zeroes
96 %<bitfield>?ab... select from array of values in big endian order
98 %L print as an iWMMXt N/M width field.
99 %Z print the Immediate of a WSHUFH instruction.
100 %l like 'A' except use byte offsets for 'B' & 'H'
101 versions.
102 %i print 5-bit immediate in bits 8,3..0
103 (print "32" when 0)
104 %r print register offset address for wldt/wstr instruction
107 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
109 static const struct opcode32 coprocessor_opcodes[] =
111 /* XScale instructions. */
112 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
113 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
114 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
115 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
116 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
118 /* Intel Wireless MMX technology instructions. */
119 #define FIRST_IWMMXT_INSN 0x0e130130
120 #define IWMMXT_INSN_COUNT 73
121 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
122 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
123 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
124 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
125 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
126 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
127 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
128 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
129 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
130 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
131 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
132 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
133 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
134 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
135 {ARM_CEXT_XSCALE, 0x0e130190, 0x0f3f0fff, "torvsc%22-23w%c\t%12-15r"},
136 {ARM_CEXT_XSCALE, 0x0e2001c0, 0x0f300fff, "wabs%22-23w%c\t%12-15g, %16-19g"},
137 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
138 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
139 {ARM_CEXT_XSCALE, 0x0e2001a0, 0x0f300ff0, "waddbhus%22?ml%c\t%12-15g, %16-19g, %0-3g"},
140 {ARM_CEXT_XSCALE, 0x0ea001a0, 0x0ff00ff0, "waddsubhx%c\t%12-15g, %16-19g, %0-3g"},
141 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
142 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
143 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
144 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
145 {ARM_CEXT_XSCALE, 0x0e400000, 0x0fe00ff0, "wavg4%20'r%c\t%12-15g, %16-19g, %0-3g"},
146 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
147 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
148 {ARM_CEXT_XSCALE, 0xfc500100, 0xfe500f00, "wldrd\t%12-15g, %r"},
149 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
150 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
151 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
152 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fc00ff0, "wmadd%21?su%20'x%c\t%12-15g, %16-19g, %0-3g"},
153 {ARM_CEXT_XSCALE, 0x0ec00100, 0x0fd00ff0, "wmadd%21?sun%c\t%12-15g, %16-19g, %0-3g"},
154 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
155 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f100fe0, "wmerge%c\t%12-15g, %16-19g, %0-3g, #%21-23d"},
156 {ARM_CEXT_XSCALE, 0x0e0000a0, 0x0f800ff0, "wmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
157 {ARM_CEXT_XSCALE, 0x0e800120, 0x0f800ff0, "wmiaw%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
158 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
159 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%23'r%c\t%12-15g, %16-19g, %0-3g"},
160 {ARM_CEXT_XSCALE, 0x0ed00100, 0x0fd00ff0, "wmul%21?sumr%c\t%12-15g, %16-19g, %0-3g"},
161 {ARM_CEXT_XSCALE, 0x0ee000c0, 0x0fe00ff0, "wmulwsm%20`r%c\t%12-15g, %16-19g, %0-3g"},
162 {ARM_CEXT_XSCALE, 0x0ec000c0, 0x0fe00ff0, "wmulwum%20`r%c\t%12-15g, %16-19g, %0-3g"},
163 {ARM_CEXT_XSCALE, 0x0eb000c0, 0x0ff00ff0, "wmulwl%c\t%12-15g, %16-19g, %0-3g"},
164 {ARM_CEXT_XSCALE, 0x0e8000a0, 0x0f800ff0, "wqmia%21?tb%20?tb%22'n%c\t%12-15g, %16-19g, %0-3g"},
165 {ARM_CEXT_XSCALE, 0x0e100080, 0x0fd00ff0, "wqmulm%21'r%c\t%12-15g, %16-19g, %0-3g"},
166 {ARM_CEXT_XSCALE, 0x0ec000e0, 0x0fd00ff0, "wqmulwm%21'r%c\t%12-15g, %16-19g, %0-3g"},
167 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
168 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
169 {ARM_CEXT_XSCALE, 0xfe300040, 0xff300ef0, "wror%22-23w\t%12-15g, %16-19g, #%i"},
170 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%c\t%12-15g, %16-19g, %0-3g"},
171 {ARM_CEXT_XSCALE, 0x0e300140, 0x0f300ff0, "wror%22-23wg%c\t%12-15g, %16-19g, %0-3G"},
172 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
173 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
174 {ARM_CEXT_XSCALE, 0xfe100040, 0xff300ef0, "wsll%22-23w\t%12-15g, %16-19g, #%i"},
175 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
176 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
177 {ARM_CEXT_XSCALE, 0xfe000040, 0xff300ef0, "wsra%22-23w\t%12-15g, %16-19g, #%i"},
178 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
179 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
180 {ARM_CEXT_XSCALE, 0xfe200040, 0xff300ef0, "wsrl%22-23w\t%12-15g, %16-19g, #%i"},
181 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
182 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
183 {ARM_CEXT_XSCALE, 0xfc400100, 0xfe500f00, "wstrd\t%12-15g, %r"},
184 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
185 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
186 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
187 {ARM_CEXT_XSCALE, 0x0ed001c0, 0x0ff00ff0, "wsubaddhx%c\t%12-15g, %16-19g, %0-3g"},
188 {ARM_CEXT_XSCALE, 0x0e1001c0, 0x0f300ff0, "wabsdiff%22-23w%c\t%12-15g, %16-19g, %0-3g"},
189 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0fd00fff, "wunpckeh%21?sub%c\t%12-15g, %16-19g"},
190 {ARM_CEXT_XSCALE, 0x0e4000c0, 0x0fd00fff, "wunpckeh%21?suh%c\t%12-15g, %16-19g"},
191 {ARM_CEXT_XSCALE, 0x0e8000c0, 0x0fd00fff, "wunpckeh%21?suw%c\t%12-15g, %16-19g"},
192 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
193 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
194 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
195 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
197 /* Floating point coprocessor (FPA) instructions */
198 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
199 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
200 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
201 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
202 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
203 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
204 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
205 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
206 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
207 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
208 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
209 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
210 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
211 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
212 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
213 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
214 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
215 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
216 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
217 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
218 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
219 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
220 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
221 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
222 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
223 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
224 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
225 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
226 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
227 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
228 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
229 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
230 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
231 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
232 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
233 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
234 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
235 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
236 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
237 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
238 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
239 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
240 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
242 /* Register load/store */
243 {FPU_NEON_EXT_V1, 0x0d200b00, 0x0fb00f01, "vstmdb%c\t%16-19r%21'!, %B"},
244 {FPU_NEON_EXT_V1, 0x0d300b00, 0x0fb00f01, "vldmdb%c\t%16-19r%21'!, %B"},
245 {FPU_NEON_EXT_V1, 0x0c800b00, 0x0f900f01, "vstmia%c\t%16-19r%21'!, %B"},
246 {FPU_NEON_EXT_V1, 0x0c900b00, 0x0f900f01, "vldmia%c\t%16-19r%21'!, %B"},
247 {FPU_NEON_EXT_V1, 0x0d000b00, 0x0f300f00, "vstr%c\t%12-15,22D, %C"},
248 {FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
250 /* Data transfer between ARM and NEON registers */
251 {FPU_NEON_EXT_V1, 0x0e800b10, 0x0ff00f70, "vdup%c.32\t%16-19,7D, %12-15r"},
252 {FPU_NEON_EXT_V1, 0x0e800b30, 0x0ff00f70, "vdup%c.16\t%16-19,7D, %12-15r"},
253 {FPU_NEON_EXT_V1, 0x0ea00b10, 0x0ff00f70, "vdup%c.32\t%16-19,7Q, %12-15r"},
254 {FPU_NEON_EXT_V1, 0x0ea00b30, 0x0ff00f70, "vdup%c.16\t%16-19,7Q, %12-15r"},
255 {FPU_NEON_EXT_V1, 0x0ec00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7D, %12-15r"},
256 {FPU_NEON_EXT_V1, 0x0ee00b10, 0x0ff00f70, "vdup%c.8\t%16-19,7Q, %12-15r"},
257 {FPU_NEON_EXT_V1, 0x0c400b10, 0x0ff00fd0, "vmov%c\t%0-3,5D, %12-15r, %16-19r"},
258 {FPU_NEON_EXT_V1, 0x0c500b10, 0x0ff00fd0, "vmov%c\t%12-15r, %16-19r, %0-3,5D"},
259 {FPU_NEON_EXT_V1, 0x0e000b10, 0x0fd00f70, "vmov%c.32\t%16-19,7D[%21d], %12-15r"},
260 {FPU_NEON_EXT_V1, 0x0e100b10, 0x0f500f70, "vmov%c.32\t%12-15r, %16-19,7D[%21d]"},
261 {FPU_NEON_EXT_V1, 0x0e000b30, 0x0fd00f30, "vmov%c.16\t%16-19,7D[%6,21d], %12-15r"},
262 {FPU_NEON_EXT_V1, 0x0e100b30, 0x0f500f30, "vmov%c.%23?us16\t%12-15r, %16-19,7D[%6,21d]"},
263 {FPU_NEON_EXT_V1, 0x0e400b10, 0x0fd00f10, "vmov%c.8\t%16-19,7D[%5,6,21d], %12-15r"},
264 {FPU_NEON_EXT_V1, 0x0e500b10, 0x0f500f10, "vmov%c.%23?us8\t%12-15r, %16-19,7D[%5,6,21d]"},
266 /* Floating point coprocessor (VFP) instructions */
267 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
268 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
269 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
270 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
271 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
272 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
273 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
274 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
275 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
276 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
277 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
278 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%z2, %12-15r"},
279 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %z2"},
280 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%z2, %12-15r"},
281 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %z2"},
282 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
283 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
284 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%y2, %12-15r"},
285 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %y2"},
286 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%y1"},
287 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fbf0f70, "fcmp%7'ezd%c\t%z1"},
288 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%y1, %y0"},
289 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%y1, %y0"},
290 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fbf0fd0, "fcpyd%c\t%z1, %z0"},
291 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fbf0fd0, "fabsd%c\t%z1, %z0"},
292 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%y1, %y0"},
293 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%y1, %y0"},
294 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fbf0fd0, "fnegd%c\t%z1, %z0"},
295 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fbf0fd0, "fsqrtd%c\t%z1, %z0"},
296 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fbf0fd0, "fcvtds%c\t%z1, %y0"},
297 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0fd0, "fcvtsd%c\t%y1, %z0"},
298 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%y1, %y0"},
299 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%y1, %y0"},
300 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fbf0fd0, "fuitod%c\t%z1, %y0"},
301 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fbf0fd0, "fsitod%c\t%z1, %y0"},
302 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%y1, %y0"},
303 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fbf0f50, "fcmp%7'ed%c\t%z1, %z0"},
304 {FPU_VFP_EXT_V3, 0x0eba0a40, 0x0fbe0f50, "f%16?us%7?lhtos%c\t%y1, #%5,0-3k"},
305 {FPU_VFP_EXT_V3, 0x0eba0b40, 0x0fbe0f50, "f%16?us%7?lhtod%c\t%z1, #%5,0-3k"},
306 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%y1, %y0"},
307 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f50, "fto%16?sui%7'zd%c\t%y1, %z0"},
308 {FPU_VFP_EXT_V3, 0x0ebe0a40, 0x0fbe0f50, "fto%16?us%7?lhs%c\t%y1, #%5,0-3k"},
309 {FPU_VFP_EXT_V3, 0x0ebe0b40, 0x0fbe0f50, "fto%16?us%7?lhd%c\t%z1, #%5,0-3k"},
310 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0fb00ff0, "fmrrd%c\t%12-15r, %16-19r, %z0"},
311 {FPU_VFP_EXT_V3, 0x0eb00a00, 0x0fb00ff0, "fconsts%c\t%y1, #%0-3,16-19d"},
312 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%0-3,16-19d"},
313 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%y4, %12-15r, %16-19r"},
314 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00fd0, "fmdrr%c\t%z0, %12-15r, %16-19r"},
315 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %y4"},
316 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%y1, %y2, %y0"},
317 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%y1, %y2, %y0"},
318 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0fb00f50, "fmacd%c\t%z1, %z2, %z0"},
319 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0fb00f50, "fnmacd%c\t%z1, %z2, %z0"},
320 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%y1, %y2, %y0"},
321 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%y1, %y2, %y0"},
322 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0fb00f50, "fmscd%c\t%z1, %z2, %z0"},
323 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0fb00f50, "fnmscd%c\t%z1, %z2, %z0"},
324 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%y1, %y2, %y0"},
325 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%y1, %y2, %y0"},
326 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0fb00f50, "fmuld%c\t%z1, %z2, %z0"},
327 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0fb00f50, "fnmuld%c\t%z1, %z2, %z0"},
328 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%y1, %y2, %y0"},
329 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%y1, %y2, %y0"},
330 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0fb00f50, "faddd%c\t%z1, %z2, %z0"},
331 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0fb00f50, "fsubd%c\t%z1, %z2, %z0"},
332 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%y1, %y2, %y0"},
333 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0fb00f50, "fdivd%c\t%z1, %z2, %z0"},
334 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %y3"},
335 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0fb00f00, "fstmdb%0?xd%c\t%16-19r!, %z3"},
336 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %y3"},
337 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0fb00f00, "fldmdb%0?xd%c\t%16-19r!, %z3"},
338 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%y1, %A"},
339 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f300f00, "fstd%c\t%z1, %A"},
340 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%y1, %A"},
341 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f300f00, "fldd%c\t%z1, %A"},
342 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %y3"},
343 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0f900f00, "fstmia%0?xd%c\t%16-19r%21'!, %z3"},
344 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %y3"},
345 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0f900f00, "fldmia%0?xd%c\t%16-19r%21'!, %z3"},
347 /* Cirrus coprocessor instructions. */
348 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
349 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
350 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
351 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
352 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
353 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
354 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
355 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
356 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
357 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
358 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
359 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
360 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
361 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
362 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
363 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
364 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
365 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
366 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
367 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
368 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
369 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
370 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
371 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
372 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
373 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
374 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
375 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
376 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
377 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
378 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
379 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
380 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
381 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
382 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
383 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
384 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
385 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
386 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
387 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
388 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
389 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
390 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
391 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
392 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
393 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
394 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
395 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
396 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
397 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
398 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
399 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
400 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
401 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
402 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
403 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
404 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
405 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
406 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
407 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
408 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
409 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
410 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
411 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
412 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
413 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
414 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
415 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
416 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
417 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
418 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
419 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
420 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
421 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
422 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
423 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
424 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
425 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
426 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
427 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
428 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
429 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
430 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
431 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
433 /* Generic coprocessor instructions */
434 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
435 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
436 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
437 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
438 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
439 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
440 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
442 /* V6 coprocessor instructions */
443 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
444 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
446 /* V5 coprocessor instructions */
447 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l%c\t%8-11d, cr%12-15d, %A"},
448 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l%c\t%8-11d, cr%12-15d, %A"},
449 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
450 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
451 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
453 {0, 0, 0, 0}
456 /* Neon opcode table: This does not encode the top byte -- that is
457 checked by the print_insn_neon routine, as it depends on whether we are
458 doing thumb32 or arm32 disassembly. */
460 /* print_insn_neon recognizes the following format control codes:
462 %% %
464 %c print condition code
465 %A print v{st,ld}[1234] operands
466 %B print v{st,ld}[1234] any one operands
467 %C print v{st,ld}[1234] single->all operands
468 %D print scalar
469 %E print vmov, vmvn, vorr, vbic encoded constant
470 %F print vtbl,vtbx register list
472 %<bitfield>r print as an ARM register
473 %<bitfield>d print the bitfield in decimal
474 %<bitfield>e print the 2^N - bitfield in decimal
475 %<bitfield>D print as a NEON D register
476 %<bitfield>Q print as a NEON Q register
477 %<bitfield>R print as a NEON D or Q register
478 %<bitfield>Sn print byte scaled width limited by n
479 %<bitfield>Tn print short scaled width limited by n
480 %<bitfield>Un print long scaled width limited by n
482 %<bitfield>'c print specified char iff bitfield is all ones
483 %<bitfield>`c print specified char iff bitfield is all zeroes
484 %<bitfield>?ab... select from array of values in big endian order */
486 static const struct opcode32 neon_opcodes[] =
488 /* Extract */
489 {FPU_NEON_EXT_V1, 0xf2b00840, 0xffb00850, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
490 {FPU_NEON_EXT_V1, 0xf2b00000, 0xffb00810, "vext%c.8\t%12-15,22R, %16-19,7R, %0-3,5R, #%8-11d"},
492 /* Move data element to all lanes */
493 {FPU_NEON_EXT_V1, 0xf3b40c00, 0xffb70f90, "vdup%c.32\t%12-15,22R, %0-3,5D[%19d]"},
494 {FPU_NEON_EXT_V1, 0xf3b20c00, 0xffb30f90, "vdup%c.16\t%12-15,22R, %0-3,5D[%18-19d]"},
495 {FPU_NEON_EXT_V1, 0xf3b10c00, 0xffb10f90, "vdup%c.8\t%12-15,22R, %0-3,5D[%17-19d]"},
497 /* Table lookup */
498 {FPU_NEON_EXT_V1, 0xf3b00800, 0xffb00c50, "vtbl%c.8\t%12-15,22D, %F, %0-3,5D"},
499 {FPU_NEON_EXT_V1, 0xf3b00840, 0xffb00c50, "vtbx%c.8\t%12-15,22D, %F, %0-3,5D"},
501 /* Two registers, miscellaneous */
502 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfebf0fd0, "vmovl%c.%24?us8\t%12-15,22Q, %0-3,5D"},
503 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfebf0fd0, "vmovl%c.%24?us16\t%12-15,22Q, %0-3,5D"},
504 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfebf0fd0, "vmovl%c.%24?us32\t%12-15,22Q, %0-3,5D"},
505 {FPU_NEON_EXT_V1, 0xf3b00500, 0xffbf0f90, "vcnt%c.8\t%12-15,22R, %0-3,5R"},
506 {FPU_NEON_EXT_V1, 0xf3b00580, 0xffbf0f90, "vmvn%c\t%12-15,22R, %0-3,5R"},
507 {FPU_NEON_EXT_V1, 0xf3b20000, 0xffbf0f90, "vswp%c\t%12-15,22R, %0-3,5R"},
508 {FPU_NEON_EXT_V1, 0xf3b20200, 0xffb30fd0, "vmovn%c.i%18-19T2\t%12-15,22D, %0-3,5Q"},
509 {FPU_NEON_EXT_V1, 0xf3b20240, 0xffb30fd0, "vqmovun%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
510 {FPU_NEON_EXT_V1, 0xf3b20280, 0xffb30fd0, "vqmovn%c.s%18-19T2\t%12-15,22D, %0-3,5Q"},
511 {FPU_NEON_EXT_V1, 0xf3b202c0, 0xffb30fd0, "vqmovn%c.u%18-19T2\t%12-15,22D, %0-3,5Q"},
512 {FPU_NEON_EXT_V1, 0xf3b20300, 0xffb30fd0, "vshll%c.i%18-19S2\t%12-15,22Q, %0-3,5D, #%18-19S2"},
513 {FPU_NEON_EXT_V1, 0xf3bb0400, 0xffbf0e90, "vrecpe%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
514 {FPU_NEON_EXT_V1, 0xf3bb0480, 0xffbf0e90, "vrsqrte%c.%8?fu%18-19S2\t%12-15,22R, %0-3,5R"},
515 {FPU_NEON_EXT_V1, 0xf3b00000, 0xffb30f90, "vrev64%c.%18-19S2\t%12-15,22R, %0-3,5R"},
516 {FPU_NEON_EXT_V1, 0xf3b00080, 0xffb30f90, "vrev32%c.%18-19S2\t%12-15,22R, %0-3,5R"},
517 {FPU_NEON_EXT_V1, 0xf3b00100, 0xffb30f90, "vrev16%c.%18-19S2\t%12-15,22R, %0-3,5R"},
518 {FPU_NEON_EXT_V1, 0xf3b00400, 0xffb30f90, "vcls%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
519 {FPU_NEON_EXT_V1, 0xf3b00480, 0xffb30f90, "vclz%c.i%18-19S2\t%12-15,22R, %0-3,5R"},
520 {FPU_NEON_EXT_V1, 0xf3b00700, 0xffb30f90, "vqabs%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
521 {FPU_NEON_EXT_V1, 0xf3b00780, 0xffb30f90, "vqneg%c.s%18-19S2\t%12-15,22R, %0-3,5R"},
522 {FPU_NEON_EXT_V1, 0xf3b20080, 0xffb30f90, "vtrn%c.%18-19S2\t%12-15,22R, %0-3,5R"},
523 {FPU_NEON_EXT_V1, 0xf3b20100, 0xffb30f90, "vuzp%c.%18-19S2\t%12-15,22R, %0-3,5R"},
524 {FPU_NEON_EXT_V1, 0xf3b20180, 0xffb30f90, "vzip%c.%18-19S2\t%12-15,22R, %0-3,5R"},
525 {FPU_NEON_EXT_V1, 0xf3b10000, 0xffb30b90, "vcgt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
526 {FPU_NEON_EXT_V1, 0xf3b10080, 0xffb30b90, "vcge%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
527 {FPU_NEON_EXT_V1, 0xf3b10100, 0xffb30b90, "vceq%c.%10?fi%18-19S2\t%12-15,22R, %0-3,5R, #0"},
528 {FPU_NEON_EXT_V1, 0xf3b10180, 0xffb30b90, "vcle%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
529 {FPU_NEON_EXT_V1, 0xf3b10200, 0xffb30b90, "vclt%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R, #0"},
530 {FPU_NEON_EXT_V1, 0xf3b10300, 0xffb30b90, "vabs%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
531 {FPU_NEON_EXT_V1, 0xf3b10380, 0xffb30b90, "vneg%c.%10?fs%18-19S2\t%12-15,22R, %0-3,5R"},
532 {FPU_NEON_EXT_V1, 0xf3b00200, 0xffb30f10, "vpaddl%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
533 {FPU_NEON_EXT_V1, 0xf3b00600, 0xffb30f10, "vpadal%c.%7?us%18-19S2\t%12-15,22R, %0-3,5R"},
534 {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"},
536 /* Three registers of the same length */
537 {FPU_NEON_EXT_V1, 0xf2000110, 0xffb00f10, "vand%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
538 {FPU_NEON_EXT_V1, 0xf2100110, 0xffb00f10, "vbic%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
539 {FPU_NEON_EXT_V1, 0xf2200110, 0xffb00f10, "vorr%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
540 {FPU_NEON_EXT_V1, 0xf2300110, 0xffb00f10, "vorn%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
541 {FPU_NEON_EXT_V1, 0xf3000110, 0xffb00f10, "veor%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
542 {FPU_NEON_EXT_V1, 0xf3100110, 0xffb00f10, "vbsl%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
543 {FPU_NEON_EXT_V1, 0xf3200110, 0xffb00f10, "vbit%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
544 {FPU_NEON_EXT_V1, 0xf3300110, 0xffb00f10, "vbif%c\t%12-15,22R, %16-19,7R, %0-3,5R"},
545 {FPU_NEON_EXT_V1, 0xf2000d00, 0xffa00f10, "vadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
546 {FPU_NEON_EXT_V1, 0xf2000d10, 0xffa00f10, "vmla%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
547 {FPU_NEON_EXT_V1, 0xf2000e00, 0xffa00f10, "vceq%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
548 {FPU_NEON_EXT_V1, 0xf2000f00, 0xffa00f10, "vmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
549 {FPU_NEON_EXT_V1, 0xf2000f10, 0xffa00f10, "vrecps%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
550 {FPU_NEON_EXT_V1, 0xf2200d00, 0xffa00f10, "vsub%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
551 {FPU_NEON_EXT_V1, 0xf2200d10, 0xffa00f10, "vmls%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
552 {FPU_NEON_EXT_V1, 0xf2200f00, 0xffa00f10, "vmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
553 {FPU_NEON_EXT_V1, 0xf2200f10, 0xffa00f10, "vrsqrts%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
554 {FPU_NEON_EXT_V1, 0xf3000d00, 0xffa00f10, "vpadd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
555 {FPU_NEON_EXT_V1, 0xf3000d10, 0xffa00f10, "vmul%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
556 {FPU_NEON_EXT_V1, 0xf3000e00, 0xffa00f10, "vcge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
557 {FPU_NEON_EXT_V1, 0xf3000e10, 0xffa00f10, "vacge%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
558 {FPU_NEON_EXT_V1, 0xf3000f00, 0xffa00f10, "vpmax%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
559 {FPU_NEON_EXT_V1, 0xf3200d00, 0xffa00f10, "vabd%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
560 {FPU_NEON_EXT_V1, 0xf3200e00, 0xffa00f10, "vcgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
561 {FPU_NEON_EXT_V1, 0xf3200e10, 0xffa00f10, "vacgt%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
562 {FPU_NEON_EXT_V1, 0xf3200f00, 0xffa00f10, "vpmin%c.f%20U0\t%12-15,22R, %16-19,7R, %0-3,5R"},
563 {FPU_NEON_EXT_V1, 0xf2000800, 0xff800f10, "vadd%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
564 {FPU_NEON_EXT_V1, 0xf2000810, 0xff800f10, "vtst%c.%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
565 {FPU_NEON_EXT_V1, 0xf2000900, 0xff800f10, "vmla%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
566 {FPU_NEON_EXT_V1, 0xf2000b00, 0xff800f10, "vqdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
567 {FPU_NEON_EXT_V1, 0xf2000b10, 0xff800f10, "vpadd%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
568 {FPU_NEON_EXT_V1, 0xf3000800, 0xff800f10, "vsub%c.i%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
569 {FPU_NEON_EXT_V1, 0xf3000810, 0xff800f10, "vceq%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
570 {FPU_NEON_EXT_V1, 0xf3000900, 0xff800f10, "vmls%c.i%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
571 {FPU_NEON_EXT_V1, 0xf3000b00, 0xff800f10, "vqrdmulh%c.s%20-21S6\t%12-15,22R, %16-19,7R, %0-3,5R"},
572 {FPU_NEON_EXT_V1, 0xf2000000, 0xfe800f10, "vhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
573 {FPU_NEON_EXT_V1, 0xf2000010, 0xfe800f10, "vqadd%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
574 {FPU_NEON_EXT_V1, 0xf2000100, 0xfe800f10, "vrhadd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
575 {FPU_NEON_EXT_V1, 0xf2000200, 0xfe800f10, "vhsub%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
576 {FPU_NEON_EXT_V1, 0xf2000210, 0xfe800f10, "vqsub%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
577 {FPU_NEON_EXT_V1, 0xf2000300, 0xfe800f10, "vcgt%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
578 {FPU_NEON_EXT_V1, 0xf2000310, 0xfe800f10, "vcge%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
579 {FPU_NEON_EXT_V1, 0xf2000400, 0xfe800f10, "vshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
580 {FPU_NEON_EXT_V1, 0xf2000410, 0xfe800f10, "vqshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
581 {FPU_NEON_EXT_V1, 0xf2000500, 0xfe800f10, "vrshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
582 {FPU_NEON_EXT_V1, 0xf2000510, 0xfe800f10, "vqrshl%c.%24?us%20-21S3\t%12-15,22R, %16-19,7R, %0-3,5R"},
583 {FPU_NEON_EXT_V1, 0xf2000600, 0xfe800f10, "vmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
584 {FPU_NEON_EXT_V1, 0xf2000610, 0xfe800f10, "vmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
585 {FPU_NEON_EXT_V1, 0xf2000700, 0xfe800f10, "vabd%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
586 {FPU_NEON_EXT_V1, 0xf2000710, 0xfe800f10, "vaba%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
587 {FPU_NEON_EXT_V1, 0xf2000910, 0xfe800f10, "vmul%c.%24?pi%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
588 {FPU_NEON_EXT_V1, 0xf2000a00, 0xfe800f10, "vpmax%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
589 {FPU_NEON_EXT_V1, 0xf2000a10, 0xfe800f10, "vpmin%c.%24?us%20-21S2\t%12-15,22R, %16-19,7R, %0-3,5R"},
591 /* One register and an immediate value */
592 {FPU_NEON_EXT_V1, 0xf2800e10, 0xfeb80fb0, "vmov%c.i8\t%12-15,22R, %E"},
593 {FPU_NEON_EXT_V1, 0xf2800e30, 0xfeb80fb0, "vmov%c.i64\t%12-15,22R, %E"},
594 {FPU_NEON_EXT_V1, 0xf2800f10, 0xfeb80fb0, "vmov%c.f32\t%12-15,22R, %E"},
595 {FPU_NEON_EXT_V1, 0xf2800810, 0xfeb80db0, "vmov%c.i16\t%12-15,22R, %E"},
596 {FPU_NEON_EXT_V1, 0xf2800830, 0xfeb80db0, "vmvn%c.i16\t%12-15,22R, %E"},
597 {FPU_NEON_EXT_V1, 0xf2800910, 0xfeb80db0, "vorr%c.i16\t%12-15,22R, %E"},
598 {FPU_NEON_EXT_V1, 0xf2800930, 0xfeb80db0, "vbic%c.i16\t%12-15,22R, %E"},
599 {FPU_NEON_EXT_V1, 0xf2800c10, 0xfeb80eb0, "vmov%c.i32\t%12-15,22R, %E"},
600 {FPU_NEON_EXT_V1, 0xf2800c30, 0xfeb80eb0, "vmvn%c.i32\t%12-15,22R, %E"},
601 {FPU_NEON_EXT_V1, 0xf2800110, 0xfeb809b0, "vorr%c.i32\t%12-15,22R, %E"},
602 {FPU_NEON_EXT_V1, 0xf2800130, 0xfeb809b0, "vbic%c.i32\t%12-15,22R, %E"},
603 {FPU_NEON_EXT_V1, 0xf2800010, 0xfeb808b0, "vmov%c.i32\t%12-15,22R, %E"},
604 {FPU_NEON_EXT_V1, 0xf2800030, 0xfeb808b0, "vmvn%c.i32\t%12-15,22R, %E"},
606 /* Two registers and a shift amount */
607 {FPU_NEON_EXT_V1, 0xf2880810, 0xffb80fd0, "vshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
608 {FPU_NEON_EXT_V1, 0xf2880850, 0xffb80fd0, "vrshrn%c.i16\t%12-15,22D, %0-3,5Q, #%16-18e"},
609 {FPU_NEON_EXT_V1, 0xf2880810, 0xfeb80fd0, "vqshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
610 {FPU_NEON_EXT_V1, 0xf2880850, 0xfeb80fd0, "vqrshrun%c.s16\t%12-15,22D, %0-3,5Q, #%16-18e"},
611 {FPU_NEON_EXT_V1, 0xf2880910, 0xfeb80fd0, "vqshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
612 {FPU_NEON_EXT_V1, 0xf2880950, 0xfeb80fd0, "vqrshrn%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-18e"},
613 {FPU_NEON_EXT_V1, 0xf2880a10, 0xfeb80fd0, "vshll%c.%24?us8\t%12-15,22D, %0-3,5Q, #%16-18d"},
614 {FPU_NEON_EXT_V1, 0xf2900810, 0xffb00fd0, "vshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
615 {FPU_NEON_EXT_V1, 0xf2900850, 0xffb00fd0, "vrshrn%c.i32\t%12-15,22D, %0-3,5Q, #%16-19e"},
616 {FPU_NEON_EXT_V1, 0xf2880510, 0xffb80f90, "vshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
617 {FPU_NEON_EXT_V1, 0xf3880410, 0xffb80f90, "vsri%c.8\t%12-15,22R, %0-3,5R, #%16-18e"},
618 {FPU_NEON_EXT_V1, 0xf3880510, 0xffb80f90, "vsli%c.8\t%12-15,22R, %0-3,5R, #%16-18d"},
619 {FPU_NEON_EXT_V1, 0xf3880610, 0xffb80f90, "vqshlu%c.s8\t%12-15,22R, %0-3,5R, #%16-18d"},
620 {FPU_NEON_EXT_V1, 0xf2900810, 0xfeb00fd0, "vqshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
621 {FPU_NEON_EXT_V1, 0xf2900850, 0xfeb00fd0, "vqrshrun%c.s32\t%12-15,22D, %0-3,5Q, #%16-19e"},
622 {FPU_NEON_EXT_V1, 0xf2900910, 0xfeb00fd0, "vqshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
623 {FPU_NEON_EXT_V1, 0xf2900950, 0xfeb00fd0, "vqrshrn%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-19e"},
624 {FPU_NEON_EXT_V1, 0xf2900a10, 0xfeb00fd0, "vshll%c.%24?us16\t%12-15,22D, %0-3,5Q, #%16-19d"},
625 {FPU_NEON_EXT_V1, 0xf2880010, 0xfeb80f90, "vshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
626 {FPU_NEON_EXT_V1, 0xf2880110, 0xfeb80f90, "vsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
627 {FPU_NEON_EXT_V1, 0xf2880210, 0xfeb80f90, "vrshr%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
628 {FPU_NEON_EXT_V1, 0xf2880310, 0xfeb80f90, "vrsra%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18e"},
629 {FPU_NEON_EXT_V1, 0xf2880710, 0xfeb80f90, "vqshl%c.%24?us8\t%12-15,22R, %0-3,5R, #%16-18d"},
630 {FPU_NEON_EXT_V1, 0xf2a00810, 0xffa00fd0, "vshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
631 {FPU_NEON_EXT_V1, 0xf2a00850, 0xffa00fd0, "vrshrn%c.i64\t%12-15,22D, %0-3,5Q, #%16-20e"},
632 {FPU_NEON_EXT_V1, 0xf2900510, 0xffb00f90, "vshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
633 {FPU_NEON_EXT_V1, 0xf3900410, 0xffb00f90, "vsri%c.16\t%12-15,22R, %0-3,5R, #%16-19e"},
634 {FPU_NEON_EXT_V1, 0xf3900510, 0xffb00f90, "vsli%c.16\t%12-15,22R, %0-3,5R, #%16-19d"},
635 {FPU_NEON_EXT_V1, 0xf3900610, 0xffb00f90, "vqshlu%c.s16\t%12-15,22R, %0-3,5R, #%16-19d"},
636 {FPU_NEON_EXT_V1, 0xf2a00a10, 0xfea00fd0, "vshll%c.%24?us32\t%12-15,22D, %0-3,5Q, #%16-20d"},
637 {FPU_NEON_EXT_V1, 0xf2900010, 0xfeb00f90, "vshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
638 {FPU_NEON_EXT_V1, 0xf2900110, 0xfeb00f90, "vsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
639 {FPU_NEON_EXT_V1, 0xf2900210, 0xfeb00f90, "vrshr%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
640 {FPU_NEON_EXT_V1, 0xf2900310, 0xfeb00f90, "vrsra%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19e"},
641 {FPU_NEON_EXT_V1, 0xf2900710, 0xfeb00f90, "vqshl%c.%24?us16\t%12-15,22R, %0-3,5R, #%16-19d"},
642 {FPU_NEON_EXT_V1, 0xf2800810, 0xfec00fd0, "vqshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
643 {FPU_NEON_EXT_V1, 0xf2800850, 0xfec00fd0, "vqrshrun%c.s64\t%12-15,22D, %0-3,5Q, #%16-20e"},
644 {FPU_NEON_EXT_V1, 0xf2800910, 0xfec00fd0, "vqshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
645 {FPU_NEON_EXT_V1, 0xf2800950, 0xfec00fd0, "vqrshrn%c.%24?us64\t%12-15,22D, %0-3,5Q, #%16-20e"},
646 {FPU_NEON_EXT_V1, 0xf2a00510, 0xffa00f90, "vshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
647 {FPU_NEON_EXT_V1, 0xf3a00410, 0xffa00f90, "vsri%c.32\t%12-15,22R, %0-3,5R, #%16-20e"},
648 {FPU_NEON_EXT_V1, 0xf3a00510, 0xffa00f90, "vsli%c.32\t%12-15,22R, %0-3,5R, #%16-20d"},
649 {FPU_NEON_EXT_V1, 0xf3a00610, 0xffa00f90, "vqshlu%c.s32\t%12-15,22R, %0-3,5R, #%16-20d"},
650 {FPU_NEON_EXT_V1, 0xf2a00010, 0xfea00f90, "vshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
651 {FPU_NEON_EXT_V1, 0xf2a00110, 0xfea00f90, "vsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
652 {FPU_NEON_EXT_V1, 0xf2a00210, 0xfea00f90, "vrshr%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
653 {FPU_NEON_EXT_V1, 0xf2a00310, 0xfea00f90, "vrsra%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20e"},
654 {FPU_NEON_EXT_V1, 0xf2a00710, 0xfea00f90, "vqshl%c.%24?us32\t%12-15,22R, %0-3,5R, #%16-20d"},
655 {FPU_NEON_EXT_V1, 0xf2800590, 0xff800f90, "vshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
656 {FPU_NEON_EXT_V1, 0xf3800490, 0xff800f90, "vsri%c.64\t%12-15,22R, %0-3,5R, #%16-21e"},
657 {FPU_NEON_EXT_V1, 0xf3800590, 0xff800f90, "vsli%c.64\t%12-15,22R, %0-3,5R, #%16-21d"},
658 {FPU_NEON_EXT_V1, 0xf3800690, 0xff800f90, "vqshlu%c.s64\t%12-15,22R, %0-3,5R, #%16-21d"},
659 {FPU_NEON_EXT_V1, 0xf2800090, 0xfe800f90, "vshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
660 {FPU_NEON_EXT_V1, 0xf2800190, 0xfe800f90, "vsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
661 {FPU_NEON_EXT_V1, 0xf2800290, 0xfe800f90, "vrshr%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
662 {FPU_NEON_EXT_V1, 0xf2800390, 0xfe800f90, "vrsra%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21e"},
663 {FPU_NEON_EXT_V1, 0xf2800790, 0xfe800f90, "vqshl%c.%24?us64\t%12-15,22R, %0-3,5R, #%16-21d"},
664 {FPU_NEON_EXT_V1, 0xf2a00e10, 0xfea00e90, "vcvt%c.%24,8?usff32.%24,8?ffus32\t%12-15,22R, %0-3,5R, #%16-20e"},
666 /* Three registers of different lengths */
667 {FPU_NEON_EXT_V1, 0xf2800e00, 0xfea00f50, "vmull%c.p%20S0\t%12-15,22Q, %16-19,7D, %0-3,5D"},
668 {FPU_NEON_EXT_V1, 0xf2800400, 0xff800f50, "vaddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
669 {FPU_NEON_EXT_V1, 0xf2800600, 0xff800f50, "vsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
670 {FPU_NEON_EXT_V1, 0xf2800900, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
671 {FPU_NEON_EXT_V1, 0xf2800b00, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
672 {FPU_NEON_EXT_V1, 0xf2800d00, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %0-3,5D"},
673 {FPU_NEON_EXT_V1, 0xf3800400, 0xff800f50, "vraddhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
674 {FPU_NEON_EXT_V1, 0xf3800600, 0xff800f50, "vrsubhn%c.i%20-21T2\t%12-15,22D, %16-19,7Q, %0-3,5Q"},
675 {FPU_NEON_EXT_V1, 0xf2800000, 0xfe800f50, "vaddl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
676 {FPU_NEON_EXT_V1, 0xf2800100, 0xfe800f50, "vaddw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
677 {FPU_NEON_EXT_V1, 0xf2800200, 0xfe800f50, "vsubl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
678 {FPU_NEON_EXT_V1, 0xf2800300, 0xfe800f50, "vsubw%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7Q, %0-3,5D"},
679 {FPU_NEON_EXT_V1, 0xf2800500, 0xfe800f50, "vabal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
680 {FPU_NEON_EXT_V1, 0xf2800700, 0xfe800f50, "vabdl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
681 {FPU_NEON_EXT_V1, 0xf2800800, 0xfe800f50, "vmlal%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
682 {FPU_NEON_EXT_V1, 0xf2800a00, 0xfe800f50, "vmlsl%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
683 {FPU_NEON_EXT_V1, 0xf2800c00, 0xfe800f50, "vmull%c.%24?us%20-21S2\t%12-15,22Q, %16-19,7D, %0-3,5D"},
685 /* Two registers and a scalar */
686 {FPU_NEON_EXT_V1, 0xf2800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
687 {FPU_NEON_EXT_V1, 0xf2800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
688 {FPU_NEON_EXT_V1, 0xf2800340, 0xff800f50, "vqdmlal%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
689 {FPU_NEON_EXT_V1, 0xf2800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
690 {FPU_NEON_EXT_V1, 0xf2800540, 0xff800f50, "vmls%c.f%20-21S6\t%12-15,22D, %16-19,7D, %D"},
691 {FPU_NEON_EXT_V1, 0xf2800740, 0xff800f50, "vqdmlsl%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
692 {FPU_NEON_EXT_V1, 0xf2800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22D, %16-19,7D, %D"},
693 {FPU_NEON_EXT_V1, 0xf2800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22D, %16-19,7D, %D"},
694 {FPU_NEON_EXT_V1, 0xf2800b40, 0xff800f50, "vqdmull%c.s%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
695 {FPU_NEON_EXT_V1, 0xf2800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
696 {FPU_NEON_EXT_V1, 0xf2800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22D, %16-19,7D, %D"},
697 {FPU_NEON_EXT_V1, 0xf3800040, 0xff800f50, "vmla%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
698 {FPU_NEON_EXT_V1, 0xf3800140, 0xff800f50, "vmla%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
699 {FPU_NEON_EXT_V1, 0xf3800440, 0xff800f50, "vmls%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
700 {FPU_NEON_EXT_V1, 0xf3800540, 0xff800f50, "vmls%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
701 {FPU_NEON_EXT_V1, 0xf3800840, 0xff800f50, "vmul%c.i%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
702 {FPU_NEON_EXT_V1, 0xf3800940, 0xff800f50, "vmul%c.f%20-21Sa\t%12-15,22Q, %16-19,7Q, %D"},
703 {FPU_NEON_EXT_V1, 0xf3800c40, 0xff800f50, "vqdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
704 {FPU_NEON_EXT_V1, 0xf3800d40, 0xff800f50, "vqrdmulh%c.s%20-21S6\t%12-15,22Q, %16-19,7Q, %D"},
705 {FPU_NEON_EXT_V1, 0xf2800240, 0xfe800f50, "vmlal%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
706 {FPU_NEON_EXT_V1, 0xf2800640, 0xfe800f50, "vmlsl%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
707 {FPU_NEON_EXT_V1, 0xf2800a40, 0xfe800f50, "vmull%c.%24?us%20-21S6\t%12-15,22Q, %16-19,7D, %D"},
709 /* Element and structure load/store */
710 {FPU_NEON_EXT_V1, 0xf4a00fc0, 0xffb00fc0, "vld4%c.32\t%C"},
711 {FPU_NEON_EXT_V1, 0xf4a00c00, 0xffb00f00, "vld1%c.%6-7S2\t%C"},
712 {FPU_NEON_EXT_V1, 0xf4a00d00, 0xffb00f00, "vld2%c.%6-7S2\t%C"},
713 {FPU_NEON_EXT_V1, 0xf4a00e00, 0xffb00f00, "vld3%c.%6-7S2\t%C"},
714 {FPU_NEON_EXT_V1, 0xf4a00f00, 0xffb00f00, "vld4%c.%6-7S2\t%C"},
715 {FPU_NEON_EXT_V1, 0xf4000200, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
716 {FPU_NEON_EXT_V1, 0xf4000300, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
717 {FPU_NEON_EXT_V1, 0xf4000400, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
718 {FPU_NEON_EXT_V1, 0xf4000500, 0xff900f00, "v%21?ls%21?dt3%c.%6-7S2\t%A"},
719 {FPU_NEON_EXT_V1, 0xf4000600, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
720 {FPU_NEON_EXT_V1, 0xf4000700, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
721 {FPU_NEON_EXT_V1, 0xf4000800, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
722 {FPU_NEON_EXT_V1, 0xf4000900, 0xff900f00, "v%21?ls%21?dt2%c.%6-7S2\t%A"},
723 {FPU_NEON_EXT_V1, 0xf4000a00, 0xff900f00, "v%21?ls%21?dt1%c.%6-7S3\t%A"},
724 {FPU_NEON_EXT_V1, 0xf4000000, 0xff900e00, "v%21?ls%21?dt4%c.%6-7S2\t%A"},
725 {FPU_NEON_EXT_V1, 0xf4800000, 0xff900300, "v%21?ls%21?dt1%c.%10-11S2\t%B"},
726 {FPU_NEON_EXT_V1, 0xf4800100, 0xff900300, "v%21?ls%21?dt2%c.%10-11S2\t%B"},
727 {FPU_NEON_EXT_V1, 0xf4800200, 0xff900300, "v%21?ls%21?dt3%c.%10-11S2\t%B"},
728 {FPU_NEON_EXT_V1, 0xf4800300, 0xff900300, "v%21?ls%21?dt4%c.%10-11S2\t%B"},
730 {0,0 ,0, 0}
733 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
734 ordered: they must be searched linearly from the top to obtain a correct
735 match. */
737 /* print_insn_arm recognizes the following format control codes:
739 %% %
741 %a print address for ldr/str instruction
742 %s print address for ldr/str halfword/signextend instruction
743 %b print branch destination
744 %c print condition code (always bits 28-31)
745 %m print register mask for ldm/stm instruction
746 %o print operand2 (immediate or register + shift)
747 %p print 'p' iff bits 12-15 are 15
748 %t print 't' iff bit 21 set and bit 24 clear
749 %B print arm BLX(1) destination
750 %C print the PSR sub type.
751 %U print barrier type.
752 %P print address for pli instruction.
754 %<bitfield>r print as an ARM register
755 %<bitfield>d print the bitfield in decimal
756 %<bitfield>W print the bitfield plus one in decimal
757 %<bitfield>x print the bitfield in hex
758 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
760 %<bitfield>'c print specified char iff bitfield is all ones
761 %<bitfield>`c print specified char iff bitfield is all zeroes
762 %<bitfield>?ab... select from array of values in big endian order
764 %e print arm SMI operand (bits 0..7,8..19).
765 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
766 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
768 static const struct opcode32 arm_opcodes[] =
770 /* ARM instructions. */
771 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
772 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
773 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
774 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
775 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
776 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
777 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
779 /* V7 instructions. */
780 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
781 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
782 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
783 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
784 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
786 /* ARM V6T2 instructions. */
787 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
788 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
789 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
790 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
791 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
792 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
793 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
794 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
795 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
797 /* ARM V6Z instructions. */
798 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
800 /* ARM V6K instructions. */
801 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
802 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
803 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
804 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
805 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
806 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
807 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
809 /* ARM V6K NOP hints. */
810 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
811 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
812 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
813 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
814 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
816 /* ARM V6 instructions. */
817 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
818 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
819 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
820 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
821 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
822 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
823 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
824 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
825 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
826 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
827 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
828 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
829 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
830 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
831 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
832 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
833 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
834 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
835 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
836 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
837 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
838 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
839 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
840 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
841 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
842 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
843 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
844 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
845 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
846 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
847 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
848 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
849 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
850 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
851 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
852 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
853 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
854 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
855 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
856 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
857 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
858 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
859 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
860 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
861 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
862 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
863 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
864 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
865 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
866 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
867 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
868 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
869 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
870 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
871 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
872 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
873 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
874 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
875 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
876 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
877 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
878 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
879 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
880 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
881 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
882 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
883 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
884 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
885 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
886 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
887 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
888 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
889 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
890 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
891 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
893 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
894 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
895 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
897 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
898 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
899 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
900 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
901 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
902 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
903 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
904 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
905 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
906 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
907 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
908 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
909 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
910 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
911 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
912 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
913 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
914 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
915 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
916 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
917 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
918 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
919 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
920 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
921 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
922 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
923 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
924 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
925 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
926 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
927 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
928 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
929 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
930 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
931 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
932 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
933 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
934 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
935 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
936 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
937 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
938 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
940 /* V5J instruction. */
941 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
943 /* V5 Instructions. */
944 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
945 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
946 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
947 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
949 /* V5E "El Segundo" Instructions. */
950 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
951 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
952 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
953 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
954 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
955 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
956 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
958 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
959 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
961 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
962 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
963 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
964 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
966 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
967 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
968 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
969 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
971 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
972 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
974 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
975 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
976 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
977 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
979 /* ARM Instructions. */
980 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
981 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
982 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
983 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
984 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
985 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
986 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
987 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
988 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
989 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
990 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
991 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
992 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
993 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
994 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
995 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
996 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
997 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
998 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
999 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
1000 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
1001 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
1002 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
1003 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
1004 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
1005 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
1006 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
1007 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1008 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1010 /* The rest. */
1011 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
1012 {0, 0x00000000, 0x00000000, 0}
1015 /* print_insn_thumb16 recognizes the following format control codes:
1017 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1018 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1019 %<bitfield>I print bitfield as a signed decimal
1020 (top bit of range being the sign bit)
1021 %N print Thumb register mask (with LR)
1022 %O print Thumb register mask (with PC)
1023 %M print Thumb register mask
1024 %b print CZB's 6-bit unsigned branch destination
1025 %s print Thumb right-shift immediate (6..10; 0 == 32).
1026 %c print the condition code
1027 %C print the condition code, or "s" if not conditional
1028 %x print warning if conditional an not at end of IT block"
1029 %X print "\t; unpredictable <IT:code>" if conditional
1030 %I print IT instruction suffix and operands
1031 %<bitfield>r print bitfield as an ARM register
1032 %<bitfield>d print bitfield as a decimal
1033 %<bitfield>H print (bitfield * 2) as a decimal
1034 %<bitfield>W print (bitfield * 4) as a decimal
1035 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1036 %<bitfield>B print Thumb branch destination (signed displacement)
1037 %<bitfield>c print bitfield as a condition code
1038 %<bitnum>'c print specified char iff bit is one
1039 %<bitnum>?ab print a if bit is one else print b. */
1041 static const struct opcode16 thumb_opcodes[] =
1043 /* Thumb instructions. */
1045 /* ARM V6K no-argument instructions. */
1046 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1047 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1048 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1049 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1050 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1051 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1053 /* ARM V6T2 instructions. */
1054 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1055 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1056 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1058 /* ARM V6. */
1059 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1060 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1061 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1062 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1063 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1064 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1065 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1066 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1067 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1068 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1069 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1071 /* ARM V5 ISA extends Thumb. */
1072 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1073 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1074 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1075 /* ARM V4T ISA (Thumb v1). */
1076 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t(mov r8, r8)"},
1077 /* Format 4. */
1078 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1079 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1080 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1081 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1082 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1083 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1084 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1085 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1086 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1087 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1088 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1089 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1090 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1091 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1092 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1093 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1094 /* format 13 */
1095 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1096 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1097 /* format 5 */
1098 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1099 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1100 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1101 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1102 /* format 14 */
1103 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1104 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1105 /* format 2 */
1106 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1107 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1108 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1109 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1110 /* format 8 */
1111 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1112 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1113 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1114 /* format 7 */
1115 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1116 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1117 /* format 1 */
1118 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1119 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1120 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1121 /* format 3 */
1122 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1123 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1124 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1125 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1126 /* format 6 */
1127 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1128 /* format 9 */
1129 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1130 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1131 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1132 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1133 /* format 10 */
1134 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1135 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1136 /* format 11 */
1137 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1138 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1139 /* format 12 */
1140 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
1141 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1142 /* format 15 */
1143 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1144 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1145 /* format 17 */
1146 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1147 /* format 16 */
1148 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1149 /* format 18 */
1150 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1152 /* The E800 .. FFFF range is unconditionally redirected to the
1153 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1154 are processed via that table. Thus, we can never encounter a
1155 bare "second half of BL/BLX(1)" instruction here. */
1156 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
1157 {0, 0, 0, 0}
1160 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1161 We adopt the convention that hw1 is the high 16 bits of .value and
1162 .mask, hw2 the low 16 bits.
1164 print_insn_thumb32 recognizes the following format control codes:
1166 %% %
1168 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1169 %M print a modified 12-bit immediate (same location)
1170 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1171 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1172 %S print a possibly-shifted Rm
1174 %a print the address of a plain load/store
1175 %w print the width and signedness of a core load/store
1176 %m print register mask for ldm/stm
1178 %E print the lsb and width fields of a bfc/bfi instruction
1179 %F print the lsb and width fields of a sbfx/ubfx instruction
1180 %b print a conditional branch offset
1181 %B print an unconditional branch offset
1182 %s print the shift field of an SSAT instruction
1183 %R print the rotation field of an SXT instruction
1184 %U print barrier type.
1185 %P print address for pli instruction.
1186 %c print the condition code
1187 %x print warning if conditional an not at end of IT block"
1188 %X print "\t; unpredictable <IT:code>" if conditional
1190 %<bitfield>d print bitfield in decimal
1191 %<bitfield>W print bitfield*4 in decimal
1192 %<bitfield>r print bitfield as an ARM register
1193 %<bitfield>c print bitfield as a condition code
1195 %<bitfield>'c print specified char iff bitfield is all ones
1196 %<bitfield>`c print specified char iff bitfield is all zeroes
1197 %<bitfield>?ab... select from array of values in big endian order
1199 With one exception at the bottom (done because BL and BLX(1) need
1200 to come dead last), this table was machine-sorted first in
1201 decreasing order of number of bits set in the mask, then in
1202 increasing numeric order of mask, then in increasing numeric order
1203 of opcode. This order is not the clearest for a human reader, but
1204 is guaranteed never to catch a special-case bit pattern with a more
1205 general mask, which is important, because this instruction encoding
1206 makes heavy use of special-case bit patterns. */
1207 static const struct opcode32 thumb32_opcodes[] =
1209 /* V7 instructions. */
1210 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1211 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1212 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1213 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1214 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1215 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1216 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1218 /* Instructions defined in the basic V6T2 set. */
1219 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1220 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1221 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1222 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1223 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev%c.w"},
1224 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1226 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1227 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1228 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1229 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1230 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1231 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1232 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1233 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1234 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1235 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1236 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1237 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1238 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1239 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1240 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1241 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1242 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t#%0-4d%21'!"},
1243 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t#%0-4d%21'!"},
1244 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1245 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1246 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1247 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1248 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1249 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1250 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1251 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1252 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1253 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1254 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1255 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1256 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1257 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1258 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %0-3r, %16-19r"},
1259 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %0-3r, %16-19r"},
1260 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %0-3r, %16-19r"},
1261 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %0-3r, %16-19r"},
1262 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1263 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1264 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1265 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1266 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1267 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1268 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1269 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1270 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1271 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1272 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1273 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1274 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1275 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1276 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1277 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1278 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1279 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1280 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1281 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1282 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1283 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1284 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1285 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1286 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1287 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1288 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1289 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1290 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1291 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1292 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1293 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1294 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1295 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1296 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1297 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1298 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1299 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1300 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1301 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1302 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1303 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1304 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1305 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1306 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1307 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1308 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1309 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1310 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1311 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1312 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1313 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1314 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1315 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1316 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1317 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1318 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1319 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1320 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1321 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1322 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1323 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1324 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1325 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1326 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1327 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1328 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1329 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1330 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1331 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1332 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1333 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1334 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1335 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1336 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1337 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1338 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1339 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1340 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1341 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1342 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1343 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1344 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1345 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1346 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1347 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1348 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1349 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1350 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1351 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1352 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1353 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1354 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1355 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1356 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1358 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1359 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1360 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1361 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1362 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1363 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1364 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1365 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1366 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1367 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1368 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1369 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1370 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1371 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1372 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1373 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1374 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1375 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1376 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1377 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1378 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1379 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1380 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1381 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1382 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1383 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1384 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1385 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1386 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1387 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1388 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1389 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1390 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1391 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1392 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1393 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1394 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1395 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1397 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1398 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1399 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1400 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1401 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1403 /* These have been 32-bit since the invention of Thumb. */
1404 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1405 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1407 /* Fallback. */
1408 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1409 {0, 0, 0, 0}
1412 static const char *const arm_conditional[] =
1413 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1414 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1416 static const char *const arm_fp_const[] =
1417 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1419 static const char *const arm_shift[] =
1420 {"lsl", "lsr", "asr", "ror"};
1422 typedef struct
1424 const char *name;
1425 const char *description;
1426 const char *reg_names[16];
1428 arm_regname;
1430 static const arm_regname regnames[] =
1432 { "raw" , "Select raw register names",
1433 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1434 { "gcc", "Select register names used by GCC",
1435 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1436 { "std", "Select register names used in ARM's ISA documentation",
1437 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1438 { "apcs", "Select register names used in the APCS",
1439 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1440 { "atpcs", "Select register names used in the ATPCS",
1441 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1442 { "special-atpcs", "Select special register names used in the ATPCS",
1443 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1446 static const char *const iwmmxt_wwnames[] =
1447 {"b", "h", "w", "d"};
1449 static const char *const iwmmxt_wwssnames[] =
1450 {"b", "bus", "bc", "bss",
1451 "h", "hus", "hc", "hss",
1452 "w", "wus", "wc", "wss",
1453 "d", "dus", "dc", "dss"
1456 static const char *const iwmmxt_regnames[] =
1457 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1458 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1461 static const char *const iwmmxt_cregnames[] =
1462 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1463 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1466 /* Default to GCC register name set. */
1467 static unsigned int regname_selected = 1;
1469 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1470 #define arm_regnames regnames[regname_selected].reg_names
1472 static bfd_boolean force_thumb = FALSE;
1474 /* Current IT instruction state. This contains the same state as the IT
1475 bits in the CPSR. */
1476 static unsigned int ifthen_state;
1477 /* IT state for the next instruction. */
1478 static unsigned int ifthen_next_state;
1479 /* The address of the insn for which the IT state is valid. */
1480 static bfd_vma ifthen_address;
1481 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1483 /* Cached mapping symbol state. */
1484 enum map_type {
1485 MAP_ARM,
1486 MAP_THUMB,
1487 MAP_DATA
1490 enum map_type last_type;
1491 int last_mapping_sym = -1;
1492 bfd_vma last_mapping_addr = 0;
1495 /* Functions. */
1497 get_arm_regname_num_options (void)
1499 return NUM_ARM_REGNAMES;
1503 set_arm_regname_option (int option)
1505 int old = regname_selected;
1506 regname_selected = option;
1507 return old;
1511 get_arm_regnames (int option, const char **setname, const char **setdescription,
1512 const char *const **register_names)
1514 *setname = regnames[option].name;
1515 *setdescription = regnames[option].description;
1516 *register_names = regnames[option].reg_names;
1517 return 16;
1520 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1521 Returns pointer to following character of the format string and
1522 fills in *VALUEP and *WIDTHP with the extracted value and number of
1523 bits extracted. WIDTHP can be NULL. */
1525 static const char *
1526 arm_decode_bitfield (const char *ptr, unsigned long insn,
1527 unsigned long *valuep, int *widthp)
1529 unsigned long value = 0;
1530 int width = 0;
1534 int start, end;
1535 int bits;
1537 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1538 start = start * 10 + *ptr - '0';
1539 if (*ptr == '-')
1540 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1541 end = end * 10 + *ptr - '0';
1542 else
1543 end = start;
1544 bits = end - start;
1545 if (bits < 0)
1546 abort ();
1547 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1548 width += bits + 1;
1550 while (*ptr++ == ',');
1551 *valuep = value;
1552 if (widthp)
1553 *widthp = width;
1554 return ptr - 1;
1557 static void
1558 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1560 func (stream, "%s", arm_regnames[given & 0xf]);
1562 if ((given & 0xff0) != 0)
1564 if ((given & 0x10) == 0)
1566 int amount = (given & 0xf80) >> 7;
1567 int shift = (given & 0x60) >> 5;
1569 if (amount == 0)
1571 if (shift == 3)
1573 func (stream, ", rrx");
1574 return;
1577 amount = 32;
1580 func (stream, ", %s #%d", arm_shift[shift], amount);
1582 else
1583 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1584 arm_regnames[(given & 0xf00) >> 8]);
1588 /* Print one coprocessor instruction on INFO->STREAM.
1589 Return TRUE if the instuction matched, FALSE if this is not a
1590 recognised coprocessor instruction. */
1592 static bfd_boolean
1593 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1594 bfd_boolean thumb)
1596 const struct opcode32 *insn;
1597 void *stream = info->stream;
1598 fprintf_ftype func = info->fprintf_func;
1599 unsigned long mask;
1600 unsigned long value;
1601 int cond;
1603 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1605 if (insn->value == FIRST_IWMMXT_INSN
1606 && info->mach != bfd_mach_arm_XScale
1607 && info->mach != bfd_mach_arm_iWMMXt
1608 && info->mach != bfd_mach_arm_iWMMXt2)
1609 insn = insn + IWMMXT_INSN_COUNT;
1611 mask = insn->mask;
1612 value = insn->value;
1613 if (thumb)
1615 /* The high 4 bits are 0xe for Arm conditional instructions, and
1616 0xe for arm unconditional instructions. The rest of the
1617 encoding is the same. */
1618 mask |= 0xf0000000;
1619 value |= 0xe0000000;
1620 if (ifthen_state)
1621 cond = IFTHEN_COND;
1622 else
1623 cond = 16;
1625 else
1627 /* Only match unconditional instuctions against unconditional
1628 patterns. */
1629 if ((given & 0xf0000000) == 0xf0000000)
1631 mask |= 0xf0000000;
1632 cond = 16;
1634 else
1636 cond = (given >> 28) & 0xf;
1637 if (cond == 0xe)
1638 cond = 16;
1641 if ((given & mask) == value)
1643 const char *c;
1645 for (c = insn->assembler; *c; c++)
1647 if (*c == '%')
1649 switch (*++c)
1651 case '%':
1652 func (stream, "%%");
1653 break;
1655 case 'A':
1656 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1658 if ((given & (1 << 24)) != 0)
1660 int offset = given & 0xff;
1662 if (offset)
1663 func (stream, ", #%s%d]%s",
1664 ((given & 0x00800000) == 0 ? "-" : ""),
1665 offset * 4,
1666 ((given & 0x00200000) != 0 ? "!" : ""));
1667 else
1668 func (stream, "]");
1670 else
1672 int offset = given & 0xff;
1674 func (stream, "]");
1676 if (given & (1 << 21))
1678 if (offset)
1679 func (stream, ", #%s%d",
1680 ((given & 0x00800000) == 0 ? "-" : ""),
1681 offset * 4);
1683 else
1684 func (stream, ", {%d}", offset);
1686 break;
1688 case 'B':
1690 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1691 int offset = (given >> 1) & 0x3f;
1693 if (offset == 1)
1694 func (stream, "{d%d}", regno);
1695 else if (regno + offset > 32)
1696 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1697 else
1698 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1700 break;
1702 case 'C':
1704 int rn = (given >> 16) & 0xf;
1705 int offset = (given & 0xff) * 4;
1706 int add = (given >> 23) & 1;
1708 func (stream, "[%s", arm_regnames[rn]);
1710 if (offset)
1712 if (!add)
1713 offset = -offset;
1714 func (stream, ", #%d", offset);
1716 func (stream, "]");
1717 if (rn == 15)
1719 func (stream, "\t; ");
1720 /* FIXME: Unsure if info->bytes_per_chunk is the
1721 right thing to use here. */
1722 info->print_address_func (offset + pc
1723 + info->bytes_per_chunk * 2, info);
1726 break;
1728 case 'c':
1729 func (stream, "%s", arm_conditional[cond]);
1730 break;
1732 case 'I':
1733 /* Print a Cirrus/DSP shift immediate. */
1734 /* Immediates are 7bit signed ints with bits 0..3 in
1735 bits 0..3 of opcode and bits 4..6 in bits 5..7
1736 of opcode. */
1738 int imm;
1740 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1742 /* Is ``imm'' a negative number? */
1743 if (imm & 0x40)
1744 imm |= (-1 << 7);
1746 func (stream, "%d", imm);
1749 break;
1751 case 'F':
1752 switch (given & 0x00408000)
1754 case 0:
1755 func (stream, "4");
1756 break;
1757 case 0x8000:
1758 func (stream, "1");
1759 break;
1760 case 0x00400000:
1761 func (stream, "2");
1762 break;
1763 default:
1764 func (stream, "3");
1766 break;
1768 case 'P':
1769 switch (given & 0x00080080)
1771 case 0:
1772 func (stream, "s");
1773 break;
1774 case 0x80:
1775 func (stream, "d");
1776 break;
1777 case 0x00080000:
1778 func (stream, "e");
1779 break;
1780 default:
1781 func (stream, _("<illegal precision>"));
1782 break;
1784 break;
1785 case 'Q':
1786 switch (given & 0x00408000)
1788 case 0:
1789 func (stream, "s");
1790 break;
1791 case 0x8000:
1792 func (stream, "d");
1793 break;
1794 case 0x00400000:
1795 func (stream, "e");
1796 break;
1797 default:
1798 func (stream, "p");
1799 break;
1801 break;
1802 case 'R':
1803 switch (given & 0x60)
1805 case 0:
1806 break;
1807 case 0x20:
1808 func (stream, "p");
1809 break;
1810 case 0x40:
1811 func (stream, "m");
1812 break;
1813 default:
1814 func (stream, "z");
1815 break;
1817 break;
1819 case '0': case '1': case '2': case '3': case '4':
1820 case '5': case '6': case '7': case '8': case '9':
1822 int width;
1823 unsigned long value;
1825 c = arm_decode_bitfield (c, given, &value, &width);
1827 switch (*c)
1829 case 'r':
1830 func (stream, "%s", arm_regnames[value]);
1831 break;
1832 case 'D':
1833 func (stream, "d%ld", value);
1834 break;
1835 case 'Q':
1836 if (value & 1)
1837 func (stream, "<illegal reg q%ld.5>", value >> 1);
1838 else
1839 func (stream, "q%ld", value >> 1);
1840 break;
1841 case 'd':
1842 func (stream, "%ld", value);
1843 break;
1844 case 'k':
1846 int from = (given & (1 << 7)) ? 32 : 16;
1847 func (stream, "%ld", from - value);
1849 break;
1851 case 'f':
1852 if (value > 7)
1853 func (stream, "#%s", arm_fp_const[value & 7]);
1854 else
1855 func (stream, "f%ld", value);
1856 break;
1858 case 'w':
1859 if (width == 2)
1860 func (stream, "%s", iwmmxt_wwnames[value]);
1861 else
1862 func (stream, "%s", iwmmxt_wwssnames[value]);
1863 break;
1865 case 'g':
1866 func (stream, "%s", iwmmxt_regnames[value]);
1867 break;
1868 case 'G':
1869 func (stream, "%s", iwmmxt_cregnames[value]);
1870 break;
1871 case '`':
1872 c++;
1873 if (value == 0)
1874 func (stream, "%c", *c);
1875 break;
1876 case '\'':
1877 c++;
1878 if (value == ((1ul << width) - 1))
1879 func (stream, "%c", *c);
1880 break;
1881 case '?':
1882 func (stream, "%c", c[(1 << width) - (int)value]);
1883 c += 1 << width;
1884 break;
1885 default:
1886 abort ();
1888 break;
1890 case 'y':
1891 case 'z':
1893 int single = *c++ == 'y';
1894 int regno;
1896 switch (*c)
1898 case '4': /* Sm pair */
1899 func (stream, "{");
1900 /* Fall through. */
1901 case '0': /* Sm, Dm */
1902 regno = given & 0x0000000f;
1903 if (single)
1905 regno <<= 1;
1906 regno += (given >> 5) & 1;
1908 else
1909 regno += ((given >> 5) & 1) << 4;
1910 break;
1912 case '1': /* Sd, Dd */
1913 regno = (given >> 12) & 0x0000000f;
1914 if (single)
1916 regno <<= 1;
1917 regno += (given >> 22) & 1;
1919 else
1920 regno += ((given >> 22) & 1) << 4;
1921 break;
1923 case '2': /* Sn, Dn */
1924 regno = (given >> 16) & 0x0000000f;
1925 if (single)
1927 regno <<= 1;
1928 regno += (given >> 7) & 1;
1930 else
1931 regno += ((given >> 7) & 1) << 4;
1932 break;
1934 case '3': /* List */
1935 func (stream, "{");
1936 regno = (given >> 12) & 0x0000000f;
1937 if (single)
1939 regno <<= 1;
1940 regno += (given >> 22) & 1;
1942 else
1943 regno += ((given >> 22) & 1) << 4;
1944 break;
1946 default:
1947 abort ();
1950 func (stream, "%c%d", single ? 's' : 'd', regno);
1952 if (*c == '3')
1954 int count = given & 0xff;
1956 if (single == 0)
1957 count >>= 1;
1959 if (--count)
1961 func (stream, "-%c%d",
1962 single ? 's' : 'd',
1963 regno + count);
1966 func (stream, "}");
1968 else if (*c == '4')
1969 func (stream, ", %c%d}", single ? 's' : 'd',
1970 regno + 1);
1972 break;
1974 case 'L':
1975 switch (given & 0x00400100)
1977 case 0x00000000: func (stream, "b"); break;
1978 case 0x00400000: func (stream, "h"); break;
1979 case 0x00000100: func (stream, "w"); break;
1980 case 0x00400100: func (stream, "d"); break;
1981 default:
1982 break;
1984 break;
1986 case 'Z':
1988 int value;
1989 /* given (20, 23) | given (0, 3) */
1990 value = ((given >> 16) & 0xf0) | (given & 0xf);
1991 func (stream, "%d", value);
1993 break;
1995 case 'l':
1996 /* This is like the 'A' operator, except that if
1997 the width field "M" is zero, then the offset is
1998 *not* multiplied by four. */
2000 int offset = given & 0xff;
2001 int multiplier = (given & 0x00000100) ? 4 : 1;
2003 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2005 if (offset)
2007 if ((given & 0x01000000) != 0)
2008 func (stream, ", #%s%d]%s",
2009 ((given & 0x00800000) == 0 ? "-" : ""),
2010 offset * multiplier,
2011 ((given & 0x00200000) != 0 ? "!" : ""));
2012 else
2013 func (stream, "], #%s%d",
2014 ((given & 0x00800000) == 0 ? "-" : ""),
2015 offset * multiplier);
2017 else
2018 func (stream, "]");
2020 break;
2022 case 'r':
2024 int imm4 = (given >> 4) & 0xf;
2025 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2026 int ubit = (given >> 23) & 1;
2027 const char *rm = arm_regnames [given & 0xf];
2028 const char *rn = arm_regnames [(given >> 16) & 0xf];
2030 switch (puw_bits)
2032 case 1:
2033 /* fall through */
2034 case 3:
2035 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2036 if (imm4)
2037 func (stream, ", lsl #%d", imm4);
2038 break;
2040 case 4:
2041 /* fall through */
2042 case 5:
2043 /* fall through */
2044 case 6:
2045 /* fall through */
2046 case 7:
2047 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2048 if (imm4 > 0)
2049 func (stream, ", lsl #%d", imm4);
2050 func (stream, "]");
2051 if (puw_bits == 5 || puw_bits == 7)
2052 func (stream, "!");
2053 break;
2055 default:
2056 func (stream, "INVALID");
2059 break;
2061 case 'i':
2063 long imm5;
2064 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2065 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2067 break;
2069 default:
2070 abort ();
2074 else
2075 func (stream, "%c", *c);
2077 return TRUE;
2080 return FALSE;
2083 static void
2084 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2086 void *stream = info->stream;
2087 fprintf_ftype func = info->fprintf_func;
2089 if (((given & 0x000f0000) == 0x000f0000)
2090 && ((given & 0x02000000) == 0))
2092 int offset = given & 0xfff;
2094 func (stream, "[pc");
2096 if (given & 0x01000000)
2098 if ((given & 0x00800000) == 0)
2099 offset = - offset;
2101 /* Pre-indexed. */
2102 func (stream, ", #%d]", offset);
2104 offset += pc + 8;
2106 /* Cope with the possibility of write-back
2107 being used. Probably a very dangerous thing
2108 for the programmer to do, but who are we to
2109 argue ? */
2110 if (given & 0x00200000)
2111 func (stream, "!");
2113 else
2115 /* Post indexed. */
2116 func (stream, "], #%d", offset);
2118 /* ie ignore the offset. */
2119 offset = pc + 8;
2122 func (stream, "\t; ");
2123 info->print_address_func (offset, info);
2125 else
2127 func (stream, "[%s",
2128 arm_regnames[(given >> 16) & 0xf]);
2129 if ((given & 0x01000000) != 0)
2131 if ((given & 0x02000000) == 0)
2133 int offset = given & 0xfff;
2134 if (offset)
2135 func (stream, ", #%s%d",
2136 (((given & 0x00800000) == 0)
2137 ? "-" : ""), offset);
2139 else
2141 func (stream, ", %s",
2142 (((given & 0x00800000) == 0)
2143 ? "-" : ""));
2144 arm_decode_shift (given, func, stream);
2147 func (stream, "]%s",
2148 ((given & 0x00200000) != 0) ? "!" : "");
2150 else
2152 if ((given & 0x02000000) == 0)
2154 int offset = given & 0xfff;
2155 if (offset)
2156 func (stream, "], #%s%d",
2157 (((given & 0x00800000) == 0)
2158 ? "-" : ""), offset);
2159 else
2160 func (stream, "]");
2162 else
2164 func (stream, "], %s",
2165 (((given & 0x00800000) == 0)
2166 ? "-" : ""));
2167 arm_decode_shift (given, func, stream);
2173 /* Print one neon instruction on INFO->STREAM.
2174 Return TRUE if the instuction matched, FALSE if this is not a
2175 recognised neon instruction. */
2177 static bfd_boolean
2178 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2180 const struct opcode32 *insn;
2181 void *stream = info->stream;
2182 fprintf_ftype func = info->fprintf_func;
2184 if (thumb)
2186 if ((given & 0xef000000) == 0xef000000)
2188 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2189 unsigned long bit28 = given & (1 << 28);
2191 given &= 0x00ffffff;
2192 if (bit28)
2193 given |= 0xf3000000;
2194 else
2195 given |= 0xf2000000;
2197 else if ((given & 0xff000000) == 0xf9000000)
2198 given ^= 0xf9000000 ^ 0xf4000000;
2199 else
2200 return FALSE;
2203 for (insn = neon_opcodes; insn->assembler; insn++)
2205 if ((given & insn->mask) == insn->value)
2207 const char *c;
2209 for (c = insn->assembler; *c; c++)
2211 if (*c == '%')
2213 switch (*++c)
2215 case '%':
2216 func (stream, "%%");
2217 break;
2219 case 'c':
2220 if (thumb && ifthen_state)
2221 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2222 break;
2224 case 'A':
2226 static const unsigned char enc[16] =
2228 0x4, 0x14, /* st4 0,1 */
2229 0x4, /* st1 2 */
2230 0x4, /* st2 3 */
2231 0x3, /* st3 4 */
2232 0x13, /* st3 5 */
2233 0x3, /* st1 6 */
2234 0x1, /* st1 7 */
2235 0x2, /* st2 8 */
2236 0x12, /* st2 9 */
2237 0x2, /* st1 10 */
2238 0, 0, 0, 0, 0
2240 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2241 int rn = ((given >> 16) & 0xf);
2242 int rm = ((given >> 0) & 0xf);
2243 int align = ((given >> 4) & 0x3);
2244 int type = ((given >> 8) & 0xf);
2245 int n = enc[type] & 0xf;
2246 int stride = (enc[type] >> 4) + 1;
2247 int ix;
2249 func (stream, "{");
2250 if (stride > 1)
2251 for (ix = 0; ix != n; ix++)
2252 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2253 else if (n == 1)
2254 func (stream, "d%d", rd);
2255 else
2256 func (stream, "d%d-d%d", rd, rd + n - 1);
2257 func (stream, "}, [%s", arm_regnames[rn]);
2258 if (align)
2259 func (stream, ", :%d", 32 << align);
2260 func (stream, "]");
2261 if (rm == 0xd)
2262 func (stream, "!");
2263 else if (rm != 0xf)
2264 func (stream, ", %s", arm_regnames[rm]);
2266 break;
2268 case 'B':
2270 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2271 int rn = ((given >> 16) & 0xf);
2272 int rm = ((given >> 0) & 0xf);
2273 int idx_align = ((given >> 4) & 0xf);
2274 int align = 0;
2275 int size = ((given >> 10) & 0x3);
2276 int idx = idx_align >> (size + 1);
2277 int length = ((given >> 8) & 3) + 1;
2278 int stride = 1;
2279 int i;
2281 if (length > 1 && size > 0)
2282 stride = (idx_align & (1 << size)) ? 2 : 1;
2284 switch (length)
2286 case 1:
2288 int amask = (1 << size) - 1;
2289 if ((idx_align & (1 << size)) != 0)
2290 return FALSE;
2291 if (size > 0)
2293 if ((idx_align & amask) == amask)
2294 align = 8 << size;
2295 else if ((idx_align & amask) != 0)
2296 return FALSE;
2299 break;
2301 case 2:
2302 if (size == 2 && (idx_align & 2) != 0)
2303 return FALSE;
2304 align = (idx_align & 1) ? 16 << size : 0;
2305 break;
2307 case 3:
2308 if ((size == 2 && (idx_align & 3) != 0)
2309 || (idx_align & 1) != 0)
2310 return FALSE;
2311 break;
2313 case 4:
2314 if (size == 2)
2316 if ((idx_align & 3) == 3)
2317 return FALSE;
2318 align = (idx_align & 3) * 64;
2320 else
2321 align = (idx_align & 1) ? 32 << size : 0;
2322 break;
2324 default:
2325 abort ();
2328 func (stream, "{");
2329 for (i = 0; i < length; i++)
2330 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2331 rd + i * stride, idx);
2332 func (stream, "}, [%s", arm_regnames[rn]);
2333 if (align)
2334 func (stream, ", :%d", align);
2335 func (stream, "]");
2336 if (rm == 0xd)
2337 func (stream, "!");
2338 else if (rm != 0xf)
2339 func (stream, ", %s", arm_regnames[rm]);
2341 break;
2343 case 'C':
2345 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2346 int rn = ((given >> 16) & 0xf);
2347 int rm = ((given >> 0) & 0xf);
2348 int align = ((given >> 4) & 0x1);
2349 int size = ((given >> 6) & 0x3);
2350 int type = ((given >> 8) & 0x3);
2351 int n = type + 1;
2352 int stride = ((given >> 5) & 0x1);
2353 int ix;
2355 if (stride && (n == 1))
2356 n++;
2357 else
2358 stride++;
2360 func (stream, "{");
2361 if (stride > 1)
2362 for (ix = 0; ix != n; ix++)
2363 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2364 else if (n == 1)
2365 func (stream, "d%d[]", rd);
2366 else
2367 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2368 func (stream, "}, [%s", arm_regnames[rn]);
2369 if (align)
2371 int align = (8 * (type + 1)) << size;
2372 if (type == 3)
2373 align = (size > 1) ? align >> 1 : align;
2374 if (type == 2 || (type == 0 && !size))
2375 func (stream, ", :<bad align %d>", align);
2376 else
2377 func (stream, ", :%d", align);
2379 func (stream, "]");
2380 if (rm == 0xd)
2381 func (stream, "!");
2382 else if (rm != 0xf)
2383 func (stream, ", %s", arm_regnames[rm]);
2385 break;
2387 case 'D':
2389 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2390 int size = (given >> 20) & 3;
2391 int reg = raw_reg & ((4 << size) - 1);
2392 int ix = raw_reg >> size >> 2;
2394 func (stream, "d%d[%d]", reg, ix);
2396 break;
2398 case 'E':
2399 /* Neon encoded constant for mov, mvn, vorr, vbic */
2401 int bits = 0;
2402 int cmode = (given >> 8) & 0xf;
2403 int op = (given >> 5) & 0x1;
2404 unsigned long value = 0, hival = 0;
2405 unsigned shift;
2406 int size = 0;
2407 int isfloat = 0;
2409 bits |= ((given >> 24) & 1) << 7;
2410 bits |= ((given >> 16) & 7) << 4;
2411 bits |= ((given >> 0) & 15) << 0;
2413 if (cmode < 8)
2415 shift = (cmode >> 1) & 3;
2416 value = (unsigned long)bits << (8 * shift);
2417 size = 32;
2419 else if (cmode < 12)
2421 shift = (cmode >> 1) & 1;
2422 value = (unsigned long)bits << (8 * shift);
2423 size = 16;
2425 else if (cmode < 14)
2427 shift = (cmode & 1) + 1;
2428 value = (unsigned long)bits << (8 * shift);
2429 value |= (1ul << (8 * shift)) - 1;
2430 size = 32;
2432 else if (cmode == 14)
2434 if (op)
2436 /* bit replication into bytes */
2437 int ix;
2438 unsigned long mask;
2440 value = 0;
2441 hival = 0;
2442 for (ix = 7; ix >= 0; ix--)
2444 mask = ((bits >> ix) & 1) ? 0xff : 0;
2445 if (ix <= 3)
2446 value = (value << 8) | mask;
2447 else
2448 hival = (hival << 8) | mask;
2450 size = 64;
2452 else
2454 /* byte replication */
2455 value = (unsigned long)bits;
2456 size = 8;
2459 else if (!op)
2461 /* floating point encoding */
2462 int tmp;
2464 value = (unsigned long)(bits & 0x7f) << 19;
2465 value |= (unsigned long)(bits & 0x80) << 24;
2466 tmp = bits & 0x40 ? 0x3c : 0x40;
2467 value |= (unsigned long)tmp << 24;
2468 size = 32;
2469 isfloat = 1;
2471 else
2473 func (stream, "<illegal constant %.8x:%x:%x>",
2474 bits, cmode, op);
2475 size = 32;
2476 break;
2478 switch (size)
2480 case 8:
2481 func (stream, "#%ld\t; 0x%.2lx", value, value);
2482 break;
2484 case 16:
2485 func (stream, "#%ld\t; 0x%.4lx", value, value);
2486 break;
2488 case 32:
2489 if (isfloat)
2491 unsigned char valbytes[4];
2492 double fvalue;
2494 /* Do this a byte at a time so we don't have to
2495 worry about the host's endianness. */
2496 valbytes[0] = value & 0xff;
2497 valbytes[1] = (value >> 8) & 0xff;
2498 valbytes[2] = (value >> 16) & 0xff;
2499 valbytes[3] = (value >> 24) & 0xff;
2501 floatformat_to_double
2502 (&floatformat_ieee_single_little, valbytes,
2503 &fvalue);
2505 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2506 value);
2508 else
2509 func (stream, "#%ld\t; 0x%.8lx",
2510 (long) ((value & 0x80000000)
2511 ? value | ~0xffffffffl : value), value);
2512 break;
2514 case 64:
2515 func (stream, "#0x%.8lx%.8lx", hival, value);
2516 break;
2518 default:
2519 abort ();
2522 break;
2524 case 'F':
2526 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2527 int num = (given >> 8) & 0x3;
2529 if (!num)
2530 func (stream, "{d%d}", regno);
2531 else if (num + regno >= 32)
2532 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2533 else
2534 func (stream, "{d%d-d%d}", regno, regno + num);
2536 break;
2539 case '0': case '1': case '2': case '3': case '4':
2540 case '5': case '6': case '7': case '8': case '9':
2542 int width;
2543 unsigned long value;
2545 c = arm_decode_bitfield (c, given, &value, &width);
2547 switch (*c)
2549 case 'r':
2550 func (stream, "%s", arm_regnames[value]);
2551 break;
2552 case 'd':
2553 func (stream, "%ld", value);
2554 break;
2555 case 'e':
2556 func (stream, "%ld", (1ul << width) - value);
2557 break;
2559 case 'S':
2560 case 'T':
2561 case 'U':
2562 /* various width encodings */
2564 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2565 int limit;
2566 unsigned low, high;
2568 c++;
2569 if (*c >= '0' && *c <= '9')
2570 limit = *c - '0';
2571 else if (*c >= 'a' && *c <= 'f')
2572 limit = *c - 'a' + 10;
2573 else
2574 abort ();
2575 low = limit >> 2;
2576 high = limit & 3;
2578 if (value < low || value > high)
2579 func (stream, "<illegal width %d>", base << value);
2580 else
2581 func (stream, "%d", base << value);
2583 break;
2584 case 'R':
2585 if (given & (1 << 6))
2586 goto Q;
2587 /* FALLTHROUGH */
2588 case 'D':
2589 func (stream, "d%ld", value);
2590 break;
2591 case 'Q':
2593 if (value & 1)
2594 func (stream, "<illegal reg q%ld.5>", value >> 1);
2595 else
2596 func (stream, "q%ld", value >> 1);
2597 break;
2599 case '`':
2600 c++;
2601 if (value == 0)
2602 func (stream, "%c", *c);
2603 break;
2604 case '\'':
2605 c++;
2606 if (value == ((1ul << width) - 1))
2607 func (stream, "%c", *c);
2608 break;
2609 case '?':
2610 func (stream, "%c", c[(1 << width) - (int)value]);
2611 c += 1 << width;
2612 break;
2613 default:
2614 abort ();
2616 break;
2618 default:
2619 abort ();
2623 else
2624 func (stream, "%c", *c);
2626 return TRUE;
2629 return FALSE;
2632 /* Print one ARM instruction from PC on INFO->STREAM. */
2634 static void
2635 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2637 const struct opcode32 *insn;
2638 void *stream = info->stream;
2639 fprintf_ftype func = info->fprintf_func;
2641 if (print_insn_coprocessor (pc, info, given, FALSE))
2642 return;
2644 if (print_insn_neon (info, given, FALSE))
2645 return;
2647 for (insn = arm_opcodes; insn->assembler; insn++)
2649 if (insn->value == FIRST_IWMMXT_INSN
2650 && info->mach != bfd_mach_arm_XScale
2651 && info->mach != bfd_mach_arm_iWMMXt)
2652 insn = insn + IWMMXT_INSN_COUNT;
2654 if ((given & insn->mask) == insn->value
2655 /* Special case: an instruction with all bits set in the condition field
2656 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2657 or by the catchall at the end of the table. */
2658 && ((given & 0xF0000000) != 0xF0000000
2659 || (insn->mask & 0xF0000000) == 0xF0000000
2660 || (insn->mask == 0 && insn->value == 0)))
2662 const char *c;
2664 for (c = insn->assembler; *c; c++)
2666 if (*c == '%')
2668 switch (*++c)
2670 case '%':
2671 func (stream, "%%");
2672 break;
2674 case 'a':
2675 print_arm_address (pc, info, given);
2676 break;
2678 case 'P':
2679 /* Set P address bit and use normal address
2680 printing routine. */
2681 print_arm_address (pc, info, given | (1 << 24));
2682 break;
2684 case 's':
2685 if ((given & 0x004f0000) == 0x004f0000)
2687 /* PC relative with immediate offset. */
2688 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2690 if ((given & 0x00800000) == 0)
2691 offset = -offset;
2693 func (stream, "[pc, #%d]\t; ", offset);
2694 info->print_address_func (offset + pc + 8, info);
2696 else
2698 func (stream, "[%s",
2699 arm_regnames[(given >> 16) & 0xf]);
2700 if ((given & 0x01000000) != 0)
2702 /* Pre-indexed. */
2703 if ((given & 0x00400000) == 0x00400000)
2705 /* Immediate. */
2706 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2707 if (offset)
2708 func (stream, ", #%s%d",
2709 (((given & 0x00800000) == 0)
2710 ? "-" : ""), offset);
2712 else
2714 /* Register. */
2715 func (stream, ", %s%s",
2716 (((given & 0x00800000) == 0)
2717 ? "-" : ""),
2718 arm_regnames[given & 0xf]);
2721 func (stream, "]%s",
2722 ((given & 0x00200000) != 0) ? "!" : "");
2724 else
2726 /* Post-indexed. */
2727 if ((given & 0x00400000) == 0x00400000)
2729 /* Immediate. */
2730 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2731 if (offset)
2732 func (stream, "], #%s%d",
2733 (((given & 0x00800000) == 0)
2734 ? "-" : ""), offset);
2735 else
2736 func (stream, "]");
2738 else
2740 /* Register. */
2741 func (stream, "], %s%s",
2742 (((given & 0x00800000) == 0)
2743 ? "-" : ""),
2744 arm_regnames[given & 0xf]);
2748 break;
2750 case 'b':
2752 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2753 info->print_address_func (disp*4 + pc + 8, info);
2755 break;
2757 case 'c':
2758 if (((given >> 28) & 0xf) != 0xe)
2759 func (stream, "%s",
2760 arm_conditional [(given >> 28) & 0xf]);
2761 break;
2763 case 'm':
2765 int started = 0;
2766 int reg;
2768 func (stream, "{");
2769 for (reg = 0; reg < 16; reg++)
2770 if ((given & (1 << reg)) != 0)
2772 if (started)
2773 func (stream, ", ");
2774 started = 1;
2775 func (stream, "%s", arm_regnames[reg]);
2777 func (stream, "}");
2779 break;
2781 case 'o':
2782 if ((given & 0x02000000) != 0)
2784 int rotate = (given & 0xf00) >> 7;
2785 int immed = (given & 0xff);
2786 immed = (((immed << (32 - rotate))
2787 | (immed >> rotate)) & 0xffffffff);
2788 func (stream, "#%d\t; 0x%x", immed, immed);
2790 else
2791 arm_decode_shift (given, func, stream);
2792 break;
2794 case 'p':
2795 if ((given & 0x0000f000) == 0x0000f000)
2796 func (stream, "p");
2797 break;
2799 case 't':
2800 if ((given & 0x01200000) == 0x00200000)
2801 func (stream, "t");
2802 break;
2804 case 'A':
2805 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2807 if ((given & (1 << 24)) != 0)
2809 int offset = given & 0xff;
2811 if (offset)
2812 func (stream, ", #%s%d]%s",
2813 ((given & 0x00800000) == 0 ? "-" : ""),
2814 offset * 4,
2815 ((given & 0x00200000) != 0 ? "!" : ""));
2816 else
2817 func (stream, "]");
2819 else
2821 int offset = given & 0xff;
2823 func (stream, "]");
2825 if (given & (1 << 21))
2827 if (offset)
2828 func (stream, ", #%s%d",
2829 ((given & 0x00800000) == 0 ? "-" : ""),
2830 offset * 4);
2832 else
2833 func (stream, ", {%d}", offset);
2835 break;
2837 case 'B':
2838 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2840 bfd_vma address;
2841 bfd_vma offset = 0;
2843 if (given & 0x00800000)
2844 /* Is signed, hi bits should be ones. */
2845 offset = (-1) ^ 0x00ffffff;
2847 /* Offset is (SignExtend(offset field)<<2). */
2848 offset += given & 0x00ffffff;
2849 offset <<= 2;
2850 address = offset + pc + 8;
2852 if (given & 0x01000000)
2853 /* H bit allows addressing to 2-byte boundaries. */
2854 address += 2;
2856 info->print_address_func (address, info);
2858 break;
2860 case 'C':
2861 func (stream, "_");
2862 if (given & 0x80000)
2863 func (stream, "f");
2864 if (given & 0x40000)
2865 func (stream, "s");
2866 if (given & 0x20000)
2867 func (stream, "x");
2868 if (given & 0x10000)
2869 func (stream, "c");
2870 break;
2872 case 'U':
2873 switch (given & 0xf)
2875 case 0xf: func(stream, "sy"); break;
2876 case 0x7: func(stream, "un"); break;
2877 case 0xe: func(stream, "st"); break;
2878 case 0x6: func(stream, "unst"); break;
2879 default:
2880 func(stream, "#%d", (int)given & 0xf);
2881 break;
2883 break;
2885 case '0': case '1': case '2': case '3': case '4':
2886 case '5': case '6': case '7': case '8': case '9':
2888 int width;
2889 unsigned long value;
2891 c = arm_decode_bitfield (c, given, &value, &width);
2893 switch (*c)
2895 case 'r':
2896 func (stream, "%s", arm_regnames[value]);
2897 break;
2898 case 'd':
2899 func (stream, "%ld", value);
2900 break;
2901 case 'b':
2902 func (stream, "%ld", value * 8);
2903 break;
2904 case 'W':
2905 func (stream, "%ld", value + 1);
2906 break;
2907 case 'x':
2908 func (stream, "0x%08lx", value);
2910 /* Some SWI instructions have special
2911 meanings. */
2912 if ((given & 0x0fffffff) == 0x0FF00000)
2913 func (stream, "\t; IMB");
2914 else if ((given & 0x0fffffff) == 0x0FF00001)
2915 func (stream, "\t; IMBRange");
2916 break;
2917 case 'X':
2918 func (stream, "%01lx", value & 0xf);
2919 break;
2920 case '`':
2921 c++;
2922 if (value == 0)
2923 func (stream, "%c", *c);
2924 break;
2925 case '\'':
2926 c++;
2927 if (value == ((1ul << width) - 1))
2928 func (stream, "%c", *c);
2929 break;
2930 case '?':
2931 func (stream, "%c", c[(1 << width) - (int)value]);
2932 c += 1 << width;
2933 break;
2934 default:
2935 abort ();
2937 break;
2939 case 'e':
2941 int imm;
2943 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2944 func (stream, "%d", imm);
2946 break;
2948 case 'E':
2949 /* LSB and WIDTH fields of BFI or BFC. The machine-
2950 language instruction encodes LSB and MSB. */
2952 long msb = (given & 0x001f0000) >> 16;
2953 long lsb = (given & 0x00000f80) >> 7;
2955 long width = msb - lsb + 1;
2956 if (width > 0)
2957 func (stream, "#%lu, #%lu", lsb, width);
2958 else
2959 func (stream, "(invalid: %lu:%lu)", lsb, msb);
2961 break;
2963 case 'V':
2964 /* 16-bit unsigned immediate from a MOVT or MOVW
2965 instruction, encoded in bits 0:11 and 15:19. */
2967 long hi = (given & 0x000f0000) >> 4;
2968 long lo = (given & 0x00000fff);
2969 long imm16 = hi | lo;
2970 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2972 break;
2974 default:
2975 abort ();
2979 else
2980 func (stream, "%c", *c);
2982 return;
2985 abort ();
2988 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2990 static void
2991 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2993 const struct opcode16 *insn;
2994 void *stream = info->stream;
2995 fprintf_ftype func = info->fprintf_func;
2997 for (insn = thumb_opcodes; insn->assembler; insn++)
2998 if ((given & insn->mask) == insn->value)
3000 const char *c = insn->assembler;
3001 for (; *c; c++)
3003 int domaskpc = 0;
3004 int domasklr = 0;
3006 if (*c != '%')
3008 func (stream, "%c", *c);
3009 continue;
3012 switch (*++c)
3014 case '%':
3015 func (stream, "%%");
3016 break;
3018 case 'c':
3019 if (ifthen_state)
3020 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3021 break;
3023 case 'C':
3024 if (ifthen_state)
3025 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3026 else
3027 func (stream, "s");
3028 break;
3030 case 'I':
3032 unsigned int tmp;
3034 ifthen_next_state = given & 0xff;
3035 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3036 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3037 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3039 break;
3041 case 'x':
3042 if (ifthen_next_state)
3043 func (stream, "\t; unpredictable branch in IT block\n");
3044 break;
3046 case 'X':
3047 if (ifthen_state)
3048 func (stream, "\t; unpredictable <IT:%s>",
3049 arm_conditional[IFTHEN_COND]);
3050 break;
3052 case 'S':
3054 long reg;
3056 reg = (given >> 3) & 0x7;
3057 if (given & (1 << 6))
3058 reg += 8;
3060 func (stream, "%s", arm_regnames[reg]);
3062 break;
3064 case 'D':
3066 long reg;
3068 reg = given & 0x7;
3069 if (given & (1 << 7))
3070 reg += 8;
3072 func (stream, "%s", arm_regnames[reg]);
3074 break;
3076 case 'N':
3077 if (given & (1 << 8))
3078 domasklr = 1;
3079 /* Fall through. */
3080 case 'O':
3081 if (*c == 'O' && (given & (1 << 8)))
3082 domaskpc = 1;
3083 /* Fall through. */
3084 case 'M':
3086 int started = 0;
3087 int reg;
3089 func (stream, "{");
3091 /* It would be nice if we could spot
3092 ranges, and generate the rS-rE format: */
3093 for (reg = 0; (reg < 8); reg++)
3094 if ((given & (1 << reg)) != 0)
3096 if (started)
3097 func (stream, ", ");
3098 started = 1;
3099 func (stream, "%s", arm_regnames[reg]);
3102 if (domasklr)
3104 if (started)
3105 func (stream, ", ");
3106 started = 1;
3107 func (stream, arm_regnames[14] /* "lr" */);
3110 if (domaskpc)
3112 if (started)
3113 func (stream, ", ");
3114 func (stream, arm_regnames[15] /* "pc" */);
3117 func (stream, "}");
3119 break;
3121 case 'b':
3122 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3124 bfd_vma address = (pc + 4
3125 + ((given & 0x00f8) >> 2)
3126 + ((given & 0x0200) >> 3));
3127 info->print_address_func (address, info);
3129 break;
3131 case 's':
3132 /* Right shift immediate -- bits 6..10; 1-31 print
3133 as themselves, 0 prints as 32. */
3135 long imm = (given & 0x07c0) >> 6;
3136 if (imm == 0)
3137 imm = 32;
3138 func (stream, "#%ld", imm);
3140 break;
3142 case '0': case '1': case '2': case '3': case '4':
3143 case '5': case '6': case '7': case '8': case '9':
3145 int bitstart = *c++ - '0';
3146 int bitend = 0;
3148 while (*c >= '0' && *c <= '9')
3149 bitstart = (bitstart * 10) + *c++ - '0';
3151 switch (*c)
3153 case '-':
3155 long reg;
3157 c++;
3158 while (*c >= '0' && *c <= '9')
3159 bitend = (bitend * 10) + *c++ - '0';
3160 if (!bitend)
3161 abort ();
3162 reg = given >> bitstart;
3163 reg &= (2 << (bitend - bitstart)) - 1;
3164 switch (*c)
3166 case 'r':
3167 func (stream, "%s", arm_regnames[reg]);
3168 break;
3170 case 'd':
3171 func (stream, "%ld", reg);
3172 break;
3174 case 'H':
3175 func (stream, "%ld", reg << 1);
3176 break;
3178 case 'W':
3179 func (stream, "%ld", reg << 2);
3180 break;
3182 case 'a':
3183 /* PC-relative address -- the bottom two
3184 bits of the address are dropped
3185 before the calculation. */
3186 info->print_address_func
3187 (((pc + 4) & ~3) + (reg << 2), info);
3188 break;
3190 case 'x':
3191 func (stream, "0x%04lx", reg);
3192 break;
3194 case 'B':
3195 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3196 info->print_address_func (reg * 2 + pc + 4, info);
3197 break;
3199 case 'c':
3200 func (stream, "%s", arm_conditional [reg]);
3201 break;
3203 default:
3204 abort ();
3207 break;
3209 case '\'':
3210 c++;
3211 if ((given & (1 << bitstart)) != 0)
3212 func (stream, "%c", *c);
3213 break;
3215 case '?':
3216 ++c;
3217 if ((given & (1 << bitstart)) != 0)
3218 func (stream, "%c", *c++);
3219 else
3220 func (stream, "%c", *++c);
3221 break;
3223 default:
3224 abort ();
3227 break;
3229 default:
3230 abort ();
3233 return;
3236 /* No match. */
3237 abort ();
3240 /* Return the name of an V7M special register. */
3241 static const char *
3242 psr_name (int regno)
3244 switch (regno)
3246 case 0: return "APSR";
3247 case 1: return "IAPSR";
3248 case 2: return "EAPSR";
3249 case 3: return "PSR";
3250 case 5: return "IPSR";
3251 case 6: return "EPSR";
3252 case 7: return "IEPSR";
3253 case 8: return "MSP";
3254 case 9: return "PSP";
3255 case 16: return "PRIMASK";
3256 case 17: return "BASEPRI";
3257 case 18: return "BASEPRI_MASK";
3258 case 19: return "FAULTMASK";
3259 case 20: return "CONTROL";
3260 default: return "<unknown>";
3264 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3266 static void
3267 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3269 const struct opcode32 *insn;
3270 void *stream = info->stream;
3271 fprintf_ftype func = info->fprintf_func;
3273 if (print_insn_coprocessor (pc, info, given, TRUE))
3274 return;
3276 if (print_insn_neon (info, given, TRUE))
3277 return;
3279 for (insn = thumb32_opcodes; insn->assembler; insn++)
3280 if ((given & insn->mask) == insn->value)
3282 const char *c = insn->assembler;
3283 for (; *c; c++)
3285 if (*c != '%')
3287 func (stream, "%c", *c);
3288 continue;
3291 switch (*++c)
3293 case '%':
3294 func (stream, "%%");
3295 break;
3297 case 'c':
3298 if (ifthen_state)
3299 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3300 break;
3302 case 'x':
3303 if (ifthen_next_state)
3304 func (stream, "\t; unpredictable branch in IT block\n");
3305 break;
3307 case 'X':
3308 if (ifthen_state)
3309 func (stream, "\t; unpredictable <IT:%s>",
3310 arm_conditional[IFTHEN_COND]);
3311 break;
3313 case 'I':
3315 unsigned int imm12 = 0;
3316 imm12 |= (given & 0x000000ffu);
3317 imm12 |= (given & 0x00007000u) >> 4;
3318 imm12 |= (given & 0x04000000u) >> 15;
3319 func (stream, "#%u\t; 0x%x", imm12, imm12);
3321 break;
3323 case 'M':
3325 unsigned int bits = 0, imm, imm8, mod;
3326 bits |= (given & 0x000000ffu);
3327 bits |= (given & 0x00007000u) >> 4;
3328 bits |= (given & 0x04000000u) >> 15;
3329 imm8 = (bits & 0x0ff);
3330 mod = (bits & 0xf00) >> 8;
3331 switch (mod)
3333 case 0: imm = imm8; break;
3334 case 1: imm = ((imm8<<16) | imm8); break;
3335 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3336 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3337 default:
3338 mod = (bits & 0xf80) >> 7;
3339 imm8 = (bits & 0x07f) | 0x80;
3340 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3342 func (stream, "#%u\t; 0x%x", imm, imm);
3344 break;
3346 case 'J':
3348 unsigned int imm = 0;
3349 imm |= (given & 0x000000ffu);
3350 imm |= (given & 0x00007000u) >> 4;
3351 imm |= (given & 0x04000000u) >> 15;
3352 imm |= (given & 0x000f0000u) >> 4;
3353 func (stream, "#%u\t; 0x%x", imm, imm);
3355 break;
3357 case 'K':
3359 unsigned int imm = 0;
3360 imm |= (given & 0x000f0000u) >> 16;
3361 imm |= (given & 0x00000ff0u) >> 0;
3362 imm |= (given & 0x0000000fu) << 12;
3363 func (stream, "#%u\t; 0x%x", imm, imm);
3365 break;
3367 case 'S':
3369 unsigned int reg = (given & 0x0000000fu);
3370 unsigned int stp = (given & 0x00000030u) >> 4;
3371 unsigned int imm = 0;
3372 imm |= (given & 0x000000c0u) >> 6;
3373 imm |= (given & 0x00007000u) >> 10;
3375 func (stream, "%s", arm_regnames[reg]);
3376 switch (stp)
3378 case 0:
3379 if (imm > 0)
3380 func (stream, ", lsl #%u", imm);
3381 break;
3383 case 1:
3384 if (imm == 0)
3385 imm = 32;
3386 func (stream, ", lsr #%u", imm);
3387 break;
3389 case 2:
3390 if (imm == 0)
3391 imm = 32;
3392 func (stream, ", asr #%u", imm);
3393 break;
3395 case 3:
3396 if (imm == 0)
3397 func (stream, ", rrx");
3398 else
3399 func (stream, ", ror #%u", imm);
3402 break;
3404 case 'a':
3406 unsigned int Rn = (given & 0x000f0000) >> 16;
3407 unsigned int U = (given & 0x00800000) >> 23;
3408 unsigned int op = (given & 0x00000f00) >> 8;
3409 unsigned int i12 = (given & 0x00000fff);
3410 unsigned int i8 = (given & 0x000000ff);
3411 bfd_boolean writeback = FALSE, postind = FALSE;
3412 int offset = 0;
3414 func (stream, "[%s", arm_regnames[Rn]);
3415 if (U) /* 12-bit positive immediate offset */
3416 offset = i12;
3417 else if (Rn == 15) /* 12-bit negative immediate offset */
3418 offset = -(int)i12;
3419 else if (op == 0x0) /* shifted register offset */
3421 unsigned int Rm = (i8 & 0x0f);
3422 unsigned int sh = (i8 & 0x30) >> 4;
3423 func (stream, ", %s", arm_regnames[Rm]);
3424 if (sh)
3425 func (stream, ", lsl #%u", sh);
3426 func (stream, "]");
3427 break;
3429 else switch (op)
3431 case 0xE: /* 8-bit positive immediate offset */
3432 offset = i8;
3433 break;
3435 case 0xC: /* 8-bit negative immediate offset */
3436 offset = -i8;
3437 break;
3439 case 0xF: /* 8-bit + preindex with wb */
3440 offset = i8;
3441 writeback = TRUE;
3442 break;
3444 case 0xD: /* 8-bit - preindex with wb */
3445 offset = -i8;
3446 writeback = TRUE;
3447 break;
3449 case 0xB: /* 8-bit + postindex */
3450 offset = i8;
3451 postind = TRUE;
3452 break;
3454 case 0x9: /* 8-bit - postindex */
3455 offset = -i8;
3456 postind = TRUE;
3457 break;
3459 default:
3460 func (stream, ", <undefined>]");
3461 goto skip;
3464 if (postind)
3465 func (stream, "], #%d", offset);
3466 else
3468 if (offset)
3469 func (stream, ", #%d", offset);
3470 func (stream, writeback ? "]!" : "]");
3473 if (Rn == 15)
3475 func (stream, "\t; ");
3476 info->print_address_func (((pc + 4) & ~3) + offset, info);
3479 skip:
3480 break;
3482 case 'A':
3484 unsigned int P = (given & 0x01000000) >> 24;
3485 unsigned int U = (given & 0x00800000) >> 23;
3486 unsigned int W = (given & 0x00400000) >> 21;
3487 unsigned int Rn = (given & 0x000f0000) >> 16;
3488 unsigned int off = (given & 0x000000ff);
3490 func (stream, "[%s", arm_regnames[Rn]);
3491 if (P)
3493 if (off || !U)
3494 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3495 func (stream, "]");
3496 if (W)
3497 func (stream, "!");
3499 else
3501 func (stream, "], ");
3502 if (W)
3503 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3504 else
3505 func (stream, "{%u}", off);
3508 break;
3510 case 'w':
3512 unsigned int Sbit = (given & 0x01000000) >> 24;
3513 unsigned int type = (given & 0x00600000) >> 21;
3514 switch (type)
3516 case 0: func (stream, Sbit ? "sb" : "b"); break;
3517 case 1: func (stream, Sbit ? "sh" : "h"); break;
3518 case 2:
3519 if (Sbit)
3520 func (stream, "??");
3521 break;
3522 case 3:
3523 func (stream, "??");
3524 break;
3527 break;
3529 case 'm':
3531 int started = 0;
3532 int reg;
3534 func (stream, "{");
3535 for (reg = 0; reg < 16; reg++)
3536 if ((given & (1 << reg)) != 0)
3538 if (started)
3539 func (stream, ", ");
3540 started = 1;
3541 func (stream, "%s", arm_regnames[reg]);
3543 func (stream, "}");
3545 break;
3547 case 'E':
3549 unsigned int msb = (given & 0x0000001f);
3550 unsigned int lsb = 0;
3551 lsb |= (given & 0x000000c0u) >> 6;
3552 lsb |= (given & 0x00007000u) >> 10;
3553 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3555 break;
3557 case 'F':
3559 unsigned int width = (given & 0x0000001f) + 1;
3560 unsigned int lsb = 0;
3561 lsb |= (given & 0x000000c0u) >> 6;
3562 lsb |= (given & 0x00007000u) >> 10;
3563 func (stream, "#%u, #%u", lsb, width);
3565 break;
3567 case 'b':
3569 unsigned int S = (given & 0x04000000u) >> 26;
3570 unsigned int J1 = (given & 0x00002000u) >> 13;
3571 unsigned int J2 = (given & 0x00000800u) >> 11;
3572 int offset = 0;
3574 offset |= !S << 20;
3575 offset |= J2 << 19;
3576 offset |= J1 << 18;
3577 offset |= (given & 0x003f0000) >> 4;
3578 offset |= (given & 0x000007ff) << 1;
3579 offset -= (1 << 20);
3581 info->print_address_func (pc + 4 + offset, info);
3583 break;
3585 case 'B':
3587 unsigned int S = (given & 0x04000000u) >> 26;
3588 unsigned int I1 = (given & 0x00002000u) >> 13;
3589 unsigned int I2 = (given & 0x00000800u) >> 11;
3590 int offset = 0;
3592 offset |= !S << 24;
3593 offset |= !(I1 ^ S) << 23;
3594 offset |= !(I2 ^ S) << 22;
3595 offset |= (given & 0x03ff0000u) >> 4;
3596 offset |= (given & 0x000007ffu) << 1;
3597 offset -= (1 << 24);
3598 offset += pc + 4;
3600 /* BLX target addresses are always word aligned. */
3601 if ((given & 0x00001000u) == 0)
3602 offset &= ~2u;
3604 info->print_address_func (offset, info);
3606 break;
3608 case 's':
3610 unsigned int shift = 0;
3611 shift |= (given & 0x000000c0u) >> 6;
3612 shift |= (given & 0x00007000u) >> 10;
3613 if (given & 0x00200000u)
3614 func (stream, ", asr #%u", shift);
3615 else if (shift)
3616 func (stream, ", lsl #%u", shift);
3617 /* else print nothing - lsl #0 */
3619 break;
3621 case 'R':
3623 unsigned int rot = (given & 0x00000030) >> 4;
3624 if (rot)
3625 func (stream, ", ror #%u", rot * 8);
3627 break;
3629 case 'U':
3630 switch (given & 0xf)
3632 case 0xf: func(stream, "sy"); break;
3633 case 0x7: func(stream, "un"); break;
3634 case 0xe: func(stream, "st"); break;
3635 case 0x6: func(stream, "unst"); break;
3636 default:
3637 func(stream, "#%d", (int)given & 0xf);
3638 break;
3640 break;
3642 case 'C':
3643 if ((given & 0xff) == 0)
3645 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3646 if (given & 0x800)
3647 func (stream, "f");
3648 if (given & 0x400)
3649 func (stream, "s");
3650 if (given & 0x200)
3651 func (stream, "x");
3652 if (given & 0x100)
3653 func (stream, "c");
3655 else
3657 func (stream, psr_name (given & 0xff));
3659 break;
3661 case 'D':
3662 if ((given & 0xff) == 0)
3663 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3664 else
3665 func (stream, psr_name (given & 0xff));
3666 break;
3668 case '0': case '1': case '2': case '3': case '4':
3669 case '5': case '6': case '7': case '8': case '9':
3671 int width;
3672 unsigned long val;
3674 c = arm_decode_bitfield (c, given, &val, &width);
3676 switch (*c)
3678 case 'd': func (stream, "%lu", val); break;
3679 case 'W': func (stream, "%lu", val * 4); break;
3680 case 'r': func (stream, "%s", arm_regnames[val]); break;
3682 case 'c':
3683 func (stream, "%s", arm_conditional[val]);
3684 break;
3686 case '\'':
3687 c++;
3688 if (val == ((1ul << width) - 1))
3689 func (stream, "%c", *c);
3690 break;
3692 case '`':
3693 c++;
3694 if (val == 0)
3695 func (stream, "%c", *c);
3696 break;
3698 case '?':
3699 func (stream, "%c", c[(1 << width) - (int)val]);
3700 c += 1 << width;
3701 break;
3703 default:
3704 abort ();
3707 break;
3709 default:
3710 abort ();
3713 return;
3716 /* No match. */
3717 abort ();
3720 /* Print data bytes on INFO->STREAM. */
3722 static void
3723 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
3724 long given)
3726 switch (info->bytes_per_chunk)
3728 case 1:
3729 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3730 break;
3731 case 2:
3732 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3733 break;
3734 case 4:
3735 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3736 break;
3737 default:
3738 abort ();
3742 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3743 being displayed in symbol relative addresses. */
3745 bfd_boolean
3746 arm_symbol_is_valid (asymbol * sym,
3747 struct disassemble_info * info ATTRIBUTE_UNUSED)
3749 const char * name;
3751 if (sym == NULL)
3752 return FALSE;
3754 name = bfd_asymbol_name (sym);
3756 return (name && *name != '$');
3759 /* Parse an individual disassembler option. */
3761 void
3762 parse_arm_disassembler_option (char *option)
3764 if (option == NULL)
3765 return;
3767 if (CONST_STRNEQ (option, "reg-names-"))
3769 int i;
3771 option += 10;
3773 for (i = NUM_ARM_REGNAMES; i--;)
3774 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3776 regname_selected = i;
3777 break;
3780 if (i < 0)
3781 /* XXX - should break 'option' at following delimiter. */
3782 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3784 else if (CONST_STRNEQ (option, "force-thumb"))
3785 force_thumb = 1;
3786 else if (CONST_STRNEQ (option, "no-force-thumb"))
3787 force_thumb = 0;
3788 else
3789 /* XXX - should break 'option' at following delimiter. */
3790 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3792 return;
3795 /* Parse the string of disassembler options, spliting it at whitespaces
3796 or commas. (Whitespace separators supported for backwards compatibility). */
3798 static void
3799 parse_disassembler_options (char *options)
3801 if (options == NULL)
3802 return;
3804 while (*options)
3806 parse_arm_disassembler_option (options);
3808 /* Skip forward to next seperator. */
3809 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3810 ++ options;
3811 /* Skip forward past seperators. */
3812 while (ISSPACE (*options) || (*options == ','))
3813 ++ options;
3817 /* Search back through the insn stream to determine if this instruction is
3818 conditionally executed. */
3819 static void
3820 find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3821 bfd_boolean little)
3823 unsigned char b[2];
3824 unsigned int insn;
3825 int status;
3826 /* COUNT is twice the number of instructions seen. It will be odd if we
3827 just crossed an instruction boundary. */
3828 int count;
3829 int it_count;
3830 unsigned int seen_it;
3831 bfd_vma addr;
3833 ifthen_address = pc;
3834 ifthen_state = 0;
3836 addr = pc;
3837 count = 1;
3838 it_count = 0;
3839 seen_it = 0;
3840 /* Scan backwards looking for IT instructions, keeping track of where
3841 instruction boundaries are. We don't know if something is actually an
3842 IT instruction until we find a definite instruction boundary. */
3843 for (;;)
3845 if (addr == 0 || info->symbol_at_address_func(addr, info))
3847 /* A symbol must be on an instruction boundary, and will not
3848 be within an IT block. */
3849 if (seen_it && (count & 1))
3850 break;
3852 return;
3854 addr -= 2;
3855 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3856 if (status)
3857 return;
3859 if (little)
3860 insn = (b[0]) | (b[1] << 8);
3861 else
3862 insn = (b[1]) | (b[0] << 8);
3863 if (seen_it)
3865 if ((insn & 0xf800) < 0xe800)
3867 /* Addr + 2 is an instruction boundary. See if this matches
3868 the expected boundary based on the position of the last
3869 IT candidate. */
3870 if (count & 1)
3871 break;
3872 seen_it = 0;
3875 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3877 /* This could be an IT instruction. */
3878 seen_it = insn;
3879 it_count = count >> 1;
3881 if ((insn & 0xf800) >= 0xe800)
3882 count++;
3883 else
3884 count = (count + 2) | 1;
3885 /* IT blocks contain at most 4 instructions. */
3886 if (count >= 8 && !seen_it)
3887 return;
3889 /* We found an IT instruction. */
3890 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3891 if ((ifthen_state & 0xf) == 0)
3892 ifthen_state = 0;
3895 /* Try to infer the code type (Arm or Thumb) from a symbol.
3896 Returns nonzero if *MAP_TYPE was set. */
3898 static int
3899 get_sym_code_type (struct disassemble_info *info, int n,
3900 enum map_type *map_type)
3902 elf_symbol_type *es;
3903 unsigned int type;
3904 const char *name;
3906 es = *(elf_symbol_type **)(info->symtab + n);
3907 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3909 /* If the symbol has function type then use that. */
3910 if (type == STT_FUNC || type == STT_ARM_TFUNC)
3912 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
3913 return TRUE;
3916 /* Check for mapping symbols. */
3917 name = bfd_asymbol_name(info->symtab[n]);
3918 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
3919 && (name[2] == 0 || name[2] == '.'))
3921 *map_type = ((name[1] == 'a') ? MAP_ARM
3922 : (name[1] == 't') ? MAP_THUMB
3923 : MAP_DATA);
3924 return TRUE;
3927 return FALSE;
3930 /* NOTE: There are no checks in these routines that
3931 the relevant number of data bytes exist. */
3933 static int
3934 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3936 unsigned char b[4];
3937 long given;
3938 int status;
3939 int is_thumb = FALSE;
3940 int is_data = FALSE;
3941 unsigned int size = 4;
3942 void (*printer) (bfd_vma, struct disassemble_info *, long);
3943 bfd_boolean found = FALSE;
3945 if (info->disassembler_options)
3947 parse_disassembler_options (info->disassembler_options);
3949 /* To avoid repeated parsing of these options, we remove them here. */
3950 info->disassembler_options = NULL;
3953 /* First check the full symtab for a mapping symbol, even if there
3954 are no usable non-mapping symbols for this address. */
3955 if (info->symtab != NULL
3956 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3958 bfd_vma addr;
3959 int n;
3960 int last_sym = -1;
3961 enum map_type type;
3963 if (pc <= last_mapping_addr)
3964 last_mapping_sym = -1;
3965 is_thumb = (last_type == MAP_THUMB);
3966 found = FALSE;
3967 /* Start scanning at the start of the function, or wherever
3968 we finished last time. */
3969 n = info->symtab_pos + 1;
3970 if (n < last_mapping_sym)
3971 n = last_mapping_sym;
3973 /* Scan up to the location being disassembled. */
3974 for (; n < info->symtab_size; n++)
3976 addr = bfd_asymbol_value (info->symtab[n]);
3977 if (addr > pc)
3978 break;
3979 if (get_sym_code_type (info, n, &type))
3981 last_sym = n;
3982 found = TRUE;
3986 if (!found)
3988 n = info->symtab_pos;
3989 if (n < last_mapping_sym - 1)
3990 n = last_mapping_sym - 1;
3992 /* No mapping symbol found at this address. Look backwards
3993 for a preceeding one. */
3994 for (; n >= 0; n--)
3996 if (get_sym_code_type (info, n, &type))
3998 last_sym = n;
3999 found = TRUE;
4000 break;
4005 last_mapping_sym = last_sym;
4006 last_type = type;
4007 is_thumb = (last_type == MAP_THUMB);
4008 is_data = (last_type == MAP_DATA);
4010 /* Look a little bit ahead to see if we should print out
4011 two or four bytes of data. If there's a symbol,
4012 mapping or otherwise, after two bytes then don't
4013 print more. */
4014 if (is_data)
4016 size = 4 - (pc & 3);
4017 for (n = last_sym + 1; n < info->symtab_size; n++)
4019 addr = bfd_asymbol_value (info->symtab[n]);
4020 if (addr > pc)
4022 if (addr - pc < size)
4023 size = addr - pc;
4024 break;
4027 /* If the next symbol is after three bytes, we need to
4028 print only part of the data, so that we can use either
4029 .byte or .short. */
4030 if (size == 3)
4031 size = (pc & 1) ? 1 : 2;
4035 if (info->symbols != NULL)
4037 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4039 coff_symbol_type * cs;
4041 cs = coffsymbol (*info->symbols);
4042 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4043 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4044 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4045 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4046 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4048 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4049 && !found)
4051 /* If no mapping symbol has been found then fall back to the type
4052 of the function symbol. */
4053 elf_symbol_type * es;
4054 unsigned int type;
4056 es = *(elf_symbol_type **)(info->symbols);
4057 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4059 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4063 if (force_thumb)
4064 is_thumb = TRUE;
4066 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4067 info->bytes_per_line = 4;
4069 if (is_data)
4071 int i;
4073 /* size was already set above. */
4074 info->bytes_per_chunk = size;
4075 printer = print_insn_data;
4077 status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
4078 given = 0;
4079 if (little)
4080 for (i = size - 1; i >= 0; i--)
4081 given = b[i] | (given << 8);
4082 else
4083 for (i = 0; i < (int) size; i++)
4084 given = b[i] | (given << 8);
4086 else if (!is_thumb)
4088 /* In ARM mode endianness is a straightforward issue: the instruction
4089 is four bytes long and is either ordered 0123 or 3210. */
4090 printer = print_insn_arm;
4091 info->bytes_per_chunk = 4;
4092 size = 4;
4094 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4095 if (little)
4096 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4097 else
4098 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4100 else
4102 /* In Thumb mode we have the additional wrinkle of two
4103 instruction lengths. Fortunately, the bits that determine
4104 the length of the current instruction are always to be found
4105 in the first two bytes. */
4106 printer = print_insn_thumb16;
4107 info->bytes_per_chunk = 2;
4108 size = 2;
4110 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4111 if (little)
4112 given = (b[0]) | (b[1] << 8);
4113 else
4114 given = (b[1]) | (b[0] << 8);
4116 if (!status)
4118 /* These bit patterns signal a four-byte Thumb
4119 instruction. */
4120 if ((given & 0xF800) == 0xF800
4121 || (given & 0xF800) == 0xF000
4122 || (given & 0xF800) == 0xE800)
4124 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4125 if (little)
4126 given = (b[0]) | (b[1] << 8) | (given << 16);
4127 else
4128 given = (b[1]) | (b[0] << 8) | (given << 16);
4130 printer = print_insn_thumb32;
4131 size = 4;
4135 if (ifthen_address != pc)
4136 find_ifthen_state(pc, info, little);
4138 if (ifthen_state)
4140 if ((ifthen_state & 0xf) == 0x8)
4141 ifthen_next_state = 0;
4142 else
4143 ifthen_next_state = (ifthen_state & 0xe0)
4144 | ((ifthen_state & 0xf) << 1);
4148 if (status)
4150 info->memory_error_func (status, pc, info);
4151 return -1;
4153 if (info->flags & INSN_HAS_RELOC)
4154 /* If the instruction has a reloc associated with it, then
4155 the offset field in the instruction will actually be the
4156 addend for the reloc. (We are using REL type relocs).
4157 In such cases, we can ignore the pc when computing
4158 addresses, since the addend is not currently pc-relative. */
4159 pc = 0;
4161 printer (pc, info, given);
4163 if (is_thumb)
4165 ifthen_state = ifthen_next_state;
4166 ifthen_address += size;
4168 return size;
4172 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4174 return print_insn (pc, info, FALSE);
4178 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4180 return print_insn (pc, info, TRUE);
4183 void
4184 print_arm_disassembler_options (FILE *stream)
4186 int i;
4188 fprintf (stream, _("\n\
4189 The following ARM specific disassembler options are supported for use with\n\
4190 the -M switch:\n"));
4192 for (i = NUM_ARM_REGNAMES; i--;)
4193 fprintf (stream, " reg-names-%s %*c%s\n",
4194 regnames[i].name,
4195 (int)(14 - strlen (regnames[i].name)), ' ',
4196 regnames[i].description);
4198 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4199 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");