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