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