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