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