bfd/
[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]%21'!"},
1407 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1408 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1409 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1410 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1411 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1412
1413 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1414 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1415 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1416 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1417 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1418
1419 /* These have been 32-bit since the invention of Thumb. */
1420 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1421 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1422
1423 /* Fallback. */
1424 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1425 {0, 0, 0, 0}
1426 };
1427
1428 static const char *const arm_conditional[] =
1429 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1430 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1431
1432 static const char *const arm_fp_const[] =
1433 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1434
1435 static const char *const arm_shift[] =
1436 {"lsl", "lsr", "asr", "ror"};
1437
1438 typedef struct
1439 {
1440 const char *name;
1441 const char *description;
1442 const char *reg_names[16];
1443 }
1444 arm_regname;
1445
1446 static const arm_regname regnames[] =
1447 {
1448 { "raw" , "Select raw register names",
1449 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1450 { "gcc", "Select register names used by GCC",
1451 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1452 { "std", "Select register names used in ARM's ISA documentation",
1453 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1454 { "apcs", "Select register names used in the APCS",
1455 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1456 { "atpcs", "Select register names used in the ATPCS",
1457 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1458 { "special-atpcs", "Select special register names used in the ATPCS",
1459 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1460 };
1461
1462 static const char *const iwmmxt_wwnames[] =
1463 {"b", "h", "w", "d"};
1464
1465 static const char *const iwmmxt_wwssnames[] =
1466 {"b", "bus", "bc", "bss",
1467 "h", "hus", "hc", "hss",
1468 "w", "wus", "wc", "wss",
1469 "d", "dus", "dc", "dss"
1470 };
1471
1472 static const char *const iwmmxt_regnames[] =
1473 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1474 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1475 };
1476
1477 static const char *const iwmmxt_cregnames[] =
1478 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1479 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1480 };
1481
1482 /* Default to GCC register name set. */
1483 static unsigned int regname_selected = 1;
1484
1485 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1486 #define arm_regnames regnames[regname_selected].reg_names
1487
1488 static bfd_boolean force_thumb = FALSE;
1489
1490 /* Current IT instruction state. This contains the same state as the IT
1491 bits in the CPSR. */
1492 static unsigned int ifthen_state;
1493 /* IT state for the next instruction. */
1494 static unsigned int ifthen_next_state;
1495 /* The address of the insn for which the IT state is valid. */
1496 static bfd_vma ifthen_address;
1497 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1498
1499 /* Cached mapping symbol state. */
1500 enum map_type {
1501 MAP_ARM,
1502 MAP_THUMB,
1503 MAP_DATA
1504 };
1505
1506 enum map_type last_type;
1507 int last_mapping_sym = -1;
1508 bfd_vma last_mapping_addr = 0;
1509
1510 \f
1511 /* Functions. */
1512 int
1513 get_arm_regname_num_options (void)
1514 {
1515 return NUM_ARM_REGNAMES;
1516 }
1517
1518 int
1519 set_arm_regname_option (int option)
1520 {
1521 int old = regname_selected;
1522 regname_selected = option;
1523 return old;
1524 }
1525
1526 int
1527 get_arm_regnames (int option, const char **setname, const char **setdescription,
1528 const char *const **register_names)
1529 {
1530 *setname = regnames[option].name;
1531 *setdescription = regnames[option].description;
1532 *register_names = regnames[option].reg_names;
1533 return 16;
1534 }
1535
1536 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1537 Returns pointer to following character of the format string and
1538 fills in *VALUEP and *WIDTHP with the extracted value and number of
1539 bits extracted. WIDTHP can be NULL. */
1540
1541 static const char *
1542 arm_decode_bitfield (const char *ptr, unsigned long insn,
1543 unsigned long *valuep, int *widthp)
1544 {
1545 unsigned long value = 0;
1546 int width = 0;
1547
1548 do
1549 {
1550 int start, end;
1551 int bits;
1552
1553 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1554 start = start * 10 + *ptr - '0';
1555 if (*ptr == '-')
1556 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1557 end = end * 10 + *ptr - '0';
1558 else
1559 end = start;
1560 bits = end - start;
1561 if (bits < 0)
1562 abort ();
1563 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1564 width += bits + 1;
1565 }
1566 while (*ptr++ == ',');
1567 *valuep = value;
1568 if (widthp)
1569 *widthp = width;
1570 return ptr - 1;
1571 }
1572
1573 static void
1574 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1575 int print_shift)
1576 {
1577 func (stream, "%s", arm_regnames[given & 0xf]);
1578
1579 if ((given & 0xff0) != 0)
1580 {
1581 if ((given & 0x10) == 0)
1582 {
1583 int amount = (given & 0xf80) >> 7;
1584 int shift = (given & 0x60) >> 5;
1585
1586 if (amount == 0)
1587 {
1588 if (shift == 3)
1589 {
1590 func (stream, ", rrx");
1591 return;
1592 }
1593
1594 amount = 32;
1595 }
1596
1597 if (print_shift)
1598 func (stream, ", %s #%d", arm_shift[shift], amount);
1599 else
1600 func (stream, ", #%d", amount);
1601 }
1602 else if (print_shift)
1603 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1604 arm_regnames[(given & 0xf00) >> 8]);
1605 else
1606 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1607 }
1608 }
1609
1610 /* Print one coprocessor instruction on INFO->STREAM.
1611 Return TRUE if the instuction matched, FALSE if this is not a
1612 recognised coprocessor instruction. */
1613
1614 static bfd_boolean
1615 print_insn_coprocessor (bfd_vma pc, struct disassemble_info *info, long given,
1616 bfd_boolean thumb)
1617 {
1618 const struct opcode32 *insn;
1619 void *stream = info->stream;
1620 fprintf_ftype func = info->fprintf_func;
1621 unsigned long mask;
1622 unsigned long value;
1623 int cond;
1624
1625 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1626 {
1627 if (insn->value == FIRST_IWMMXT_INSN
1628 && info->mach != bfd_mach_arm_XScale
1629 && info->mach != bfd_mach_arm_iWMMXt
1630 && info->mach != bfd_mach_arm_iWMMXt2)
1631 insn = insn + IWMMXT_INSN_COUNT;
1632
1633 mask = insn->mask;
1634 value = insn->value;
1635 if (thumb)
1636 {
1637 /* The high 4 bits are 0xe for Arm conditional instructions, and
1638 0xe for arm unconditional instructions. The rest of the
1639 encoding is the same. */
1640 mask |= 0xf0000000;
1641 value |= 0xe0000000;
1642 if (ifthen_state)
1643 cond = IFTHEN_COND;
1644 else
1645 cond = 16;
1646 }
1647 else
1648 {
1649 /* Only match unconditional instuctions against unconditional
1650 patterns. */
1651 if ((given & 0xf0000000) == 0xf0000000)
1652 {
1653 mask |= 0xf0000000;
1654 cond = 16;
1655 }
1656 else
1657 {
1658 cond = (given >> 28) & 0xf;
1659 if (cond == 0xe)
1660 cond = 16;
1661 }
1662 }
1663 if ((given & mask) == value)
1664 {
1665 const char *c;
1666
1667 for (c = insn->assembler; *c; c++)
1668 {
1669 if (*c == '%')
1670 {
1671 switch (*++c)
1672 {
1673 case '%':
1674 func (stream, "%%");
1675 break;
1676
1677 case 'A':
1678 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1679
1680 if ((given & (1 << 24)) != 0)
1681 {
1682 int offset = given & 0xff;
1683
1684 if (offset)
1685 func (stream, ", #%s%d]%s",
1686 ((given & 0x00800000) == 0 ? "-" : ""),
1687 offset * 4,
1688 ((given & 0x00200000) != 0 ? "!" : ""));
1689 else
1690 func (stream, "]");
1691 }
1692 else
1693 {
1694 int offset = given & 0xff;
1695
1696 func (stream, "]");
1697
1698 if (given & (1 << 21))
1699 {
1700 if (offset)
1701 func (stream, ", #%s%d",
1702 ((given & 0x00800000) == 0 ? "-" : ""),
1703 offset * 4);
1704 }
1705 else
1706 func (stream, ", {%d}", offset);
1707 }
1708 break;
1709
1710 case 'B':
1711 {
1712 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1713 int offset = (given >> 1) & 0x3f;
1714
1715 if (offset == 1)
1716 func (stream, "{d%d}", regno);
1717 else if (regno + offset > 32)
1718 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1719 else
1720 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1721 }
1722 break;
1723
1724 case 'C':
1725 {
1726 int rn = (given >> 16) & 0xf;
1727 int offset = (given & 0xff) * 4;
1728 int add = (given >> 23) & 1;
1729
1730 func (stream, "[%s", arm_regnames[rn]);
1731
1732 if (offset)
1733 {
1734 if (!add)
1735 offset = -offset;
1736 func (stream, ", #%d", offset);
1737 }
1738 func (stream, "]");
1739 if (rn == 15)
1740 {
1741 func (stream, "\t; ");
1742 /* FIXME: Unsure if info->bytes_per_chunk is the
1743 right thing to use here. */
1744 info->print_address_func (offset + pc
1745 + info->bytes_per_chunk * 2, info);
1746 }
1747 }
1748 break;
1749
1750 case 'c':
1751 func (stream, "%s", arm_conditional[cond]);
1752 break;
1753
1754 case 'I':
1755 /* Print a Cirrus/DSP shift immediate. */
1756 /* Immediates are 7bit signed ints with bits 0..3 in
1757 bits 0..3 of opcode and bits 4..6 in bits 5..7
1758 of opcode. */
1759 {
1760 int imm;
1761
1762 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1763
1764 /* Is ``imm'' a negative number? */
1765 if (imm & 0x40)
1766 imm |= (-1 << 7);
1767
1768 func (stream, "%d", imm);
1769 }
1770
1771 break;
1772
1773 case 'F':
1774 switch (given & 0x00408000)
1775 {
1776 case 0:
1777 func (stream, "4");
1778 break;
1779 case 0x8000:
1780 func (stream, "1");
1781 break;
1782 case 0x00400000:
1783 func (stream, "2");
1784 break;
1785 default:
1786 func (stream, "3");
1787 }
1788 break;
1789
1790 case 'P':
1791 switch (given & 0x00080080)
1792 {
1793 case 0:
1794 func (stream, "s");
1795 break;
1796 case 0x80:
1797 func (stream, "d");
1798 break;
1799 case 0x00080000:
1800 func (stream, "e");
1801 break;
1802 default:
1803 func (stream, _("<illegal precision>"));
1804 break;
1805 }
1806 break;
1807 case 'Q':
1808 switch (given & 0x00408000)
1809 {
1810 case 0:
1811 func (stream, "s");
1812 break;
1813 case 0x8000:
1814 func (stream, "d");
1815 break;
1816 case 0x00400000:
1817 func (stream, "e");
1818 break;
1819 default:
1820 func (stream, "p");
1821 break;
1822 }
1823 break;
1824 case 'R':
1825 switch (given & 0x60)
1826 {
1827 case 0:
1828 break;
1829 case 0x20:
1830 func (stream, "p");
1831 break;
1832 case 0x40:
1833 func (stream, "m");
1834 break;
1835 default:
1836 func (stream, "z");
1837 break;
1838 }
1839 break;
1840
1841 case '0': case '1': case '2': case '3': case '4':
1842 case '5': case '6': case '7': case '8': case '9':
1843 {
1844 int width;
1845 unsigned long value;
1846
1847 c = arm_decode_bitfield (c, given, &value, &width);
1848
1849 switch (*c)
1850 {
1851 case 'r':
1852 func (stream, "%s", arm_regnames[value]);
1853 break;
1854 case 'D':
1855 func (stream, "d%ld", value);
1856 break;
1857 case 'Q':
1858 if (value & 1)
1859 func (stream, "<illegal reg q%ld.5>", value >> 1);
1860 else
1861 func (stream, "q%ld", value >> 1);
1862 break;
1863 case 'd':
1864 func (stream, "%ld", value);
1865 break;
1866 case 'k':
1867 {
1868 int from = (given & (1 << 7)) ? 32 : 16;
1869 func (stream, "%ld", from - value);
1870 }
1871 break;
1872
1873 case 'f':
1874 if (value > 7)
1875 func (stream, "#%s", arm_fp_const[value & 7]);
1876 else
1877 func (stream, "f%ld", value);
1878 break;
1879
1880 case 'w':
1881 if (width == 2)
1882 func (stream, "%s", iwmmxt_wwnames[value]);
1883 else
1884 func (stream, "%s", iwmmxt_wwssnames[value]);
1885 break;
1886
1887 case 'g':
1888 func (stream, "%s", iwmmxt_regnames[value]);
1889 break;
1890 case 'G':
1891 func (stream, "%s", iwmmxt_cregnames[value]);
1892 break;
1893
1894 case 'x':
1895 func (stream, "0x%lx", value);
1896 break;
1897
1898 case '`':
1899 c++;
1900 if (value == 0)
1901 func (stream, "%c", *c);
1902 break;
1903 case '\'':
1904 c++;
1905 if (value == ((1ul << width) - 1))
1906 func (stream, "%c", *c);
1907 break;
1908 case '?':
1909 func (stream, "%c", c[(1 << width) - (int)value]);
1910 c += 1 << width;
1911 break;
1912 default:
1913 abort ();
1914 }
1915 break;
1916
1917 case 'y':
1918 case 'z':
1919 {
1920 int single = *c++ == 'y';
1921 int regno;
1922
1923 switch (*c)
1924 {
1925 case '4': /* Sm pair */
1926 func (stream, "{");
1927 /* Fall through. */
1928 case '0': /* Sm, Dm */
1929 regno = given & 0x0000000f;
1930 if (single)
1931 {
1932 regno <<= 1;
1933 regno += (given >> 5) & 1;
1934 }
1935 else
1936 regno += ((given >> 5) & 1) << 4;
1937 break;
1938
1939 case '1': /* Sd, Dd */
1940 regno = (given >> 12) & 0x0000000f;
1941 if (single)
1942 {
1943 regno <<= 1;
1944 regno += (given >> 22) & 1;
1945 }
1946 else
1947 regno += ((given >> 22) & 1) << 4;
1948 break;
1949
1950 case '2': /* Sn, Dn */
1951 regno = (given >> 16) & 0x0000000f;
1952 if (single)
1953 {
1954 regno <<= 1;
1955 regno += (given >> 7) & 1;
1956 }
1957 else
1958 regno += ((given >> 7) & 1) << 4;
1959 break;
1960
1961 case '3': /* List */
1962 func (stream, "{");
1963 regno = (given >> 12) & 0x0000000f;
1964 if (single)
1965 {
1966 regno <<= 1;
1967 regno += (given >> 22) & 1;
1968 }
1969 else
1970 regno += ((given >> 22) & 1) << 4;
1971 break;
1972
1973 default:
1974 abort ();
1975 }
1976
1977 func (stream, "%c%d", single ? 's' : 'd', regno);
1978
1979 if (*c == '3')
1980 {
1981 int count = given & 0xff;
1982
1983 if (single == 0)
1984 count >>= 1;
1985
1986 if (--count)
1987 {
1988 func (stream, "-%c%d",
1989 single ? 's' : 'd',
1990 regno + count);
1991 }
1992
1993 func (stream, "}");
1994 }
1995 else if (*c == '4')
1996 func (stream, ", %c%d}", single ? 's' : 'd',
1997 regno + 1);
1998 }
1999 break;
2000
2001 case 'L':
2002 switch (given & 0x00400100)
2003 {
2004 case 0x00000000: func (stream, "b"); break;
2005 case 0x00400000: func (stream, "h"); break;
2006 case 0x00000100: func (stream, "w"); break;
2007 case 0x00400100: func (stream, "d"); break;
2008 default:
2009 break;
2010 }
2011 break;
2012
2013 case 'Z':
2014 {
2015 int value;
2016 /* given (20, 23) | given (0, 3) */
2017 value = ((given >> 16) & 0xf0) | (given & 0xf);
2018 func (stream, "%d", value);
2019 }
2020 break;
2021
2022 case 'l':
2023 /* This is like the 'A' operator, except that if
2024 the width field "M" is zero, then the offset is
2025 *not* multiplied by four. */
2026 {
2027 int offset = given & 0xff;
2028 int multiplier = (given & 0x00000100) ? 4 : 1;
2029
2030 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2031
2032 if (offset)
2033 {
2034 if ((given & 0x01000000) != 0)
2035 func (stream, ", #%s%d]%s",
2036 ((given & 0x00800000) == 0 ? "-" : ""),
2037 offset * multiplier,
2038 ((given & 0x00200000) != 0 ? "!" : ""));
2039 else
2040 func (stream, "], #%s%d",
2041 ((given & 0x00800000) == 0 ? "-" : ""),
2042 offset * multiplier);
2043 }
2044 else
2045 func (stream, "]");
2046 }
2047 break;
2048
2049 case 'r':
2050 {
2051 int imm4 = (given >> 4) & 0xf;
2052 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2053 int ubit = (given >> 23) & 1;
2054 const char *rm = arm_regnames [given & 0xf];
2055 const char *rn = arm_regnames [(given >> 16) & 0xf];
2056
2057 switch (puw_bits)
2058 {
2059 case 1:
2060 /* fall through */
2061 case 3:
2062 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2063 if (imm4)
2064 func (stream, ", lsl #%d", imm4);
2065 break;
2066
2067 case 4:
2068 /* fall through */
2069 case 5:
2070 /* fall through */
2071 case 6:
2072 /* fall through */
2073 case 7:
2074 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2075 if (imm4 > 0)
2076 func (stream, ", lsl #%d", imm4);
2077 func (stream, "]");
2078 if (puw_bits == 5 || puw_bits == 7)
2079 func (stream, "!");
2080 break;
2081
2082 default:
2083 func (stream, "INVALID");
2084 }
2085 }
2086 break;
2087
2088 case 'i':
2089 {
2090 long imm5;
2091 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2092 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2093 }
2094 break;
2095
2096 default:
2097 abort ();
2098 }
2099 }
2100 }
2101 else
2102 func (stream, "%c", *c);
2103 }
2104 return TRUE;
2105 }
2106 }
2107 return FALSE;
2108 }
2109
2110 static void
2111 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2112 {
2113 void *stream = info->stream;
2114 fprintf_ftype func = info->fprintf_func;
2115
2116 if (((given & 0x000f0000) == 0x000f0000)
2117 && ((given & 0x02000000) == 0))
2118 {
2119 int offset = given & 0xfff;
2120
2121 func (stream, "[pc");
2122
2123 if (given & 0x01000000)
2124 {
2125 if ((given & 0x00800000) == 0)
2126 offset = - offset;
2127
2128 /* Pre-indexed. */
2129 func (stream, ", #%d]", offset);
2130
2131 offset += pc + 8;
2132
2133 /* Cope with the possibility of write-back
2134 being used. Probably a very dangerous thing
2135 for the programmer to do, but who are we to
2136 argue ? */
2137 if (given & 0x00200000)
2138 func (stream, "!");
2139 }
2140 else
2141 {
2142 /* Post indexed. */
2143 func (stream, "], #%d", offset);
2144
2145 /* ie ignore the offset. */
2146 offset = pc + 8;
2147 }
2148
2149 func (stream, "\t; ");
2150 info->print_address_func (offset, info);
2151 }
2152 else
2153 {
2154 func (stream, "[%s",
2155 arm_regnames[(given >> 16) & 0xf]);
2156 if ((given & 0x01000000) != 0)
2157 {
2158 if ((given & 0x02000000) == 0)
2159 {
2160 int offset = given & 0xfff;
2161 if (offset)
2162 func (stream, ", #%s%d",
2163 (((given & 0x00800000) == 0)
2164 ? "-" : ""), offset);
2165 }
2166 else
2167 {
2168 func (stream, ", %s",
2169 (((given & 0x00800000) == 0)
2170 ? "-" : ""));
2171 arm_decode_shift (given, func, stream, 1);
2172 }
2173
2174 func (stream, "]%s",
2175 ((given & 0x00200000) != 0) ? "!" : "");
2176 }
2177 else
2178 {
2179 if ((given & 0x02000000) == 0)
2180 {
2181 int offset = given & 0xfff;
2182 if (offset)
2183 func (stream, "], #%s%d",
2184 (((given & 0x00800000) == 0)
2185 ? "-" : ""), offset);
2186 else
2187 func (stream, "]");
2188 }
2189 else
2190 {
2191 func (stream, "], %s",
2192 (((given & 0x00800000) == 0)
2193 ? "-" : ""));
2194 arm_decode_shift (given, func, stream, 1);
2195 }
2196 }
2197 }
2198 }
2199
2200 /* Print one neon instruction on INFO->STREAM.
2201 Return TRUE if the instuction matched, FALSE if this is not a
2202 recognised neon instruction. */
2203
2204 static bfd_boolean
2205 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2206 {
2207 const struct opcode32 *insn;
2208 void *stream = info->stream;
2209 fprintf_ftype func = info->fprintf_func;
2210
2211 if (thumb)
2212 {
2213 if ((given & 0xef000000) == 0xef000000)
2214 {
2215 /* move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2216 unsigned long bit28 = given & (1 << 28);
2217
2218 given &= 0x00ffffff;
2219 if (bit28)
2220 given |= 0xf3000000;
2221 else
2222 given |= 0xf2000000;
2223 }
2224 else if ((given & 0xff000000) == 0xf9000000)
2225 given ^= 0xf9000000 ^ 0xf4000000;
2226 else
2227 return FALSE;
2228 }
2229
2230 for (insn = neon_opcodes; insn->assembler; insn++)
2231 {
2232 if ((given & insn->mask) == insn->value)
2233 {
2234 const char *c;
2235
2236 for (c = insn->assembler; *c; c++)
2237 {
2238 if (*c == '%')
2239 {
2240 switch (*++c)
2241 {
2242 case '%':
2243 func (stream, "%%");
2244 break;
2245
2246 case 'c':
2247 if (thumb && ifthen_state)
2248 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2249 break;
2250
2251 case 'A':
2252 {
2253 static const unsigned char enc[16] =
2254 {
2255 0x4, 0x14, /* st4 0,1 */
2256 0x4, /* st1 2 */
2257 0x4, /* st2 3 */
2258 0x3, /* st3 4 */
2259 0x13, /* st3 5 */
2260 0x3, /* st1 6 */
2261 0x1, /* st1 7 */
2262 0x2, /* st2 8 */
2263 0x12, /* st2 9 */
2264 0x2, /* st1 10 */
2265 0, 0, 0, 0, 0
2266 };
2267 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2268 int rn = ((given >> 16) & 0xf);
2269 int rm = ((given >> 0) & 0xf);
2270 int align = ((given >> 4) & 0x3);
2271 int type = ((given >> 8) & 0xf);
2272 int n = enc[type] & 0xf;
2273 int stride = (enc[type] >> 4) + 1;
2274 int ix;
2275
2276 func (stream, "{");
2277 if (stride > 1)
2278 for (ix = 0; ix != n; ix++)
2279 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2280 else if (n == 1)
2281 func (stream, "d%d", rd);
2282 else
2283 func (stream, "d%d-d%d", rd, rd + n - 1);
2284 func (stream, "}, [%s", arm_regnames[rn]);
2285 if (align)
2286 func (stream, ", :%d", 32 << align);
2287 func (stream, "]");
2288 if (rm == 0xd)
2289 func (stream, "!");
2290 else if (rm != 0xf)
2291 func (stream, ", %s", arm_regnames[rm]);
2292 }
2293 break;
2294
2295 case 'B':
2296 {
2297 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2298 int rn = ((given >> 16) & 0xf);
2299 int rm = ((given >> 0) & 0xf);
2300 int idx_align = ((given >> 4) & 0xf);
2301 int align = 0;
2302 int size = ((given >> 10) & 0x3);
2303 int idx = idx_align >> (size + 1);
2304 int length = ((given >> 8) & 3) + 1;
2305 int stride = 1;
2306 int i;
2307
2308 if (length > 1 && size > 0)
2309 stride = (idx_align & (1 << size)) ? 2 : 1;
2310
2311 switch (length)
2312 {
2313 case 1:
2314 {
2315 int amask = (1 << size) - 1;
2316 if ((idx_align & (1 << size)) != 0)
2317 return FALSE;
2318 if (size > 0)
2319 {
2320 if ((idx_align & amask) == amask)
2321 align = 8 << size;
2322 else if ((idx_align & amask) != 0)
2323 return FALSE;
2324 }
2325 }
2326 break;
2327
2328 case 2:
2329 if (size == 2 && (idx_align & 2) != 0)
2330 return FALSE;
2331 align = (idx_align & 1) ? 16 << size : 0;
2332 break;
2333
2334 case 3:
2335 if ((size == 2 && (idx_align & 3) != 0)
2336 || (idx_align & 1) != 0)
2337 return FALSE;
2338 break;
2339
2340 case 4:
2341 if (size == 2)
2342 {
2343 if ((idx_align & 3) == 3)
2344 return FALSE;
2345 align = (idx_align & 3) * 64;
2346 }
2347 else
2348 align = (idx_align & 1) ? 32 << size : 0;
2349 break;
2350
2351 default:
2352 abort ();
2353 }
2354
2355 func (stream, "{");
2356 for (i = 0; i < length; i++)
2357 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2358 rd + i * stride, idx);
2359 func (stream, "}, [%s", arm_regnames[rn]);
2360 if (align)
2361 func (stream, ", :%d", align);
2362 func (stream, "]");
2363 if (rm == 0xd)
2364 func (stream, "!");
2365 else if (rm != 0xf)
2366 func (stream, ", %s", arm_regnames[rm]);
2367 }
2368 break;
2369
2370 case 'C':
2371 {
2372 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2373 int rn = ((given >> 16) & 0xf);
2374 int rm = ((given >> 0) & 0xf);
2375 int align = ((given >> 4) & 0x1);
2376 int size = ((given >> 6) & 0x3);
2377 int type = ((given >> 8) & 0x3);
2378 int n = type + 1;
2379 int stride = ((given >> 5) & 0x1);
2380 int ix;
2381
2382 if (stride && (n == 1))
2383 n++;
2384 else
2385 stride++;
2386
2387 func (stream, "{");
2388 if (stride > 1)
2389 for (ix = 0; ix != n; ix++)
2390 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2391 else if (n == 1)
2392 func (stream, "d%d[]", rd);
2393 else
2394 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2395 func (stream, "}, [%s", arm_regnames[rn]);
2396 if (align)
2397 {
2398 int align = (8 * (type + 1)) << size;
2399 if (type == 3)
2400 align = (size > 1) ? align >> 1 : align;
2401 if (type == 2 || (type == 0 && !size))
2402 func (stream, ", :<bad align %d>", align);
2403 else
2404 func (stream, ", :%d", align);
2405 }
2406 func (stream, "]");
2407 if (rm == 0xd)
2408 func (stream, "!");
2409 else if (rm != 0xf)
2410 func (stream, ", %s", arm_regnames[rm]);
2411 }
2412 break;
2413
2414 case 'D':
2415 {
2416 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2417 int size = (given >> 20) & 3;
2418 int reg = raw_reg & ((4 << size) - 1);
2419 int ix = raw_reg >> size >> 2;
2420
2421 func (stream, "d%d[%d]", reg, ix);
2422 }
2423 break;
2424
2425 case 'E':
2426 /* Neon encoded constant for mov, mvn, vorr, vbic */
2427 {
2428 int bits = 0;
2429 int cmode = (given >> 8) & 0xf;
2430 int op = (given >> 5) & 0x1;
2431 unsigned long value = 0, hival = 0;
2432 unsigned shift;
2433 int size = 0;
2434 int isfloat = 0;
2435
2436 bits |= ((given >> 24) & 1) << 7;
2437 bits |= ((given >> 16) & 7) << 4;
2438 bits |= ((given >> 0) & 15) << 0;
2439
2440 if (cmode < 8)
2441 {
2442 shift = (cmode >> 1) & 3;
2443 value = (unsigned long)bits << (8 * shift);
2444 size = 32;
2445 }
2446 else if (cmode < 12)
2447 {
2448 shift = (cmode >> 1) & 1;
2449 value = (unsigned long)bits << (8 * shift);
2450 size = 16;
2451 }
2452 else if (cmode < 14)
2453 {
2454 shift = (cmode & 1) + 1;
2455 value = (unsigned long)bits << (8 * shift);
2456 value |= (1ul << (8 * shift)) - 1;
2457 size = 32;
2458 }
2459 else if (cmode == 14)
2460 {
2461 if (op)
2462 {
2463 /* bit replication into bytes */
2464 int ix;
2465 unsigned long mask;
2466
2467 value = 0;
2468 hival = 0;
2469 for (ix = 7; ix >= 0; ix--)
2470 {
2471 mask = ((bits >> ix) & 1) ? 0xff : 0;
2472 if (ix <= 3)
2473 value = (value << 8) | mask;
2474 else
2475 hival = (hival << 8) | mask;
2476 }
2477 size = 64;
2478 }
2479 else
2480 {
2481 /* byte replication */
2482 value = (unsigned long)bits;
2483 size = 8;
2484 }
2485 }
2486 else if (!op)
2487 {
2488 /* floating point encoding */
2489 int tmp;
2490
2491 value = (unsigned long)(bits & 0x7f) << 19;
2492 value |= (unsigned long)(bits & 0x80) << 24;
2493 tmp = bits & 0x40 ? 0x3c : 0x40;
2494 value |= (unsigned long)tmp << 24;
2495 size = 32;
2496 isfloat = 1;
2497 }
2498 else
2499 {
2500 func (stream, "<illegal constant %.8x:%x:%x>",
2501 bits, cmode, op);
2502 size = 32;
2503 break;
2504 }
2505 switch (size)
2506 {
2507 case 8:
2508 func (stream, "#%ld\t; 0x%.2lx", value, value);
2509 break;
2510
2511 case 16:
2512 func (stream, "#%ld\t; 0x%.4lx", value, value);
2513 break;
2514
2515 case 32:
2516 if (isfloat)
2517 {
2518 unsigned char valbytes[4];
2519 double fvalue;
2520
2521 /* Do this a byte at a time so we don't have to
2522 worry about the host's endianness. */
2523 valbytes[0] = value & 0xff;
2524 valbytes[1] = (value >> 8) & 0xff;
2525 valbytes[2] = (value >> 16) & 0xff;
2526 valbytes[3] = (value >> 24) & 0xff;
2527
2528 floatformat_to_double
2529 (&floatformat_ieee_single_little, valbytes,
2530 &fvalue);
2531
2532 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2533 value);
2534 }
2535 else
2536 func (stream, "#%ld\t; 0x%.8lx",
2537 (long) ((value & 0x80000000)
2538 ? value | ~0xffffffffl : value), value);
2539 break;
2540
2541 case 64:
2542 func (stream, "#0x%.8lx%.8lx", hival, value);
2543 break;
2544
2545 default:
2546 abort ();
2547 }
2548 }
2549 break;
2550
2551 case 'F':
2552 {
2553 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2554 int num = (given >> 8) & 0x3;
2555
2556 if (!num)
2557 func (stream, "{d%d}", regno);
2558 else if (num + regno >= 32)
2559 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2560 else
2561 func (stream, "{d%d-d%d}", regno, regno + num);
2562 }
2563 break;
2564
2565
2566 case '0': case '1': case '2': case '3': case '4':
2567 case '5': case '6': case '7': case '8': case '9':
2568 {
2569 int width;
2570 unsigned long value;
2571
2572 c = arm_decode_bitfield (c, given, &value, &width);
2573
2574 switch (*c)
2575 {
2576 case 'r':
2577 func (stream, "%s", arm_regnames[value]);
2578 break;
2579 case 'd':
2580 func (stream, "%ld", value);
2581 break;
2582 case 'e':
2583 func (stream, "%ld", (1ul << width) - value);
2584 break;
2585
2586 case 'S':
2587 case 'T':
2588 case 'U':
2589 /* various width encodings */
2590 {
2591 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2592 int limit;
2593 unsigned low, high;
2594
2595 c++;
2596 if (*c >= '0' && *c <= '9')
2597 limit = *c - '0';
2598 else if (*c >= 'a' && *c <= 'f')
2599 limit = *c - 'a' + 10;
2600 else
2601 abort ();
2602 low = limit >> 2;
2603 high = limit & 3;
2604
2605 if (value < low || value > high)
2606 func (stream, "<illegal width %d>", base << value);
2607 else
2608 func (stream, "%d", base << value);
2609 }
2610 break;
2611 case 'R':
2612 if (given & (1 << 6))
2613 goto Q;
2614 /* FALLTHROUGH */
2615 case 'D':
2616 func (stream, "d%ld", value);
2617 break;
2618 case 'Q':
2619 Q:
2620 if (value & 1)
2621 func (stream, "<illegal reg q%ld.5>", value >> 1);
2622 else
2623 func (stream, "q%ld", value >> 1);
2624 break;
2625
2626 case '`':
2627 c++;
2628 if (value == 0)
2629 func (stream, "%c", *c);
2630 break;
2631 case '\'':
2632 c++;
2633 if (value == ((1ul << width) - 1))
2634 func (stream, "%c", *c);
2635 break;
2636 case '?':
2637 func (stream, "%c", c[(1 << width) - (int)value]);
2638 c += 1 << width;
2639 break;
2640 default:
2641 abort ();
2642 }
2643 break;
2644
2645 default:
2646 abort ();
2647 }
2648 }
2649 }
2650 else
2651 func (stream, "%c", *c);
2652 }
2653 return TRUE;
2654 }
2655 }
2656 return FALSE;
2657 }
2658
2659 /* Print one ARM instruction from PC on INFO->STREAM. */
2660
2661 static void
2662 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2663 {
2664 const struct opcode32 *insn;
2665 void *stream = info->stream;
2666 fprintf_ftype func = info->fprintf_func;
2667
2668 if (print_insn_coprocessor (pc, info, given, FALSE))
2669 return;
2670
2671 if (print_insn_neon (info, given, FALSE))
2672 return;
2673
2674 for (insn = arm_opcodes; insn->assembler; insn++)
2675 {
2676 if (insn->value == FIRST_IWMMXT_INSN
2677 && info->mach != bfd_mach_arm_XScale
2678 && info->mach != bfd_mach_arm_iWMMXt)
2679 insn = insn + IWMMXT_INSN_COUNT;
2680
2681 if ((given & insn->mask) == insn->value
2682 /* Special case: an instruction with all bits set in the condition field
2683 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2684 or by the catchall at the end of the table. */
2685 && ((given & 0xF0000000) != 0xF0000000
2686 || (insn->mask & 0xF0000000) == 0xF0000000
2687 || (insn->mask == 0 && insn->value == 0)))
2688 {
2689 const char *c;
2690
2691 for (c = insn->assembler; *c; c++)
2692 {
2693 if (*c == '%')
2694 {
2695 switch (*++c)
2696 {
2697 case '%':
2698 func (stream, "%%");
2699 break;
2700
2701 case 'a':
2702 print_arm_address (pc, info, given);
2703 break;
2704
2705 case 'P':
2706 /* Set P address bit and use normal address
2707 printing routine. */
2708 print_arm_address (pc, info, given | (1 << 24));
2709 break;
2710
2711 case 's':
2712 if ((given & 0x004f0000) == 0x004f0000)
2713 {
2714 /* PC relative with immediate offset. */
2715 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2716
2717 if ((given & 0x00800000) == 0)
2718 offset = -offset;
2719
2720 func (stream, "[pc, #%d]\t; ", offset);
2721 info->print_address_func (offset + pc + 8, info);
2722 }
2723 else
2724 {
2725 func (stream, "[%s",
2726 arm_regnames[(given >> 16) & 0xf]);
2727 if ((given & 0x01000000) != 0)
2728 {
2729 /* Pre-indexed. */
2730 if ((given & 0x00400000) == 0x00400000)
2731 {
2732 /* Immediate. */
2733 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2734 if (offset)
2735 func (stream, ", #%s%d",
2736 (((given & 0x00800000) == 0)
2737 ? "-" : ""), offset);
2738 }
2739 else
2740 {
2741 /* Register. */
2742 func (stream, ", %s%s",
2743 (((given & 0x00800000) == 0)
2744 ? "-" : ""),
2745 arm_regnames[given & 0xf]);
2746 }
2747
2748 func (stream, "]%s",
2749 ((given & 0x00200000) != 0) ? "!" : "");
2750 }
2751 else
2752 {
2753 /* Post-indexed. */
2754 if ((given & 0x00400000) == 0x00400000)
2755 {
2756 /* Immediate. */
2757 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2758 if (offset)
2759 func (stream, "], #%s%d",
2760 (((given & 0x00800000) == 0)
2761 ? "-" : ""), offset);
2762 else
2763 func (stream, "]");
2764 }
2765 else
2766 {
2767 /* Register. */
2768 func (stream, "], %s%s",
2769 (((given & 0x00800000) == 0)
2770 ? "-" : ""),
2771 arm_regnames[given & 0xf]);
2772 }
2773 }
2774 }
2775 break;
2776
2777 case 'b':
2778 {
2779 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2780 info->print_address_func (disp*4 + pc + 8, info);
2781 }
2782 break;
2783
2784 case 'c':
2785 if (((given >> 28) & 0xf) != 0xe)
2786 func (stream, "%s",
2787 arm_conditional [(given >> 28) & 0xf]);
2788 break;
2789
2790 case 'm':
2791 {
2792 int started = 0;
2793 int reg;
2794
2795 func (stream, "{");
2796 for (reg = 0; reg < 16; reg++)
2797 if ((given & (1 << reg)) != 0)
2798 {
2799 if (started)
2800 func (stream, ", ");
2801 started = 1;
2802 func (stream, "%s", arm_regnames[reg]);
2803 }
2804 func (stream, "}");
2805 }
2806 break;
2807
2808 case 'q':
2809 arm_decode_shift (given, func, stream, 0);
2810 break;
2811
2812 case 'o':
2813 if ((given & 0x02000000) != 0)
2814 {
2815 int rotate = (given & 0xf00) >> 7;
2816 int immed = (given & 0xff);
2817 immed = (((immed << (32 - rotate))
2818 | (immed >> rotate)) & 0xffffffff);
2819 func (stream, "#%d\t; 0x%x", immed, immed);
2820 }
2821 else
2822 arm_decode_shift (given, func, stream, 1);
2823 break;
2824
2825 case 'p':
2826 if ((given & 0x0000f000) == 0x0000f000)
2827 func (stream, "p");
2828 break;
2829
2830 case 't':
2831 if ((given & 0x01200000) == 0x00200000)
2832 func (stream, "t");
2833 break;
2834
2835 case 'A':
2836 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2837
2838 if ((given & (1 << 24)) != 0)
2839 {
2840 int offset = given & 0xff;
2841
2842 if (offset)
2843 func (stream, ", #%s%d]%s",
2844 ((given & 0x00800000) == 0 ? "-" : ""),
2845 offset * 4,
2846 ((given & 0x00200000) != 0 ? "!" : ""));
2847 else
2848 func (stream, "]");
2849 }
2850 else
2851 {
2852 int offset = given & 0xff;
2853
2854 func (stream, "]");
2855
2856 if (given & (1 << 21))
2857 {
2858 if (offset)
2859 func (stream, ", #%s%d",
2860 ((given & 0x00800000) == 0 ? "-" : ""),
2861 offset * 4);
2862 }
2863 else
2864 func (stream, ", {%d}", offset);
2865 }
2866 break;
2867
2868 case 'B':
2869 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2870 {
2871 bfd_vma address;
2872 bfd_vma offset = 0;
2873
2874 if (given & 0x00800000)
2875 /* Is signed, hi bits should be ones. */
2876 offset = (-1) ^ 0x00ffffff;
2877
2878 /* Offset is (SignExtend(offset field)<<2). */
2879 offset += given & 0x00ffffff;
2880 offset <<= 2;
2881 address = offset + pc + 8;
2882
2883 if (given & 0x01000000)
2884 /* H bit allows addressing to 2-byte boundaries. */
2885 address += 2;
2886
2887 info->print_address_func (address, info);
2888 }
2889 break;
2890
2891 case 'C':
2892 func (stream, "_");
2893 if (given & 0x80000)
2894 func (stream, "f");
2895 if (given & 0x40000)
2896 func (stream, "s");
2897 if (given & 0x20000)
2898 func (stream, "x");
2899 if (given & 0x10000)
2900 func (stream, "c");
2901 break;
2902
2903 case 'U':
2904 switch (given & 0xf)
2905 {
2906 case 0xf: func(stream, "sy"); break;
2907 case 0x7: func(stream, "un"); break;
2908 case 0xe: func(stream, "st"); break;
2909 case 0x6: func(stream, "unst"); break;
2910 default:
2911 func(stream, "#%d", (int)given & 0xf);
2912 break;
2913 }
2914 break;
2915
2916 case '0': case '1': case '2': case '3': case '4':
2917 case '5': case '6': case '7': case '8': case '9':
2918 {
2919 int width;
2920 unsigned long value;
2921
2922 c = arm_decode_bitfield (c, given, &value, &width);
2923
2924 switch (*c)
2925 {
2926 case 'r':
2927 func (stream, "%s", arm_regnames[value]);
2928 break;
2929 case 'd':
2930 func (stream, "%ld", value);
2931 break;
2932 case 'b':
2933 func (stream, "%ld", value * 8);
2934 break;
2935 case 'W':
2936 func (stream, "%ld", value + 1);
2937 break;
2938 case 'x':
2939 func (stream, "0x%08lx", value);
2940
2941 /* Some SWI instructions have special
2942 meanings. */
2943 if ((given & 0x0fffffff) == 0x0FF00000)
2944 func (stream, "\t; IMB");
2945 else if ((given & 0x0fffffff) == 0x0FF00001)
2946 func (stream, "\t; IMBRange");
2947 break;
2948 case 'X':
2949 func (stream, "%01lx", value & 0xf);
2950 break;
2951 case '`':
2952 c++;
2953 if (value == 0)
2954 func (stream, "%c", *c);
2955 break;
2956 case '\'':
2957 c++;
2958 if (value == ((1ul << width) - 1))
2959 func (stream, "%c", *c);
2960 break;
2961 case '?':
2962 func (stream, "%c", c[(1 << width) - (int)value]);
2963 c += 1 << width;
2964 break;
2965 default:
2966 abort ();
2967 }
2968 break;
2969
2970 case 'e':
2971 {
2972 int imm;
2973
2974 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2975 func (stream, "%d", imm);
2976 }
2977 break;
2978
2979 case 'E':
2980 /* LSB and WIDTH fields of BFI or BFC. The machine-
2981 language instruction encodes LSB and MSB. */
2982 {
2983 long msb = (given & 0x001f0000) >> 16;
2984 long lsb = (given & 0x00000f80) >> 7;
2985
2986 long width = msb - lsb + 1;
2987 if (width > 0)
2988 func (stream, "#%lu, #%lu", lsb, width);
2989 else
2990 func (stream, "(invalid: %lu:%lu)", lsb, msb);
2991 }
2992 break;
2993
2994 case 'V':
2995 /* 16-bit unsigned immediate from a MOVT or MOVW
2996 instruction, encoded in bits 0:11 and 15:19. */
2997 {
2998 long hi = (given & 0x000f0000) >> 4;
2999 long lo = (given & 0x00000fff);
3000 long imm16 = hi | lo;
3001 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
3002 }
3003 break;
3004
3005 default:
3006 abort ();
3007 }
3008 }
3009 }
3010 else
3011 func (stream, "%c", *c);
3012 }
3013 return;
3014 }
3015 }
3016 abort ();
3017 }
3018
3019 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3020
3021 static void
3022 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3023 {
3024 const struct opcode16 *insn;
3025 void *stream = info->stream;
3026 fprintf_ftype func = info->fprintf_func;
3027
3028 for (insn = thumb_opcodes; insn->assembler; insn++)
3029 if ((given & insn->mask) == insn->value)
3030 {
3031 const char *c = insn->assembler;
3032 for (; *c; c++)
3033 {
3034 int domaskpc = 0;
3035 int domasklr = 0;
3036
3037 if (*c != '%')
3038 {
3039 func (stream, "%c", *c);
3040 continue;
3041 }
3042
3043 switch (*++c)
3044 {
3045 case '%':
3046 func (stream, "%%");
3047 break;
3048
3049 case 'c':
3050 if (ifthen_state)
3051 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3052 break;
3053
3054 case 'C':
3055 if (ifthen_state)
3056 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3057 else
3058 func (stream, "s");
3059 break;
3060
3061 case 'I':
3062 {
3063 unsigned int tmp;
3064
3065 ifthen_next_state = given & 0xff;
3066 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3067 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3068 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3069 }
3070 break;
3071
3072 case 'x':
3073 if (ifthen_next_state)
3074 func (stream, "\t; unpredictable branch in IT block\n");
3075 break;
3076
3077 case 'X':
3078 if (ifthen_state)
3079 func (stream, "\t; unpredictable <IT:%s>",
3080 arm_conditional[IFTHEN_COND]);
3081 break;
3082
3083 case 'S':
3084 {
3085 long reg;
3086
3087 reg = (given >> 3) & 0x7;
3088 if (given & (1 << 6))
3089 reg += 8;
3090
3091 func (stream, "%s", arm_regnames[reg]);
3092 }
3093 break;
3094
3095 case 'D':
3096 {
3097 long reg;
3098
3099 reg = given & 0x7;
3100 if (given & (1 << 7))
3101 reg += 8;
3102
3103 func (stream, "%s", arm_regnames[reg]);
3104 }
3105 break;
3106
3107 case 'N':
3108 if (given & (1 << 8))
3109 domasklr = 1;
3110 /* Fall through. */
3111 case 'O':
3112 if (*c == 'O' && (given & (1 << 8)))
3113 domaskpc = 1;
3114 /* Fall through. */
3115 case 'M':
3116 {
3117 int started = 0;
3118 int reg;
3119
3120 func (stream, "{");
3121
3122 /* It would be nice if we could spot
3123 ranges, and generate the rS-rE format: */
3124 for (reg = 0; (reg < 8); reg++)
3125 if ((given & (1 << reg)) != 0)
3126 {
3127 if (started)
3128 func (stream, ", ");
3129 started = 1;
3130 func (stream, "%s", arm_regnames[reg]);
3131 }
3132
3133 if (domasklr)
3134 {
3135 if (started)
3136 func (stream, ", ");
3137 started = 1;
3138 func (stream, arm_regnames[14] /* "lr" */);
3139 }
3140
3141 if (domaskpc)
3142 {
3143 if (started)
3144 func (stream, ", ");
3145 func (stream, arm_regnames[15] /* "pc" */);
3146 }
3147
3148 func (stream, "}");
3149 }
3150 break;
3151
3152 case 'b':
3153 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3154 {
3155 bfd_vma address = (pc + 4
3156 + ((given & 0x00f8) >> 2)
3157 + ((given & 0x0200) >> 3));
3158 info->print_address_func (address, info);
3159 }
3160 break;
3161
3162 case 's':
3163 /* Right shift immediate -- bits 6..10; 1-31 print
3164 as themselves, 0 prints as 32. */
3165 {
3166 long imm = (given & 0x07c0) >> 6;
3167 if (imm == 0)
3168 imm = 32;
3169 func (stream, "#%ld", imm);
3170 }
3171 break;
3172
3173 case '0': case '1': case '2': case '3': case '4':
3174 case '5': case '6': case '7': case '8': case '9':
3175 {
3176 int bitstart = *c++ - '0';
3177 int bitend = 0;
3178
3179 while (*c >= '0' && *c <= '9')
3180 bitstart = (bitstart * 10) + *c++ - '0';
3181
3182 switch (*c)
3183 {
3184 case '-':
3185 {
3186 long reg;
3187
3188 c++;
3189 while (*c >= '0' && *c <= '9')
3190 bitend = (bitend * 10) + *c++ - '0';
3191 if (!bitend)
3192 abort ();
3193 reg = given >> bitstart;
3194 reg &= (2 << (bitend - bitstart)) - 1;
3195 switch (*c)
3196 {
3197 case 'r':
3198 func (stream, "%s", arm_regnames[reg]);
3199 break;
3200
3201 case 'd':
3202 func (stream, "%ld", reg);
3203 break;
3204
3205 case 'H':
3206 func (stream, "%ld", reg << 1);
3207 break;
3208
3209 case 'W':
3210 func (stream, "%ld", reg << 2);
3211 break;
3212
3213 case 'a':
3214 /* PC-relative address -- the bottom two
3215 bits of the address are dropped
3216 before the calculation. */
3217 info->print_address_func
3218 (((pc + 4) & ~3) + (reg << 2), info);
3219 break;
3220
3221 case 'x':
3222 func (stream, "0x%04lx", reg);
3223 break;
3224
3225 case 'B':
3226 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3227 info->print_address_func (reg * 2 + pc + 4, info);
3228 break;
3229
3230 case 'c':
3231 func (stream, "%s", arm_conditional [reg]);
3232 break;
3233
3234 default:
3235 abort ();
3236 }
3237 }
3238 break;
3239
3240 case '\'':
3241 c++;
3242 if ((given & (1 << bitstart)) != 0)
3243 func (stream, "%c", *c);
3244 break;
3245
3246 case '?':
3247 ++c;
3248 if ((given & (1 << bitstart)) != 0)
3249 func (stream, "%c", *c++);
3250 else
3251 func (stream, "%c", *++c);
3252 break;
3253
3254 default:
3255 abort ();
3256 }
3257 }
3258 break;
3259
3260 default:
3261 abort ();
3262 }
3263 }
3264 return;
3265 }
3266
3267 /* No match. */
3268 abort ();
3269 }
3270
3271 /* Return the name of an V7M special register. */
3272 static const char *
3273 psr_name (int regno)
3274 {
3275 switch (regno)
3276 {
3277 case 0: return "APSR";
3278 case 1: return "IAPSR";
3279 case 2: return "EAPSR";
3280 case 3: return "PSR";
3281 case 5: return "IPSR";
3282 case 6: return "EPSR";
3283 case 7: return "IEPSR";
3284 case 8: return "MSP";
3285 case 9: return "PSP";
3286 case 16: return "PRIMASK";
3287 case 17: return "BASEPRI";
3288 case 18: return "BASEPRI_MASK";
3289 case 19: return "FAULTMASK";
3290 case 20: return "CONTROL";
3291 default: return "<unknown>";
3292 }
3293 }
3294
3295 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3296
3297 static void
3298 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3299 {
3300 const struct opcode32 *insn;
3301 void *stream = info->stream;
3302 fprintf_ftype func = info->fprintf_func;
3303
3304 if (print_insn_coprocessor (pc, info, given, TRUE))
3305 return;
3306
3307 if (print_insn_neon (info, given, TRUE))
3308 return;
3309
3310 for (insn = thumb32_opcodes; insn->assembler; insn++)
3311 if ((given & insn->mask) == insn->value)
3312 {
3313 const char *c = insn->assembler;
3314 for (; *c; c++)
3315 {
3316 if (*c != '%')
3317 {
3318 func (stream, "%c", *c);
3319 continue;
3320 }
3321
3322 switch (*++c)
3323 {
3324 case '%':
3325 func (stream, "%%");
3326 break;
3327
3328 case 'c':
3329 if (ifthen_state)
3330 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3331 break;
3332
3333 case 'x':
3334 if (ifthen_next_state)
3335 func (stream, "\t; unpredictable branch in IT block\n");
3336 break;
3337
3338 case 'X':
3339 if (ifthen_state)
3340 func (stream, "\t; unpredictable <IT:%s>",
3341 arm_conditional[IFTHEN_COND]);
3342 break;
3343
3344 case 'I':
3345 {
3346 unsigned int imm12 = 0;
3347 imm12 |= (given & 0x000000ffu);
3348 imm12 |= (given & 0x00007000u) >> 4;
3349 imm12 |= (given & 0x04000000u) >> 15;
3350 func (stream, "#%u\t; 0x%x", imm12, imm12);
3351 }
3352 break;
3353
3354 case 'M':
3355 {
3356 unsigned int bits = 0, imm, imm8, mod;
3357 bits |= (given & 0x000000ffu);
3358 bits |= (given & 0x00007000u) >> 4;
3359 bits |= (given & 0x04000000u) >> 15;
3360 imm8 = (bits & 0x0ff);
3361 mod = (bits & 0xf00) >> 8;
3362 switch (mod)
3363 {
3364 case 0: imm = imm8; break;
3365 case 1: imm = ((imm8<<16) | imm8); break;
3366 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3367 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3368 default:
3369 mod = (bits & 0xf80) >> 7;
3370 imm8 = (bits & 0x07f) | 0x80;
3371 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3372 }
3373 func (stream, "#%u\t; 0x%x", imm, imm);
3374 }
3375 break;
3376
3377 case 'J':
3378 {
3379 unsigned int imm = 0;
3380 imm |= (given & 0x000000ffu);
3381 imm |= (given & 0x00007000u) >> 4;
3382 imm |= (given & 0x04000000u) >> 15;
3383 imm |= (given & 0x000f0000u) >> 4;
3384 func (stream, "#%u\t; 0x%x", imm, imm);
3385 }
3386 break;
3387
3388 case 'K':
3389 {
3390 unsigned int imm = 0;
3391 imm |= (given & 0x000f0000u) >> 16;
3392 imm |= (given & 0x00000ff0u) >> 0;
3393 imm |= (given & 0x0000000fu) << 12;
3394 func (stream, "#%u\t; 0x%x", imm, imm);
3395 }
3396 break;
3397
3398 case 'S':
3399 {
3400 unsigned int reg = (given & 0x0000000fu);
3401 unsigned int stp = (given & 0x00000030u) >> 4;
3402 unsigned int imm = 0;
3403 imm |= (given & 0x000000c0u) >> 6;
3404 imm |= (given & 0x00007000u) >> 10;
3405
3406 func (stream, "%s", arm_regnames[reg]);
3407 switch (stp)
3408 {
3409 case 0:
3410 if (imm > 0)
3411 func (stream, ", lsl #%u", imm);
3412 break;
3413
3414 case 1:
3415 if (imm == 0)
3416 imm = 32;
3417 func (stream, ", lsr #%u", imm);
3418 break;
3419
3420 case 2:
3421 if (imm == 0)
3422 imm = 32;
3423 func (stream, ", asr #%u", imm);
3424 break;
3425
3426 case 3:
3427 if (imm == 0)
3428 func (stream, ", rrx");
3429 else
3430 func (stream, ", ror #%u", imm);
3431 }
3432 }
3433 break;
3434
3435 case 'a':
3436 {
3437 unsigned int Rn = (given & 0x000f0000) >> 16;
3438 unsigned int U = (given & 0x00800000) >> 23;
3439 unsigned int op = (given & 0x00000f00) >> 8;
3440 unsigned int i12 = (given & 0x00000fff);
3441 unsigned int i8 = (given & 0x000000ff);
3442 bfd_boolean writeback = FALSE, postind = FALSE;
3443 int offset = 0;
3444
3445 func (stream, "[%s", arm_regnames[Rn]);
3446 if (U) /* 12-bit positive immediate offset */
3447 offset = i12;
3448 else if (Rn == 15) /* 12-bit negative immediate offset */
3449 offset = -(int)i12;
3450 else if (op == 0x0) /* shifted register offset */
3451 {
3452 unsigned int Rm = (i8 & 0x0f);
3453 unsigned int sh = (i8 & 0x30) >> 4;
3454 func (stream, ", %s", arm_regnames[Rm]);
3455 if (sh)
3456 func (stream, ", lsl #%u", sh);
3457 func (stream, "]");
3458 break;
3459 }
3460 else switch (op)
3461 {
3462 case 0xE: /* 8-bit positive immediate offset */
3463 offset = i8;
3464 break;
3465
3466 case 0xC: /* 8-bit negative immediate offset */
3467 offset = -i8;
3468 break;
3469
3470 case 0xF: /* 8-bit + preindex with wb */
3471 offset = i8;
3472 writeback = TRUE;
3473 break;
3474
3475 case 0xD: /* 8-bit - preindex with wb */
3476 offset = -i8;
3477 writeback = TRUE;
3478 break;
3479
3480 case 0xB: /* 8-bit + postindex */
3481 offset = i8;
3482 postind = TRUE;
3483 break;
3484
3485 case 0x9: /* 8-bit - postindex */
3486 offset = -i8;
3487 postind = TRUE;
3488 break;
3489
3490 default:
3491 func (stream, ", <undefined>]");
3492 goto skip;
3493 }
3494
3495 if (postind)
3496 func (stream, "], #%d", offset);
3497 else
3498 {
3499 if (offset)
3500 func (stream, ", #%d", offset);
3501 func (stream, writeback ? "]!" : "]");
3502 }
3503
3504 if (Rn == 15)
3505 {
3506 func (stream, "\t; ");
3507 info->print_address_func (((pc + 4) & ~3) + offset, info);
3508 }
3509 }
3510 skip:
3511 break;
3512
3513 case 'A':
3514 {
3515 unsigned int P = (given & 0x01000000) >> 24;
3516 unsigned int U = (given & 0x00800000) >> 23;
3517 unsigned int W = (given & 0x00400000) >> 21;
3518 unsigned int Rn = (given & 0x000f0000) >> 16;
3519 unsigned int off = (given & 0x000000ff);
3520
3521 func (stream, "[%s", arm_regnames[Rn]);
3522 if (P)
3523 {
3524 if (off || !U)
3525 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3526 func (stream, "]");
3527 if (W)
3528 func (stream, "!");
3529 }
3530 else
3531 {
3532 func (stream, "], ");
3533 if (W)
3534 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3535 else
3536 func (stream, "{%u}", off);
3537 }
3538 }
3539 break;
3540
3541 case 'w':
3542 {
3543 unsigned int Sbit = (given & 0x01000000) >> 24;
3544 unsigned int type = (given & 0x00600000) >> 21;
3545 switch (type)
3546 {
3547 case 0: func (stream, Sbit ? "sb" : "b"); break;
3548 case 1: func (stream, Sbit ? "sh" : "h"); break;
3549 case 2:
3550 if (Sbit)
3551 func (stream, "??");
3552 break;
3553 case 3:
3554 func (stream, "??");
3555 break;
3556 }
3557 }
3558 break;
3559
3560 case 'm':
3561 {
3562 int started = 0;
3563 int reg;
3564
3565 func (stream, "{");
3566 for (reg = 0; reg < 16; reg++)
3567 if ((given & (1 << reg)) != 0)
3568 {
3569 if (started)
3570 func (stream, ", ");
3571 started = 1;
3572 func (stream, "%s", arm_regnames[reg]);
3573 }
3574 func (stream, "}");
3575 }
3576 break;
3577
3578 case 'E':
3579 {
3580 unsigned int msb = (given & 0x0000001f);
3581 unsigned int lsb = 0;
3582 lsb |= (given & 0x000000c0u) >> 6;
3583 lsb |= (given & 0x00007000u) >> 10;
3584 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3585 }
3586 break;
3587
3588 case 'F':
3589 {
3590 unsigned int width = (given & 0x0000001f) + 1;
3591 unsigned int lsb = 0;
3592 lsb |= (given & 0x000000c0u) >> 6;
3593 lsb |= (given & 0x00007000u) >> 10;
3594 func (stream, "#%u, #%u", lsb, width);
3595 }
3596 break;
3597
3598 case 'b':
3599 {
3600 unsigned int S = (given & 0x04000000u) >> 26;
3601 unsigned int J1 = (given & 0x00002000u) >> 13;
3602 unsigned int J2 = (given & 0x00000800u) >> 11;
3603 int offset = 0;
3604
3605 offset |= !S << 20;
3606 offset |= J2 << 19;
3607 offset |= J1 << 18;
3608 offset |= (given & 0x003f0000) >> 4;
3609 offset |= (given & 0x000007ff) << 1;
3610 offset -= (1 << 20);
3611
3612 info->print_address_func (pc + 4 + offset, info);
3613 }
3614 break;
3615
3616 case 'B':
3617 {
3618 unsigned int S = (given & 0x04000000u) >> 26;
3619 unsigned int I1 = (given & 0x00002000u) >> 13;
3620 unsigned int I2 = (given & 0x00000800u) >> 11;
3621 int offset = 0;
3622
3623 offset |= !S << 24;
3624 offset |= !(I1 ^ S) << 23;
3625 offset |= !(I2 ^ S) << 22;
3626 offset |= (given & 0x03ff0000u) >> 4;
3627 offset |= (given & 0x000007ffu) << 1;
3628 offset -= (1 << 24);
3629 offset += pc + 4;
3630
3631 /* BLX target addresses are always word aligned. */
3632 if ((given & 0x00001000u) == 0)
3633 offset &= ~2u;
3634
3635 info->print_address_func (offset, info);
3636 }
3637 break;
3638
3639 case 's':
3640 {
3641 unsigned int shift = 0;
3642 shift |= (given & 0x000000c0u) >> 6;
3643 shift |= (given & 0x00007000u) >> 10;
3644 if (given & 0x00200000u)
3645 func (stream, ", asr #%u", shift);
3646 else if (shift)
3647 func (stream, ", lsl #%u", shift);
3648 /* else print nothing - lsl #0 */
3649 }
3650 break;
3651
3652 case 'R':
3653 {
3654 unsigned int rot = (given & 0x00000030) >> 4;
3655 if (rot)
3656 func (stream, ", ror #%u", rot * 8);
3657 }
3658 break;
3659
3660 case 'U':
3661 switch (given & 0xf)
3662 {
3663 case 0xf: func(stream, "sy"); break;
3664 case 0x7: func(stream, "un"); break;
3665 case 0xe: func(stream, "st"); break;
3666 case 0x6: func(stream, "unst"); break;
3667 default:
3668 func(stream, "#%d", (int)given & 0xf);
3669 break;
3670 }
3671 break;
3672
3673 case 'C':
3674 if ((given & 0xff) == 0)
3675 {
3676 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3677 if (given & 0x800)
3678 func (stream, "f");
3679 if (given & 0x400)
3680 func (stream, "s");
3681 if (given & 0x200)
3682 func (stream, "x");
3683 if (given & 0x100)
3684 func (stream, "c");
3685 }
3686 else
3687 {
3688 func (stream, psr_name (given & 0xff));
3689 }
3690 break;
3691
3692 case 'D':
3693 if ((given & 0xff) == 0)
3694 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3695 else
3696 func (stream, psr_name (given & 0xff));
3697 break;
3698
3699 case '0': case '1': case '2': case '3': case '4':
3700 case '5': case '6': case '7': case '8': case '9':
3701 {
3702 int width;
3703 unsigned long val;
3704
3705 c = arm_decode_bitfield (c, given, &val, &width);
3706
3707 switch (*c)
3708 {
3709 case 'd': func (stream, "%lu", val); break;
3710 case 'W': func (stream, "%lu", val * 4); break;
3711 case 'r': func (stream, "%s", arm_regnames[val]); break;
3712
3713 case 'c':
3714 func (stream, "%s", arm_conditional[val]);
3715 break;
3716
3717 case '\'':
3718 c++;
3719 if (val == ((1ul << width) - 1))
3720 func (stream, "%c", *c);
3721 break;
3722
3723 case '`':
3724 c++;
3725 if (val == 0)
3726 func (stream, "%c", *c);
3727 break;
3728
3729 case '?':
3730 func (stream, "%c", c[(1 << width) - (int)val]);
3731 c += 1 << width;
3732 break;
3733
3734 default:
3735 abort ();
3736 }
3737 }
3738 break;
3739
3740 default:
3741 abort ();
3742 }
3743 }
3744 return;
3745 }
3746
3747 /* No match. */
3748 abort ();
3749 }
3750
3751 /* Print data bytes on INFO->STREAM. */
3752
3753 static void
3754 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED, struct disassemble_info *info,
3755 long given)
3756 {
3757 switch (info->bytes_per_chunk)
3758 {
3759 case 1:
3760 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3761 break;
3762 case 2:
3763 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3764 break;
3765 case 4:
3766 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3767 break;
3768 default:
3769 abort ();
3770 }
3771 }
3772
3773 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3774 being displayed in symbol relative addresses. */
3775
3776 bfd_boolean
3777 arm_symbol_is_valid (asymbol * sym,
3778 struct disassemble_info * info ATTRIBUTE_UNUSED)
3779 {
3780 const char * name;
3781
3782 if (sym == NULL)
3783 return FALSE;
3784
3785 name = bfd_asymbol_name (sym);
3786
3787 return (name && *name != '$');
3788 }
3789
3790 /* Parse an individual disassembler option. */
3791
3792 void
3793 parse_arm_disassembler_option (char *option)
3794 {
3795 if (option == NULL)
3796 return;
3797
3798 if (CONST_STRNEQ (option, "reg-names-"))
3799 {
3800 int i;
3801
3802 option += 10;
3803
3804 for (i = NUM_ARM_REGNAMES; i--;)
3805 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3806 {
3807 regname_selected = i;
3808 break;
3809 }
3810
3811 if (i < 0)
3812 /* XXX - should break 'option' at following delimiter. */
3813 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3814 }
3815 else if (CONST_STRNEQ (option, "force-thumb"))
3816 force_thumb = 1;
3817 else if (CONST_STRNEQ (option, "no-force-thumb"))
3818 force_thumb = 0;
3819 else
3820 /* XXX - should break 'option' at following delimiter. */
3821 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3822
3823 return;
3824 }
3825
3826 /* Parse the string of disassembler options, spliting it at whitespaces
3827 or commas. (Whitespace separators supported for backwards compatibility). */
3828
3829 static void
3830 parse_disassembler_options (char *options)
3831 {
3832 if (options == NULL)
3833 return;
3834
3835 while (*options)
3836 {
3837 parse_arm_disassembler_option (options);
3838
3839 /* Skip forward to next seperator. */
3840 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3841 ++ options;
3842 /* Skip forward past seperators. */
3843 while (ISSPACE (*options) || (*options == ','))
3844 ++ options;
3845 }
3846 }
3847
3848 /* Search back through the insn stream to determine if this instruction is
3849 conditionally executed. */
3850 static void
3851 find_ifthen_state (bfd_vma pc, struct disassemble_info *info,
3852 bfd_boolean little)
3853 {
3854 unsigned char b[2];
3855 unsigned int insn;
3856 int status;
3857 /* COUNT is twice the number of instructions seen. It will be odd if we
3858 just crossed an instruction boundary. */
3859 int count;
3860 int it_count;
3861 unsigned int seen_it;
3862 bfd_vma addr;
3863
3864 ifthen_address = pc;
3865 ifthen_state = 0;
3866
3867 addr = pc;
3868 count = 1;
3869 it_count = 0;
3870 seen_it = 0;
3871 /* Scan backwards looking for IT instructions, keeping track of where
3872 instruction boundaries are. We don't know if something is actually an
3873 IT instruction until we find a definite instruction boundary. */
3874 for (;;)
3875 {
3876 if (addr == 0 || info->symbol_at_address_func(addr, info))
3877 {
3878 /* A symbol must be on an instruction boundary, and will not
3879 be within an IT block. */
3880 if (seen_it && (count & 1))
3881 break;
3882
3883 return;
3884 }
3885 addr -= 2;
3886 status = info->read_memory_func (addr, (bfd_byte *)b, 2, info);
3887 if (status)
3888 return;
3889
3890 if (little)
3891 insn = (b[0]) | (b[1] << 8);
3892 else
3893 insn = (b[1]) | (b[0] << 8);
3894 if (seen_it)
3895 {
3896 if ((insn & 0xf800) < 0xe800)
3897 {
3898 /* Addr + 2 is an instruction boundary. See if this matches
3899 the expected boundary based on the position of the last
3900 IT candidate. */
3901 if (count & 1)
3902 break;
3903 seen_it = 0;
3904 }
3905 }
3906 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
3907 {
3908 /* This could be an IT instruction. */
3909 seen_it = insn;
3910 it_count = count >> 1;
3911 }
3912 if ((insn & 0xf800) >= 0xe800)
3913 count++;
3914 else
3915 count = (count + 2) | 1;
3916 /* IT blocks contain at most 4 instructions. */
3917 if (count >= 8 && !seen_it)
3918 return;
3919 }
3920 /* We found an IT instruction. */
3921 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
3922 if ((ifthen_state & 0xf) == 0)
3923 ifthen_state = 0;
3924 }
3925
3926 /* Try to infer the code type (Arm or Thumb) from a symbol.
3927 Returns nonzero if *MAP_TYPE was set. */
3928
3929 static int
3930 get_sym_code_type (struct disassemble_info *info, int n,
3931 enum map_type *map_type)
3932 {
3933 elf_symbol_type *es;
3934 unsigned int type;
3935 const char *name;
3936
3937 es = *(elf_symbol_type **)(info->symtab + n);
3938 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
3939
3940 /* If the symbol has function type then use that. */
3941 if (type == STT_FUNC || type == STT_ARM_TFUNC)
3942 {
3943 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
3944 return TRUE;
3945 }
3946
3947 /* Check for mapping symbols. */
3948 name = bfd_asymbol_name(info->symtab[n]);
3949 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
3950 && (name[2] == 0 || name[2] == '.'))
3951 {
3952 *map_type = ((name[1] == 'a') ? MAP_ARM
3953 : (name[1] == 't') ? MAP_THUMB
3954 : MAP_DATA);
3955 return TRUE;
3956 }
3957
3958 return FALSE;
3959 }
3960
3961 /* NOTE: There are no checks in these routines that
3962 the relevant number of data bytes exist. */
3963
3964 static int
3965 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
3966 {
3967 unsigned char b[4];
3968 long given;
3969 int status;
3970 int is_thumb = FALSE;
3971 int is_data = FALSE;
3972 unsigned int size = 4;
3973 void (*printer) (bfd_vma, struct disassemble_info *, long);
3974 bfd_boolean found = FALSE;
3975
3976 if (info->disassembler_options)
3977 {
3978 parse_disassembler_options (info->disassembler_options);
3979
3980 /* To avoid repeated parsing of these options, we remove them here. */
3981 info->disassembler_options = NULL;
3982 }
3983
3984 /* First check the full symtab for a mapping symbol, even if there
3985 are no usable non-mapping symbols for this address. */
3986 if (info->symtab != NULL
3987 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
3988 {
3989 bfd_vma addr;
3990 int n;
3991 int last_sym = -1;
3992 enum map_type type = MAP_ARM;
3993
3994 if (pc <= last_mapping_addr)
3995 last_mapping_sym = -1;
3996 is_thumb = (last_type == MAP_THUMB);
3997 found = FALSE;
3998 /* Start scanning at the start of the function, or wherever
3999 we finished last time. */
4000 n = info->symtab_pos + 1;
4001 if (n < last_mapping_sym)
4002 n = last_mapping_sym;
4003
4004 /* Scan up to the location being disassembled. */
4005 for (; n < info->symtab_size; n++)
4006 {
4007 addr = bfd_asymbol_value (info->symtab[n]);
4008 if (addr > pc)
4009 break;
4010 if ((info->section == NULL
4011 || info->section == info->symtab[n]->section)
4012 && get_sym_code_type (info, n, &type))
4013 {
4014 last_sym = n;
4015 found = TRUE;
4016 }
4017 }
4018
4019 if (!found)
4020 {
4021 n = info->symtab_pos;
4022 if (n < last_mapping_sym - 1)
4023 n = last_mapping_sym - 1;
4024
4025 /* No mapping symbol found at this address. Look backwards
4026 for a preceeding one. */
4027 for (; n >= 0; n--)
4028 {
4029 if (get_sym_code_type (info, n, &type))
4030 {
4031 last_sym = n;
4032 found = TRUE;
4033 break;
4034 }
4035 }
4036 }
4037
4038 last_mapping_sym = last_sym;
4039 last_type = type;
4040 is_thumb = (last_type == MAP_THUMB);
4041 is_data = (last_type == MAP_DATA);
4042
4043 /* Look a little bit ahead to see if we should print out
4044 two or four bytes of data. If there's a symbol,
4045 mapping or otherwise, after two bytes then don't
4046 print more. */
4047 if (is_data)
4048 {
4049 size = 4 - (pc & 3);
4050 for (n = last_sym + 1; n < info->symtab_size; n++)
4051 {
4052 addr = bfd_asymbol_value (info->symtab[n]);
4053 if (addr > pc)
4054 {
4055 if (addr - pc < size)
4056 size = addr - pc;
4057 break;
4058 }
4059 }
4060 /* If the next symbol is after three bytes, we need to
4061 print only part of the data, so that we can use either
4062 .byte or .short. */
4063 if (size == 3)
4064 size = (pc & 1) ? 1 : 2;
4065 }
4066 }
4067
4068 if (info->symbols != NULL)
4069 {
4070 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4071 {
4072 coff_symbol_type * cs;
4073
4074 cs = coffsymbol (*info->symbols);
4075 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4076 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4077 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4078 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4079 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4080 }
4081 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4082 && !found)
4083 {
4084 /* If no mapping symbol has been found then fall back to the type
4085 of the function symbol. */
4086 elf_symbol_type * es;
4087 unsigned int type;
4088
4089 es = *(elf_symbol_type **)(info->symbols);
4090 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4091
4092 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4093 }
4094 }
4095
4096 if (force_thumb)
4097 is_thumb = TRUE;
4098
4099 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4100 info->bytes_per_line = 4;
4101
4102 if (is_data)
4103 {
4104 int i;
4105
4106 /* size was already set above. */
4107 info->bytes_per_chunk = size;
4108 printer = print_insn_data;
4109
4110 status = info->read_memory_func (pc, (bfd_byte *)b, size, info);
4111 given = 0;
4112 if (little)
4113 for (i = size - 1; i >= 0; i--)
4114 given = b[i] | (given << 8);
4115 else
4116 for (i = 0; i < (int) size; i++)
4117 given = b[i] | (given << 8);
4118 }
4119 else if (!is_thumb)
4120 {
4121 /* In ARM mode endianness is a straightforward issue: the instruction
4122 is four bytes long and is either ordered 0123 or 3210. */
4123 printer = print_insn_arm;
4124 info->bytes_per_chunk = 4;
4125 size = 4;
4126
4127 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
4128 if (little)
4129 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4130 else
4131 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4132 }
4133 else
4134 {
4135 /* In Thumb mode we have the additional wrinkle of two
4136 instruction lengths. Fortunately, the bits that determine
4137 the length of the current instruction are always to be found
4138 in the first two bytes. */
4139 printer = print_insn_thumb16;
4140 info->bytes_per_chunk = 2;
4141 size = 2;
4142
4143 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
4144 if (little)
4145 given = (b[0]) | (b[1] << 8);
4146 else
4147 given = (b[1]) | (b[0] << 8);
4148
4149 if (!status)
4150 {
4151 /* These bit patterns signal a four-byte Thumb
4152 instruction. */
4153 if ((given & 0xF800) == 0xF800
4154 || (given & 0xF800) == 0xF000
4155 || (given & 0xF800) == 0xE800)
4156 {
4157 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
4158 if (little)
4159 given = (b[0]) | (b[1] << 8) | (given << 16);
4160 else
4161 given = (b[1]) | (b[0] << 8) | (given << 16);
4162
4163 printer = print_insn_thumb32;
4164 size = 4;
4165 }
4166 }
4167
4168 if (ifthen_address != pc)
4169 find_ifthen_state(pc, info, little);
4170
4171 if (ifthen_state)
4172 {
4173 if ((ifthen_state & 0xf) == 0x8)
4174 ifthen_next_state = 0;
4175 else
4176 ifthen_next_state = (ifthen_state & 0xe0)
4177 | ((ifthen_state & 0xf) << 1);
4178 }
4179 }
4180
4181 if (status)
4182 {
4183 info->memory_error_func (status, pc, info);
4184 return -1;
4185 }
4186 if (info->flags & INSN_HAS_RELOC)
4187 /* If the instruction has a reloc associated with it, then
4188 the offset field in the instruction will actually be the
4189 addend for the reloc. (We are using REL type relocs).
4190 In such cases, we can ignore the pc when computing
4191 addresses, since the addend is not currently pc-relative. */
4192 pc = 0;
4193
4194 printer (pc, info, given);
4195
4196 if (is_thumb)
4197 {
4198 ifthen_state = ifthen_next_state;
4199 ifthen_address += size;
4200 }
4201 return size;
4202 }
4203
4204 int
4205 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4206 {
4207 return print_insn (pc, info, FALSE);
4208 }
4209
4210 int
4211 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4212 {
4213 return print_insn (pc, info, TRUE);
4214 }
4215
4216 void
4217 print_arm_disassembler_options (FILE *stream)
4218 {
4219 int i;
4220
4221 fprintf (stream, _("\n\
4222 The following ARM specific disassembler options are supported for use with\n\
4223 the -M switch:\n"));
4224
4225 for (i = NUM_ARM_REGNAMES; i--;)
4226 fprintf (stream, " reg-names-%s %*c%s\n",
4227 regnames[i].name,
4228 (int)(14 - strlen (regnames[i].name)), ' ',
4229 regnames[i].description);
4230
4231 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4232 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
4233 }
This page took 0.160789 seconds and 4 git commands to generate.