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