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