3bfad52e5f8f86cdc9fd7c3f4c21a447bad50800
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
3 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
6
7 This file is part of libopcodes.
8
9 This library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
13
14 It is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
17 License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
22 MA 02110-1301, USA. */
23
24 #include "sysdep.h"
25
26 #include "dis-asm.h"
27 #include "opcode/arm.h"
28 #include "opintl.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
31
32 /* FIXME: This shouldn't be done here. */
33 #include "coff/internal.h"
34 #include "libcoff.h"
35 #include "elf-bfd.h"
36 #include "elf/internal.h"
37 #include "elf/arm.h"
38
39 /* FIXME: Belongs in global header. */
40 #ifndef strneq
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
42 #endif
43
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
46 #endif
47
48 struct opcode32
49 {
50 unsigned long arch; /* Architecture defining this insn. */
51 unsigned long value; /* If arch == 0 then value is a sentinel. */
52 unsigned long mask; /* Recognise insn if (op & mask) == value. */
53 const char * assembler; /* How to disassemble this insn. */
54 };
55
56 struct opcode16
57 {
58 unsigned long arch; /* Architecture defining this insn. */
59 unsigned short value, mask; /* Recognise insn if (op & mask) == value. */
60 const char *assembler; /* How to disassemble this insn. */
61 };
62
63 /* print_insn_coprocessor recognizes the following format control codes:
64
65 %% %
66
67 %c print condition code (always bits 28-31 in ARM mode)
68 %q print shifter argument
69 %u print condition code (unconditional in ARM mode)
70 %A print address for ldc/stc/ldf/stf instruction
71 %B print vstm/vldm register list
72 %I print cirrus signed shift immediate: bits 0..3|4..6
73 %F print the COUNT field of a LFM/SFM instruction.
74 %P print floating point precision in arithmetic insn
75 %Q print floating point precision in ldf/stf insn
76 %R print floating point rounding mode
77
78 %<bitfield>r print as an ARM register
79 %<bitfield>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 if (! allow_unpredictable)
2935 {
2936 /* Writeback is automatically implied by post- addressing.
2937 Setting the W bit is unnecessary and ARM specify it as
2938 being unpredictable. */
2939 if (WRITEBACK_BIT_SET
2940 /* Specifying the PC register as the post-indexed
2941 registers is also unpredictable. */
2942 || ((given & 0xf) == 0xf))
2943 func (stream, UNPREDICTABLE_INSTRUCTION);
2944 }
2945 }
2946 }
2947 break;
2948
2949 case 'b':
2950 {
2951 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2952 info->print_address_func (disp * 4 + pc + 8, info);
2953 }
2954 break;
2955
2956 case 'c':
2957 if (((given >> 28) & 0xf) != 0xe)
2958 func (stream, "%s",
2959 arm_conditional [(given >> 28) & 0xf]);
2960 break;
2961
2962 case 'm':
2963 {
2964 int started = 0;
2965 int reg;
2966
2967 func (stream, "{");
2968 for (reg = 0; reg < 16; reg++)
2969 if ((given & (1 << reg)) != 0)
2970 {
2971 if (started)
2972 func (stream, ", ");
2973 started = 1;
2974 func (stream, "%s", arm_regnames[reg]);
2975 }
2976 func (stream, "}");
2977 }
2978 break;
2979
2980 case 'q':
2981 arm_decode_shift (given, func, stream, FALSE);
2982 break;
2983
2984 case 'o':
2985 if ((given & 0x02000000) != 0)
2986 {
2987 int rotate = (given & 0xf00) >> 7;
2988 int immed = (given & 0xff);
2989
2990 immed = (((immed << (32 - rotate))
2991 | (immed >> rotate)) & 0xffffffff);
2992 func (stream, "#%d", immed);
2993 value_in_comment = immed;
2994 }
2995 else
2996 arm_decode_shift (given, func, stream, TRUE);
2997 break;
2998
2999 case 'p':
3000 if ((given & 0x0000f000) == 0x0000f000)
3001 {
3002 /* The p-variants of tst/cmp/cmn/teq are the pre-V6
3003 mechanism for setting PSR flag bits. They are
3004 obsolete in V6 onwards. */
3005 if (((((arm_feature_set *) info->private_data)->core) & ARM_EXT_V6) == 0)
3006 func (stream, "p");
3007 }
3008 break;
3009
3010 case 't':
3011 if ((given & 0x01200000) == 0x00200000)
3012 func (stream, "t");
3013 break;
3014
3015 case 'A':
3016 {
3017 int offset = given & 0xff;
3018
3019 value_in_comment = offset * 4;
3020 if (NEGATIVE_BIT_SET)
3021 value_in_comment = - value_in_comment;
3022
3023 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
3024
3025 if (PRE_BIT_SET)
3026 {
3027 if (offset)
3028 func (stream, ", #%d]%s",
3029 value_in_comment,
3030 WRITEBACK_BIT_SET ? "!" : "");
3031 else
3032 func (stream, "]");
3033 }
3034 else
3035 {
3036 func (stream, "]");
3037
3038 if (WRITEBACK_BIT_SET)
3039 {
3040 if (offset)
3041 func (stream, ", #%d", value_in_comment);
3042 }
3043 else
3044 {
3045 func (stream, ", {%d}", offset);
3046 value_in_comment = offset;
3047 }
3048 }
3049 }
3050 break;
3051
3052 case 'B':
3053 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3054 {
3055 bfd_vma address;
3056 bfd_vma offset = 0;
3057
3058 if (! NEGATIVE_BIT_SET)
3059 /* Is signed, hi bits should be ones. */
3060 offset = (-1) ^ 0x00ffffff;
3061
3062 /* Offset is (SignExtend(offset field)<<2). */
3063 offset += given & 0x00ffffff;
3064 offset <<= 2;
3065 address = offset + pc + 8;
3066
3067 if (given & 0x01000000)
3068 /* H bit allows addressing to 2-byte boundaries. */
3069 address += 2;
3070
3071 info->print_address_func (address, info);
3072 }
3073 break;
3074
3075 case 'C':
3076 func (stream, "_");
3077 if (given & 0x80000)
3078 func (stream, "f");
3079 if (given & 0x40000)
3080 func (stream, "s");
3081 if (given & 0x20000)
3082 func (stream, "x");
3083 if (given & 0x10000)
3084 func (stream, "c");
3085 break;
3086
3087 case 'U':
3088 switch (given & 0xf)
3089 {
3090 case 0xf: func (stream, "sy"); break;
3091 case 0x7: func (stream, "un"); break;
3092 case 0xe: func (stream, "st"); break;
3093 case 0x6: func (stream, "unst"); break;
3094 default:
3095 func (stream, "#%d", (int) given & 0xf);
3096 break;
3097 }
3098 break;
3099
3100 case '0': case '1': case '2': case '3': case '4':
3101 case '5': case '6': case '7': case '8': case '9':
3102 {
3103 int width;
3104 unsigned long value;
3105
3106 c = arm_decode_bitfield (c, given, &value, &width);
3107
3108 switch (*c)
3109 {
3110 case 'r':
3111 func (stream, "%s", arm_regnames[value]);
3112 break;
3113 case 'd':
3114 func (stream, "%ld", value);
3115 value_in_comment = value;
3116 break;
3117 case 'b':
3118 func (stream, "%ld", value * 8);
3119 value_in_comment = value * 8;
3120 break;
3121 case 'W':
3122 func (stream, "%ld", value + 1);
3123 value_in_comment = value + 1;
3124 break;
3125 case 'x':
3126 func (stream, "0x%08lx", value);
3127
3128 /* Some SWI instructions have special
3129 meanings. */
3130 if ((given & 0x0fffffff) == 0x0FF00000)
3131 func (stream, "\t; IMB");
3132 else if ((given & 0x0fffffff) == 0x0FF00001)
3133 func (stream, "\t; IMBRange");
3134 break;
3135 case 'X':
3136 func (stream, "%01lx", value & 0xf);
3137 value_in_comment = value;
3138 break;
3139 case '`':
3140 c++;
3141 if (value == 0)
3142 func (stream, "%c", *c);
3143 break;
3144 case '\'':
3145 c++;
3146 if (value == ((1ul << width) - 1))
3147 func (stream, "%c", *c);
3148 break;
3149 case '?':
3150 func (stream, "%c", c[(1 << width) - (int) value]);
3151 c += 1 << width;
3152 break;
3153 default:
3154 abort ();
3155 }
3156 break;
3157
3158 case 'e':
3159 {
3160 int imm;
3161
3162 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3163 func (stream, "%d", imm);
3164 value_in_comment = imm;
3165 }
3166 break;
3167
3168 case 'E':
3169 /* LSB and WIDTH fields of BFI or BFC. The machine-
3170 language instruction encodes LSB and MSB. */
3171 {
3172 long msb = (given & 0x001f0000) >> 16;
3173 long lsb = (given & 0x00000f80) >> 7;
3174 long width = msb - lsb + 1;
3175
3176 if (width > 0)
3177 func (stream, "#%lu, #%lu", lsb, width);
3178 else
3179 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3180 }
3181 break;
3182
3183 case 'V':
3184 /* 16-bit unsigned immediate from a MOVT or MOVW
3185 instruction, encoded in bits 0:11 and 15:19. */
3186 {
3187 long hi = (given & 0x000f0000) >> 4;
3188 long lo = (given & 0x00000fff);
3189 long imm16 = hi | lo;
3190
3191 func (stream, "#%lu", imm16);
3192 value_in_comment = imm16;
3193 }
3194 break;
3195
3196 default:
3197 abort ();
3198 }
3199 }
3200 }
3201 else
3202 func (stream, "%c", *c);
3203 }
3204
3205 if (value_in_comment > 32 || value_in_comment < -16)
3206 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3207 return;
3208 }
3209 }
3210 abort ();
3211 }
3212
3213 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3214
3215 static void
3216 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3217 {
3218 const struct opcode16 *insn;
3219 void *stream = info->stream;
3220 fprintf_ftype func = info->fprintf_func;
3221
3222 for (insn = thumb_opcodes; insn->assembler; insn++)
3223 if ((given & insn->mask) == insn->value)
3224 {
3225 signed long value_in_comment = 0;
3226 const char *c = insn->assembler;
3227
3228 for (; *c; c++)
3229 {
3230 int domaskpc = 0;
3231 int domasklr = 0;
3232
3233 if (*c != '%')
3234 {
3235 func (stream, "%c", *c);
3236 continue;
3237 }
3238
3239 switch (*++c)
3240 {
3241 case '%':
3242 func (stream, "%%");
3243 break;
3244
3245 case 'c':
3246 if (ifthen_state)
3247 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3248 break;
3249
3250 case 'C':
3251 if (ifthen_state)
3252 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3253 else
3254 func (stream, "s");
3255 break;
3256
3257 case 'I':
3258 {
3259 unsigned int tmp;
3260
3261 ifthen_next_state = given & 0xff;
3262 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3263 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3264 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3265 }
3266 break;
3267
3268 case 'x':
3269 if (ifthen_next_state)
3270 func (stream, "\t; unpredictable branch in IT block\n");
3271 break;
3272
3273 case 'X':
3274 if (ifthen_state)
3275 func (stream, "\t; unpredictable <IT:%s>",
3276 arm_conditional[IFTHEN_COND]);
3277 break;
3278
3279 case 'S':
3280 {
3281 long reg;
3282
3283 reg = (given >> 3) & 0x7;
3284 if (given & (1 << 6))
3285 reg += 8;
3286
3287 func (stream, "%s", arm_regnames[reg]);
3288 }
3289 break;
3290
3291 case 'D':
3292 {
3293 long reg;
3294
3295 reg = given & 0x7;
3296 if (given & (1 << 7))
3297 reg += 8;
3298
3299 func (stream, "%s", arm_regnames[reg]);
3300 }
3301 break;
3302
3303 case 'N':
3304 if (given & (1 << 8))
3305 domasklr = 1;
3306 /* Fall through. */
3307 case 'O':
3308 if (*c == 'O' && (given & (1 << 8)))
3309 domaskpc = 1;
3310 /* Fall through. */
3311 case 'M':
3312 {
3313 int started = 0;
3314 int reg;
3315
3316 func (stream, "{");
3317
3318 /* It would be nice if we could spot
3319 ranges, and generate the rS-rE format: */
3320 for (reg = 0; (reg < 8); reg++)
3321 if ((given & (1 << reg)) != 0)
3322 {
3323 if (started)
3324 func (stream, ", ");
3325 started = 1;
3326 func (stream, "%s", arm_regnames[reg]);
3327 }
3328
3329 if (domasklr)
3330 {
3331 if (started)
3332 func (stream, ", ");
3333 started = 1;
3334 func (stream, arm_regnames[14] /* "lr" */);
3335 }
3336
3337 if (domaskpc)
3338 {
3339 if (started)
3340 func (stream, ", ");
3341 func (stream, arm_regnames[15] /* "pc" */);
3342 }
3343
3344 func (stream, "}");
3345 }
3346 break;
3347
3348 case 'b':
3349 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3350 {
3351 bfd_vma address = (pc + 4
3352 + ((given & 0x00f8) >> 2)
3353 + ((given & 0x0200) >> 3));
3354 info->print_address_func (address, info);
3355 }
3356 break;
3357
3358 case 's':
3359 /* Right shift immediate -- bits 6..10; 1-31 print
3360 as themselves, 0 prints as 32. */
3361 {
3362 long imm = (given & 0x07c0) >> 6;
3363 if (imm == 0)
3364 imm = 32;
3365 func (stream, "#%ld", imm);
3366 }
3367 break;
3368
3369 case '0': case '1': case '2': case '3': case '4':
3370 case '5': case '6': case '7': case '8': case '9':
3371 {
3372 int bitstart = *c++ - '0';
3373 int bitend = 0;
3374
3375 while (*c >= '0' && *c <= '9')
3376 bitstart = (bitstart * 10) + *c++ - '0';
3377
3378 switch (*c)
3379 {
3380 case '-':
3381 {
3382 long reg;
3383
3384 c++;
3385 while (*c >= '0' && *c <= '9')
3386 bitend = (bitend * 10) + *c++ - '0';
3387 if (!bitend)
3388 abort ();
3389 reg = given >> bitstart;
3390 reg &= (2 << (bitend - bitstart)) - 1;
3391 switch (*c)
3392 {
3393 case 'r':
3394 func (stream, "%s", arm_regnames[reg]);
3395 break;
3396
3397 case 'd':
3398 func (stream, "%ld", reg);
3399 value_in_comment = reg;
3400 break;
3401
3402 case 'H':
3403 func (stream, "%ld", reg << 1);
3404 value_in_comment = reg << 1;
3405 break;
3406
3407 case 'W':
3408 func (stream, "%ld", reg << 2);
3409 value_in_comment = reg << 2;
3410 break;
3411
3412 case 'a':
3413 /* PC-relative address -- the bottom two
3414 bits of the address are dropped
3415 before the calculation. */
3416 info->print_address_func
3417 (((pc + 4) & ~3) + (reg << 2), info);
3418 value_in_comment = 0;
3419 break;
3420
3421 case 'x':
3422 func (stream, "0x%04lx", reg);
3423 break;
3424
3425 case 'B':
3426 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3427 info->print_address_func (reg * 2 + pc + 4, info);
3428 value_in_comment = 0;
3429 break;
3430
3431 case 'c':
3432 func (stream, "%s", arm_conditional [reg]);
3433 break;
3434
3435 default:
3436 abort ();
3437 }
3438 }
3439 break;
3440
3441 case '\'':
3442 c++;
3443 if ((given & (1 << bitstart)) != 0)
3444 func (stream, "%c", *c);
3445 break;
3446
3447 case '?':
3448 ++c;
3449 if ((given & (1 << bitstart)) != 0)
3450 func (stream, "%c", *c++);
3451 else
3452 func (stream, "%c", *++c);
3453 break;
3454
3455 default:
3456 abort ();
3457 }
3458 }
3459 break;
3460
3461 default:
3462 abort ();
3463 }
3464 }
3465
3466 if (value_in_comment > 32 || value_in_comment < -16)
3467 func (stream, "\t; 0x%lx", value_in_comment);
3468 return;
3469 }
3470
3471 /* No match. */
3472 abort ();
3473 }
3474
3475 /* Return the name of an V7M special register. */
3476
3477 static const char *
3478 psr_name (int regno)
3479 {
3480 switch (regno)
3481 {
3482 case 0: return "APSR";
3483 case 1: return "IAPSR";
3484 case 2: return "EAPSR";
3485 case 3: return "PSR";
3486 case 5: return "IPSR";
3487 case 6: return "EPSR";
3488 case 7: return "IEPSR";
3489 case 8: return "MSP";
3490 case 9: return "PSP";
3491 case 16: return "PRIMASK";
3492 case 17: return "BASEPRI";
3493 case 18: return "BASEPRI_MASK";
3494 case 19: return "FAULTMASK";
3495 case 20: return "CONTROL";
3496 default: return "<unknown>";
3497 }
3498 }
3499
3500 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3501
3502 static void
3503 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3504 {
3505 const struct opcode32 *insn;
3506 void *stream = info->stream;
3507 fprintf_ftype func = info->fprintf_func;
3508
3509 if (print_insn_coprocessor (pc, info, given, TRUE))
3510 return;
3511
3512 if (print_insn_neon (info, given, TRUE))
3513 return;
3514
3515 for (insn = thumb32_opcodes; insn->assembler; insn++)
3516 if ((given & insn->mask) == insn->value)
3517 {
3518 signed long value_in_comment = 0;
3519 const char *c = insn->assembler;
3520
3521 for (; *c; c++)
3522 {
3523 if (*c != '%')
3524 {
3525 func (stream, "%c", *c);
3526 continue;
3527 }
3528
3529 switch (*++c)
3530 {
3531 case '%':
3532 func (stream, "%%");
3533 break;
3534
3535 case 'c':
3536 if (ifthen_state)
3537 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3538 break;
3539
3540 case 'x':
3541 if (ifthen_next_state)
3542 func (stream, "\t; unpredictable branch in IT block\n");
3543 break;
3544
3545 case 'X':
3546 if (ifthen_state)
3547 func (stream, "\t; unpredictable <IT:%s>",
3548 arm_conditional[IFTHEN_COND]);
3549 break;
3550
3551 case 'I':
3552 {
3553 unsigned int imm12 = 0;
3554
3555 imm12 |= (given & 0x000000ffu);
3556 imm12 |= (given & 0x00007000u) >> 4;
3557 imm12 |= (given & 0x04000000u) >> 15;
3558 func (stream, "#%u", imm12);
3559 value_in_comment = imm12;
3560 }
3561 break;
3562
3563 case 'M':
3564 {
3565 unsigned int bits = 0, imm, imm8, mod;
3566
3567 bits |= (given & 0x000000ffu);
3568 bits |= (given & 0x00007000u) >> 4;
3569 bits |= (given & 0x04000000u) >> 15;
3570 imm8 = (bits & 0x0ff);
3571 mod = (bits & 0xf00) >> 8;
3572 switch (mod)
3573 {
3574 case 0: imm = imm8; break;
3575 case 1: imm = ((imm8 << 16) | imm8); break;
3576 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3577 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3578 default:
3579 mod = (bits & 0xf80) >> 7;
3580 imm8 = (bits & 0x07f) | 0x80;
3581 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3582 }
3583 func (stream, "#%u", imm);
3584 value_in_comment = imm;
3585 }
3586 break;
3587
3588 case 'J':
3589 {
3590 unsigned int imm = 0;
3591
3592 imm |= (given & 0x000000ffu);
3593 imm |= (given & 0x00007000u) >> 4;
3594 imm |= (given & 0x04000000u) >> 15;
3595 imm |= (given & 0x000f0000u) >> 4;
3596 func (stream, "#%u", imm);
3597 value_in_comment = imm;
3598 }
3599 break;
3600
3601 case 'K':
3602 {
3603 unsigned int imm = 0;
3604
3605 imm |= (given & 0x000f0000u) >> 16;
3606 imm |= (given & 0x00000ff0u) >> 0;
3607 imm |= (given & 0x0000000fu) << 12;
3608 func (stream, "#%u", imm);
3609 value_in_comment = imm;
3610 }
3611 break;
3612
3613 case 'S':
3614 {
3615 unsigned int reg = (given & 0x0000000fu);
3616 unsigned int stp = (given & 0x00000030u) >> 4;
3617 unsigned int imm = 0;
3618 imm |= (given & 0x000000c0u) >> 6;
3619 imm |= (given & 0x00007000u) >> 10;
3620
3621 func (stream, "%s", arm_regnames[reg]);
3622 switch (stp)
3623 {
3624 case 0:
3625 if (imm > 0)
3626 func (stream, ", lsl #%u", imm);
3627 break;
3628
3629 case 1:
3630 if (imm == 0)
3631 imm = 32;
3632 func (stream, ", lsr #%u", imm);
3633 break;
3634
3635 case 2:
3636 if (imm == 0)
3637 imm = 32;
3638 func (stream, ", asr #%u", imm);
3639 break;
3640
3641 case 3:
3642 if (imm == 0)
3643 func (stream, ", rrx");
3644 else
3645 func (stream, ", ror #%u", imm);
3646 }
3647 }
3648 break;
3649
3650 case 'a':
3651 {
3652 unsigned int Rn = (given & 0x000f0000) >> 16;
3653 unsigned int U = ! NEGATIVE_BIT_SET;
3654 unsigned int op = (given & 0x00000f00) >> 8;
3655 unsigned int i12 = (given & 0x00000fff);
3656 unsigned int i8 = (given & 0x000000ff);
3657 bfd_boolean writeback = FALSE, postind = FALSE;
3658 int offset = 0;
3659
3660 func (stream, "[%s", arm_regnames[Rn]);
3661 if (U) /* 12-bit positive immediate offset. */
3662 {
3663 offset = i12;
3664 if (Rn != 15)
3665 value_in_comment = offset;
3666 }
3667 else if (Rn == 15) /* 12-bit negative immediate offset. */
3668 offset = - (int) i12;
3669 else if (op == 0x0) /* Shifted register offset. */
3670 {
3671 unsigned int Rm = (i8 & 0x0f);
3672 unsigned int sh = (i8 & 0x30) >> 4;
3673
3674 func (stream, ", %s", arm_regnames[Rm]);
3675 if (sh)
3676 func (stream, ", lsl #%u", sh);
3677 func (stream, "]");
3678 break;
3679 }
3680 else switch (op)
3681 {
3682 case 0xE: /* 8-bit positive immediate offset. */
3683 offset = i8;
3684 break;
3685
3686 case 0xC: /* 8-bit negative immediate offset. */
3687 offset = -i8;
3688 break;
3689
3690 case 0xF: /* 8-bit + preindex with wb. */
3691 offset = i8;
3692 writeback = TRUE;
3693 break;
3694
3695 case 0xD: /* 8-bit - preindex with wb. */
3696 offset = -i8;
3697 writeback = TRUE;
3698 break;
3699
3700 case 0xB: /* 8-bit + postindex. */
3701 offset = i8;
3702 postind = TRUE;
3703 break;
3704
3705 case 0x9: /* 8-bit - postindex. */
3706 offset = -i8;
3707 postind = TRUE;
3708 break;
3709
3710 default:
3711 func (stream, ", <undefined>]");
3712 goto skip;
3713 }
3714
3715 if (postind)
3716 func (stream, "], #%d", offset);
3717 else
3718 {
3719 if (offset)
3720 func (stream, ", #%d", offset);
3721 func (stream, writeback ? "]!" : "]");
3722 }
3723
3724 if (Rn == 15)
3725 {
3726 func (stream, "\t; ");
3727 info->print_address_func (((pc + 4) & ~3) + offset, info);
3728 }
3729 }
3730 skip:
3731 break;
3732
3733 case 'A':
3734 {
3735 unsigned int U = ! NEGATIVE_BIT_SET;
3736 unsigned int W = WRITEBACK_BIT_SET;
3737 unsigned int Rn = (given & 0x000f0000) >> 16;
3738 unsigned int off = (given & 0x000000ff);
3739
3740 func (stream, "[%s", arm_regnames[Rn]);
3741
3742 if (PRE_BIT_SET)
3743 {
3744 if (off || !U)
3745 {
3746 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3747 value_in_comment = off * 4 * U ? 1 : -1;
3748 }
3749 func (stream, "]");
3750 if (W)
3751 func (stream, "!");
3752 }
3753 else
3754 {
3755 func (stream, "], ");
3756 if (W)
3757 {
3758 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3759 value_in_comment = off * 4 * U ? 1 : -1;
3760 }
3761 else
3762 {
3763 func (stream, "{%u}", off);
3764 value_in_comment = off;
3765 }
3766 }
3767 }
3768 break;
3769
3770 case 'w':
3771 {
3772 unsigned int Sbit = (given & 0x01000000) >> 24;
3773 unsigned int type = (given & 0x00600000) >> 21;
3774
3775 switch (type)
3776 {
3777 case 0: func (stream, Sbit ? "sb" : "b"); break;
3778 case 1: func (stream, Sbit ? "sh" : "h"); break;
3779 case 2:
3780 if (Sbit)
3781 func (stream, "??");
3782 break;
3783 case 3:
3784 func (stream, "??");
3785 break;
3786 }
3787 }
3788 break;
3789
3790 case 'm':
3791 {
3792 int started = 0;
3793 int reg;
3794
3795 func (stream, "{");
3796 for (reg = 0; reg < 16; reg++)
3797 if ((given & (1 << reg)) != 0)
3798 {
3799 if (started)
3800 func (stream, ", ");
3801 started = 1;
3802 func (stream, "%s", arm_regnames[reg]);
3803 }
3804 func (stream, "}");
3805 }
3806 break;
3807
3808 case 'E':
3809 {
3810 unsigned int msb = (given & 0x0000001f);
3811 unsigned int lsb = 0;
3812
3813 lsb |= (given & 0x000000c0u) >> 6;
3814 lsb |= (given & 0x00007000u) >> 10;
3815 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3816 }
3817 break;
3818
3819 case 'F':
3820 {
3821 unsigned int width = (given & 0x0000001f) + 1;
3822 unsigned int lsb = 0;
3823
3824 lsb |= (given & 0x000000c0u) >> 6;
3825 lsb |= (given & 0x00007000u) >> 10;
3826 func (stream, "#%u, #%u", lsb, width);
3827 }
3828 break;
3829
3830 case 'b':
3831 {
3832 unsigned int S = (given & 0x04000000u) >> 26;
3833 unsigned int J1 = (given & 0x00002000u) >> 13;
3834 unsigned int J2 = (given & 0x00000800u) >> 11;
3835 int offset = 0;
3836
3837 offset |= !S << 20;
3838 offset |= J2 << 19;
3839 offset |= J1 << 18;
3840 offset |= (given & 0x003f0000) >> 4;
3841 offset |= (given & 0x000007ff) << 1;
3842 offset -= (1 << 20);
3843
3844 info->print_address_func (pc + 4 + offset, info);
3845 }
3846 break;
3847
3848 case 'B':
3849 {
3850 unsigned int S = (given & 0x04000000u) >> 26;
3851 unsigned int I1 = (given & 0x00002000u) >> 13;
3852 unsigned int I2 = (given & 0x00000800u) >> 11;
3853 int offset = 0;
3854
3855 offset |= !S << 24;
3856 offset |= !(I1 ^ S) << 23;
3857 offset |= !(I2 ^ S) << 22;
3858 offset |= (given & 0x03ff0000u) >> 4;
3859 offset |= (given & 0x000007ffu) << 1;
3860 offset -= (1 << 24);
3861 offset += pc + 4;
3862
3863 /* BLX target addresses are always word aligned. */
3864 if ((given & 0x00001000u) == 0)
3865 offset &= ~2u;
3866
3867 info->print_address_func (offset, info);
3868 }
3869 break;
3870
3871 case 's':
3872 {
3873 unsigned int shift = 0;
3874
3875 shift |= (given & 0x000000c0u) >> 6;
3876 shift |= (given & 0x00007000u) >> 10;
3877 if (WRITEBACK_BIT_SET)
3878 func (stream, ", asr #%u", shift);
3879 else if (shift)
3880 func (stream, ", lsl #%u", shift);
3881 /* else print nothing - lsl #0 */
3882 }
3883 break;
3884
3885 case 'R':
3886 {
3887 unsigned int rot = (given & 0x00000030) >> 4;
3888
3889 if (rot)
3890 func (stream, ", ror #%u", rot * 8);
3891 }
3892 break;
3893
3894 case 'U':
3895 switch (given & 0xf)
3896 {
3897 case 0xf: func (stream, "sy"); break;
3898 case 0x7: func (stream, "un"); break;
3899 case 0xe: func (stream, "st"); break;
3900 case 0x6: func (stream, "unst"); break;
3901 default:
3902 func (stream, "#%d", (int) given & 0xf);
3903 break;
3904 }
3905 break;
3906
3907 case 'C':
3908 if ((given & 0xff) == 0)
3909 {
3910 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3911 if (given & 0x800)
3912 func (stream, "f");
3913 if (given & 0x400)
3914 func (stream, "s");
3915 if (given & 0x200)
3916 func (stream, "x");
3917 if (given & 0x100)
3918 func (stream, "c");
3919 }
3920 else
3921 {
3922 func (stream, psr_name (given & 0xff));
3923 }
3924 break;
3925
3926 case 'D':
3927 if ((given & 0xff) == 0)
3928 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3929 else
3930 func (stream, psr_name (given & 0xff));
3931 break;
3932
3933 case '0': case '1': case '2': case '3': case '4':
3934 case '5': case '6': case '7': case '8': case '9':
3935 {
3936 int width;
3937 unsigned long val;
3938
3939 c = arm_decode_bitfield (c, given, &val, &width);
3940
3941 switch (*c)
3942 {
3943 case 'd':
3944 func (stream, "%lu", val);
3945 value_in_comment = val;
3946 break;
3947 case 'W':
3948 func (stream, "%lu", val * 4);
3949 value_in_comment = val * 4;
3950 break;
3951 case 'r': func (stream, "%s", arm_regnames[val]); break;
3952
3953 case 'c':
3954 func (stream, "%s", arm_conditional[val]);
3955 break;
3956
3957 case '\'':
3958 c++;
3959 if (val == ((1ul << width) - 1))
3960 func (stream, "%c", *c);
3961 break;
3962
3963 case '`':
3964 c++;
3965 if (val == 0)
3966 func (stream, "%c", *c);
3967 break;
3968
3969 case '?':
3970 func (stream, "%c", c[(1 << width) - (int) val]);
3971 c += 1 << width;
3972 break;
3973
3974 case 'x':
3975 func (stream, "0x%lx", val & 0xffffffffUL);
3976 break;
3977
3978 default:
3979 abort ();
3980 }
3981 }
3982 break;
3983
3984 default:
3985 abort ();
3986 }
3987 }
3988
3989 if (value_in_comment > 32 || value_in_comment < -16)
3990 func (stream, "\t; 0x%lx", value_in_comment);
3991 return;
3992 }
3993
3994 /* No match. */
3995 abort ();
3996 }
3997
3998 /* Print data bytes on INFO->STREAM. */
3999
4000 static void
4001 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
4002 struct disassemble_info *info,
4003 long given)
4004 {
4005 switch (info->bytes_per_chunk)
4006 {
4007 case 1:
4008 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
4009 break;
4010 case 2:
4011 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
4012 break;
4013 case 4:
4014 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
4015 break;
4016 default:
4017 abort ();
4018 }
4019 }
4020
4021 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
4022 being displayed in symbol relative addresses. */
4023
4024 bfd_boolean
4025 arm_symbol_is_valid (asymbol * sym,
4026 struct disassemble_info * info ATTRIBUTE_UNUSED)
4027 {
4028 const char * name;
4029
4030 if (sym == NULL)
4031 return FALSE;
4032
4033 name = bfd_asymbol_name (sym);
4034
4035 return (name && *name != '$');
4036 }
4037
4038 /* Parse an individual disassembler option. */
4039
4040 void
4041 parse_arm_disassembler_option (char *option)
4042 {
4043 if (option == NULL)
4044 return;
4045
4046 if (CONST_STRNEQ (option, "reg-names-"))
4047 {
4048 int i;
4049
4050 option += 10;
4051
4052 for (i = NUM_ARM_REGNAMES; i--;)
4053 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4054 {
4055 regname_selected = i;
4056 break;
4057 }
4058
4059 if (i < 0)
4060 /* XXX - should break 'option' at following delimiter. */
4061 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4062 }
4063 else if (CONST_STRNEQ (option, "force-thumb"))
4064 force_thumb = 1;
4065 else if (CONST_STRNEQ (option, "no-force-thumb"))
4066 force_thumb = 0;
4067 else
4068 /* XXX - should break 'option' at following delimiter. */
4069 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4070
4071 return;
4072 }
4073
4074 /* Parse the string of disassembler options, spliting it at whitespaces
4075 or commas. (Whitespace separators supported for backwards compatibility). */
4076
4077 static void
4078 parse_disassembler_options (char *options)
4079 {
4080 if (options == NULL)
4081 return;
4082
4083 while (*options)
4084 {
4085 parse_arm_disassembler_option (options);
4086
4087 /* Skip forward to next seperator. */
4088 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4089 ++ options;
4090 /* Skip forward past seperators. */
4091 while (ISSPACE (*options) || (*options == ','))
4092 ++ options;
4093 }
4094 }
4095
4096 /* Search back through the insn stream to determine if this instruction is
4097 conditionally executed. */
4098
4099 static void
4100 find_ifthen_state (bfd_vma pc,
4101 struct disassemble_info *info,
4102 bfd_boolean little)
4103 {
4104 unsigned char b[2];
4105 unsigned int insn;
4106 int status;
4107 /* COUNT is twice the number of instructions seen. It will be odd if we
4108 just crossed an instruction boundary. */
4109 int count;
4110 int it_count;
4111 unsigned int seen_it;
4112 bfd_vma addr;
4113
4114 ifthen_address = pc;
4115 ifthen_state = 0;
4116
4117 addr = pc;
4118 count = 1;
4119 it_count = 0;
4120 seen_it = 0;
4121 /* Scan backwards looking for IT instructions, keeping track of where
4122 instruction boundaries are. We don't know if something is actually an
4123 IT instruction until we find a definite instruction boundary. */
4124 for (;;)
4125 {
4126 if (addr == 0 || info->symbol_at_address_func (addr, info))
4127 {
4128 /* A symbol must be on an instruction boundary, and will not
4129 be within an IT block. */
4130 if (seen_it && (count & 1))
4131 break;
4132
4133 return;
4134 }
4135 addr -= 2;
4136 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4137 if (status)
4138 return;
4139
4140 if (little)
4141 insn = (b[0]) | (b[1] << 8);
4142 else
4143 insn = (b[1]) | (b[0] << 8);
4144 if (seen_it)
4145 {
4146 if ((insn & 0xf800) < 0xe800)
4147 {
4148 /* Addr + 2 is an instruction boundary. See if this matches
4149 the expected boundary based on the position of the last
4150 IT candidate. */
4151 if (count & 1)
4152 break;
4153 seen_it = 0;
4154 }
4155 }
4156 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4157 {
4158 /* This could be an IT instruction. */
4159 seen_it = insn;
4160 it_count = count >> 1;
4161 }
4162 if ((insn & 0xf800) >= 0xe800)
4163 count++;
4164 else
4165 count = (count + 2) | 1;
4166 /* IT blocks contain at most 4 instructions. */
4167 if (count >= 8 && !seen_it)
4168 return;
4169 }
4170 /* We found an IT instruction. */
4171 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4172 if ((ifthen_state & 0xf) == 0)
4173 ifthen_state = 0;
4174 }
4175
4176 /* Try to infer the code type (Arm or Thumb) from a symbol.
4177 Returns nonzero if *MAP_TYPE was set. */
4178
4179 static int
4180 get_sym_code_type (struct disassemble_info *info,
4181 int n,
4182 enum map_type *map_type)
4183 {
4184 elf_symbol_type *es;
4185 unsigned int type;
4186 const char *name;
4187
4188 es = *(elf_symbol_type **)(info->symtab + n);
4189 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4190
4191 /* If the symbol has function type then use that. */
4192 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4193 {
4194 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4195 return TRUE;
4196 }
4197
4198 /* Check for mapping symbols. */
4199 name = bfd_asymbol_name (info->symtab[n]);
4200 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4201 && (name[2] == 0 || name[2] == '.'))
4202 {
4203 *map_type = ((name[1] == 'a') ? MAP_ARM
4204 : (name[1] == 't') ? MAP_THUMB
4205 : MAP_DATA);
4206 return TRUE;
4207 }
4208
4209 return FALSE;
4210 }
4211
4212 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4213 of the supplied arm_feature_set structure with bitmasks indicating
4214 the support base architectures and coprocessor extensions.
4215
4216 FIXME: This could more efficiently implemented as a constant array,
4217 although it would also be less robust. */
4218
4219 static void
4220 select_arm_features (unsigned long mach,
4221 arm_feature_set * features)
4222 {
4223 #undef ARM_FEATURE
4224 #define ARM_FEATURE(ARCH,CEXT) \
4225 features->core = (ARCH); \
4226 features->coproc = (CEXT) | FPU_FPA; \
4227 return
4228
4229 switch (mach)
4230 {
4231 case bfd_mach_arm_2: ARM_ARCH_V2;
4232 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4233 case bfd_mach_arm_3: ARM_ARCH_V3;
4234 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4235 case bfd_mach_arm_4: ARM_ARCH_V4;
4236 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4237 case bfd_mach_arm_5: ARM_ARCH_V5;
4238 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4239 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4240 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4241 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4242 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4243 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4244 /* If the machine type is unknown allow all
4245 architecture types and all extensions. */
4246 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4247 default:
4248 abort ();
4249 }
4250 }
4251
4252
4253 /* NOTE: There are no checks in these routines that
4254 the relevant number of data bytes exist. */
4255
4256 static int
4257 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4258 {
4259 unsigned char b[4];
4260 long given;
4261 int status;
4262 int is_thumb = FALSE;
4263 int is_data = FALSE;
4264 int little_code;
4265 unsigned int size = 4;
4266 void (*printer) (bfd_vma, struct disassemble_info *, long);
4267 bfd_boolean found = FALSE;
4268
4269 if (info->disassembler_options)
4270 {
4271 parse_disassembler_options (info->disassembler_options);
4272
4273 /* To avoid repeated parsing of these options, we remove them here. */
4274 info->disassembler_options = NULL;
4275 }
4276
4277 /* PR 10288: Control which instructions will be disassembled. */
4278 if (info->private_data == NULL)
4279 {
4280 static arm_feature_set features;
4281
4282 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4283 /* If the user did not use the -m command line switch then default to
4284 disassembling all types of ARM instruction.
4285
4286 The info->mach value has to be ignored as this will be based on
4287 the default archictecture for the target and/or hints in the notes
4288 section, but it will never be greater than the current largest arm
4289 machine value (iWMMXt2), which is only equivalent to the V5TE
4290 architecture. ARM architectures have advanced beyond the machine
4291 value encoding, and these newer architectures would be ignored if
4292 the machine value was used.
4293
4294 Ie the -m switch is used to restrict which instructions will be
4295 disassembled. If it is necessary to use the -m switch to tell
4296 objdump that an ARM binary is being disassembled, eg because the
4297 input is a raw binary file, but it is also desired to disassemble
4298 all ARM instructions then use "-marm". This will select the
4299 "unknown" arm architecture which is compatible with any ARM
4300 instruction. */
4301 info->mach = bfd_mach_arm_unknown;
4302
4303 /* Compute the architecture bitmask from the machine number.
4304 Note: This assumes that the machine number will not change
4305 during disassembly.... */
4306 select_arm_features (info->mach, & features);
4307
4308 info->private_data = & features;
4309 }
4310
4311 /* Decide if our code is going to be little-endian, despite what the
4312 function argument might say. */
4313 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4314
4315 /* First check the full symtab for a mapping symbol, even if there
4316 are no usable non-mapping symbols for this address. */
4317 if (info->symtab_size != 0
4318 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4319 {
4320 bfd_vma addr;
4321 int n;
4322 int last_sym = -1;
4323 enum map_type type = MAP_ARM;
4324
4325 if (pc <= last_mapping_addr)
4326 last_mapping_sym = -1;
4327 is_thumb = (last_type == MAP_THUMB);
4328 found = FALSE;
4329 /* Start scanning at the start of the function, or wherever
4330 we finished last time. */
4331 n = info->symtab_pos + 1;
4332 if (n < last_mapping_sym)
4333 n = last_mapping_sym;
4334
4335 /* Scan up to the location being disassembled. */
4336 for (; n < info->symtab_size; n++)
4337 {
4338 addr = bfd_asymbol_value (info->symtab[n]);
4339 if (addr > pc)
4340 break;
4341 if ((info->section == NULL
4342 || info->section == info->symtab[n]->section)
4343 && get_sym_code_type (info, n, &type))
4344 {
4345 last_sym = n;
4346 found = TRUE;
4347 }
4348 }
4349
4350 if (!found)
4351 {
4352 n = info->symtab_pos;
4353 if (n < last_mapping_sym - 1)
4354 n = last_mapping_sym - 1;
4355
4356 /* No mapping symbol found at this address. Look backwards
4357 for a preceeding one. */
4358 for (; n >= 0; n--)
4359 {
4360 if ((info->section == NULL
4361 || info->section == info->symtab[n]->section)
4362 && get_sym_code_type (info, n, &type))
4363 {
4364 last_sym = n;
4365 found = TRUE;
4366 break;
4367 }
4368 }
4369 }
4370
4371 last_mapping_sym = last_sym;
4372 last_type = type;
4373 is_thumb = (last_type == MAP_THUMB);
4374 is_data = (last_type == MAP_DATA);
4375
4376 /* Look a little bit ahead to see if we should print out
4377 two or four bytes of data. If there's a symbol,
4378 mapping or otherwise, after two bytes then don't
4379 print more. */
4380 if (is_data)
4381 {
4382 size = 4 - (pc & 3);
4383 for (n = last_sym + 1; n < info->symtab_size; n++)
4384 {
4385 addr = bfd_asymbol_value (info->symtab[n]);
4386 if (addr > pc)
4387 {
4388 if (addr - pc < size)
4389 size = addr - pc;
4390 break;
4391 }
4392 }
4393 /* If the next symbol is after three bytes, we need to
4394 print only part of the data, so that we can use either
4395 .byte or .short. */
4396 if (size == 3)
4397 size = (pc & 1) ? 1 : 2;
4398 }
4399 }
4400
4401 if (info->symbols != NULL)
4402 {
4403 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4404 {
4405 coff_symbol_type * cs;
4406
4407 cs = coffsymbol (*info->symbols);
4408 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4409 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4410 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4411 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4412 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4413 }
4414 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4415 && !found)
4416 {
4417 /* If no mapping symbol has been found then fall back to the type
4418 of the function symbol. */
4419 elf_symbol_type * es;
4420 unsigned int type;
4421
4422 es = *(elf_symbol_type **)(info->symbols);
4423 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4424
4425 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4426 }
4427 }
4428
4429 if (force_thumb)
4430 is_thumb = TRUE;
4431
4432 if (is_data)
4433 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4434 else
4435 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4436
4437 info->bytes_per_line = 4;
4438
4439 /* PR 10263: Disassemble data if requested to do so by the user. */
4440 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4441 {
4442 int i;
4443
4444 /* Size was already set above. */
4445 info->bytes_per_chunk = size;
4446 printer = print_insn_data;
4447
4448 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4449 given = 0;
4450 if (little)
4451 for (i = size - 1; i >= 0; i--)
4452 given = b[i] | (given << 8);
4453 else
4454 for (i = 0; i < (int) size; i++)
4455 given = b[i] | (given << 8);
4456 }
4457 else if (!is_thumb)
4458 {
4459 /* In ARM mode endianness is a straightforward issue: the instruction
4460 is four bytes long and is either ordered 0123 or 3210. */
4461 printer = print_insn_arm;
4462 info->bytes_per_chunk = 4;
4463 size = 4;
4464
4465 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4466 if (little_code)
4467 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4468 else
4469 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4470 }
4471 else
4472 {
4473 /* In Thumb mode we have the additional wrinkle of two
4474 instruction lengths. Fortunately, the bits that determine
4475 the length of the current instruction are always to be found
4476 in the first two bytes. */
4477 printer = print_insn_thumb16;
4478 info->bytes_per_chunk = 2;
4479 size = 2;
4480
4481 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4482 if (little_code)
4483 given = (b[0]) | (b[1] << 8);
4484 else
4485 given = (b[1]) | (b[0] << 8);
4486
4487 if (!status)
4488 {
4489 /* These bit patterns signal a four-byte Thumb
4490 instruction. */
4491 if ((given & 0xF800) == 0xF800
4492 || (given & 0xF800) == 0xF000
4493 || (given & 0xF800) == 0xE800)
4494 {
4495 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4496 if (little_code)
4497 given = (b[0]) | (b[1] << 8) | (given << 16);
4498 else
4499 given = (b[1]) | (b[0] << 8) | (given << 16);
4500
4501 printer = print_insn_thumb32;
4502 size = 4;
4503 }
4504 }
4505
4506 if (ifthen_address != pc)
4507 find_ifthen_state (pc, info, little_code);
4508
4509 if (ifthen_state)
4510 {
4511 if ((ifthen_state & 0xf) == 0x8)
4512 ifthen_next_state = 0;
4513 else
4514 ifthen_next_state = (ifthen_state & 0xe0)
4515 | ((ifthen_state & 0xf) << 1);
4516 }
4517 }
4518
4519 if (status)
4520 {
4521 info->memory_error_func (status, pc, info);
4522 return -1;
4523 }
4524 if (info->flags & INSN_HAS_RELOC)
4525 /* If the instruction has a reloc associated with it, then
4526 the offset field in the instruction will actually be the
4527 addend for the reloc. (We are using REL type relocs).
4528 In such cases, we can ignore the pc when computing
4529 addresses, since the addend is not currently pc-relative. */
4530 pc = 0;
4531
4532 printer (pc, info, given);
4533
4534 if (is_thumb)
4535 {
4536 ifthen_state = ifthen_next_state;
4537 ifthen_address += size;
4538 }
4539 return size;
4540 }
4541
4542 int
4543 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4544 {
4545 /* Detect BE8-ness and record it in the disassembler info. */
4546 if (info->flavour == bfd_target_elf_flavour
4547 && info->section != NULL
4548 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4549 info->endian_code = BFD_ENDIAN_LITTLE;
4550
4551 return print_insn (pc, info, FALSE);
4552 }
4553
4554 int
4555 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4556 {
4557 return print_insn (pc, info, TRUE);
4558 }
4559
4560 void
4561 print_arm_disassembler_options (FILE *stream)
4562 {
4563 int i;
4564
4565 fprintf (stream, _("\n\
4566 The following ARM specific disassembler options are supported for use with\n\
4567 the -M switch:\n"));
4568
4569 for (i = NUM_ARM_REGNAMES; i--;)
4570 fprintf (stream, " reg-names-%s %*c%s\n",
4571 regnames[i].name,
4572 (int)(14 - strlen (regnames[i].name)), ' ',
4573 regnames[i].description);
4574
4575 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4576 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
4577 }
This page took 0.260654 seconds and 3 git commands to generate.