2006-10-30 Paul Brook <paul@codesourcery.com>
[binutils.git] / opcodes / arm-dis.c
blob7a02e319cfbd1f64dba85c66d2f966922f13f39c
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, #%16-19,0-3d"},
312 {FPU_VFP_EXT_V3, 0x0eb00b00, 0x0fb00ff0, "fconstd%c\t%z1, #%16-19,0-3d"},
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 Thumb state. */
1484 int last_is_thumb;
1485 int last_mapping_sym = -1;
1486 bfd_vma last_mapping_addr = 0;
1489 /* Functions. */
1491 get_arm_regname_num_options (void)
1493 return NUM_ARM_REGNAMES;
1497 set_arm_regname_option (int option)
1499 int old = regname_selected;
1500 regname_selected = option;
1501 return old;
1505 get_arm_regnames (int option, const char **setname, const char **setdescription,
1506 const char *const **register_names)
1508 *setname = regnames[option].name;
1509 *setdescription = regnames[option].description;
1510 *register_names = regnames[option].reg_names;
1511 return 16;
1514 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1515 Returns pointer to following character of the format string and
1516 fills in *VALUEP and *WIDTHP with the extracted value and number of
1517 bits extracted. WIDTHP can be NULL. */
1519 static const char *
1520 arm_decode_bitfield (const char *ptr, unsigned long insn,
1521 unsigned long *valuep, int *widthp)
1523 unsigned long value = 0;
1524 int width = 0;
1528 int start, end;
1529 int bits;
1531 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1532 start = start * 10 + *ptr - '0';
1533 if (*ptr == '-')
1534 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1535 end = end * 10 + *ptr - '0';
1536 else
1537 end = start;
1538 bits = end - start;
1539 if (bits < 0)
1540 abort ();
1541 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1542 width += bits + 1;
1544 while (*ptr++ == ',');
1545 *valuep = value;
1546 if (widthp)
1547 *widthp = width;
1548 return ptr - 1;
1551 static void
1552 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1554 func (stream, "%s", arm_regnames[given & 0xf]);
1556 if ((given & 0xff0) != 0)
1558 if ((given & 0x10) == 0)
1560 int amount = (given & 0xf80) >> 7;
1561 int shift = (given & 0x60) >> 5;
1563 if (amount == 0)
1565 if (shift == 3)
1567 func (stream, ", rrx");
1568 return;
1571 amount = 32;
1574 func (stream, ", %s #%d", arm_shift[shift], amount);
1576 else
1577 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1578 arm_regnames[(given & 0xf00) >> 8]);
1582 /* Print one coprocessor instruction on INFO->STREAM.
1583 Return TRUE if the instuction matched, FALSE if this is not a
1584 recognised coprocessor instruction. */
1586 static bfd_boolean
1587 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1588 bfd_boolean thumb)
1590 const struct opcode32 *insn;
1591 void *stream = info->stream;
1592 fprintf_ftype func = info->fprintf_func;
1593 unsigned long mask;
1594 unsigned long value;
1595 int cond;
1597 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1599 if (insn->value == FIRST_IWMMXT_INSN
1600 && info->mach != bfd_mach_arm_XScale
1601 && info->mach != bfd_mach_arm_iWMMXt
1602 && info->mach != bfd_mach_arm_iWMMXt2)
1603 insn = insn + IWMMXT_INSN_COUNT;
1605 mask = insn->mask;
1606 value = insn->value;
1607 if (thumb)
1609 /* The high 4 bits are 0xe for Arm conditional instructions, and
1610 0xe for arm unconditional instructions. The rest of the
1611 encoding is the same. */
1612 mask |= 0xf0000000;
1613 value |= 0xe0000000;
1614 if (ifthen_state)
1615 cond = IFTHEN_COND;
1616 else
1617 cond = 16;
1619 else
1621 /* Only match unconditional instuctions against unconditional
1622 patterns. */
1623 if ((given & 0xf0000000) == 0xf0000000)
1625 mask |= 0xf0000000;
1626 cond = 16;
1628 else
1630 cond = (given >> 28) & 0xf;
1631 if (cond == 0xe)
1632 cond = 16;
1635 if ((given & mask) == value)
1637 const char *c;
1639 for (c = insn->assembler; *c; c++)
1641 if (*c == '%')
1643 switch (*++c)
1645 case '%':
1646 func (stream, "%%");
1647 break;
1649 case 'A':
1650 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1652 if ((given & (1 << 24)) != 0)
1654 int offset = given & 0xff;
1656 if (offset)
1657 func (stream, ", #%s%d]%s",
1658 ((given & 0x00800000) == 0 ? "-" : ""),
1659 offset * 4,
1660 ((given & 0x00200000) != 0 ? "!" : ""));
1661 else
1662 func (stream, "]");
1664 else
1666 int offset = given & 0xff;
1668 func (stream, "]");
1670 if (given & (1 << 21))
1672 if (offset)
1673 func (stream, ", #%s%d",
1674 ((given & 0x00800000) == 0 ? "-" : ""),
1675 offset * 4);
1677 else
1678 func (stream, ", {%d}", offset);
1680 break;
1682 case 'B':
1684 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1685 int offset = (given >> 1) & 0x3f;
1687 if (offset == 1)
1688 func (stream, "{d%d}", regno);
1689 else if (regno + offset > 32)
1690 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1691 else
1692 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1694 break;
1696 case 'C':
1698 int rn = (given >> 16) & 0xf;
1699 int offset = (given & 0xff) * 4;
1700 int add = (given >> 23) & 1;
1702 func (stream, "[%s", arm_regnames[rn]);
1704 if (offset)
1706 if (!add)
1707 offset = -offset;
1708 func (stream, ", #%d", offset);
1710 func (stream, "]");
1711 if (rn == 15)
1713 func (stream, "\t; ");
1714 /* FIXME: Unsure if info->bytes_per_chunk is the
1715 right thing to use here. */
1716 info->print_address_func (offset + pc
1717 + info->bytes_per_chunk * 2, info);
1720 break;
1722 case 'c':
1723 func (stream, "%s", arm_conditional[cond]);
1724 break;
1726 case 'I':
1727 /* Print a Cirrus/DSP shift immediate. */
1728 /* Immediates are 7bit signed ints with bits 0..3 in
1729 bits 0..3 of opcode and bits 4..6 in bits 5..7
1730 of opcode. */
1732 int imm;
1734 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1736 /* Is ``imm'' a negative number? */
1737 if (imm & 0x40)
1738 imm |= (-1 << 7);
1740 func (stream, "%d", imm);
1743 break;
1745 case 'F':
1746 switch (given & 0x00408000)
1748 case 0:
1749 func (stream, "4");
1750 break;
1751 case 0x8000:
1752 func (stream, "1");
1753 break;
1754 case 0x00400000:
1755 func (stream, "2");
1756 break;
1757 default:
1758 func (stream, "3");
1760 break;
1762 case 'P':
1763 switch (given & 0x00080080)
1765 case 0:
1766 func (stream, "s");
1767 break;
1768 case 0x80:
1769 func (stream, "d");
1770 break;
1771 case 0x00080000:
1772 func (stream, "e");
1773 break;
1774 default:
1775 func (stream, _("<illegal precision>"));
1776 break;
1778 break;
1779 case 'Q':
1780 switch (given & 0x00408000)
1782 case 0:
1783 func (stream, "s");
1784 break;
1785 case 0x8000:
1786 func (stream, "d");
1787 break;
1788 case 0x00400000:
1789 func (stream, "e");
1790 break;
1791 default:
1792 func (stream, "p");
1793 break;
1795 break;
1796 case 'R':
1797 switch (given & 0x60)
1799 case 0:
1800 break;
1801 case 0x20:
1802 func (stream, "p");
1803 break;
1804 case 0x40:
1805 func (stream, "m");
1806 break;
1807 default:
1808 func (stream, "z");
1809 break;
1811 break;
1813 case '0': case '1': case '2': case '3': case '4':
1814 case '5': case '6': case '7': case '8': case '9':
1816 int width;
1817 unsigned long value;
1819 c = arm_decode_bitfield (c, given, &value, &width);
1821 switch (*c)
1823 case 'r':
1824 func (stream, "%s", arm_regnames[value]);
1825 break;
1826 case 'D':
1827 func (stream, "d%ld", value);
1828 break;
1829 case 'Q':
1830 if (value & 1)
1831 func (stream, "<illegal reg q%ld.5>", value >> 1);
1832 else
1833 func (stream, "q%ld", value >> 1);
1834 break;
1835 case 'd':
1836 func (stream, "%ld", value);
1837 break;
1838 case 'k':
1840 int from = (given & (1 << 7)) ? 32 : 16;
1841 func (stream, "%ld", from - value);
1843 break;
1845 case 'f':
1846 if (value > 7)
1847 func (stream, "#%s", arm_fp_const[value & 7]);
1848 else
1849 func (stream, "f%ld", value);
1850 break;
1852 case 'w':
1853 if (width == 2)
1854 func (stream, "%s", iwmmxt_wwnames[value]);
1855 else
1856 func (stream, "%s", iwmmxt_wwssnames[value]);
1857 break;
1859 case 'g':
1860 func (stream, "%s", iwmmxt_regnames[value]);
1861 break;
1862 case 'G':
1863 func (stream, "%s", iwmmxt_cregnames[value]);
1864 break;
1865 case '`':
1866 c++;
1867 if (value == 0)
1868 func (stream, "%c", *c);
1869 break;
1870 case '\'':
1871 c++;
1872 if (value == ((1ul << width) - 1))
1873 func (stream, "%c", *c);
1874 break;
1875 case '?':
1876 func (stream, "%c", c[(1 << width) - (int)value]);
1877 c += 1 << width;
1878 break;
1879 default:
1880 abort ();
1882 break;
1884 case 'y':
1885 case 'z':
1887 int single = *c++ == 'y';
1888 int regno;
1890 switch (*c)
1892 case '4': /* Sm pair */
1893 func (stream, "{");
1894 /* Fall through. */
1895 case '0': /* Sm, Dm */
1896 regno = given & 0x0000000f;
1897 if (single)
1899 regno <<= 1;
1900 regno += (given >> 5) & 1;
1902 else
1903 regno += ((given >> 5) & 1) << 4;
1904 break;
1906 case '1': /* Sd, Dd */
1907 regno = (given >> 12) & 0x0000000f;
1908 if (single)
1910 regno <<= 1;
1911 regno += (given >> 22) & 1;
1913 else
1914 regno += ((given >> 22) & 1) << 4;
1915 break;
1917 case '2': /* Sn, Dn */
1918 regno = (given >> 16) & 0x0000000f;
1919 if (single)
1921 regno <<= 1;
1922 regno += (given >> 7) & 1;
1924 else
1925 regno += ((given >> 7) & 1) << 4;
1926 break;
1928 case '3': /* List */
1929 func (stream, "{");
1930 regno = (given >> 12) & 0x0000000f;
1931 if (single)
1933 regno <<= 1;
1934 regno += (given >> 22) & 1;
1936 else
1937 regno += ((given >> 22) & 1) << 4;
1938 break;
1940 default:
1941 abort ();
1944 func (stream, "%c%d", single ? 's' : 'd', regno);
1946 if (*c == '3')
1948 int count = given & 0xff;
1950 if (single == 0)
1951 count >>= 1;
1953 if (--count)
1955 func (stream, "-%c%d",
1956 single ? 's' : 'd',
1957 regno + count);
1960 func (stream, "}");
1962 else if (*c == '4')
1963 func (stream, ", %c%d}", single ? 's' : 'd',
1964 regno + 1);
1966 break;
1968 case 'L':
1969 switch (given & 0x00400100)
1971 case 0x00000000: func (stream, "b"); break;
1972 case 0x00400000: func (stream, "h"); break;
1973 case 0x00000100: func (stream, "w"); break;
1974 case 0x00400100: func (stream, "d"); break;
1975 default:
1976 break;
1978 break;
1980 case 'Z':
1982 int value;
1983 /* given (20, 23) | given (0, 3) */
1984 value = ((given >> 16) & 0xf0) | (given & 0xf);
1985 func (stream, "%d", value);
1987 break;
1989 case 'l':
1990 /* This is like the 'A' operator, except that if
1991 the width field "M" is zero, then the offset is
1992 *not* multiplied by four. */
1994 int offset = given & 0xff;
1995 int multiplier = (given & 0x00000100) ? 4 : 1;
1997 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1999 if (offset)
2001 if ((given & 0x01000000) != 0)
2002 func (stream, ", #%s%d]%s",
2003 ((given & 0x00800000) == 0 ? "-" : ""),
2004 offset * multiplier,
2005 ((given & 0x00200000) != 0 ? "!" : ""));
2006 else
2007 func (stream, "], #%s%d",
2008 ((given & 0x00800000) == 0 ? "-" : ""),
2009 offset * multiplier);
2011 else
2012 func (stream, "]");
2014 break;
2016 case 'r':
2018 int imm4 = (given >> 4) & 0xf;
2019 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2020 int ubit = (given >> 23) & 1;
2021 const char *rm = arm_regnames [given & 0xf];
2022 const char *rn = arm_regnames [(given >> 16) & 0xf];
2024 switch (puw_bits)
2026 case 1:
2027 /* fall through */
2028 case 3:
2029 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2030 if (imm4)
2031 func (stream, ", lsl #%d", imm4);
2032 break;
2034 case 4:
2035 /* fall through */
2036 case 5:
2037 /* fall through */
2038 case 6:
2039 /* fall through */
2040 case 7:
2041 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2042 if (imm4 > 0)
2043 func (stream, ", lsl #%d", imm4);
2044 func (stream, "]");
2045 if (puw_bits == 5 || puw_bits == 7)
2046 func (stream, "!");
2047 break;
2049 default:
2050 func (stream, "INVALID");
2053 break;
2055 case 'i':
2057 long imm5;
2058 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2059 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2061 break;
2063 default:
2064 abort ();
2068 else
2069 func (stream, "%c", *c);
2071 return TRUE;
2074 return FALSE;
2077 static void
2078 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2080 void *stream = info->stream;
2081 fprintf_ftype func = info->fprintf_func;
2083 if (((given & 0x000f0000) == 0x000f0000)
2084 && ((given & 0x02000000) == 0))
2086 int offset = given & 0xfff;
2088 func (stream, "[pc");
2090 if (given & 0x01000000)
2092 if ((given & 0x00800000) == 0)
2093 offset = - offset;
2095 /* Pre-indexed. */
2096 func (stream, ", #%d]", offset);
2098 offset += pc + 8;
2100 /* Cope with the possibility of write-back
2101 being used. Probably a very dangerous thing
2102 for the programmer to do, but who are we to
2103 argue ? */
2104 if (given & 0x00200000)
2105 func (stream, "!");
2107 else
2109 /* Post indexed. */
2110 func (stream, "], #%d", offset);
2112 /* ie ignore the offset. */
2113 offset = pc + 8;
2116 func (stream, "\t; ");
2117 info->print_address_func (offset, info);
2119 else
2121 func (stream, "[%s",
2122 arm_regnames[(given >> 16) & 0xf]);
2123 if ((given & 0x01000000) != 0)
2125 if ((given & 0x02000000) == 0)
2127 int offset = given & 0xfff;
2128 if (offset)
2129 func (stream, ", #%s%d",
2130 (((given & 0x00800000) == 0)
2131 ? "-" : ""), offset);
2133 else
2135 func (stream, ", %s",
2136 (((given & 0x00800000) == 0)
2137 ? "-" : ""));
2138 arm_decode_shift (given, func, stream);
2141 func (stream, "]%s",
2142 ((given & 0x00200000) != 0) ? "!" : "");
2144 else
2146 if ((given & 0x02000000) == 0)
2148 int offset = given & 0xfff;
2149 if (offset)
2150 func (stream, "], #%s%d",
2151 (((given & 0x00800000) == 0)
2152 ? "-" : ""), offset);
2153 else
2154 func (stream, "]");
2156 else
2158 func (stream, "], %s",
2159 (((given & 0x00800000) == 0)
2160 ? "-" : ""));
2161 arm_decode_shift (given, func, stream);
2167 /* Print one neon instruction on INFO->STREAM.
2168 Return TRUE if the instuction matched, FALSE if this is not a
2169 recognised neon instruction. */
2171 static bfd_boolean
2172 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2174 const struct opcode32 *insn;
2175 void *stream = info->stream;
2176 fprintf_ftype func = info->fprintf_func;
2178 if (thumb)
2180 if ((given & 0xef000000) == 0xef000000)
2182 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2183 unsigned long bit28 = given & (1 << 28);
2185 given &= 0x00ffffff;
2186 if (bit28)
2187 given |= 0xf3000000;
2188 else
2189 given |= 0xf2000000;
2191 else if ((given & 0xff000000) == 0xf9000000)
2192 given ^= 0xf9000000 ^ 0xf4000000;
2193 else
2194 return FALSE;
2197 for (insn = neon_opcodes; insn->assembler; insn++)
2199 if ((given & insn->mask) == insn->value)
2201 const char *c;
2203 for (c = insn->assembler; *c; c++)
2205 if (*c == '%')
2207 switch (*++c)
2209 case '%':
2210 func (stream, "%%");
2211 break;
2213 case 'c':
2214 if (thumb && ifthen_state)
2215 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2216 break;
2218 case 'A':
2220 static const unsigned char enc[16] =
2222 0x4, 0x14, /* st4 0,1 */
2223 0x4, /* st1 2 */
2224 0x4, /* st2 3 */
2225 0x3, /* st3 4 */
2226 0x13, /* st3 5 */
2227 0x3, /* st1 6 */
2228 0x1, /* st1 7 */
2229 0x2, /* st2 8 */
2230 0x12, /* st2 9 */
2231 0x2, /* st1 10 */
2232 0, 0, 0, 0, 0
2234 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2235 int rn = ((given >> 16) & 0xf);
2236 int rm = ((given >> 0) & 0xf);
2237 int align = ((given >> 4) & 0x3);
2238 int type = ((given >> 8) & 0xf);
2239 int n = enc[type] & 0xf;
2240 int stride = (enc[type] >> 4) + 1;
2241 int ix;
2243 func (stream, "{");
2244 if (stride > 1)
2245 for (ix = 0; ix != n; ix++)
2246 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2247 else if (n == 1)
2248 func (stream, "d%d", rd);
2249 else
2250 func (stream, "d%d-d%d", rd, rd + n - 1);
2251 func (stream, "}, [%s", arm_regnames[rn]);
2252 if (align)
2253 func (stream, ", :%d", 32 << align);
2254 func (stream, "]");
2255 if (rm == 0xd)
2256 func (stream, "!");
2257 else if (rm != 0xf)
2258 func (stream, ", %s", arm_regnames[rm]);
2260 break;
2262 case 'B':
2264 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2265 int rn = ((given >> 16) & 0xf);
2266 int rm = ((given >> 0) & 0xf);
2267 int idx_align = ((given >> 4) & 0xf);
2268 int align = 0;
2269 int size = ((given >> 10) & 0x3);
2270 int idx = idx_align >> (size + 1);
2271 int length = ((given >> 8) & 3) + 1;
2272 int stride = 1;
2273 int i;
2275 if (length > 1 && size > 0)
2276 stride = (idx_align & (1 << size)) ? 2 : 1;
2278 switch (length)
2280 case 1:
2282 int amask = (1 << size) - 1;
2283 if ((idx_align & (1 << size)) != 0)
2284 return FALSE;
2285 if (size > 0)
2287 if ((idx_align & amask) == amask)
2288 align = 8 << size;
2289 else if ((idx_align & amask) != 0)
2290 return FALSE;
2293 break;
2295 case 2:
2296 if (size == 2 && (idx_align & 2) != 0)
2297 return FALSE;
2298 align = (idx_align & 1) ? 16 << size : 0;
2299 break;
2301 case 3:
2302 if ((size == 2 && (idx_align & 3) != 0)
2303 || (idx_align & 1) != 0)
2304 return FALSE;
2305 break;
2307 case 4:
2308 if (size == 2)
2310 if ((idx_align & 3) == 3)
2311 return FALSE;
2312 align = (idx_align & 3) * 64;
2314 else
2315 align = (idx_align & 1) ? 32 << size : 0;
2316 break;
2318 default:
2319 abort ();
2322 func (stream, "{");
2323 for (i = 0; i < length; i++)
2324 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2325 rd + i * stride, idx);
2326 func (stream, "}, [%s", arm_regnames[rn]);
2327 if (align)
2328 func (stream, ", :%d", align);
2329 func (stream, "]");
2330 if (rm == 0xd)
2331 func (stream, "!");
2332 else if (rm != 0xf)
2333 func (stream, ", %s", arm_regnames[rm]);
2335 break;
2337 case 'C':
2339 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2340 int rn = ((given >> 16) & 0xf);
2341 int rm = ((given >> 0) & 0xf);
2342 int align = ((given >> 4) & 0x1);
2343 int size = ((given >> 6) & 0x3);
2344 int type = ((given >> 8) & 0x3);
2345 int n = type + 1;
2346 int stride = ((given >> 5) & 0x1);
2347 int ix;
2349 if (stride && (n == 1))
2350 n++;
2351 else
2352 stride++;
2354 func (stream, "{");
2355 if (stride > 1)
2356 for (ix = 0; ix != n; ix++)
2357 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2358 else if (n == 1)
2359 func (stream, "d%d[]", rd);
2360 else
2361 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2362 func (stream, "}, [%s", arm_regnames[rn]);
2363 if (align)
2365 int align = (8 * (type + 1)) << size;
2366 if (type == 3)
2367 align = (size > 1) ? align >> 1 : align;
2368 if (type == 2 || (type == 0 && !size))
2369 func (stream, ", :<bad align %d>", align);
2370 else
2371 func (stream, ", :%d", align);
2373 func (stream, "]");
2374 if (rm == 0xd)
2375 func (stream, "!");
2376 else if (rm != 0xf)
2377 func (stream, ", %s", arm_regnames[rm]);
2379 break;
2381 case 'D':
2383 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2384 int size = (given >> 20) & 3;
2385 int reg = raw_reg & ((4 << size) - 1);
2386 int ix = raw_reg >> size >> 2;
2388 func (stream, "d%d[%d]", reg, ix);
2390 break;
2392 case 'E':
2393 /* Neon encoded constant for mov, mvn, vorr, vbic */
2395 int bits = 0;
2396 int cmode = (given >> 8) & 0xf;
2397 int op = (given >> 5) & 0x1;
2398 unsigned long value = 0, hival = 0;
2399 unsigned shift;
2400 int size = 0;
2401 int isfloat = 0;
2403 bits |= ((given >> 24) & 1) << 7;
2404 bits |= ((given >> 16) & 7) << 4;
2405 bits |= ((given >> 0) & 15) << 0;
2407 if (cmode < 8)
2409 shift = (cmode >> 1) & 3;
2410 value = (unsigned long)bits << (8 * shift);
2411 size = 32;
2413 else if (cmode < 12)
2415 shift = (cmode >> 1) & 1;
2416 value = (unsigned long)bits << (8 * shift);
2417 size = 16;
2419 else if (cmode < 14)
2421 shift = (cmode & 1) + 1;
2422 value = (unsigned long)bits << (8 * shift);
2423 value |= (1ul << (8 * shift)) - 1;
2424 size = 32;
2426 else if (cmode == 14)
2428 if (op)
2430 /* bit replication into bytes */
2431 int ix;
2432 unsigned long mask;
2434 value = 0;
2435 hival = 0;
2436 for (ix = 7; ix >= 0; ix--)
2438 mask = ((bits >> ix) & 1) ? 0xff : 0;
2439 if (ix <= 3)
2440 value = (value << 8) | mask;
2441 else
2442 hival = (hival << 8) | mask;
2444 size = 64;
2446 else
2448 /* byte replication */
2449 value = (unsigned long)bits;
2450 size = 8;
2453 else if (!op)
2455 /* floating point encoding */
2456 int tmp;
2458 value = (unsigned long)(bits & 0x7f) << 19;
2459 value |= (unsigned long)(bits & 0x80) << 24;
2460 tmp = bits & 0x40 ? 0x3c : 0x40;
2461 value |= (unsigned long)tmp << 24;
2462 size = 32;
2463 isfloat = 1;
2465 else
2467 func (stream, "<illegal constant %.8x:%x:%x>",
2468 bits, cmode, op);
2469 size = 32;
2470 break;
2472 switch (size)
2474 case 8:
2475 func (stream, "#%ld\t; 0x%.2lx", value, value);
2476 break;
2478 case 16:
2479 func (stream, "#%ld\t; 0x%.4lx", value, value);
2480 break;
2482 case 32:
2483 if (isfloat)
2485 unsigned char valbytes[4];
2486 double fvalue;
2488 /* Do this a byte at a time so we don't have to
2489 worry about the host's endianness. */
2490 valbytes[0] = value & 0xff;
2491 valbytes[1] = (value >> 8) & 0xff;
2492 valbytes[2] = (value >> 16) & 0xff;
2493 valbytes[3] = (value >> 24) & 0xff;
2495 floatformat_to_double
2496 (&floatformat_ieee_single_little, valbytes,
2497 &fvalue);
2499 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2500 value);
2502 else
2503 func (stream, "#%ld\t; 0x%.8lx",
2504 (long) ((value & 0x80000000)
2505 ? value | ~0xffffffffl : value), value);
2506 break;
2508 case 64:
2509 func (stream, "#0x%.8lx%.8lx", hival, value);
2510 break;
2512 default:
2513 abort ();
2516 break;
2518 case 'F':
2520 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2521 int num = (given >> 8) & 0x3;
2523 if (!num)
2524 func (stream, "{d%d}", regno);
2525 else if (num + regno >= 32)
2526 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2527 else
2528 func (stream, "{d%d-d%d}", regno, regno + num);
2530 break;
2533 case '0': case '1': case '2': case '3': case '4':
2534 case '5': case '6': case '7': case '8': case '9':
2536 int width;
2537 unsigned long value;
2539 c = arm_decode_bitfield (c, given, &value, &width);
2541 switch (*c)
2543 case 'r':
2544 func (stream, "%s", arm_regnames[value]);
2545 break;
2546 case 'd':
2547 func (stream, "%ld", value);
2548 break;
2549 case 'e':
2550 func (stream, "%ld", (1ul << width) - value);
2551 break;
2553 case 'S':
2554 case 'T':
2555 case 'U':
2556 /* various width encodings */
2558 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2559 int limit;
2560 unsigned low, high;
2562 c++;
2563 if (*c >= '0' && *c <= '9')
2564 limit = *c - '0';
2565 else if (*c >= 'a' && *c <= 'f')
2566 limit = *c - 'a' + 10;
2567 else
2568 abort ();
2569 low = limit >> 2;
2570 high = limit & 3;
2572 if (value < low || value > high)
2573 func (stream, "<illegal width %d>", base << value);
2574 else
2575 func (stream, "%d", base << value);
2577 break;
2578 case 'R':
2579 if (given & (1 << 6))
2580 goto Q;
2581 /* FALLTHROUGH */
2582 case 'D':
2583 func (stream, "d%ld", value);
2584 break;
2585 case 'Q':
2587 if (value & 1)
2588 func (stream, "<illegal reg q%ld.5>", value >> 1);
2589 else
2590 func (stream, "q%ld", value >> 1);
2591 break;
2593 case '`':
2594 c++;
2595 if (value == 0)
2596 func (stream, "%c", *c);
2597 break;
2598 case '\'':
2599 c++;
2600 if (value == ((1ul << width) - 1))
2601 func (stream, "%c", *c);
2602 break;
2603 case '?':
2604 func (stream, "%c", c[(1 << width) - (int)value]);
2605 c += 1 << width;
2606 break;
2607 default:
2608 abort ();
2610 break;
2612 default:
2613 abort ();
2617 else
2618 func (stream, "%c", *c);
2620 return TRUE;
2623 return FALSE;
2626 /* Print one ARM instruction from PC on INFO->STREAM. */
2628 static void
2629 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2631 const struct opcode32 *insn;
2632 void *stream = info->stream;
2633 fprintf_ftype func = info->fprintf_func;
2635 if (print_insn_coprocessor (pc, info, given, FALSE))
2636 return;
2638 if (print_insn_neon (info, given, FALSE))
2639 return;
2641 for (insn = arm_opcodes; insn->assembler; insn++)
2643 if (insn->value == FIRST_IWMMXT_INSN
2644 && info->mach != bfd_mach_arm_XScale
2645 && info->mach != bfd_mach_arm_iWMMXt)
2646 insn = insn + IWMMXT_INSN_COUNT;
2648 if ((given & insn->mask) == insn->value
2649 /* Special case: an instruction with all bits set in the condition field
2650 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2651 or by the catchall at the end of the table. */
2652 && ((given & 0xF0000000) != 0xF0000000
2653 || (insn->mask & 0xF0000000) == 0xF0000000
2654 || (insn->mask == 0 && insn->value == 0)))
2656 const char *c;
2658 for (c = insn->assembler; *c; c++)
2660 if (*c == '%')
2662 switch (*++c)
2664 case '%':
2665 func (stream, "%%");
2666 break;
2668 case 'a':
2669 print_arm_address (pc, info, given);
2670 break;
2672 case 'P':
2673 /* Set P address bit and use normal address
2674 printing routine. */
2675 print_arm_address (pc, info, given | (1 << 24));
2676 break;
2678 case 's':
2679 if ((given & 0x004f0000) == 0x004f0000)
2681 /* PC relative with immediate offset. */
2682 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2684 if ((given & 0x00800000) == 0)
2685 offset = -offset;
2687 func (stream, "[pc, #%d]\t; ", offset);
2688 info->print_address_func (offset + pc + 8, info);
2690 else
2692 func (stream, "[%s",
2693 arm_regnames[(given >> 16) & 0xf]);
2694 if ((given & 0x01000000) != 0)
2696 /* Pre-indexed. */
2697 if ((given & 0x00400000) == 0x00400000)
2699 /* Immediate. */
2700 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2701 if (offset)
2702 func (stream, ", #%s%d",
2703 (((given & 0x00800000) == 0)
2704 ? "-" : ""), offset);
2706 else
2708 /* Register. */
2709 func (stream, ", %s%s",
2710 (((given & 0x00800000) == 0)
2711 ? "-" : ""),
2712 arm_regnames[given & 0xf]);
2715 func (stream, "]%s",
2716 ((given & 0x00200000) != 0) ? "!" : "");
2718 else
2720 /* Post-indexed. */
2721 if ((given & 0x00400000) == 0x00400000)
2723 /* Immediate. */
2724 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2725 if (offset)
2726 func (stream, "], #%s%d",
2727 (((given & 0x00800000) == 0)
2728 ? "-" : ""), offset);
2729 else
2730 func (stream, "]");
2732 else
2734 /* Register. */
2735 func (stream, "], %s%s",
2736 (((given & 0x00800000) == 0)
2737 ? "-" : ""),
2738 arm_regnames[given & 0xf]);
2742 break;
2744 case 'b':
2746 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2747 info->print_address_func (disp*4 + pc + 8, info);
2749 break;
2751 case 'c':
2752 if (((given >> 28) & 0xf) != 0xe)
2753 func (stream, "%s",
2754 arm_conditional [(given >> 28) & 0xf]);
2755 break;
2757 case 'm':
2759 int started = 0;
2760 int reg;
2762 func (stream, "{");
2763 for (reg = 0; reg < 16; reg++)
2764 if ((given & (1 << reg)) != 0)
2766 if (started)
2767 func (stream, ", ");
2768 started = 1;
2769 func (stream, "%s", arm_regnames[reg]);
2771 func (stream, "}");
2773 break;
2775 case 'o':
2776 if ((given & 0x02000000) != 0)
2778 int rotate = (given & 0xf00) >> 7;
2779 int immed = (given & 0xff);
2780 immed = (((immed << (32 - rotate))
2781 | (immed >> rotate)) & 0xffffffff);
2782 func (stream, "#%d\t; 0x%x", immed, immed);
2784 else
2785 arm_decode_shift (given, func, stream);
2786 break;
2788 case 'p':
2789 if ((given & 0x0000f000) == 0x0000f000)
2790 func (stream, "p");
2791 break;
2793 case 't':
2794 if ((given & 0x01200000) == 0x00200000)
2795 func (stream, "t");
2796 break;
2798 case 'A':
2799 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2801 if ((given & (1 << 24)) != 0)
2803 int offset = given & 0xff;
2805 if (offset)
2806 func (stream, ", #%s%d]%s",
2807 ((given & 0x00800000) == 0 ? "-" : ""),
2808 offset * 4,
2809 ((given & 0x00200000) != 0 ? "!" : ""));
2810 else
2811 func (stream, "]");
2813 else
2815 int offset = given & 0xff;
2817 func (stream, "]");
2819 if (given & (1 << 21))
2821 if (offset)
2822 func (stream, ", #%s%d",
2823 ((given & 0x00800000) == 0 ? "-" : ""),
2824 offset * 4);
2826 else
2827 func (stream, ", {%d}", offset);
2829 break;
2831 case 'B':
2832 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2834 bfd_vma address;
2835 bfd_vma offset = 0;
2837 if (given & 0x00800000)
2838 /* Is signed, hi bits should be ones. */
2839 offset = (-1) ^ 0x00ffffff;
2841 /* Offset is (SignExtend(offset field)<<2). */
2842 offset += given & 0x00ffffff;
2843 offset <<= 2;
2844 address = offset + pc + 8;
2846 if (given & 0x01000000)
2847 /* H bit allows addressing to 2-byte boundaries. */
2848 address += 2;
2850 info->print_address_func (address, info);
2852 break;
2854 case 'C':
2855 func (stream, "_");
2856 if (given & 0x80000)
2857 func (stream, "f");
2858 if (given & 0x40000)
2859 func (stream, "s");
2860 if (given & 0x20000)
2861 func (stream, "x");
2862 if (given & 0x10000)
2863 func (stream, "c");
2864 break;
2866 case 'U':
2867 switch (given & 0xf)
2869 case 0xf: func(stream, "sy"); break;
2870 case 0x7: func(stream, "un"); break;
2871 case 0xe: func(stream, "st"); break;
2872 case 0x6: func(stream, "unst"); break;
2873 default:
2874 func(stream, "#%d", (int)given & 0xf);
2875 break;
2877 break;
2879 case '0': case '1': case '2': case '3': case '4':
2880 case '5': case '6': case '7': case '8': case '9':
2882 int width;
2883 unsigned long value;
2885 c = arm_decode_bitfield (c, given, &value, &width);
2887 switch (*c)
2889 case 'r':
2890 func (stream, "%s", arm_regnames[value]);
2891 break;
2892 case 'd':
2893 func (stream, "%ld", value);
2894 break;
2895 case 'b':
2896 func (stream, "%ld", value * 8);
2897 break;
2898 case 'W':
2899 func (stream, "%ld", value + 1);
2900 break;
2901 case 'x':
2902 func (stream, "0x%08lx", value);
2904 /* Some SWI instructions have special
2905 meanings. */
2906 if ((given & 0x0fffffff) == 0x0FF00000)
2907 func (stream, "\t; IMB");
2908 else if ((given & 0x0fffffff) == 0x0FF00001)
2909 func (stream, "\t; IMBRange");
2910 break;
2911 case 'X':
2912 func (stream, "%01lx", value & 0xf);
2913 break;
2914 case '`':
2915 c++;
2916 if (value == 0)
2917 func (stream, "%c", *c);
2918 break;
2919 case '\'':
2920 c++;
2921 if (value == ((1ul << width) - 1))
2922 func (stream, "%c", *c);
2923 break;
2924 case '?':
2925 func (stream, "%c", c[(1 << width) - (int)value]);
2926 c += 1 << width;
2927 break;
2928 default:
2929 abort ();
2931 break;
2933 case 'e':
2935 int imm;
2937 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2938 func (stream, "%d", imm);
2940 break;
2942 case 'E':
2943 /* LSB and WIDTH fields of BFI or BFC. The machine-
2944 language instruction encodes LSB and MSB. */
2946 long msb = (given & 0x001f0000) >> 16;
2947 long lsb = (given & 0x00000f80) >> 7;
2949 long width = msb - lsb + 1;
2950 if (width > 0)
2951 func (stream, "#%lu, #%lu", lsb, width);
2952 else
2953 func (stream, "(invalid: %lu:%lu)", lsb, msb);
2955 break;
2957 case 'V':
2958 /* 16-bit unsigned immediate from a MOVT or MOVW
2959 instruction, encoded in bits 0:11 and 15:19. */
2961 long hi = (given & 0x000f0000) >> 4;
2962 long lo = (given & 0x00000fff);
2963 long imm16 = hi | lo;
2964 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2966 break;
2968 default:
2969 abort ();
2973 else
2974 func (stream, "%c", *c);
2976 return;
2979 abort ();
2982 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2984 static void
2985 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2987 const struct opcode16 *insn;
2988 void *stream = info->stream;
2989 fprintf_ftype func = info->fprintf_func;
2991 for (insn = thumb_opcodes; insn->assembler; insn++)
2992 if ((given & insn->mask) == insn->value)
2994 const char *c = insn->assembler;
2995 for (; *c; c++)
2997 int domaskpc = 0;
2998 int domasklr = 0;
3000 if (*c != '%')
3002 func (stream, "%c", *c);
3003 continue;
3006 switch (*++c)
3008 case '%':
3009 func (stream, "%%");
3010 break;
3012 case 'c':
3013 if (ifthen_state)
3014 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3015 break;
3017 case 'C':
3018 if (ifthen_state)
3019 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3020 else
3021 func (stream, "s");
3022 break;
3024 case 'I':
3026 unsigned int tmp;
3028 ifthen_next_state = given & 0xff;
3029 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3030 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3031 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3033 break;
3035 case 'x':
3036 if (ifthen_next_state)
3037 func (stream, "\t; unpredictable branch in IT block\n");
3038 break;
3040 case 'X':
3041 if (ifthen_state)
3042 func (stream, "\t; unpredictable <IT:%s>",
3043 arm_conditional[IFTHEN_COND]);
3044 break;
3046 case 'S':
3048 long reg;
3050 reg = (given >> 3) & 0x7;
3051 if (given & (1 << 6))
3052 reg += 8;
3054 func (stream, "%s", arm_regnames[reg]);
3056 break;
3058 case 'D':
3060 long reg;
3062 reg = given & 0x7;
3063 if (given & (1 << 7))
3064 reg += 8;
3066 func (stream, "%s", arm_regnames[reg]);
3068 break;
3070 case 'N':
3071 if (given & (1 << 8))
3072 domasklr = 1;
3073 /* Fall through. */
3074 case 'O':
3075 if (*c == 'O' && (given & (1 << 8)))
3076 domaskpc = 1;
3077 /* Fall through. */
3078 case 'M':
3080 int started = 0;
3081 int reg;
3083 func (stream, "{");
3085 /* It would be nice if we could spot
3086 ranges, and generate the rS-rE format: */
3087 for (reg = 0; (reg < 8); reg++)
3088 if ((given & (1 << reg)) != 0)
3090 if (started)
3091 func (stream, ", ");
3092 started = 1;
3093 func (stream, "%s", arm_regnames[reg]);
3096 if (domasklr)
3098 if (started)
3099 func (stream, ", ");
3100 started = 1;
3101 func (stream, arm_regnames[14] /* "lr" */);
3104 if (domaskpc)
3106 if (started)
3107 func (stream, ", ");
3108 func (stream, arm_regnames[15] /* "pc" */);
3111 func (stream, "}");
3113 break;
3115 case 'b':
3116 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3118 bfd_vma address = (pc + 4
3119 + ((given & 0x00f8) >> 2)
3120 + ((given & 0x0200) >> 3));
3121 info->print_address_func (address, info);
3123 break;
3125 case 's':
3126 /* Right shift immediate -- bits 6..10; 1-31 print
3127 as themselves, 0 prints as 32. */
3129 long imm = (given & 0x07c0) >> 6;
3130 if (imm == 0)
3131 imm = 32;
3132 func (stream, "#%ld", imm);
3134 break;
3136 case '0': case '1': case '2': case '3': case '4':
3137 case '5': case '6': case '7': case '8': case '9':
3139 int bitstart = *c++ - '0';
3140 int bitend = 0;
3142 while (*c >= '0' && *c <= '9')
3143 bitstart = (bitstart * 10) + *c++ - '0';
3145 switch (*c)
3147 case '-':
3149 long reg;
3151 c++;
3152 while (*c >= '0' && *c <= '9')
3153 bitend = (bitend * 10) + *c++ - '0';
3154 if (!bitend)
3155 abort ();
3156 reg = given >> bitstart;
3157 reg &= (2 << (bitend - bitstart)) - 1;
3158 switch (*c)
3160 case 'r':
3161 func (stream, "%s", arm_regnames[reg]);
3162 break;
3164 case 'd':
3165 func (stream, "%ld", reg);
3166 break;
3168 case 'H':
3169 func (stream, "%ld", reg << 1);
3170 break;
3172 case 'W':
3173 func (stream, "%ld", reg << 2);
3174 break;
3176 case 'a':
3177 /* PC-relative address -- the bottom two
3178 bits of the address are dropped
3179 before the calculation. */
3180 info->print_address_func
3181 (((pc + 4) & ~3) + (reg << 2), info);
3182 break;
3184 case 'x':
3185 func (stream, "0x%04lx", reg);
3186 break;
3188 case 'B':
3189 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3190 info->print_address_func (reg * 2 + pc + 4, info);
3191 break;
3193 case 'c':
3194 func (stream, "%s", arm_conditional [reg]);
3195 break;
3197 default:
3198 abort ();
3201 break;
3203 case '\'':
3204 c++;
3205 if ((given & (1 << bitstart)) != 0)
3206 func (stream, "%c", *c);
3207 break;
3209 case '?':
3210 ++c;
3211 if ((given & (1 << bitstart)) != 0)
3212 func (stream, "%c", *c++);
3213 else
3214 func (stream, "%c", *++c);
3215 break;
3217 default:
3218 abort ();
3221 break;
3223 default:
3224 abort ();
3227 return;
3230 /* No match. */
3231 abort ();
3234 /* Return the name of an V7M special register. */
3235 static const char *
3236 psr_name (int regno)
3238 switch (regno)
3240 case 0: return "APSR";
3241 case 1: return "IAPSR";
3242 case 2: return "EAPSR";
3243 case 3: return "PSR";
3244 case 5: return "IPSR";
3245 case 6: return "EPSR";
3246 case 7: return "IEPSR";
3247 case 8: return "MSP";
3248 case 9: return "PSP";
3249 case 16: return "PRIMASK";
3250 case 17: return "BASEPRI";
3251 case 18: return "BASEPRI_MASK";
3252 case 19: return "FAULTMASK";
3253 case 20: return "CONTROL";
3254 default: return "<unknown>";
3258 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3260 static void
3261 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3263 const struct opcode32 *insn;
3264 void *stream = info->stream;
3265 fprintf_ftype func = info->fprintf_func;
3267 if (print_insn_coprocessor (pc, info, given, TRUE))
3268 return;
3270 if (print_insn_neon (info, given, TRUE))
3271 return;
3273 for (insn = thumb32_opcodes; insn->assembler; insn++)
3274 if ((given & insn->mask) == insn->value)
3276 const char *c = insn->assembler;
3277 for (; *c; c++)
3279 if (*c != '%')
3281 func (stream, "%c", *c);
3282 continue;
3285 switch (*++c)
3287 case '%':
3288 func (stream, "%%");
3289 break;
3291 case 'c':
3292 if (ifthen_state)
3293 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3294 break;
3296 case 'x':
3297 if (ifthen_next_state)
3298 func (stream, "\t; unpredictable branch in IT block\n");
3299 break;
3301 case 'X':
3302 if (ifthen_state)
3303 func (stream, "\t; unpredictable <IT:%s>",
3304 arm_conditional[IFTHEN_COND]);
3305 break;
3307 case 'I':
3309 unsigned int imm12 = 0;
3310 imm12 |= (given & 0x000000ffu);
3311 imm12 |= (given & 0x00007000u) >> 4;
3312 imm12 |= (given & 0x04000000u) >> 15;
3313 func (stream, "#%u\t; 0x%x", imm12, imm12);
3315 break;
3317 case 'M':
3319 unsigned int bits = 0, imm, imm8, mod;
3320 bits |= (given & 0x000000ffu);
3321 bits |= (given & 0x00007000u) >> 4;
3322 bits |= (given & 0x04000000u) >> 15;
3323 imm8 = (bits & 0x0ff);
3324 mod = (bits & 0xf00) >> 8;
3325 switch (mod)
3327 case 0: imm = imm8; break;
3328 case 1: imm = ((imm8<<16) | imm8); break;
3329 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3330 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3331 default:
3332 mod = (bits & 0xf80) >> 7;
3333 imm8 = (bits & 0x07f) | 0x80;
3334 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3336 func (stream, "#%u\t; 0x%x", imm, imm);
3338 break;
3340 case 'J':
3342 unsigned int imm = 0;
3343 imm |= (given & 0x000000ffu);
3344 imm |= (given & 0x00007000u) >> 4;
3345 imm |= (given & 0x04000000u) >> 15;
3346 imm |= (given & 0x000f0000u) >> 4;
3347 func (stream, "#%u\t; 0x%x", imm, imm);
3349 break;
3351 case 'K':
3353 unsigned int imm = 0;
3354 imm |= (given & 0x000f0000u) >> 16;
3355 imm |= (given & 0x00000ff0u) >> 0;
3356 imm |= (given & 0x0000000fu) << 12;
3357 func (stream, "#%u\t; 0x%x", imm, imm);
3359 break;
3361 case 'S':
3363 unsigned int reg = (given & 0x0000000fu);
3364 unsigned int stp = (given & 0x00000030u) >> 4;
3365 unsigned int imm = 0;
3366 imm |= (given & 0x000000c0u) >> 6;
3367 imm |= (given & 0x00007000u) >> 10;
3369 func (stream, "%s", arm_regnames[reg]);
3370 switch (stp)
3372 case 0:
3373 if (imm > 0)
3374 func (stream, ", lsl #%u", imm);
3375 break;
3377 case 1:
3378 if (imm == 0)
3379 imm = 32;
3380 func (stream, ", lsr #%u", imm);
3381 break;
3383 case 2:
3384 if (imm == 0)
3385 imm = 32;
3386 func (stream, ", asr #%u", imm);
3387 break;
3389 case 3:
3390 if (imm == 0)
3391 func (stream, ", rrx");
3392 else
3393 func (stream, ", ror #%u", imm);
3396 break;
3398 case 'a':
3400 unsigned int Rn = (given & 0x000f0000) >> 16;
3401 unsigned int U = (given & 0x00800000) >> 23;
3402 unsigned int op = (given & 0x00000f00) >> 8;
3403 unsigned int i12 = (given & 0x00000fff);
3404 unsigned int i8 = (given & 0x000000ff);
3405 bfd_boolean writeback = FALSE, postind = FALSE;
3406 int offset = 0;
3408 func (stream, "[%s", arm_regnames[Rn]);
3409 if (U) /* 12-bit positive immediate offset */
3410 offset = i12;
3411 else if (Rn == 15) /* 12-bit negative immediate offset */
3412 offset = -(int)i12;
3413 else if (op == 0x0) /* shifted register offset */
3415 unsigned int Rm = (i8 & 0x0f);
3416 unsigned int sh = (i8 & 0x30) >> 4;
3417 func (stream, ", %s", arm_regnames[Rm]);
3418 if (sh)
3419 func (stream, ", lsl #%u", sh);
3420 func (stream, "]");
3421 break;
3423 else switch (op)
3425 case 0xE: /* 8-bit positive immediate offset */
3426 offset = i8;
3427 break;
3429 case 0xC: /* 8-bit negative immediate offset */
3430 offset = -i8;
3431 break;
3433 case 0xF: /* 8-bit + preindex with wb */
3434 offset = i8;
3435 writeback = TRUE;
3436 break;
3438 case 0xD: /* 8-bit - preindex with wb */
3439 offset = -i8;
3440 writeback = TRUE;
3441 break;
3443 case 0xB: /* 8-bit + postindex */
3444 offset = i8;
3445 postind = TRUE;
3446 break;
3448 case 0x9: /* 8-bit - postindex */
3449 offset = -i8;
3450 postind = TRUE;
3451 break;
3453 default:
3454 func (stream, ", <undefined>]");
3455 goto skip;
3458 if (postind)
3459 func (stream, "], #%d", offset);
3460 else
3462 if (offset)
3463 func (stream, ", #%d", offset);
3464 func (stream, writeback ? "]!" : "]");
3467 if (Rn == 15)
3469 func (stream, "\t; ");
3470 info->print_address_func (((pc + 4) & ~3) + offset, info);
3473 skip:
3474 break;
3476 case 'A':
3478 unsigned int P = (given & 0x01000000) >> 24;
3479 unsigned int U = (given & 0x00800000) >> 23;
3480 unsigned int W = (given & 0x00400000) >> 21;
3481 unsigned int Rn = (given & 0x000f0000) >> 16;
3482 unsigned int off = (given & 0x000000ff);
3484 func (stream, "[%s", arm_regnames[Rn]);
3485 if (P)
3487 if (off || !U)
3488 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3489 func (stream, "]");
3490 if (W)
3491 func (stream, "!");
3493 else
3495 func (stream, "], ");
3496 if (W)
3497 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3498 else
3499 func (stream, "{%u}", off);
3502 break;
3504 case 'w':
3506 unsigned int Sbit = (given & 0x01000000) >> 24;
3507 unsigned int type = (given & 0x00600000) >> 21;
3508 switch (type)
3510 case 0: func (stream, Sbit ? "sb" : "b"); break;
3511 case 1: func (stream, Sbit ? "sh" : "h"); break;
3512 case 2:
3513 if (Sbit)
3514 func (stream, "??");
3515 break;
3516 case 3:
3517 func (stream, "??");
3518 break;
3521 break;
3523 case 'm':
3525 int started = 0;
3526 int reg;
3528 func (stream, "{");
3529 for (reg = 0; reg < 16; reg++)
3530 if ((given & (1 << reg)) != 0)
3532 if (started)
3533 func (stream, ", ");
3534 started = 1;
3535 func (stream, "%s", arm_regnames[reg]);
3537 func (stream, "}");
3539 break;
3541 case 'E':
3543 unsigned int msb = (given & 0x0000001f);
3544 unsigned int lsb = 0;
3545 lsb |= (given & 0x000000c0u) >> 6;
3546 lsb |= (given & 0x00007000u) >> 10;
3547 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3549 break;
3551 case 'F':
3553 unsigned int width = (given & 0x0000001f) + 1;
3554 unsigned int lsb = 0;
3555 lsb |= (given & 0x000000c0u) >> 6;
3556 lsb |= (given & 0x00007000u) >> 10;
3557 func (stream, "#%u, #%u", lsb, width);
3559 break;
3561 case 'b':
3563 unsigned int S = (given & 0x04000000u) >> 26;
3564 unsigned int J1 = (given & 0x00002000u) >> 13;
3565 unsigned int J2 = (given & 0x00000800u) >> 11;
3566 int offset = 0;
3568 offset |= !S << 20;
3569 offset |= J2 << 19;
3570 offset |= J1 << 18;
3571 offset |= (given & 0x003f0000) >> 4;
3572 offset |= (given & 0x000007ff) << 1;
3573 offset -= (1 << 20);
3575 info->print_address_func (pc + 4 + offset, info);
3577 break;
3579 case 'B':
3581 unsigned int S = (given & 0x04000000u) >> 26;
3582 unsigned int I1 = (given & 0x00002000u) >> 13;
3583 unsigned int I2 = (given & 0x00000800u) >> 11;
3584 int offset = 0;
3586 offset |= !S << 24;
3587 offset |= !(I1 ^ S) << 23;
3588 offset |= !(I2 ^ S) << 22;
3589 offset |= (given & 0x03ff0000u) >> 4;
3590 offset |= (given & 0x000007ffu) << 1;
3591 offset -= (1 << 24);
3592 offset += pc + 4;
3594 /* BLX target addresses are always word aligned. */
3595 if ((given & 0x00001000u) == 0)
3596 offset &= ~2u;
3598 info->print_address_func (offset, info);
3600 break;
3602 case 's':
3604 unsigned int shift = 0;
3605 shift |= (given & 0x000000c0u) >> 6;
3606 shift |= (given & 0x00007000u) >> 10;
3607 if (given & 0x00200000u)
3608 func (stream, ", asr #%u", shift);
3609 else if (shift)
3610 func (stream, ", lsl #%u", shift);
3611 /* else print nothing - lsl #0 */
3613 break;
3615 case 'R':
3617 unsigned int rot = (given & 0x00000030) >> 4;
3618 if (rot)
3619 func (stream, ", ror #%u", rot * 8);
3621 break;
3623 case 'U':
3624 switch (given & 0xf)
3626 case 0xf: func(stream, "sy"); break;
3627 case 0x7: func(stream, "un"); break;
3628 case 0xe: func(stream, "st"); break;
3629 case 0x6: func(stream, "unst"); break;
3630 default:
3631 func(stream, "#%d", (int)given & 0xf);
3632 break;
3634 break;
3636 case 'C':
3637 if ((given & 0xff) == 0)
3639 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3640 if (given & 0x800)
3641 func (stream, "f");
3642 if (given & 0x400)
3643 func (stream, "s");
3644 if (given & 0x200)
3645 func (stream, "x");
3646 if (given & 0x100)
3647 func (stream, "c");
3649 else
3651 func (stream, psr_name (given & 0xff));
3653 break;
3655 case 'D':
3656 if ((given & 0xff) == 0)
3657 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3658 else
3659 func (stream, psr_name (given & 0xff));
3660 break;
3662 case '0': case '1': case '2': case '3': case '4':
3663 case '5': case '6': case '7': case '8': case '9':
3665 int width;
3666 unsigned long val;
3668 c = arm_decode_bitfield (c, given, &val, &width);
3670 switch (*c)
3672 case 'd': func (stream, "%lu", val); break;
3673 case 'W': func (stream, "%lu", val * 4); break;
3674 case 'r': func (stream, "%s", arm_regnames[val]); break;
3676 case 'c':
3677 func (stream, "%s", arm_conditional[val]);
3678 break;
3680 case '\'':
3681 c++;
3682 if (val == ((1ul << width) - 1))
3683 func (stream, "%c", *c);
3684 break;
3686 case '`':
3687 c++;
3688 if (val == 0)
3689 func (stream, "%c", *c);
3690 break;
3692 case '?':
3693 func (stream, "%c", c[(1 << width) - (int)val]);
3694 c += 1 << width;
3695 break;
3697 default:
3698 abort ();
3701 break;
3703 default:
3704 abort ();
3707 return;
3710 /* No match. */
3711 abort ();
3714 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3715 being displayed in symbol relative addresses. */
3717 bfd_boolean
3718 arm_symbol_is_valid (asymbol * sym,
3719 struct disassemble_info * info ATTRIBUTE_UNUSED)
3721 const char * name;
3723 if (sym == NULL)
3724 return FALSE;
3726 name = bfd_asymbol_name (sym);
3728 return (name && *name != '$');
3731 /* Parse an individual disassembler option. */
3733 void
3734 parse_arm_disassembler_option (char *option)
3736 if (option == NULL)
3737 return;
3739 if (CONST_STRNEQ (option, "reg-names-"))
3741 int i;
3743 option += 10;
3745 for (i = NUM_ARM_REGNAMES; i--;)
3746 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3748 regname_selected = i;
3749 break;
3752 if (i < 0)
3753 /* XXX - should break 'option' at following delimiter. */
3754 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3756 else if (CONST_STRNEQ (option, "force-thumb"))
3757 force_thumb = 1;
3758 else if (CONST_STRNEQ (option, "no-force-thumb"))
3759 force_thumb = 0;
3760 else
3761 /* XXX - should break 'option' at following delimiter. */
3762 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3764 return;
3767 /* Parse the string of disassembler options, spliting it at whitespaces
3768 or commas. (Whitespace separators supported for backwards compatibility). */
3770 static void
3771 parse_disassembler_options (char *options)
3773 if (options == NULL)
3774 return;
3776 while (*options)
3778 parse_arm_disassembler_option (options);
3780 /* Skip forward to next seperator. */
3781 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3782 ++ options;
3783 /* Skip forward past seperators. */
3784 while (ISSPACE (*options) || (*options == ','))
3785 ++ options;
3789 /* Search back through the insn stream to determine if this instruction is
3790 conditionally executed. */
3791 static void
3792 find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3793 bfd_boolean little)
3795 unsigned char b[2];
3796 unsigned int insn;
3797 int status;
3798 /* COUNT is twice the number of instructions seen. It will be odd if we
3799 just crossed an instruction boundary. */
3800 int count;
3801 int it_count;
3802 unsigned int seen_it;
3803 bfd_vma addr;
3805 ifthen_address = pc;
3806 ifthen_state = 0;
3808 addr = pc;
3809 count = 1;
3810 it_count = 0;
3811 seen_it = 0;
3812 /* Scan backwards looking for IT instructions, keeping track of where
3813 instruction boundaries are. We don't know if something is actually an
3814 IT instruction until we find a definite instruction boundary. */
3815 for (;;)
3817 if (addr == 0 || info->symbol_at_address_func(addr, info))
3819 /* A symbol must be on an instruction boundary, and will not
3820 be within an IT block. */
3821 if (seen_it && (count & 1))
3822 break;
3824 return;
3826 addr -= 2;
3827 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3828 if (status)
3829 return;
3831 if (little)
3832 insn = (b[0]) | (b[1] << 8);
3833 else
3834 insn = (b[1]) | (b[0] << 8);
3835 if (seen_it)
3837 if ((insn & 0xf800) < 0xe800)
3839 /* Addr + 2 is an instruction boundary. See if this matches
3840 the expected boundary based on the position of the last
3841 IT candidate. */
3842 if (count & 1)
3843 break;
3844 seen_it = 0;
3847 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3849 /* This could be an IT instruction. */
3850 seen_it = insn;
3851 it_count = count >> 1;
3853 if ((insn & 0xf800) >= 0xe800)
3854 count++;
3855 else
3856 count = (count + 2) | 1;
3857 /* IT blocks contain at most 4 instructions. */
3858 if (count >= 8 && !seen_it)
3859 return;
3861 /* We found an IT instruction. */
3862 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3863 if ((ifthen_state & 0xf) == 0)
3864 ifthen_state = 0;
3867 /* Try to infer the code type (Arm or Thumb) from a symbol.
3868 Returns nonzero if is_thumb was set. */
3870 static int
3871 get_sym_code_type (struct disassemble_info *info, int n, int *is_thumb)
3873 elf_symbol_type *es;
3874 unsigned int type;
3875 const char *name;
3877 es = *(elf_symbol_type **)(info->symbols);
3878 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3880 /* If the symbol has function type then use that. */
3881 if (type == STT_FUNC || type == STT_ARM_TFUNC)
3883 *is_thumb = (type == STT_ARM_TFUNC);
3884 return TRUE;
3887 /* Check for mapping symbols. */
3888 name = bfd_asymbol_name(info->symtab[n]);
3889 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't')
3890 && (name[2] == 0 || name[2] == '.'))
3892 *is_thumb = (name[1] == 't');
3893 return TRUE;
3896 return FALSE;
3899 /* NOTE: There are no checks in these routines that
3900 the relevant number of data bytes exist. */
3902 static int
3903 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3905 unsigned char b[4];
3906 long given;
3907 int status;
3908 int is_thumb;
3909 int size;
3910 void (*printer) (bfd_vma, struct disassemble_info *, long);
3912 if (info->disassembler_options)
3914 parse_disassembler_options (info->disassembler_options);
3916 /* To avoid repeated parsing of these options, we remove them here. */
3917 info->disassembler_options = NULL;
3920 is_thumb = force_thumb;
3922 if (!is_thumb && info->symbols != NULL)
3924 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3926 coff_symbol_type * cs;
3928 cs = coffsymbol (*info->symbols);
3929 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
3930 || cs->native->u.syment.n_sclass == C_THUMBSTAT
3931 || cs->native->u.syment.n_sclass == C_THUMBLABEL
3932 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
3933 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
3935 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
3937 bfd_vma addr;
3938 int n;
3939 int last_sym;
3940 bfd_boolean found;
3942 if (info->symtab)
3944 if (pc <= last_mapping_addr)
3945 last_mapping_sym = -1;
3946 is_thumb = last_is_thumb;
3947 found = FALSE;
3948 /* Start scanning at the start of the function, or wherever
3949 we finished last time. */
3950 n = info->symtab_pos + 1;
3951 if (n < last_mapping_sym)
3952 n = last_mapping_sym;
3954 /* Scan up to the location being disassembled. */
3955 for (; n < info->symtab_size; n++)
3957 addr = bfd_asymbol_value (info->symtab[n]);
3958 if (addr > pc)
3959 break;
3960 if (get_sym_code_type (info, n, &is_thumb))
3961 found = TRUE;
3964 last_sym = n;
3965 if (!found)
3967 if (last_mapping_sym == -1)
3968 last_mapping_sym = 0;
3969 else
3970 found = TRUE;
3972 /* No mapping symbol found at this address. Look backwards
3973 for a preceeding one. */
3974 for (n = info->symtab_pos; n >= last_mapping_sym; n--)
3976 if (get_sym_code_type (info, n, &is_thumb))
3978 found = TRUE;
3979 break;
3984 last_mapping_sym = last_sym;
3985 last_is_thumb = is_thumb;
3987 else
3988 found = FALSE;
3990 /* If no mapping symbol has been found then fall back to the type
3991 of the function symbol. */
3992 if (!found)
3994 elf_symbol_type * es;
3995 unsigned int type;
3997 es = *(elf_symbol_type **)(info->symbols);
3998 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4000 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4005 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4006 info->bytes_per_line = 4;
4008 if (!is_thumb)
4010 /* In ARM mode endianness is a straightforward issue: the instruction
4011 is four bytes long and is either ordered 0123 or 3210. */
4012 printer = print_insn_arm;
4013 info->bytes_per_chunk = 4;
4014 size = 4;
4016 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4017 if (little)
4018 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4019 else
4020 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4022 else
4024 /* In Thumb mode we have the additional wrinkle of two
4025 instruction lengths. Fortunately, the bits that determine
4026 the length of the current instruction are always to be found
4027 in the first two bytes. */
4028 printer = print_insn_thumb16;
4029 info->bytes_per_chunk = 2;
4030 size = 2;
4032 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4033 if (little)
4034 given = (b[0]) | (b[1] << 8);
4035 else
4036 given = (b[1]) | (b[0] << 8);
4038 if (!status)
4040 /* These bit patterns signal a four-byte Thumb
4041 instruction. */
4042 if ((given & 0xF800) == 0xF800
4043 || (given & 0xF800) == 0xF000
4044 || (given & 0xF800) == 0xE800)
4046 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4047 if (little)
4048 given = (b[0]) | (b[1] << 8) | (given << 16);
4049 else
4050 given = (b[1]) | (b[0] << 8) | (given << 16);
4052 printer = print_insn_thumb32;
4053 size = 4;
4057 if (ifthen_address != pc)
4058 find_ifthen_state(pc, info, little);
4060 if (ifthen_state)
4062 if ((ifthen_state & 0xf) == 0x8)
4063 ifthen_next_state = 0;
4064 else
4065 ifthen_next_state = (ifthen_state & 0xe0)
4066 | ((ifthen_state & 0xf) << 1);
4070 if (status)
4072 info->memory_error_func (status, pc, info);
4073 return -1;
4075 if (info->flags & INSN_HAS_RELOC)
4076 /* If the instruction has a reloc associated with it, then
4077 the offset field in the instruction will actually be the
4078 addend for the reloc. (We are using REL type relocs).
4079 In such cases, we can ignore the pc when computing
4080 addresses, since the addend is not currently pc-relative. */
4081 pc = 0;
4083 printer (pc, info, given);
4085 if (is_thumb)
4087 ifthen_state = ifthen_next_state;
4088 ifthen_address += size;
4090 return size;
4094 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4096 return print_insn (pc, info, FALSE);
4100 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4102 return print_insn (pc, info, TRUE);
4105 void
4106 print_arm_disassembler_options (FILE *stream)
4108 int i;
4110 fprintf (stream, _("\n\
4111 The following ARM specific disassembler options are supported for use with\n\
4112 the -M switch:\n"));
4114 for (i = NUM_ARM_REGNAMES; i--;)
4115 fprintf (stream, " reg-names-%s %*c%s\n",
4116 regnames[i].name,
4117 (int)(14 - strlen (regnames[i].name)), ' ',
4118 regnames[i].description);
4120 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4121 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");