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