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