2006-10-30 Paul Brook <paul@codesourcery.com>
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
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)
6
7 This file is part of libopcodes.
8
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.
13
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.
18
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. */
22
23 #include "sysdep.h"
24
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
29 #include "floatformat.h"
30
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"
37
38 /* FIXME: Belongs in global header. */
39 #ifndef strneq
40 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
41 #endif
42
43 #ifndef NUM_ELEM
44 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
45 #endif
46
47 struct opcode32
48 {
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. */
52 };
53
54 struct opcode16
55 {
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. */
59 };
60
61 /* print_insn_coprocessor recognizes the following format control codes:
62
63 %% %
64
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
75
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
88
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
93
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
97
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
105 */
106
107 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
108
109 static const struct opcode32 coprocessor_opcodes[] =
110 {
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"},
117
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"},
196
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"},
241
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"},
249
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]"},
265
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"},
346
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"},
432
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"},
441
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"},
445
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}"},
452
453 {0, 0, 0, 0}
454 };
455
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. */
459
460 /* print_insn_neon recognizes the following format control codes:
461
462 %% %
463
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
471
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
481
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 */
485
486 static const struct opcode32 neon_opcodes[] =
487 {
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"},
491
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]"},
496
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"},
500
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"},
535
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"},
590
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"},
605
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"},
665
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"},
684
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"},
708
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"},
729
730 {0,0 ,0, 0}
731 };
732
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. */
736
737 /* print_insn_arm recognizes the following format control codes:
738
739 %% %
740
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.
753
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"
759
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
763
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. */
767
768 static const struct opcode32 arm_opcodes[] =
769 {
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"},
778
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"},
785
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"},
796
797 /* ARM V6Z instructions. */
798 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
799
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]"},
808
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}"},
815
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"},
939
940 /* V5J instruction. */
941 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
942
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"},
948
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"},
957
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"},
960
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"},
965
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"},
970
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"},
973
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"},
978
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"},
1009
1010 /* The rest. */
1011 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
1012 {0, 0x00000000, 0x00000000, 0}
1013 };
1014
1015 /* print_insn_thumb16 recognizes the following format control codes:
1016
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. */
1040
1041 static const struct opcode16 thumb_opcodes[] =
1042 {
1043 /* Thumb instructions. */
1044
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}"},
1052
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"},
1057
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"},
1070
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"},
1151
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}
1158 };
1159
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.
1163
1164 print_insn_thumb32 recognizes the following format control codes:
1165
1166 %% %
1167
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
1173
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
1177
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
1189
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
1194
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
1198
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[] =
1208 {
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"},
1217
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}"},
1225
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"},
1396
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"},
1402
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"},
1406
1407 /* Fallback. */
1408 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1409 {0, 0, 0, 0}
1410 };
1411
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>", ""};
1415
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"};
1418
1419 static const char *const arm_shift[] =
1420 {"lsl", "lsr", "asr", "ror"};
1421
1422 typedef struct
1423 {
1424 const char *name;
1425 const char *description;
1426 const char *reg_names[16];
1427 }
1428 arm_regname;
1429
1430 static const arm_regname regnames[] =
1431 {
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" }},
1444 };
1445
1446 static const char *const iwmmxt_wwnames[] =
1447 {"b", "h", "w", "d"};
1448
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"
1454 };
1455
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"
1459 };
1460
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"
1464 };
1465
1466 /* Default to GCC register name set. */
1467 static unsigned int regname_selected = 1;
1468
1469 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1470 #define arm_regnames regnames[regname_selected].reg_names
1471
1472 static bfd_boolean force_thumb = FALSE;
1473
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)
1482
1483 /* Cached Thumb state. */
1484 int last_is_thumb;
1485 int last_mapping_sym = -1;
1486 bfd_vma last_mapping_addr = 0;
1487
1488 \f
1489 /* Functions. */
1490 int
1491 get_arm_regname_num_options (void)
1492 {
1493 return NUM_ARM_REGNAMES;
1494 }
1495
1496 int
1497 set_arm_regname_option (int option)
1498 {
1499 int old = regname_selected;
1500 regname_selected = option;
1501 return old;
1502 }
1503
1504 int
1505 get_arm_regnames (int option, const char **setname, const char **setdescription,
1506 const char *const **register_names)
1507 {
1508 *setname = regnames[option].name;
1509 *setdescription = regnames[option].description;
1510 *register_names = regnames[option].reg_names;
1511 return 16;
1512 }
1513
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. */
1518
1519 static const char *
1520 arm_decode_bitfield (const char *ptr, unsigned long insn,
1521 unsigned long *valuep, int *widthp)
1522 {
1523 unsigned long value = 0;
1524 int width = 0;
1525
1526 do
1527 {
1528 int start, end;
1529 int bits;
1530
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;
1543 }
1544 while (*ptr++ == ',');
1545 *valuep = value;
1546 if (widthp)
1547 *widthp = width;
1548 return ptr - 1;
1549 }
1550
1551 static void
1552 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1553 {
1554 func (stream, "%s", arm_regnames[given & 0xf]);
1555
1556 if ((given & 0xff0) != 0)
1557 {
1558 if ((given & 0x10) == 0)
1559 {
1560 int amount = (given & 0xf80) >> 7;
1561 int shift = (given & 0x60) >> 5;
1562
1563 if (amount == 0)
1564 {
1565 if (shift == 3)
1566 {
1567 func (stream, ", rrx");
1568 return;
1569 }
1570
1571 amount = 32;
1572 }
1573
1574 func (stream, ", %s #%d", arm_shift[shift], amount);
1575 }
1576 else
1577 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1578 arm_regnames[(given & 0xf00) >> 8]);
1579 }
1580 }
1581
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. */
1585
1586 static bfd_boolean
1587 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1588 bfd_boolean thumb)
1589 {
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;
1596
1597 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1598 {
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;
1604
1605 mask = insn->mask;
1606 value = insn->value;
1607 if (thumb)
1608 {
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;
1618 }
1619 else
1620 {
1621 /* Only match unconditional instuctions against unconditional
1622 patterns. */
1623 if ((given & 0xf0000000) == 0xf0000000)
1624 {
1625 mask |= 0xf0000000;
1626 cond = 16;
1627 }
1628 else
1629 {
1630 cond = (given >> 28) & 0xf;
1631 if (cond == 0xe)
1632 cond = 16;
1633 }
1634 }
1635 if ((given & mask) == value)
1636 {
1637 const char *c;
1638
1639 for (c = insn->assembler; *c; c++)
1640 {
1641 if (*c == '%')
1642 {
1643 switch (*++c)
1644 {
1645 case '%':
1646 func (stream, "%%");
1647 break;
1648
1649 case 'A':
1650 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1651
1652 if ((given & (1 << 24)) != 0)
1653 {
1654 int offset = given & 0xff;
1655
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, "]");
1663 }
1664 else
1665 {
1666 int offset = given & 0xff;
1667
1668 func (stream, "]");
1669
1670 if (given & (1 << 21))
1671 {
1672 if (offset)
1673 func (stream, ", #%s%d",
1674 ((given & 0x00800000) == 0 ? "-" : ""),
1675 offset * 4);
1676 }
1677 else
1678 func (stream, ", {%d}", offset);
1679 }
1680 break;
1681
1682 case 'B':
1683 {
1684 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1685 int offset = (given >> 1) & 0x3f;
1686
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);
1693 }
1694 break;
1695
1696 case 'C':
1697 {
1698 int rn = (given >> 16) & 0xf;
1699 int offset = (given & 0xff) * 4;
1700 int add = (given >> 23) & 1;
1701
1702 func (stream, "[%s", arm_regnames[rn]);
1703
1704 if (offset)
1705 {
1706 if (!add)
1707 offset = -offset;
1708 func (stream, ", #%d", offset);
1709 }
1710 func (stream, "]");
1711 if (rn == 15)
1712 {
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);
1718 }
1719 }
1720 break;
1721
1722 case 'c':
1723 func (stream, "%s", arm_conditional[cond]);
1724 break;
1725
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. */
1731 {
1732 int imm;
1733
1734 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1735
1736 /* Is ``imm'' a negative number? */
1737 if (imm & 0x40)
1738 imm |= (-1 << 7);
1739
1740 func (stream, "%d", imm);
1741 }
1742
1743 break;
1744
1745 case 'F':
1746 switch (given & 0x00408000)
1747 {
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");
1759 }
1760 break;
1761
1762 case 'P':
1763 switch (given & 0x00080080)
1764 {
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;
1777 }
1778 break;
1779 case 'Q':
1780 switch (given & 0x00408000)
1781 {
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;
1794 }
1795 break;
1796 case 'R':
1797 switch (given & 0x60)
1798 {
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;
1810 }
1811 break;
1812
1813 case '0': case '1': case '2': case '3': case '4':
1814 case '5': case '6': case '7': case '8': case '9':
1815 {
1816 int width;
1817 unsigned long value;
1818
1819 c = arm_decode_bitfield (c, given, &value, &width);
1820
1821 switch (*c)
1822 {
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':
1839 {
1840 int from = (given & (1 << 7)) ? 32 : 16;
1841 func (stream, "%ld", from - value);
1842 }
1843 break;
1844
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;
1851
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;
1858
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 ();
1881 }
1882 break;
1883
1884 case 'y':
1885 case 'z':
1886 {
1887 int single = *c++ == 'y';
1888 int regno;
1889
1890 switch (*c)
1891 {
1892 case '4': /* Sm pair */
1893 func (stream, "{");
1894 /* Fall through. */
1895 case '0': /* Sm, Dm */
1896 regno = given & 0x0000000f;
1897 if (single)
1898 {
1899 regno <<= 1;
1900 regno += (given >> 5) & 1;
1901 }
1902 else
1903 regno += ((given >> 5) & 1) << 4;
1904 break;
1905
1906 case '1': /* Sd, Dd */
1907 regno = (given >> 12) & 0x0000000f;
1908 if (single)
1909 {
1910 regno <<= 1;
1911 regno += (given >> 22) & 1;
1912 }
1913 else
1914 regno += ((given >> 22) & 1) << 4;
1915 break;
1916
1917 case '2': /* Sn, Dn */
1918 regno = (given >> 16) & 0x0000000f;
1919 if (single)
1920 {
1921 regno <<= 1;
1922 regno += (given >> 7) & 1;
1923 }
1924 else
1925 regno += ((given >> 7) & 1) << 4;
1926 break;
1927
1928 case '3': /* List */
1929 func (stream, "{");
1930 regno = (given >> 12) & 0x0000000f;
1931 if (single)
1932 {
1933 regno <<= 1;
1934 regno += (given >> 22) & 1;
1935 }
1936 else
1937 regno += ((given >> 22) & 1) << 4;
1938 break;
1939
1940 default:
1941 abort ();
1942 }
1943
1944 func (stream, "%c%d", single ? 's' : 'd', regno);
1945
1946 if (*c == '3')
1947 {
1948 int count = given & 0xff;
1949
1950 if (single == 0)
1951 count >>= 1;
1952
1953 if (--count)
1954 {
1955 func (stream, "-%c%d",
1956 single ? 's' : 'd',
1957 regno + count);
1958 }
1959
1960 func (stream, "}");
1961 }
1962 else if (*c == '4')
1963 func (stream, ", %c%d}", single ? 's' : 'd',
1964 regno + 1);
1965 }
1966 break;
1967
1968 case 'L':
1969 switch (given & 0x00400100)
1970 {
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;
1977 }
1978 break;
1979
1980 case 'Z':
1981 {
1982 int value;
1983 /* given (20, 23) | given (0, 3) */
1984 value = ((given >> 16) & 0xf0) | (given & 0xf);
1985 func (stream, "%d", value);
1986 }
1987 break;
1988
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. */
1993 {
1994 int offset = given & 0xff;
1995 int multiplier = (given & 0x00000100) ? 4 : 1;
1996
1997 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1998
1999 if (offset)
2000 {
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);
2010 }
2011 else
2012 func (stream, "]");
2013 }
2014 break;
2015
2016 case 'r':
2017 {
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];
2023
2024 switch (puw_bits)
2025 {
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;
2033
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;
2048
2049 default:
2050 func (stream, "INVALID");
2051 }
2052 }
2053 break;
2054
2055 case 'i':
2056 {
2057 long imm5;
2058 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2059 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2060 }
2061 break;
2062
2063 default:
2064 abort ();
2065 }
2066 }
2067 }
2068 else
2069 func (stream, "%c", *c);
2070 }
2071 return TRUE;
2072 }
2073 }
2074 return FALSE;
2075 }
2076
2077 static void
2078 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2079 {
2080 void *stream = info->stream;
2081 fprintf_ftype func = info->fprintf_func;
2082
2083 if (((given & 0x000f0000) == 0x000f0000)
2084 && ((given & 0x02000000) == 0))
2085 {
2086 int offset = given & 0xfff;
2087
2088 func (stream, "[pc");
2089
2090 if (given & 0x01000000)
2091 {
2092 if ((given & 0x00800000) == 0)
2093 offset = - offset;
2094
2095 /* Pre-indexed. */
2096 func (stream, ", #%d]", offset);
2097
2098 offset += pc + 8;
2099
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, "!");
2106 }
2107 else
2108 {
2109 /* Post indexed. */
2110 func (stream, "], #%d", offset);
2111
2112 /* ie ignore the offset. */
2113 offset = pc + 8;
2114 }
2115
2116 func (stream, "\t; ");
2117 info->print_address_func (offset, info);
2118 }
2119 else
2120 {
2121 func (stream, "[%s",
2122 arm_regnames[(given >> 16) & 0xf]);
2123 if ((given & 0x01000000) != 0)
2124 {
2125 if ((given & 0x02000000) == 0)
2126 {
2127 int offset = given & 0xfff;
2128 if (offset)
2129 func (stream, ", #%s%d",
2130 (((given & 0x00800000) == 0)
2131 ? "-" : ""), offset);
2132 }
2133 else
2134 {
2135 func (stream, ", %s",
2136 (((given & 0x00800000) == 0)
2137 ? "-" : ""));
2138 arm_decode_shift (given, func, stream);
2139 }
2140
2141 func (stream, "]%s",
2142 ((given & 0x00200000) != 0) ? "!" : "");
2143 }
2144 else
2145 {
2146 if ((given & 0x02000000) == 0)
2147 {
2148 int offset = given & 0xfff;
2149 if (offset)
2150 func (stream, "], #%s%d",
2151 (((given & 0x00800000) == 0)
2152 ? "-" : ""), offset);
2153 else
2154 func (stream, "]");
2155 }
2156 else
2157 {
2158 func (stream, "], %s",
2159 (((given & 0x00800000) == 0)
2160 ? "-" : ""));
2161 arm_decode_shift (given, func, stream);
2162 }
2163 }
2164 }
2165 }
2166
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. */
2170
2171 static bfd_boolean
2172 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2173 {
2174 const struct opcode32 *insn;
2175 void *stream = info->stream;
2176 fprintf_ftype func = info->fprintf_func;
2177
2178 if (thumb)
2179 {
2180 if ((given & 0xef000000) == 0xef000000)
2181 {
2182 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2183 unsigned long bit28 = given & (1 << 28);
2184
2185 given &= 0x00ffffff;
2186 if (bit28)
2187 given |= 0xf3000000;
2188 else
2189 given |= 0xf2000000;
2190 }
2191 else if ((given & 0xff000000) == 0xf9000000)
2192 given ^= 0xf9000000 ^ 0xf4000000;
2193 else
2194 return FALSE;
2195 }
2196
2197 for (insn = neon_opcodes; insn->assembler; insn++)
2198 {
2199 if ((given & insn->mask) == insn->value)
2200 {
2201 const char *c;
2202
2203 for (c = insn->assembler; *c; c++)
2204 {
2205 if (*c == '%')
2206 {
2207 switch (*++c)
2208 {
2209 case '%':
2210 func (stream, "%%");
2211 break;
2212
2213 case 'c':
2214 if (thumb && ifthen_state)
2215 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2216 break;
2217
2218 case 'A':
2219 {
2220 static const unsigned char enc[16] =
2221 {
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
2233 };
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;
2242
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]);
2259 }
2260 break;
2261
2262 case 'B':
2263 {
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;
2274
2275 if (length > 1 && size > 0)
2276 stride = (idx_align & (1 << size)) ? 2 : 1;
2277
2278 switch (length)
2279 {
2280 case 1:
2281 {
2282 int amask = (1 << size) - 1;
2283 if ((idx_align & (1 << size)) != 0)
2284 return FALSE;
2285 if (size > 0)
2286 {
2287 if ((idx_align & amask) == amask)
2288 align = 8 << size;
2289 else if ((idx_align & amask) != 0)
2290 return FALSE;
2291 }
2292 }
2293 break;
2294
2295 case 2:
2296 if (size == 2 && (idx_align & 2) != 0)
2297 return FALSE;
2298 align = (idx_align & 1) ? 16 << size : 0;
2299 break;
2300
2301 case 3:
2302 if ((size == 2 && (idx_align & 3) != 0)
2303 || (idx_align & 1) != 0)
2304 return FALSE;
2305 break;
2306
2307 case 4:
2308 if (size == 2)
2309 {
2310 if ((idx_align & 3) == 3)
2311 return FALSE;
2312 align = (idx_align & 3) * 64;
2313 }
2314 else
2315 align = (idx_align & 1) ? 32 << size : 0;
2316 break;
2317
2318 default:
2319 abort ();
2320 }
2321
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]);
2334 }
2335 break;
2336
2337 case 'C':
2338 {
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;
2348
2349 if (stride && (n == 1))
2350 n++;
2351 else
2352 stride++;
2353
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)
2364 {
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);
2372 }
2373 func (stream, "]");
2374 if (rm == 0xd)
2375 func (stream, "!");
2376 else if (rm != 0xf)
2377 func (stream, ", %s", arm_regnames[rm]);
2378 }
2379 break;
2380
2381 case 'D':
2382 {
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;
2387
2388 func (stream, "d%d[%d]", reg, ix);
2389 }
2390 break;
2391
2392 case 'E':
2393 /* Neon encoded constant for mov, mvn, vorr, vbic */
2394 {
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;
2402
2403 bits |= ((given >> 24) & 1) << 7;
2404 bits |= ((given >> 16) & 7) << 4;
2405 bits |= ((given >> 0) & 15) << 0;
2406
2407 if (cmode < 8)
2408 {
2409 shift = (cmode >> 1) & 3;
2410 value = (unsigned long)bits << (8 * shift);
2411 size = 32;
2412 }
2413 else if (cmode < 12)
2414 {
2415 shift = (cmode >> 1) & 1;
2416 value = (unsigned long)bits << (8 * shift);
2417 size = 16;
2418 }
2419 else if (cmode < 14)
2420 {
2421 shift = (cmode & 1) + 1;
2422 value = (unsigned long)bits << (8 * shift);
2423 value |= (1ul << (8 * shift)) - 1;
2424 size = 32;
2425 }
2426 else if (cmode == 14)
2427 {
2428 if (op)
2429 {
2430 /* bit replication into bytes */
2431 int ix;
2432 unsigned long mask;
2433
2434 value = 0;
2435 hival = 0;
2436 for (ix = 7; ix >= 0; ix--)
2437 {
2438 mask = ((bits >> ix) & 1) ? 0xff : 0;
2439 if (ix <= 3)
2440 value = (value << 8) | mask;
2441 else
2442 hival = (hival << 8) | mask;
2443 }
2444 size = 64;
2445 }
2446 else
2447 {
2448 /* byte replication */
2449 value = (unsigned long)bits;
2450 size = 8;
2451 }
2452 }
2453 else if (!op)
2454 {
2455 /* floating point encoding */
2456 int tmp;
2457
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;
2464 }
2465 else
2466 {
2467 func (stream, "<illegal constant %.8x:%x:%x>",
2468 bits, cmode, op);
2469 size = 32;
2470 break;
2471 }
2472 switch (size)
2473 {
2474 case 8:
2475 func (stream, "#%ld\t; 0x%.2lx", value, value);
2476 break;
2477
2478 case 16:
2479 func (stream, "#%ld\t; 0x%.4lx", value, value);
2480 break;
2481
2482 case 32:
2483 if (isfloat)
2484 {
2485 unsigned char valbytes[4];
2486 double fvalue;
2487
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;
2494
2495 floatformat_to_double
2496 (&floatformat_ieee_single_little, valbytes,
2497 &fvalue);
2498
2499 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2500 value);
2501 }
2502 else
2503 func (stream, "#%ld\t; 0x%.8lx",
2504 (long) ((value & 0x80000000)
2505 ? value | ~0xffffffffl : value), value);
2506 break;
2507
2508 case 64:
2509 func (stream, "#0x%.8lx%.8lx", hival, value);
2510 break;
2511
2512 default:
2513 abort ();
2514 }
2515 }
2516 break;
2517
2518 case 'F':
2519 {
2520 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2521 int num = (given >> 8) & 0x3;
2522
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);
2529 }
2530 break;
2531
2532
2533 case '0': case '1': case '2': case '3': case '4':
2534 case '5': case '6': case '7': case '8': case '9':
2535 {
2536 int width;
2537 unsigned long value;
2538
2539 c = arm_decode_bitfield (c, given, &value, &width);
2540
2541 switch (*c)
2542 {
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;
2552
2553 case 'S':
2554 case 'T':
2555 case 'U':
2556 /* various width encodings */
2557 {
2558 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2559 int limit;
2560 unsigned low, high;
2561
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;
2571
2572 if (value < low || value > high)
2573 func (stream, "<illegal width %d>", base << value);
2574 else
2575 func (stream, "%d", base << value);
2576 }
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':
2586 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;
2592
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 ();
2609 }
2610 break;
2611
2612 default:
2613 abort ();
2614 }
2615 }
2616 }
2617 else
2618 func (stream, "%c", *c);
2619 }
2620 return TRUE;
2621 }
2622 }
2623 return FALSE;
2624 }
2625
2626 /* Print one ARM instruction from PC on INFO->STREAM. */
2627
2628 static void
2629 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2630 {
2631 const struct opcode32 *insn;
2632 void *stream = info->stream;
2633 fprintf_ftype func = info->fprintf_func;
2634
2635 if (print_insn_coprocessor (pc, info, given, FALSE))
2636 return;
2637
2638 if (print_insn_neon (info, given, FALSE))
2639 return;
2640
2641 for (insn = arm_opcodes; insn->assembler; insn++)
2642 {
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;
2647
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)))
2655 {
2656 const char *c;
2657
2658 for (c = insn->assembler; *c; c++)
2659 {
2660 if (*c == '%')
2661 {
2662 switch (*++c)
2663 {
2664 case '%':
2665 func (stream, "%%");
2666 break;
2667
2668 case 'a':
2669 print_arm_address (pc, info, given);
2670 break;
2671
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;
2677
2678 case 's':
2679 if ((given & 0x004f0000) == 0x004f0000)
2680 {
2681 /* PC relative with immediate offset. */
2682 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2683
2684 if ((given & 0x00800000) == 0)
2685 offset = -offset;
2686
2687 func (stream, "[pc, #%d]\t; ", offset);
2688 info->print_address_func (offset + pc + 8, info);
2689 }
2690 else
2691 {
2692 func (stream, "[%s",
2693 arm_regnames[(given >> 16) & 0xf]);
2694 if ((given & 0x01000000) != 0)
2695 {
2696 /* Pre-indexed. */
2697 if ((given & 0x00400000) == 0x00400000)
2698 {
2699 /* Immediate. */
2700 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2701 if (offset)
2702 func (stream, ", #%s%d",
2703 (((given & 0x00800000) == 0)
2704 ? "-" : ""), offset);
2705 }
2706 else
2707 {
2708 /* Register. */
2709 func (stream, ", %s%s",
2710 (((given & 0x00800000) == 0)
2711 ? "-" : ""),
2712 arm_regnames[given & 0xf]);
2713 }
2714
2715 func (stream, "]%s",
2716 ((given & 0x00200000) != 0) ? "!" : "");
2717 }
2718 else
2719 {
2720 /* Post-indexed. */
2721 if ((given & 0x00400000) == 0x00400000)
2722 {
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, "]");
2731 }
2732 else
2733 {
2734 /* Register. */
2735 func (stream, "], %s%s",
2736 (((given & 0x00800000) == 0)
2737 ? "-" : ""),
2738 arm_regnames[given & 0xf]);
2739 }
2740 }
2741 }
2742 break;
2743
2744 case 'b':
2745 {
2746 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2747 info->print_address_func (disp*4 + pc + 8, info);
2748 }
2749 break;
2750
2751 case 'c':
2752 if (((given >> 28) & 0xf) != 0xe)
2753 func (stream, "%s",
2754 arm_conditional [(given >> 28) & 0xf]);
2755 break;
2756
2757 case 'm':
2758 {
2759 int started = 0;
2760 int reg;
2761
2762 func (stream, "{");
2763 for (reg = 0; reg < 16; reg++)
2764 if ((given & (1 << reg)) != 0)
2765 {
2766 if (started)
2767 func (stream, ", ");
2768 started = 1;
2769 func (stream, "%s", arm_regnames[reg]);
2770 }
2771 func (stream, "}");
2772 }
2773 break;
2774
2775 case 'o':
2776 if ((given & 0x02000000) != 0)
2777 {
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);
2783 }
2784 else
2785 arm_decode_shift (given, func, stream);
2786 break;
2787
2788 case 'p':
2789 if ((given & 0x0000f000) == 0x0000f000)
2790 func (stream, "p");
2791 break;
2792
2793 case 't':
2794 if ((given & 0x01200000) == 0x00200000)
2795 func (stream, "t");
2796 break;
2797
2798 case 'A':
2799 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2800
2801 if ((given & (1 << 24)) != 0)
2802 {
2803 int offset = given & 0xff;
2804
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, "]");
2812 }
2813 else
2814 {
2815 int offset = given & 0xff;
2816
2817 func (stream, "]");
2818
2819 if (given & (1 << 21))
2820 {
2821 if (offset)
2822 func (stream, ", #%s%d",
2823 ((given & 0x00800000) == 0 ? "-" : ""),
2824 offset * 4);
2825 }
2826 else
2827 func (stream, ", {%d}", offset);
2828 }
2829 break;
2830
2831 case 'B':
2832 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2833 {
2834 bfd_vma address;
2835 bfd_vma offset = 0;
2836
2837 if (given & 0x00800000)
2838 /* Is signed, hi bits should be ones. */
2839 offset = (-1) ^ 0x00ffffff;
2840
2841 /* Offset is (SignExtend(offset field)<<2). */
2842 offset += given & 0x00ffffff;
2843 offset <<= 2;
2844 address = offset + pc + 8;
2845
2846 if (given & 0x01000000)
2847 /* H bit allows addressing to 2-byte boundaries. */
2848 address += 2;
2849
2850 info->print_address_func (address, info);
2851 }
2852 break;
2853
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;
2865
2866 case 'U':
2867 switch (given & 0xf)
2868 {
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;
2876 }
2877 break;
2878
2879 case '0': case '1': case '2': case '3': case '4':
2880 case '5': case '6': case '7': case '8': case '9':
2881 {
2882 int width;
2883 unsigned long value;
2884
2885 c = arm_decode_bitfield (c, given, &value, &width);
2886
2887 switch (*c)
2888 {
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);
2903
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 ();
2930 }
2931 break;
2932
2933 case 'e':
2934 {
2935 int imm;
2936
2937 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2938 func (stream, "%d", imm);
2939 }
2940 break;
2941
2942 case 'E':
2943 /* LSB and WIDTH fields of BFI or BFC. The machine-
2944 language instruction encodes LSB and MSB. */
2945 {
2946 long msb = (given & 0x001f0000) >> 16;
2947 long lsb = (given & 0x00000f80) >> 7;
2948
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);
2954 }
2955 break;
2956
2957 case 'V':
2958 /* 16-bit unsigned immediate from a MOVT or MOVW
2959 instruction, encoded in bits 0:11 and 15:19. */
2960 {
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);
2965 }
2966 break;
2967
2968 default:
2969 abort ();
2970 }
2971 }
2972 }
2973 else
2974 func (stream, "%c", *c);
2975 }
2976 return;
2977 }
2978 }
2979 abort ();
2980 }
2981
2982 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2983
2984 static void
2985 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2986 {
2987 const struct opcode16 *insn;
2988 void *stream = info->stream;
2989 fprintf_ftype func = info->fprintf_func;
2990
2991 for (insn = thumb_opcodes; insn->assembler; insn++)
2992 if ((given & insn->mask) == insn->value)
2993 {
2994 const char *c = insn->assembler;
2995 for (; *c; c++)
2996 {
2997 int domaskpc = 0;
2998 int domasklr = 0;
2999
3000 if (*c != '%')
3001 {
3002 func (stream, "%c", *c);
3003 continue;
3004 }
3005
3006 switch (*++c)
3007 {
3008 case '%':
3009 func (stream, "%%");
3010 break;
3011
3012 case 'c':
3013 if (ifthen_state)
3014 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3015 break;
3016
3017 case 'C':
3018 if (ifthen_state)
3019 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3020 else
3021 func (stream, "s");
3022 break;
3023
3024 case 'I':
3025 {
3026 unsigned int tmp;
3027
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]);
3032 }
3033 break;
3034
3035 case 'x':
3036 if (ifthen_next_state)
3037 func (stream, "\t; unpredictable branch in IT block\n");
3038 break;
3039
3040 case 'X':
3041 if (ifthen_state)
3042 func (stream, "\t; unpredictable <IT:%s>",
3043 arm_conditional[IFTHEN_COND]);
3044 break;
3045
3046 case 'S':
3047 {
3048 long reg;
3049
3050 reg = (given >> 3) & 0x7;
3051 if (given & (1 << 6))
3052 reg += 8;
3053
3054 func (stream, "%s", arm_regnames[reg]);
3055 }
3056 break;
3057
3058 case 'D':
3059 {
3060 long reg;
3061
3062 reg = given & 0x7;
3063 if (given & (1 << 7))
3064 reg += 8;
3065
3066 func (stream, "%s", arm_regnames[reg]);
3067 }
3068 break;
3069
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':
3079 {
3080 int started = 0;
3081 int reg;
3082
3083 func (stream, "{");
3084
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)
3089 {
3090 if (started)
3091 func (stream, ", ");
3092 started = 1;
3093 func (stream, "%s", arm_regnames[reg]);
3094 }
3095
3096 if (domasklr)
3097 {
3098 if (started)
3099 func (stream, ", ");
3100 started = 1;
3101 func (stream, arm_regnames[14] /* "lr" */);
3102 }
3103
3104 if (domaskpc)
3105 {
3106 if (started)
3107 func (stream, ", ");
3108 func (stream, arm_regnames[15] /* "pc" */);
3109 }
3110
3111 func (stream, "}");
3112 }
3113 break;
3114
3115 case 'b':
3116 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3117 {
3118 bfd_vma address = (pc + 4
3119 + ((given & 0x00f8) >> 2)
3120 + ((given & 0x0200) >> 3));
3121 info->print_address_func (address, info);
3122 }
3123 break;
3124
3125 case 's':
3126 /* Right shift immediate -- bits 6..10; 1-31 print
3127 as themselves, 0 prints as 32. */
3128 {
3129 long imm = (given & 0x07c0) >> 6;
3130 if (imm == 0)
3131 imm = 32;
3132 func (stream, "#%ld", imm);
3133 }
3134 break;
3135
3136 case '0': case '1': case '2': case '3': case '4':
3137 case '5': case '6': case '7': case '8': case '9':
3138 {
3139 int bitstart = *c++ - '0';
3140 int bitend = 0;
3141
3142 while (*c >= '0' && *c <= '9')
3143 bitstart = (bitstart * 10) + *c++ - '0';
3144
3145 switch (*c)
3146 {
3147 case '-':
3148 {
3149 long reg;
3150
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)
3159 {
3160 case 'r':
3161 func (stream, "%s", arm_regnames[reg]);
3162 break;
3163
3164 case 'd':
3165 func (stream, "%ld", reg);
3166 break;
3167
3168 case 'H':
3169 func (stream, "%ld", reg << 1);
3170 break;
3171
3172 case 'W':
3173 func (stream, "%ld", reg << 2);
3174 break;
3175
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;
3183
3184 case 'x':
3185 func (stream, "0x%04lx", reg);
3186 break;
3187
3188 case 'B':
3189 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3190 info->print_address_func (reg * 2 + pc + 4, info);
3191 break;
3192
3193 case 'c':
3194 func (stream, "%s", arm_conditional [reg]);
3195 break;
3196
3197 default:
3198 abort ();
3199 }
3200 }
3201 break;
3202
3203 case '\'':
3204 c++;
3205 if ((given & (1 << bitstart)) != 0)
3206 func (stream, "%c", *c);
3207 break;
3208
3209 case '?':
3210 ++c;
3211 if ((given & (1 << bitstart)) != 0)
3212 func (stream, "%c", *c++);
3213 else
3214 func (stream, "%c", *++c);
3215 break;
3216
3217 default:
3218 abort ();
3219 }
3220 }
3221 break;
3222
3223 default:
3224 abort ();
3225 }
3226 }
3227 return;
3228 }
3229
3230 /* No match. */
3231 abort ();
3232 }
3233
3234 /* Return the name of an V7M special register. */
3235 static const char *
3236 psr_name (int regno)
3237 {
3238 switch (regno)
3239 {
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>";
3255 }
3256 }
3257
3258 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3259
3260 static void
3261 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3262 {
3263 const struct opcode32 *insn;
3264 void *stream = info->stream;
3265 fprintf_ftype func = info->fprintf_func;
3266
3267 if (print_insn_coprocessor (pc, info, given, TRUE))
3268 return;
3269
3270 if (print_insn_neon (info, given, TRUE))
3271 return;
3272
3273 for (insn = thumb32_opcodes; insn->assembler; insn++)
3274 if ((given & insn->mask) == insn->value)
3275 {
3276 const char *c = insn->assembler;
3277 for (; *c; c++)
3278 {
3279 if (*c != '%')
3280 {
3281 func (stream, "%c", *c);
3282 continue;
3283 }
3284
3285 switch (*++c)
3286 {
3287 case '%':
3288 func (stream, "%%");
3289 break;
3290
3291 case 'c':
3292 if (ifthen_state)
3293 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3294 break;
3295
3296 case 'x':
3297 if (ifthen_next_state)
3298 func (stream, "\t; unpredictable branch in IT block\n");
3299 break;
3300
3301 case 'X':
3302 if (ifthen_state)
3303 func (stream, "\t; unpredictable <IT:%s>",
3304 arm_conditional[IFTHEN_COND]);
3305 break;
3306
3307 case 'I':
3308 {
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);
3314 }
3315 break;
3316
3317 case 'M':
3318 {
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)
3326 {
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);
3335 }
3336 func (stream, "#%u\t; 0x%x", imm, imm);
3337 }
3338 break;
3339
3340 case 'J':
3341 {
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);
3348 }
3349 break;
3350
3351 case 'K':
3352 {
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);
3358 }
3359 break;
3360
3361 case 'S':
3362 {
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;
3368
3369 func (stream, "%s", arm_regnames[reg]);
3370 switch (stp)
3371 {
3372 case 0:
3373 if (imm > 0)
3374 func (stream, ", lsl #%u", imm);
3375 break;
3376
3377 case 1:
3378 if (imm == 0)
3379 imm = 32;
3380 func (stream, ", lsr #%u", imm);
3381 break;
3382
3383 case 2:
3384 if (imm == 0)
3385 imm = 32;
3386 func (stream, ", asr #%u", imm);
3387 break;
3388
3389 case 3:
3390 if (imm == 0)
3391 func (stream, ", rrx");
3392 else
3393 func (stream, ", ror #%u", imm);
3394 }
3395 }
3396 break;
3397
3398 case 'a':
3399 {
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;
3407
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 */
3414 {
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;
3422 }
3423 else switch (op)
3424 {
3425 case 0xE: /* 8-bit positive immediate offset */
3426 offset = i8;
3427 break;
3428
3429 case 0xC: /* 8-bit negative immediate offset */
3430 offset = -i8;
3431 break;
3432
3433 case 0xF: /* 8-bit + preindex with wb */
3434 offset = i8;
3435 writeback = TRUE;
3436 break;
3437
3438 case 0xD: /* 8-bit - preindex with wb */
3439 offset = -i8;
3440 writeback = TRUE;
3441 break;
3442
3443 case 0xB: /* 8-bit + postindex */
3444 offset = i8;
3445 postind = TRUE;
3446 break;
3447
3448 case 0x9: /* 8-bit - postindex */
3449 offset = -i8;
3450 postind = TRUE;
3451 break;
3452
3453 default:
3454 func (stream, ", <undefined>]");
3455 goto skip;
3456 }
3457
3458 if (postind)
3459 func (stream, "], #%d", offset);
3460 else
3461 {
3462 if (offset)
3463 func (stream, ", #%d", offset);
3464 func (stream, writeback ? "]!" : "]");
3465 }
3466
3467 if (Rn == 15)
3468 {
3469 func (stream, "\t; ");
3470 info->print_address_func (((pc + 4) & ~3) + offset, info);
3471 }
3472 }
3473 skip:
3474 break;
3475
3476 case 'A':
3477 {
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);
3483
3484 func (stream, "[%s", arm_regnames[Rn]);
3485 if (P)
3486 {
3487 if (off || !U)
3488 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3489 func (stream, "]");
3490 if (W)
3491 func (stream, "!");
3492 }
3493 else
3494 {
3495 func (stream, "], ");
3496 if (W)
3497 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3498 else
3499 func (stream, "{%u}", off);
3500 }
3501 }
3502 break;
3503
3504 case 'w':
3505 {
3506 unsigned int Sbit = (given & 0x01000000) >> 24;
3507 unsigned int type = (given & 0x00600000) >> 21;
3508 switch (type)
3509 {
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;
3519 }
3520 }
3521 break;
3522
3523 case 'm':
3524 {
3525 int started = 0;
3526 int reg;
3527
3528 func (stream, "{");
3529 for (reg = 0; reg < 16; reg++)
3530 if ((given & (1 << reg)) != 0)
3531 {
3532 if (started)
3533 func (stream, ", ");
3534 started = 1;
3535 func (stream, "%s", arm_regnames[reg]);
3536 }
3537 func (stream, "}");
3538 }
3539 break;
3540
3541 case 'E':
3542 {
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);
3548 }
3549 break;
3550
3551 case 'F':
3552 {
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);
3558 }
3559 break;
3560
3561 case 'b':
3562 {
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;
3567
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);
3574
3575 info->print_address_func (pc + 4 + offset, info);
3576 }
3577 break;
3578
3579 case 'B':
3580 {
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;
3585
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;
3593
3594 /* BLX target addresses are always word aligned. */
3595 if ((given & 0x00001000u) == 0)
3596 offset &= ~2u;
3597
3598 info->print_address_func (offset, info);
3599 }
3600 break;
3601
3602 case 's':
3603 {
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 */
3612 }
3613 break;
3614
3615 case 'R':
3616 {
3617 unsigned int rot = (given & 0x00000030) >> 4;
3618 if (rot)
3619 func (stream, ", ror #%u", rot * 8);
3620 }
3621 break;
3622
3623 case 'U':
3624 switch (given & 0xf)
3625 {
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;
3633 }
3634 break;
3635
3636 case 'C':
3637 if ((given & 0xff) == 0)
3638 {
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");
3648 }
3649 else
3650 {
3651 func (stream, psr_name (given & 0xff));
3652 }
3653 break;
3654
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;
3661
3662 case '0': case '1': case '2': case '3': case '4':
3663 case '5': case '6': case '7': case '8': case '9':
3664 {
3665 int width;
3666 unsigned long val;
3667
3668 c = arm_decode_bitfield (c, given, &val, &width);
3669
3670 switch (*c)
3671 {
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;
3675
3676 case 'c':
3677 func (stream, "%s", arm_conditional[val]);
3678 break;
3679
3680 case '\'':
3681 c++;
3682 if (val == ((1ul << width) - 1))
3683 func (stream, "%c", *c);
3684 break;
3685
3686 case '`':
3687 c++;
3688 if (val == 0)
3689 func (stream, "%c", *c);
3690 break;
3691
3692 case '?':
3693 func (stream, "%c", c[(1 << width) - (int)val]);
3694 c += 1 << width;
3695 break;
3696
3697 default:
3698 abort ();
3699 }
3700 }
3701 break;
3702
3703 default:
3704 abort ();
3705 }
3706 }
3707 return;
3708 }
3709
3710 /* No match. */
3711 abort ();
3712 }
3713
3714 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3715 being displayed in symbol relative addresses. */
3716
3717 bfd_boolean
3718 arm_symbol_is_valid (asymbol * sym,
3719 struct disassemble_info * info ATTRIBUTE_UNUSED)
3720 {
3721 const char * name;
3722
3723 if (sym == NULL)
3724 return FALSE;
3725
3726 name = bfd_asymbol_name (sym);
3727
3728 return (name && *name != '$');
3729 }
3730
3731 /* Parse an individual disassembler option. */
3732
3733 void
3734 parse_arm_disassembler_option (char *option)
3735 {
3736 if (option == NULL)
3737 return;
3738
3739 if (CONST_STRNEQ (option, "reg-names-"))
3740 {
3741 int i;
3742
3743 option += 10;
3744
3745 for (i = NUM_ARM_REGNAMES; i--;)
3746 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3747 {
3748 regname_selected = i;
3749 break;
3750 }
3751
3752 if (i < 0)
3753 /* XXX - should break 'option' at following delimiter. */
3754 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3755 }
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);
3763
3764 return;
3765 }
3766
3767 /* Parse the string of disassembler options, spliting it at whitespaces
3768 or commas. (Whitespace separators supported for backwards compatibility). */
3769
3770 static void
3771 parse_disassembler_options (char *options)
3772 {
3773 if (options == NULL)
3774 return;
3775
3776 while (*options)
3777 {
3778 parse_arm_disassembler_option (options);
3779
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;
3786 }
3787 }
3788
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)
3794 {
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;
3804
3805 ifthen_address = pc;
3806 ifthen_state = 0;
3807
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 (;;)
3816 {
3817 if (addr == 0 || info->symbol_at_address_func(addr, info))
3818 {
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;
3823
3824 return;
3825 }
3826 addr -= 2;
3827 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3828 if (status)
3829 return;
3830
3831 if (little)
3832 insn = (b[0]) | (b[1] << 8);
3833 else
3834 insn = (b[1]) | (b[0] << 8);
3835 if (seen_it)
3836 {
3837 if ((insn & 0xf800) < 0xe800)
3838 {
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;
3845 }
3846 }
3847 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3848 {
3849 /* This could be an IT instruction. */
3850 seen_it = insn;
3851 it_count = count >> 1;
3852 }
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;
3860 }
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;
3865 }
3866
3867 /* Try to infer the code type (Arm or Thumb) from a symbol.
3868 Returns nonzero if is_thumb was set. */
3869
3870 static int
3871 get_sym_code_type (struct disassemble_info *info, int n, int *is_thumb)
3872 {
3873 elf_symbol_type *es;
3874 unsigned int type;
3875 const char *name;
3876
3877 es = *(elf_symbol_type **)(info->symbols);
3878 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3879
3880 /* If the symbol has function type then use that. */
3881 if (type == STT_FUNC || type == STT_ARM_TFUNC)
3882 {
3883 *is_thumb = (type == STT_ARM_TFUNC);
3884 return TRUE;
3885 }
3886
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] == '.'))
3891 {
3892 *is_thumb = (name[1] == 't');
3893 return TRUE;
3894 }
3895
3896 return FALSE;
3897 }
3898
3899 /* NOTE: There are no checks in these routines that
3900 the relevant number of data bytes exist. */
3901
3902 static int
3903 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3904 {
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);
3911
3912 if (info->disassembler_options)
3913 {
3914 parse_disassembler_options (info->disassembler_options);
3915
3916 /* To avoid repeated parsing of these options, we remove them here. */
3917 info->disassembler_options = NULL;
3918 }
3919
3920 is_thumb = force_thumb;
3921
3922 if (!is_thumb && info->symbols != NULL)
3923 {
3924 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
3925 {
3926 coff_symbol_type * cs;
3927
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);
3934 }
3935 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
3936 {
3937 bfd_vma addr;
3938 int n;
3939 int last_sym;
3940 bfd_boolean found;
3941
3942 if (info->symtab)
3943 {
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;
3953
3954 /* Scan up to the location being disassembled. */
3955 for (; n < info->symtab_size; n++)
3956 {
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;
3962 }
3963
3964 last_sym = n;
3965 if (!found)
3966 {
3967 if (last_mapping_sym == -1)
3968 last_mapping_sym = 0;
3969 else
3970 found = TRUE;
3971
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--)
3975 {
3976 if (get_sym_code_type (info, n, &is_thumb))
3977 {
3978 found = TRUE;
3979 break;
3980 }
3981 }
3982 }
3983
3984 last_mapping_sym = last_sym;
3985 last_is_thumb = is_thumb;
3986 }
3987 else
3988 found = FALSE;
3989
3990 /* If no mapping symbol has been found then fall back to the type
3991 of the function symbol. */
3992 if (!found)
3993 {
3994 elf_symbol_type * es;
3995 unsigned int type;
3996
3997 es = *(elf_symbol_type **)(info->symbols);
3998 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3999
4000 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4001 }
4002 }
4003 }
4004
4005 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4006 info->bytes_per_line = 4;
4007
4008 if (!is_thumb)
4009 {
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;
4015
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);
4021 }
4022 else
4023 {
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;
4031
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);
4037
4038 if (!status)
4039 {
4040 /* These bit patterns signal a four-byte Thumb
4041 instruction. */
4042 if ((given & 0xF800) == 0xF800
4043 || (given & 0xF800) == 0xF000
4044 || (given & 0xF800) == 0xE800)
4045 {
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);
4051
4052 printer = print_insn_thumb32;
4053 size = 4;
4054 }
4055 }
4056
4057 if (ifthen_address != pc)
4058 find_ifthen_state(pc, info, little);
4059
4060 if (ifthen_state)
4061 {
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);
4067 }
4068 }
4069
4070 if (status)
4071 {
4072 info->memory_error_func (status, pc, info);
4073 return -1;
4074 }
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;
4082
4083 printer (pc, info, given);
4084
4085 if (is_thumb)
4086 {
4087 ifthen_state = ifthen_next_state;
4088 ifthen_address += size;
4089 }
4090 return size;
4091 }
4092
4093 int
4094 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4095 {
4096 return print_insn (pc, info, FALSE);
4097 }
4098
4099 int
4100 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4101 {
4102 return print_insn (pc, info, TRUE);
4103 }
4104
4105 void
4106 print_arm_disassembler_options (FILE *stream)
4107 {
4108 int i;
4109
4110 fprintf (stream, _("\n\
4111 The following ARM specific disassembler options are supported for use with\n\
4112 the -M switch:\n"));
4113
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);
4119
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");
4122 }
This page took 0.22767 seconds and 5 git commands to generate.