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