2009-11-06 Sebastian Pop <sebastian.pop@amd.com>
[binutils.git] / opcodes / arm-dis.c
blob1616fed92d406ef28c3dda8f5c37b0ee7f69644a
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)
7 This file is part of libopcodes.
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.
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.
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. */
24 #include "sysdep.h"
26 #include "dis-asm.h"
27 #include "opcode/arm.h"
28 #include "opintl.h"
29 #include "safe-ctype.h"
30 #include "floatformat.h"
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"
39 /* FIXME: Belongs in global header. */
40 #ifndef strneq
41 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
42 #endif
44 #ifndef NUM_ELEM
45 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
46 #endif
48 struct opcode32
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. */
56 struct opcode16
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. */
63 /* print_insn_coprocessor recognizes the following format control codes:
65 %% %
67 %c print condition code (always bits 28-31 in ARM mode)
68 %q print shifter argument
69 %u print condition code (unconditional in ARM mode)
70 %A print address for ldc/stc/ldf/stf instruction
71 %B print vstm/vldm register list
72 %C print vstr/vldr address operand
73 %I print cirrus signed shift immediate: bits 0..3|4..6
74 %F print the COUNT field of a LFM/SFM instruction.
75 %P print floating point precision in arithmetic insn
76 %Q print floating point precision in ldf/stf insn
77 %R print floating point rounding mode
79 %<bitfield>r print as an ARM register
80 %<bitfield>d print the bitfield in decimal
81 %<bitfield>k print immediate for VFPv3 conversion instruction
82 %<bitfield>x print the bitfield in hex
83 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
84 %<bitfield>f print a floating point constant if >7 else a
85 floating point register
86 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
87 %<bitfield>g print as an iWMMXt 64-bit register
88 %<bitfield>G print as an iWMMXt general purpose or control register
89 %<bitfield>D print as a NEON D register
90 %<bitfield>Q print as a NEON Q register
92 %y<code> print a single precision VFP reg.
93 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
94 %z<code> print a double precision VFP reg
95 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
97 %<bitfield>'c print specified char iff bitfield is all ones
98 %<bitfield>`c print specified char iff bitfield is all zeroes
99 %<bitfield>?ab... select from array of values in big endian order
101 %L print as an iWMMXt N/M width field.
102 %Z print the Immediate of a WSHUFH instruction.
103 %l like 'A' except use byte offsets for 'B' & 'H'
104 versions.
105 %i print 5-bit immediate in bits 8,3..0
106 (print "32" when 0)
107 %r print register offset address for wldt/wstr instruction. */
109 enum opcode_sentinel_enum
111 SENTINEL_IWMMXT_START = 1,
112 SENTINEL_IWMMXT_END,
113 SENTINEL_GENERIC_START
114 } opcode_sentinels;
116 #define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
118 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
120 static const struct opcode32 coprocessor_opcodes[] =
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"},
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, "" },
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\t; (stc%22'l%c %8-11d, cr%12-15d, %A)"},
251 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A\t; (ldc%22'l%c %8-11d, cr%12-15d, %A)"},
253 /* 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, %C"},
261 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %C"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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}"},
481 {0, 0, 0, 0}
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. */
488 /* print_insn_neon recognizes the following format control codes:
490 %% %
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
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
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. */
514 static const struct opcode32 neon_opcodes[] =
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"},
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]"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
766 {0,0 ,0, 0}
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. */
773 /* print_insn_arm recognizes the following format control codes:
775 %% %
777 %a print address for ldr/str instruction
778 %s print address for ldr/str halfword/signextend instruction
779 %b print branch destination
780 %c print condition code (always bits 28-31)
781 %m print register mask for ldm/stm instruction
782 %o print operand2 (immediate or register + shift)
783 %p print 'p' iff bits 12-15 are 15
784 %t print 't' iff bit 21 set and bit 24 clear
785 %B print arm BLX(1) destination
786 %C print the PSR sub type.
787 %U print barrier type.
788 %P print address for pli instruction.
790 %<bitfield>r print as an ARM register
791 %<bitfield>d print the bitfield in decimal
792 %<bitfield>W print the bitfield plus one in decimal
793 %<bitfield>x print the bitfield in hex
794 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
796 %<bitfield>'c print specified char iff bitfield is all ones
797 %<bitfield>`c print specified char iff bitfield is all zeroes
798 %<bitfield>?ab... select from array of values in big endian order
800 %e print arm SMI operand (bits 0..7,8..19).
801 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
802 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
804 static const struct opcode32 arm_opcodes[] =
806 /* ARM instructions. */
807 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
808 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
809 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
810 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
811 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
812 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
813 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
815 /* V7 instructions. */
816 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
817 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
818 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
819 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
820 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
822 /* ARM V6T2 instructions. */
823 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
824 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
825 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
826 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %s"},
827 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %s"},
828 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
829 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
830 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
831 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
833 /* ARM V6Z instructions. */
834 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
836 /* ARM V6K instructions. */
837 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
838 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
839 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
840 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
841 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
842 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
843 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
845 /* ARM V6K NOP hints. */
846 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
847 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
848 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
849 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
850 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
852 /* ARM V6 instructions. */
853 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
854 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
855 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
856 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
857 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
858 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
859 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
860 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
861 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
862 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
863 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
864 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
865 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
866 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
867 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
869 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
870 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
871 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
872 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
873 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
874 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
875 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
877 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
878 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
879 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
881 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
882 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
883 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
885 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
886 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
887 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
888 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
889 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
890 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
891 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
893 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
894 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
895 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
897 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
898 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
899 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15r, %0-3r"},
900 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15r, %0-3r"},
901 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15r, %0-3r"},
902 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
903 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
904 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
905 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
906 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
907 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
908 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
909 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
910 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
911 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
912 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
913 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
914 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
915 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
916 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
917 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
918 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
919 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
920 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
921 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
922 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
923 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
924 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
925 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
926 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
927 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
928 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
929 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
930 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
931 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
932 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
933 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
934 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
935 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
936 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
937 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
938 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
939 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
940 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
941 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
942 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
943 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
944 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
945 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
946 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
947 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
948 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
949 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
950 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
951 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
952 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
953 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
954 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
955 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
956 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
957 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
958 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
959 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
960 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
961 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
962 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
963 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
964 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
965 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
966 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
967 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
968 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
969 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
970 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
971 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
972 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
973 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
974 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
976 /* V5J instruction. */
977 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
979 /* V5 Instructions. */
980 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
981 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
982 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
983 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
985 /* V5E "El Segundo" Instructions. */
986 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
987 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
988 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
989 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
990 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
991 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
992 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
994 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
995 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
997 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
998 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
999 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1000 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1002 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1003 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1004 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1005 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1007 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1008 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1010 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1011 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1012 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1013 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1015 /* ARM Instructions. */
1016 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1017 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1018 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1019 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1020 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
1021 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
1022 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
1023 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
1024 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1025 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
1027 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1028 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1029 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
1031 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1032 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1033 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
1035 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1036 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1037 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
1039 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1040 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1041 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1043 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1044 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1045 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
1047 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1048 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1049 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
1051 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1052 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1053 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1055 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1056 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1057 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1059 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1060 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1062 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1063 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1064 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
1066 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1067 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1068 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
1070 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1071 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1072 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
1074 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1075 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1076 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
1078 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1079 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
1082 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1083 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1084 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1085 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1086 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1087 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1088 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1090 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1091 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
1094 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1095 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1096 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
1098 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1099 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1100 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1101 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1102 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1103 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1104 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1105 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1106 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1107 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1108 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1110 /* The rest. */
1111 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1112 {0, 0x00000000, 0x00000000, 0}
1115 /* print_insn_thumb16 recognizes the following format control codes:
1117 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1118 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1119 %<bitfield>I print bitfield as a signed decimal
1120 (top bit of range being the sign bit)
1121 %N print Thumb register mask (with LR)
1122 %O print Thumb register mask (with PC)
1123 %M print Thumb register mask
1124 %b print CZB's 6-bit unsigned branch destination
1125 %s print Thumb right-shift immediate (6..10; 0 == 32).
1126 %c print the condition code
1127 %C print the condition code, or "s" if not conditional
1128 %x print warning if conditional an not at end of IT block"
1129 %X print "\t; unpredictable <IT:code>" if conditional
1130 %I print IT instruction suffix and operands
1131 %<bitfield>r print bitfield as an ARM register
1132 %<bitfield>d print bitfield as a decimal
1133 %<bitfield>H print (bitfield * 2) as a decimal
1134 %<bitfield>W print (bitfield * 4) as a decimal
1135 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1136 %<bitfield>B print Thumb branch destination (signed displacement)
1137 %<bitfield>c print bitfield as a condition code
1138 %<bitnum>'c print specified char iff bit is one
1139 %<bitnum>?ab print a if bit is one else print b. */
1141 static const struct opcode16 thumb_opcodes[] =
1143 /* Thumb instructions. */
1145 /* ARM V6K no-argument instructions. */
1146 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1147 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1148 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1149 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1150 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1151 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1153 /* ARM V6T2 instructions. */
1154 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1155 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1156 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1158 /* ARM V6. */
1159 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1160 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1161 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1162 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1163 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1164 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1165 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1166 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1167 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1168 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1169 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1171 /* ARM V5 ISA extends Thumb. */
1172 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1173 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1174 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1175 /* ARM V4T ISA (Thumb v1). */
1176 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1177 /* Format 4. */
1178 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1179 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1180 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1181 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1182 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1183 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1184 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1185 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1186 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1187 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1188 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1189 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1190 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1191 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1192 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1193 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1194 /* format 13 */
1195 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1196 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1197 /* format 5 */
1198 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1199 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1200 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1201 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1202 /* format 14 */
1203 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1204 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1205 /* format 2 */
1206 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1207 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1208 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1209 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1210 /* format 8 */
1211 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1212 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1213 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1214 /* format 7 */
1215 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1216 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1217 /* format 1 */
1218 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1219 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1220 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1221 /* format 3 */
1222 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1223 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1224 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1225 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1226 /* format 6 */
1227 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1228 /* format 9 */
1229 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1230 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1231 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1232 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1233 /* format 10 */
1234 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1235 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1236 /* format 11 */
1237 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1238 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1239 /* format 12 */
1240 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1241 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1242 /* format 15 */
1243 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1244 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1245 /* format 17 */
1246 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1247 /* format 16 */
1248 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1249 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1250 /* format 18 */
1251 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1253 /* The E800 .. FFFF range is unconditionally redirected to the
1254 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1255 are processed via that table. Thus, we can never encounter a
1256 bare "second half of BL/BLX(1)" instruction here. */
1257 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1258 {0, 0, 0, 0}
1261 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1262 We adopt the convention that hw1 is the high 16 bits of .value and
1263 .mask, hw2 the low 16 bits.
1265 print_insn_thumb32 recognizes the following format control codes:
1267 %% %
1269 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1270 %M print a modified 12-bit immediate (same location)
1271 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1272 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1273 %S print a possibly-shifted Rm
1275 %a print the address of a plain load/store
1276 %w print the width and signedness of a core load/store
1277 %m print register mask for ldm/stm
1279 %E print the lsb and width fields of a bfc/bfi instruction
1280 %F print the lsb and width fields of a sbfx/ubfx instruction
1281 %b print a conditional branch offset
1282 %B print an unconditional branch offset
1283 %s print the shift field of an SSAT instruction
1284 %R print the rotation field of an SXT instruction
1285 %U print barrier type.
1286 %P print address for pli instruction.
1287 %c print the condition code
1288 %x print warning if conditional an not at end of IT block"
1289 %X print "\t; unpredictable <IT:code>" if conditional
1291 %<bitfield>d print bitfield in decimal
1292 %<bitfield>W print bitfield*4 in decimal
1293 %<bitfield>r print bitfield as an ARM register
1294 %<bitfield>c print bitfield as a condition code
1296 %<bitfield>'c print specified char iff bitfield is all ones
1297 %<bitfield>`c print specified char iff bitfield is all zeroes
1298 %<bitfield>?ab... select from array of values in big endian order
1300 With one exception at the bottom (done because BL and BLX(1) need
1301 to come dead last), this table was machine-sorted first in
1302 decreasing order of number of bits set in the mask, then in
1303 increasing numeric order of mask, then in increasing numeric order
1304 of opcode. This order is not the clearest for a human reader, but
1305 is guaranteed never to catch a special-case bit pattern with a more
1306 general mask, which is important, because this instruction encoding
1307 makes heavy use of special-case bit patterns. */
1308 static const struct opcode32 thumb32_opcodes[] =
1310 /* V7 instructions. */
1311 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1312 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1313 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1314 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1315 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1316 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1317 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1319 /* Instructions defined in the basic V6T2 set. */
1320 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1321 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1322 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1323 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1324 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1325 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1327 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1328 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1329 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1330 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1331 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1332 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1333 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1334 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1335 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1336 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1337 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1338 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1339 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1340 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1341 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1342 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1343 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1344 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1345 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1346 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1347 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1348 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1349 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1350 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1351 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1352 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1353 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1354 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1355 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1356 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1358 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1359 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1360 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1361 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1362 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
1363 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1364 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1365 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1366 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1368 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1369 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1370 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1371 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1372 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1373 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1374 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1375 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1376 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1377 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1378 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1379 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1380 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1381 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1382 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1384 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1385 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1387 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1388 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1389 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1390 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1391 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1397 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1398 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1399 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1400 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1406 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1407 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1408 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1409 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1410 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1413 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1414 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1415 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1416 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1417 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1418 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1419 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1420 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1421 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1422 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1423 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1424 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1425 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1426 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1427 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1428 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1429 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1430 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1431 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1432 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1433 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1434 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1435 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1440 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1441 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1442 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1443 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1444 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1445 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1446 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1447 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1448 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1449 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1450 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1452 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1453 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1454 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1455 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1456 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1457 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1458 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1459 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1460 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1461 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1462 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1463 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1464 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1465 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1466 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1467 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1468 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1469 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1470 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1471 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1472 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1473 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1474 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1475 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1476 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1477 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1478 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1479 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1480 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1481 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1482 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1483 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1484 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1485 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1486 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1487 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1488 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1489 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1490 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1491 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1492 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1493 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1494 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1495 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1496 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1497 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1498 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1500 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1501 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1502 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1503 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1504 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1506 /* These have been 32-bit since the invention of Thumb. */
1507 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1508 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1510 /* Fallback. */
1511 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1512 {0, 0, 0, 0}
1515 static const char *const arm_conditional[] =
1516 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1517 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1519 static const char *const arm_fp_const[] =
1520 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1522 static const char *const arm_shift[] =
1523 {"lsl", "lsr", "asr", "ror"};
1525 typedef struct
1527 const char *name;
1528 const char *description;
1529 const char *reg_names[16];
1531 arm_regname;
1533 static const arm_regname regnames[] =
1535 { "raw" , "Select raw register names",
1536 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1537 { "gcc", "Select register names used by GCC",
1538 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1539 { "std", "Select register names used in ARM's ISA documentation",
1540 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1541 { "apcs", "Select register names used in the APCS",
1542 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1543 { "atpcs", "Select register names used in the ATPCS",
1544 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1545 { "special-atpcs", "Select special register names used in the ATPCS",
1546 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1549 static const char *const iwmmxt_wwnames[] =
1550 {"b", "h", "w", "d"};
1552 static const char *const iwmmxt_wwssnames[] =
1553 {"b", "bus", "bc", "bss",
1554 "h", "hus", "hc", "hss",
1555 "w", "wus", "wc", "wss",
1556 "d", "dus", "dc", "dss"
1559 static const char *const iwmmxt_regnames[] =
1560 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1561 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1564 static const char *const iwmmxt_cregnames[] =
1565 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1566 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1569 /* Default to GCC register name set. */
1570 static unsigned int regname_selected = 1;
1572 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1573 #define arm_regnames regnames[regname_selected].reg_names
1575 static bfd_boolean force_thumb = FALSE;
1577 /* Current IT instruction state. This contains the same state as the IT
1578 bits in the CPSR. */
1579 static unsigned int ifthen_state;
1580 /* IT state for the next instruction. */
1581 static unsigned int ifthen_next_state;
1582 /* The address of the insn for which the IT state is valid. */
1583 static bfd_vma ifthen_address;
1584 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1586 /* Cached mapping symbol state. */
1587 enum map_type
1589 MAP_ARM,
1590 MAP_THUMB,
1591 MAP_DATA
1594 enum map_type last_type;
1595 int last_mapping_sym = -1;
1596 bfd_vma last_mapping_addr = 0;
1599 /* Functions. */
1601 get_arm_regname_num_options (void)
1603 return NUM_ARM_REGNAMES;
1607 set_arm_regname_option (int option)
1609 int old = regname_selected;
1610 regname_selected = option;
1611 return old;
1615 get_arm_regnames (int option,
1616 const char **setname,
1617 const char **setdescription,
1618 const char *const **register_names)
1620 *setname = regnames[option].name;
1621 *setdescription = regnames[option].description;
1622 *register_names = regnames[option].reg_names;
1623 return 16;
1626 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1627 Returns pointer to following character of the format string and
1628 fills in *VALUEP and *WIDTHP with the extracted value and number of
1629 bits extracted. WIDTHP can be NULL. */
1631 static const char *
1632 arm_decode_bitfield (const char *ptr,
1633 unsigned long insn,
1634 unsigned long *valuep,
1635 int *widthp)
1637 unsigned long value = 0;
1638 int width = 0;
1642 int start, end;
1643 int bits;
1645 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1646 start = start * 10 + *ptr - '0';
1647 if (*ptr == '-')
1648 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1649 end = end * 10 + *ptr - '0';
1650 else
1651 end = start;
1652 bits = end - start;
1653 if (bits < 0)
1654 abort ();
1655 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1656 width += bits + 1;
1658 while (*ptr++ == ',');
1659 *valuep = value;
1660 if (widthp)
1661 *widthp = width;
1662 return ptr - 1;
1665 static void
1666 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1667 bfd_boolean print_shift)
1669 func (stream, "%s", arm_regnames[given & 0xf]);
1671 if ((given & 0xff0) != 0)
1673 if ((given & 0x10) == 0)
1675 int amount = (given & 0xf80) >> 7;
1676 int shift = (given & 0x60) >> 5;
1678 if (amount == 0)
1680 if (shift == 3)
1682 func (stream, ", rrx");
1683 return;
1686 amount = 32;
1689 if (print_shift)
1690 func (stream, ", %s #%d", arm_shift[shift], amount);
1691 else
1692 func (stream, ", #%d", amount);
1694 else if ((given & 0x80) == 0x80)
1695 func (stream, ", <illegal shifter operand>");
1696 else if (print_shift)
1697 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1698 arm_regnames[(given & 0xf00) >> 8]);
1699 else
1700 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1704 /* Print one coprocessor instruction on INFO->STREAM.
1705 Return TRUE if the instuction matched, FALSE if this is not a
1706 recognised coprocessor instruction. */
1708 static bfd_boolean
1709 print_insn_coprocessor (bfd_vma pc,
1710 struct disassemble_info *info,
1711 long given,
1712 bfd_boolean thumb)
1714 const struct opcode32 *insn;
1715 void *stream = info->stream;
1716 fprintf_ftype func = info->fprintf_func;
1717 unsigned long mask;
1718 unsigned long value;
1719 unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
1720 int cond;
1722 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1724 signed long value_in_comment = 0;
1725 const char *c;
1727 if (insn->arch == 0)
1728 switch (insn->value)
1730 case SENTINEL_IWMMXT_START:
1731 if (info->mach != bfd_mach_arm_XScale
1732 && info->mach != bfd_mach_arm_iWMMXt
1733 && info->mach != bfd_mach_arm_iWMMXt2)
1735 insn++;
1736 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1737 continue;
1739 case SENTINEL_IWMMXT_END:
1740 continue;
1742 case SENTINEL_GENERIC_START:
1743 allowed_arches = ((arm_feature_set *) info->private_data)->core;
1744 continue;
1746 default:
1747 abort ();
1750 mask = insn->mask;
1751 value = insn->value;
1752 if (thumb)
1754 /* The high 4 bits are 0xe for Arm conditional instructions, and
1755 0xe for arm unconditional instructions. The rest of the
1756 encoding is the same. */
1757 mask |= 0xf0000000;
1758 value |= 0xe0000000;
1759 if (ifthen_state)
1760 cond = IFTHEN_COND;
1761 else
1762 cond = 16;
1764 else
1766 /* Only match unconditional instuctions against unconditional
1767 patterns. */
1768 if ((given & 0xf0000000) == 0xf0000000)
1770 mask |= 0xf0000000;
1771 cond = 16;
1773 else
1775 cond = (given >> 28) & 0xf;
1776 if (cond == 0xe)
1777 cond = 16;
1781 if ((given & mask) != value)
1782 continue;
1784 if ((insn->arch & allowed_arches) == 0)
1785 continue;
1787 for (c = insn->assembler; *c; c++)
1789 if (*c == '%')
1791 switch (*++c)
1793 case '%':
1794 func (stream, "%%");
1795 break;
1797 case 'A':
1799 int offset = given & 0xff;
1801 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1803 value_in_comment = offset * 4;
1804 if ((given & 0x00800000) == 0)
1805 value_in_comment = - value_in_comment;
1807 if ((given & (1 << 24)) != 0)
1809 if (offset)
1810 func (stream, ", #%d]%s",
1811 value_in_comment,
1812 ((given & 0x00200000) != 0 ? "!" : ""));
1813 else
1814 func (stream, "]");
1816 else
1818 func (stream, "]");
1820 if (given & (1 << 21))
1822 if (offset)
1823 func (stream, ", #%d", value_in_comment);
1825 else
1827 func (stream, ", {%d}", offset);
1828 value_in_comment = offset;
1832 break;
1834 case 'B':
1836 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1837 int offset = (given >> 1) & 0x3f;
1839 if (offset == 1)
1840 func (stream, "{d%d}", regno);
1841 else if (regno + offset > 32)
1842 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1843 else
1844 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1846 break;
1848 case 'C':
1850 int rn = (given >> 16) & 0xf;
1851 int offset = (given & 0xff) * 4;
1852 int add = (given >> 23) & 1;
1854 func (stream, "[%s", arm_regnames[rn]);
1856 if (offset)
1858 if (!add)
1859 offset = -offset;
1860 func (stream, ", #%d", offset);
1861 if (rn != 15)
1862 value_in_comment = offset;
1864 func (stream, "]");
1865 if (rn == 15)
1867 func (stream, "\t; ");
1868 /* FIXME: Unsure if info->bytes_per_chunk is the
1869 right thing to use here. */
1870 info->print_address_func (offset + pc
1871 + info->bytes_per_chunk * 2, info);
1874 break;
1876 case 'c':
1877 func (stream, "%s", arm_conditional[cond]);
1878 break;
1880 case 'I':
1881 /* Print a Cirrus/DSP shift immediate. */
1882 /* Immediates are 7bit signed ints with bits 0..3 in
1883 bits 0..3 of opcode and bits 4..6 in bits 5..7
1884 of opcode. */
1886 int imm;
1888 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1890 /* Is ``imm'' a negative number? */
1891 if (imm & 0x40)
1892 imm |= (-1 << 7);
1894 func (stream, "%d", imm);
1897 break;
1899 case 'F':
1900 switch (given & 0x00408000)
1902 case 0:
1903 func (stream, "4");
1904 break;
1905 case 0x8000:
1906 func (stream, "1");
1907 break;
1908 case 0x00400000:
1909 func (stream, "2");
1910 break;
1911 default:
1912 func (stream, "3");
1914 break;
1916 case 'P':
1917 switch (given & 0x00080080)
1919 case 0:
1920 func (stream, "s");
1921 break;
1922 case 0x80:
1923 func (stream, "d");
1924 break;
1925 case 0x00080000:
1926 func (stream, "e");
1927 break;
1928 default:
1929 func (stream, _("<illegal precision>"));
1930 break;
1932 break;
1934 case 'Q':
1935 switch (given & 0x00408000)
1937 case 0:
1938 func (stream, "s");
1939 break;
1940 case 0x8000:
1941 func (stream, "d");
1942 break;
1943 case 0x00400000:
1944 func (stream, "e");
1945 break;
1946 default:
1947 func (stream, "p");
1948 break;
1950 break;
1952 case 'R':
1953 switch (given & 0x60)
1955 case 0:
1956 break;
1957 case 0x20:
1958 func (stream, "p");
1959 break;
1960 case 0x40:
1961 func (stream, "m");
1962 break;
1963 default:
1964 func (stream, "z");
1965 break;
1967 break;
1969 case '0': case '1': case '2': case '3': case '4':
1970 case '5': case '6': case '7': case '8': case '9':
1972 int width;
1973 unsigned long value;
1975 c = arm_decode_bitfield (c, given, &value, &width);
1977 switch (*c)
1979 case 'r':
1980 func (stream, "%s", arm_regnames[value]);
1981 break;
1982 case 'D':
1983 func (stream, "d%ld", value);
1984 break;
1985 case 'Q':
1986 if (value & 1)
1987 func (stream, "<illegal reg q%ld.5>", value >> 1);
1988 else
1989 func (stream, "q%ld", value >> 1);
1990 break;
1991 case 'd':
1992 func (stream, "%ld", value);
1993 value_in_comment = value;
1994 break;
1995 case 'k':
1997 int from = (given & (1 << 7)) ? 32 : 16;
1998 func (stream, "%ld", from - value);
2000 break;
2002 case 'f':
2003 if (value > 7)
2004 func (stream, "#%s", arm_fp_const[value & 7]);
2005 else
2006 func (stream, "f%ld", value);
2007 break;
2009 case 'w':
2010 if (width == 2)
2011 func (stream, "%s", iwmmxt_wwnames[value]);
2012 else
2013 func (stream, "%s", iwmmxt_wwssnames[value]);
2014 break;
2016 case 'g':
2017 func (stream, "%s", iwmmxt_regnames[value]);
2018 break;
2019 case 'G':
2020 func (stream, "%s", iwmmxt_cregnames[value]);
2021 break;
2023 case 'x':
2024 func (stream, "0x%lx", (value & 0xffffffffUL));
2025 break;
2027 case '`':
2028 c++;
2029 if (value == 0)
2030 func (stream, "%c", *c);
2031 break;
2032 case '\'':
2033 c++;
2034 if (value == ((1ul << width) - 1))
2035 func (stream, "%c", *c);
2036 break;
2037 case '?':
2038 func (stream, "%c", c[(1 << width) - (int) value]);
2039 c += 1 << width;
2040 break;
2041 default:
2042 abort ();
2044 break;
2046 case 'y':
2047 case 'z':
2049 int single = *c++ == 'y';
2050 int regno;
2052 switch (*c)
2054 case '4': /* Sm pair */
2055 case '0': /* Sm, Dm */
2056 regno = given & 0x0000000f;
2057 if (single)
2059 regno <<= 1;
2060 regno += (given >> 5) & 1;
2062 else
2063 regno += ((given >> 5) & 1) << 4;
2064 break;
2066 case '1': /* Sd, Dd */
2067 regno = (given >> 12) & 0x0000000f;
2068 if (single)
2070 regno <<= 1;
2071 regno += (given >> 22) & 1;
2073 else
2074 regno += ((given >> 22) & 1) << 4;
2075 break;
2077 case '2': /* Sn, Dn */
2078 regno = (given >> 16) & 0x0000000f;
2079 if (single)
2081 regno <<= 1;
2082 regno += (given >> 7) & 1;
2084 else
2085 regno += ((given >> 7) & 1) << 4;
2086 break;
2088 case '3': /* List */
2089 func (stream, "{");
2090 regno = (given >> 12) & 0x0000000f;
2091 if (single)
2093 regno <<= 1;
2094 regno += (given >> 22) & 1;
2096 else
2097 regno += ((given >> 22) & 1) << 4;
2098 break;
2100 default:
2101 abort ();
2104 func (stream, "%c%d", single ? 's' : 'd', regno);
2106 if (*c == '3')
2108 int count = given & 0xff;
2110 if (single == 0)
2111 count >>= 1;
2113 if (--count)
2115 func (stream, "-%c%d",
2116 single ? 's' : 'd',
2117 regno + count);
2120 func (stream, "}");
2122 else if (*c == '4')
2123 func (stream, ", %c%d", single ? 's' : 'd',
2124 regno + 1);
2126 break;
2128 case 'L':
2129 switch (given & 0x00400100)
2131 case 0x00000000: func (stream, "b"); break;
2132 case 0x00400000: func (stream, "h"); break;
2133 case 0x00000100: func (stream, "w"); break;
2134 case 0x00400100: func (stream, "d"); break;
2135 default:
2136 break;
2138 break;
2140 case 'Z':
2142 int value;
2143 /* given (20, 23) | given (0, 3) */
2144 value = ((given >> 16) & 0xf0) | (given & 0xf);
2145 func (stream, "%d", value);
2147 break;
2149 case 'l':
2150 /* This is like the 'A' operator, except that if
2151 the width field "M" is zero, then the offset is
2152 *not* multiplied by four. */
2154 int offset = given & 0xff;
2155 int multiplier = (given & 0x00000100) ? 4 : 1;
2157 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2159 if (multiplier > 1)
2161 value_in_comment = offset * multiplier;
2162 if ((given & 0x00800000) == 0)
2163 value_in_comment = - value_in_comment;
2166 if (offset)
2168 if ((given & 0x01000000) != 0)
2169 func (stream, ", #%s%d]%s",
2170 ((given & 0x00800000) == 0 ? "-" : ""),
2171 offset * multiplier,
2172 ((given & 0x00200000) != 0 ? "!" : ""));
2173 else
2174 func (stream, "], #%s%d",
2175 ((given & 0x00800000) == 0 ? "-" : ""),
2176 offset * multiplier);
2178 else
2179 func (stream, "]");
2181 break;
2183 case 'r':
2185 int imm4 = (given >> 4) & 0xf;
2186 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2187 int ubit = (given >> 23) & 1;
2188 const char *rm = arm_regnames [given & 0xf];
2189 const char *rn = arm_regnames [(given >> 16) & 0xf];
2191 switch (puw_bits)
2193 case 1:
2194 case 3:
2195 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2196 if (imm4)
2197 func (stream, ", lsl #%d", imm4);
2198 break;
2200 case 4:
2201 case 5:
2202 case 6:
2203 case 7:
2204 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2205 if (imm4 > 0)
2206 func (stream, ", lsl #%d", imm4);
2207 func (stream, "]");
2208 if (puw_bits == 5 || puw_bits == 7)
2209 func (stream, "!");
2210 break;
2212 default:
2213 func (stream, "INVALID");
2216 break;
2218 case 'i':
2220 long imm5;
2221 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2222 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2224 break;
2226 default:
2227 abort ();
2231 else
2232 func (stream, "%c", *c);
2235 if (value_in_comment > 32 || value_in_comment < -16)
2236 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2238 return TRUE;
2240 return FALSE;
2243 /* Decodes and prints ARM addressing modes. Returns the offset
2244 used in the address, if any, if it is worthwhile printing the
2245 offset as a hexadecimal value in a comment at the end of the
2246 line of disassembly. */
2248 static signed long
2249 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2251 void *stream = info->stream;
2252 fprintf_ftype func = info->fprintf_func;
2253 int offset = 0;
2255 if (((given & 0x000f0000) == 0x000f0000)
2256 && ((given & 0x02000000) == 0))
2258 offset = given & 0xfff;
2260 func (stream, "[pc");
2262 if (given & 0x01000000)
2264 if ((given & 0x00800000) == 0)
2265 offset = - offset;
2267 /* Pre-indexed. */
2268 func (stream, ", #%d]", offset);
2270 offset += pc + 8;
2272 /* Cope with the possibility of write-back
2273 being used. Probably a very dangerous thing
2274 for the programmer to do, but who are we to
2275 argue ? */
2276 if (given & 0x00200000)
2277 func (stream, "!");
2279 else
2281 /* Post indexed. */
2282 func (stream, "], #%d", offset);
2284 /* ie ignore the offset. */
2285 offset = pc + 8;
2288 func (stream, "\t; ");
2289 info->print_address_func (offset, info);
2290 offset = 0;
2292 else
2294 func (stream, "[%s",
2295 arm_regnames[(given >> 16) & 0xf]);
2296 if ((given & 0x01000000) != 0)
2298 if ((given & 0x02000000) == 0)
2300 offset = given & 0xfff;
2301 if (offset)
2302 func (stream, ", #%s%d",
2303 (((given & 0x00800000) == 0)
2304 ? "-" : ""), offset);
2306 else
2308 func (stream, ", %s",
2309 (((given & 0x00800000) == 0)
2310 ? "-" : ""));
2311 arm_decode_shift (given, func, stream, TRUE);
2314 func (stream, "]%s",
2315 ((given & 0x00200000) != 0) ? "!" : "");
2317 else
2319 if ((given & 0x02000000) == 0)
2321 offset = given & 0xfff;
2322 if (offset)
2323 func (stream, "], #%s%d",
2324 (((given & 0x00800000) == 0)
2325 ? "-" : ""), offset);
2326 else
2327 func (stream, "]");
2329 else
2331 func (stream, "], %s",
2332 (((given & 0x00800000) == 0)
2333 ? "-" : ""));
2334 arm_decode_shift (given, func, stream, TRUE);
2339 return (signed long) offset;
2342 /* Print one neon instruction on INFO->STREAM.
2343 Return TRUE if the instuction matched, FALSE if this is not a
2344 recognised neon instruction. */
2346 static bfd_boolean
2347 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2349 const struct opcode32 *insn;
2350 void *stream = info->stream;
2351 fprintf_ftype func = info->fprintf_func;
2353 if (thumb)
2355 if ((given & 0xef000000) == 0xef000000)
2357 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2358 unsigned long bit28 = given & (1 << 28);
2360 given &= 0x00ffffff;
2361 if (bit28)
2362 given |= 0xf3000000;
2363 else
2364 given |= 0xf2000000;
2366 else if ((given & 0xff000000) == 0xf9000000)
2367 given ^= 0xf9000000 ^ 0xf4000000;
2368 else
2369 return FALSE;
2372 for (insn = neon_opcodes; insn->assembler; insn++)
2374 if ((given & insn->mask) == insn->value)
2376 signed long value_in_comment = 0;
2377 const char *c;
2379 for (c = insn->assembler; *c; c++)
2381 if (*c == '%')
2383 switch (*++c)
2385 case '%':
2386 func (stream, "%%");
2387 break;
2389 case 'c':
2390 if (thumb && ifthen_state)
2391 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2392 break;
2394 case 'A':
2396 static const unsigned char enc[16] =
2398 0x4, 0x14, /* st4 0,1 */
2399 0x4, /* st1 2 */
2400 0x4, /* st2 3 */
2401 0x3, /* st3 4 */
2402 0x13, /* st3 5 */
2403 0x3, /* st1 6 */
2404 0x1, /* st1 7 */
2405 0x2, /* st2 8 */
2406 0x12, /* st2 9 */
2407 0x2, /* st1 10 */
2408 0, 0, 0, 0, 0
2410 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2411 int rn = ((given >> 16) & 0xf);
2412 int rm = ((given >> 0) & 0xf);
2413 int align = ((given >> 4) & 0x3);
2414 int type = ((given >> 8) & 0xf);
2415 int n = enc[type] & 0xf;
2416 int stride = (enc[type] >> 4) + 1;
2417 int ix;
2419 func (stream, "{");
2420 if (stride > 1)
2421 for (ix = 0; ix != n; ix++)
2422 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2423 else if (n == 1)
2424 func (stream, "d%d", rd);
2425 else
2426 func (stream, "d%d-d%d", rd, rd + n - 1);
2427 func (stream, "}, [%s", arm_regnames[rn]);
2428 if (align)
2429 func (stream, ", :%d", 32 << align);
2430 func (stream, "]");
2431 if (rm == 0xd)
2432 func (stream, "!");
2433 else if (rm != 0xf)
2434 func (stream, ", %s", arm_regnames[rm]);
2436 break;
2438 case 'B':
2440 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2441 int rn = ((given >> 16) & 0xf);
2442 int rm = ((given >> 0) & 0xf);
2443 int idx_align = ((given >> 4) & 0xf);
2444 int align = 0;
2445 int size = ((given >> 10) & 0x3);
2446 int idx = idx_align >> (size + 1);
2447 int length = ((given >> 8) & 3) + 1;
2448 int stride = 1;
2449 int i;
2451 if (length > 1 && size > 0)
2452 stride = (idx_align & (1 << size)) ? 2 : 1;
2454 switch (length)
2456 case 1:
2458 int amask = (1 << size) - 1;
2459 if ((idx_align & (1 << size)) != 0)
2460 return FALSE;
2461 if (size > 0)
2463 if ((idx_align & amask) == amask)
2464 align = 8 << size;
2465 else if ((idx_align & amask) != 0)
2466 return FALSE;
2469 break;
2471 case 2:
2472 if (size == 2 && (idx_align & 2) != 0)
2473 return FALSE;
2474 align = (idx_align & 1) ? 16 << size : 0;
2475 break;
2477 case 3:
2478 if ((size == 2 && (idx_align & 3) != 0)
2479 || (idx_align & 1) != 0)
2480 return FALSE;
2481 break;
2483 case 4:
2484 if (size == 2)
2486 if ((idx_align & 3) == 3)
2487 return FALSE;
2488 align = (idx_align & 3) * 64;
2490 else
2491 align = (idx_align & 1) ? 32 << size : 0;
2492 break;
2494 default:
2495 abort ();
2498 func (stream, "{");
2499 for (i = 0; i < length; i++)
2500 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2501 rd + i * stride, idx);
2502 func (stream, "}, [%s", arm_regnames[rn]);
2503 if (align)
2504 func (stream, ", :%d", align);
2505 func (stream, "]");
2506 if (rm == 0xd)
2507 func (stream, "!");
2508 else if (rm != 0xf)
2509 func (stream, ", %s", arm_regnames[rm]);
2511 break;
2513 case 'C':
2515 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2516 int rn = ((given >> 16) & 0xf);
2517 int rm = ((given >> 0) & 0xf);
2518 int align = ((given >> 4) & 0x1);
2519 int size = ((given >> 6) & 0x3);
2520 int type = ((given >> 8) & 0x3);
2521 int n = type + 1;
2522 int stride = ((given >> 5) & 0x1);
2523 int ix;
2525 if (stride && (n == 1))
2526 n++;
2527 else
2528 stride++;
2530 func (stream, "{");
2531 if (stride > 1)
2532 for (ix = 0; ix != n; ix++)
2533 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2534 else if (n == 1)
2535 func (stream, "d%d[]", rd);
2536 else
2537 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2538 func (stream, "}, [%s", arm_regnames[rn]);
2539 if (align)
2541 int align = (8 * (type + 1)) << size;
2542 if (type == 3)
2543 align = (size > 1) ? align >> 1 : align;
2544 if (type == 2 || (type == 0 && !size))
2545 func (stream, ", :<bad align %d>", align);
2546 else
2547 func (stream, ", :%d", align);
2549 func (stream, "]");
2550 if (rm == 0xd)
2551 func (stream, "!");
2552 else if (rm != 0xf)
2553 func (stream, ", %s", arm_regnames[rm]);
2555 break;
2557 case 'D':
2559 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2560 int size = (given >> 20) & 3;
2561 int reg = raw_reg & ((4 << size) - 1);
2562 int ix = raw_reg >> size >> 2;
2564 func (stream, "d%d[%d]", reg, ix);
2566 break;
2568 case 'E':
2569 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2571 int bits = 0;
2572 int cmode = (given >> 8) & 0xf;
2573 int op = (given >> 5) & 0x1;
2574 unsigned long value = 0, hival = 0;
2575 unsigned shift;
2576 int size = 0;
2577 int isfloat = 0;
2579 bits |= ((given >> 24) & 1) << 7;
2580 bits |= ((given >> 16) & 7) << 4;
2581 bits |= ((given >> 0) & 15) << 0;
2583 if (cmode < 8)
2585 shift = (cmode >> 1) & 3;
2586 value = (unsigned long) bits << (8 * shift);
2587 size = 32;
2589 else if (cmode < 12)
2591 shift = (cmode >> 1) & 1;
2592 value = (unsigned long) bits << (8 * shift);
2593 size = 16;
2595 else if (cmode < 14)
2597 shift = (cmode & 1) + 1;
2598 value = (unsigned long) bits << (8 * shift);
2599 value |= (1ul << (8 * shift)) - 1;
2600 size = 32;
2602 else if (cmode == 14)
2604 if (op)
2606 /* Bit replication into bytes. */
2607 int ix;
2608 unsigned long mask;
2610 value = 0;
2611 hival = 0;
2612 for (ix = 7; ix >= 0; ix--)
2614 mask = ((bits >> ix) & 1) ? 0xff : 0;
2615 if (ix <= 3)
2616 value = (value << 8) | mask;
2617 else
2618 hival = (hival << 8) | mask;
2620 size = 64;
2622 else
2624 /* Byte replication. */
2625 value = (unsigned long) bits;
2626 size = 8;
2629 else if (!op)
2631 /* Floating point encoding. */
2632 int tmp;
2634 value = (unsigned long) (bits & 0x7f) << 19;
2635 value |= (unsigned long) (bits & 0x80) << 24;
2636 tmp = bits & 0x40 ? 0x3c : 0x40;
2637 value |= (unsigned long) tmp << 24;
2638 size = 32;
2639 isfloat = 1;
2641 else
2643 func (stream, "<illegal constant %.8x:%x:%x>",
2644 bits, cmode, op);
2645 size = 32;
2646 break;
2648 switch (size)
2650 case 8:
2651 func (stream, "#%ld\t; 0x%.2lx", value, value);
2652 break;
2654 case 16:
2655 func (stream, "#%ld\t; 0x%.4lx", value, value);
2656 break;
2658 case 32:
2659 if (isfloat)
2661 unsigned char valbytes[4];
2662 double fvalue;
2664 /* Do this a byte at a time so we don't have to
2665 worry about the host's endianness. */
2666 valbytes[0] = value & 0xff;
2667 valbytes[1] = (value >> 8) & 0xff;
2668 valbytes[2] = (value >> 16) & 0xff;
2669 valbytes[3] = (value >> 24) & 0xff;
2671 floatformat_to_double
2672 (&floatformat_ieee_single_little, valbytes,
2673 &fvalue);
2675 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2676 value);
2678 else
2679 func (stream, "#%ld\t; 0x%.8lx",
2680 (long) ((value & 0x80000000)
2681 ? value | ~0xffffffffl : value), value);
2682 break;
2684 case 64:
2685 func (stream, "#0x%.8lx%.8lx", hival, value);
2686 break;
2688 default:
2689 abort ();
2692 break;
2694 case 'F':
2696 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2697 int num = (given >> 8) & 0x3;
2699 if (!num)
2700 func (stream, "{d%d}", regno);
2701 else if (num + regno >= 32)
2702 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2703 else
2704 func (stream, "{d%d-d%d}", regno, regno + num);
2706 break;
2709 case '0': case '1': case '2': case '3': case '4':
2710 case '5': case '6': case '7': case '8': case '9':
2712 int width;
2713 unsigned long value;
2715 c = arm_decode_bitfield (c, given, &value, &width);
2717 switch (*c)
2719 case 'r':
2720 func (stream, "%s", arm_regnames[value]);
2721 break;
2722 case 'd':
2723 func (stream, "%ld", value);
2724 value_in_comment = value;
2725 break;
2726 case 'e':
2727 func (stream, "%ld", (1ul << width) - value);
2728 break;
2730 case 'S':
2731 case 'T':
2732 case 'U':
2733 /* Various width encodings. */
2735 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2736 int limit;
2737 unsigned low, high;
2739 c++;
2740 if (*c >= '0' && *c <= '9')
2741 limit = *c - '0';
2742 else if (*c >= 'a' && *c <= 'f')
2743 limit = *c - 'a' + 10;
2744 else
2745 abort ();
2746 low = limit >> 2;
2747 high = limit & 3;
2749 if (value < low || value > high)
2750 func (stream, "<illegal width %d>", base << value);
2751 else
2752 func (stream, "%d", base << value);
2754 break;
2755 case 'R':
2756 if (given & (1 << 6))
2757 goto Q;
2758 /* FALLTHROUGH */
2759 case 'D':
2760 func (stream, "d%ld", value);
2761 break;
2762 case 'Q':
2764 if (value & 1)
2765 func (stream, "<illegal reg q%ld.5>", value >> 1);
2766 else
2767 func (stream, "q%ld", value >> 1);
2768 break;
2770 case '`':
2771 c++;
2772 if (value == 0)
2773 func (stream, "%c", *c);
2774 break;
2775 case '\'':
2776 c++;
2777 if (value == ((1ul << width) - 1))
2778 func (stream, "%c", *c);
2779 break;
2780 case '?':
2781 func (stream, "%c", c[(1 << width) - (int) value]);
2782 c += 1 << width;
2783 break;
2784 default:
2785 abort ();
2787 break;
2789 default:
2790 abort ();
2794 else
2795 func (stream, "%c", *c);
2798 if (value_in_comment > 32 || value_in_comment < -16)
2799 func (stream, "\t; 0x%lx", value_in_comment);
2801 return TRUE;
2804 return FALSE;
2807 /* Print one ARM instruction from PC on INFO->STREAM. */
2809 static void
2810 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2812 const struct opcode32 *insn;
2813 void *stream = info->stream;
2814 fprintf_ftype func = info->fprintf_func;
2816 if (print_insn_coprocessor (pc, info, given, FALSE))
2817 return;
2819 if (print_insn_neon (info, given, FALSE))
2820 return;
2822 for (insn = arm_opcodes; insn->assembler; insn++)
2824 if ((given & insn->mask) != insn->value)
2825 continue;
2827 if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
2828 continue;
2830 /* Special case: an instruction with all bits set in the condition field
2831 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2832 or by the catchall at the end of the table. */
2833 if ((given & 0xF0000000) != 0xF0000000
2834 || (insn->mask & 0xF0000000) == 0xF0000000
2835 || (insn->mask == 0 && insn->value == 0))
2837 signed long value_in_comment = 0;
2838 const char *c;
2840 for (c = insn->assembler; *c; c++)
2842 if (*c == '%')
2844 switch (*++c)
2846 case '%':
2847 func (stream, "%%");
2848 break;
2850 case 'a':
2851 value_in_comment = print_arm_address (pc, info, given);
2852 break;
2854 case 'P':
2855 /* Set P address bit and use normal address
2856 printing routine. */
2857 value_in_comment = print_arm_address (pc, info, given | (1 << 24));
2858 break;
2860 case 's':
2861 if ((given & 0x004f0000) == 0x004f0000)
2863 /* PC relative with immediate offset. */
2864 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2866 if ((given & 0x00800000) == 0)
2867 offset = -offset;
2869 func (stream, "[pc, #%d]\t; ", offset);
2870 info->print_address_func (offset + pc + 8, info);
2872 else
2874 bfd_boolean negative = (given & 0x00800000) == 0;
2875 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2877 if (negative)
2878 offset = -offset;
2880 func (stream, "[%s",
2881 arm_regnames[(given >> 16) & 0xf]);
2883 if ((given & 0x01000000) != 0)
2885 /* Pre-indexed. */
2886 if ((given & 0x00400000) == 0x00400000)
2888 /* Immediate. */
2889 if (offset)
2890 func (stream, ", #%d", offset);
2891 value_in_comment = offset;
2893 else
2895 /* Register. */
2896 func (stream, ", %s%s", negative ? "-" : "",
2897 arm_regnames[given & 0xf]);
2900 func (stream, "]%s",
2901 ((given & 0x00200000) != 0) ? "!" : "");
2903 else
2905 /* Post-indexed. */
2906 if ((given & 0x00400000) == 0x00400000)
2908 /* Immediate. */
2909 if (offset)
2910 func (stream, "], #%d", offset);
2911 else
2912 func (stream, "]");
2914 value_in_comment = offset;
2916 else
2918 /* Register. */
2919 func (stream, "], %s%s", negative ? "-" : "",
2920 arm_regnames[given & 0xf]);
2924 break;
2926 case 'b':
2928 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2929 info->print_address_func (disp * 4 + pc + 8, info);
2931 break;
2933 case 'c':
2934 if (((given >> 28) & 0xf) != 0xe)
2935 func (stream, "%s",
2936 arm_conditional [(given >> 28) & 0xf]);
2937 break;
2939 case 'm':
2941 int started = 0;
2942 int reg;
2944 func (stream, "{");
2945 for (reg = 0; reg < 16; reg++)
2946 if ((given & (1 << reg)) != 0)
2948 if (started)
2949 func (stream, ", ");
2950 started = 1;
2951 func (stream, "%s", arm_regnames[reg]);
2953 func (stream, "}");
2955 break;
2957 case 'q':
2958 arm_decode_shift (given, func, stream, FALSE);
2959 break;
2961 case 'o':
2962 if ((given & 0x02000000) != 0)
2964 int rotate = (given & 0xf00) >> 7;
2965 int immed = (given & 0xff);
2967 immed = (((immed << (32 - rotate))
2968 | (immed >> rotate)) & 0xffffffff);
2969 func (stream, "#%d", immed);
2970 value_in_comment = immed;
2972 else
2973 arm_decode_shift (given, func, stream, TRUE);
2974 break;
2976 case 'p':
2977 if ((given & 0x0000f000) == 0x0000f000)
2978 func (stream, "p");
2979 break;
2981 case 't':
2982 if ((given & 0x01200000) == 0x00200000)
2983 func (stream, "t");
2984 break;
2986 case 'A':
2988 int offset = given & 0xff;
2990 value_in_comment = offset * 4;
2991 if ((given & 0x00800000) == 0)
2992 value_in_comment = - value_in_comment;
2994 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2996 if ((given & (1 << 24)) != 0)
2998 if (offset)
2999 func (stream, ", #%d]%s",
3000 value_in_comment,
3001 ((given & 0x00200000) != 0 ? "!" : ""));
3002 else
3003 func (stream, "]");
3005 else
3007 func (stream, "]");
3009 if (given & (1 << 21))
3011 if (offset)
3012 func (stream, ", #%d", value_in_comment);
3014 else
3016 func (stream, ", {%d}", offset);
3017 value_in_comment = offset;
3021 break;
3023 case 'B':
3024 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3026 bfd_vma address;
3027 bfd_vma offset = 0;
3029 if (given & 0x00800000)
3030 /* Is signed, hi bits should be ones. */
3031 offset = (-1) ^ 0x00ffffff;
3033 /* Offset is (SignExtend(offset field)<<2). */
3034 offset += given & 0x00ffffff;
3035 offset <<= 2;
3036 address = offset + pc + 8;
3038 if (given & 0x01000000)
3039 /* H bit allows addressing to 2-byte boundaries. */
3040 address += 2;
3042 info->print_address_func (address, info);
3044 break;
3046 case 'C':
3047 func (stream, "_");
3048 if (given & 0x80000)
3049 func (stream, "f");
3050 if (given & 0x40000)
3051 func (stream, "s");
3052 if (given & 0x20000)
3053 func (stream, "x");
3054 if (given & 0x10000)
3055 func (stream, "c");
3056 break;
3058 case 'U':
3059 switch (given & 0xf)
3061 case 0xf: func (stream, "sy"); break;
3062 case 0x7: func (stream, "un"); break;
3063 case 0xe: func (stream, "st"); break;
3064 case 0x6: func (stream, "unst"); break;
3065 default:
3066 func (stream, "#%d", (int) given & 0xf);
3067 break;
3069 break;
3071 case '0': case '1': case '2': case '3': case '4':
3072 case '5': case '6': case '7': case '8': case '9':
3074 int width;
3075 unsigned long value;
3077 c = arm_decode_bitfield (c, given, &value, &width);
3079 switch (*c)
3081 case 'r':
3082 func (stream, "%s", arm_regnames[value]);
3083 break;
3084 case 'd':
3085 func (stream, "%ld", value);
3086 value_in_comment = value;
3087 break;
3088 case 'b':
3089 func (stream, "%ld", value * 8);
3090 value_in_comment = value * 8;
3091 break;
3092 case 'W':
3093 func (stream, "%ld", value + 1);
3094 value_in_comment = value + 1;
3095 break;
3096 case 'x':
3097 func (stream, "0x%08lx", value);
3099 /* Some SWI instructions have special
3100 meanings. */
3101 if ((given & 0x0fffffff) == 0x0FF00000)
3102 func (stream, "\t; IMB");
3103 else if ((given & 0x0fffffff) == 0x0FF00001)
3104 func (stream, "\t; IMBRange");
3105 break;
3106 case 'X':
3107 func (stream, "%01lx", value & 0xf);
3108 value_in_comment = value;
3109 break;
3110 case '`':
3111 c++;
3112 if (value == 0)
3113 func (stream, "%c", *c);
3114 break;
3115 case '\'':
3116 c++;
3117 if (value == ((1ul << width) - 1))
3118 func (stream, "%c", *c);
3119 break;
3120 case '?':
3121 func (stream, "%c", c[(1 << width) - (int) value]);
3122 c += 1 << width;
3123 break;
3124 default:
3125 abort ();
3127 break;
3129 case 'e':
3131 int imm;
3133 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3134 func (stream, "%d", imm);
3135 value_in_comment = imm;
3137 break;
3139 case 'E':
3140 /* LSB and WIDTH fields of BFI or BFC. The machine-
3141 language instruction encodes LSB and MSB. */
3143 long msb = (given & 0x001f0000) >> 16;
3144 long lsb = (given & 0x00000f80) >> 7;
3145 long width = msb - lsb + 1;
3147 if (width > 0)
3148 func (stream, "#%lu, #%lu", lsb, width);
3149 else
3150 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3152 break;
3154 case 'V':
3155 /* 16-bit unsigned immediate from a MOVT or MOVW
3156 instruction, encoded in bits 0:11 and 15:19. */
3158 long hi = (given & 0x000f0000) >> 4;
3159 long lo = (given & 0x00000fff);
3160 long imm16 = hi | lo;
3162 func (stream, "#%lu", imm16);
3163 value_in_comment = imm16;
3165 break;
3167 default:
3168 abort ();
3172 else
3173 func (stream, "%c", *c);
3176 if (value_in_comment > 32 || value_in_comment < -16)
3177 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3178 return;
3181 abort ();
3184 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3186 static void
3187 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3189 const struct opcode16 *insn;
3190 void *stream = info->stream;
3191 fprintf_ftype func = info->fprintf_func;
3193 for (insn = thumb_opcodes; insn->assembler; insn++)
3194 if ((given & insn->mask) == insn->value)
3196 signed long value_in_comment = 0;
3197 const char *c = insn->assembler;
3199 for (; *c; c++)
3201 int domaskpc = 0;
3202 int domasklr = 0;
3204 if (*c != '%')
3206 func (stream, "%c", *c);
3207 continue;
3210 switch (*++c)
3212 case '%':
3213 func (stream, "%%");
3214 break;
3216 case 'c':
3217 if (ifthen_state)
3218 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3219 break;
3221 case 'C':
3222 if (ifthen_state)
3223 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3224 else
3225 func (stream, "s");
3226 break;
3228 case 'I':
3230 unsigned int tmp;
3232 ifthen_next_state = given & 0xff;
3233 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3234 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3235 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3237 break;
3239 case 'x':
3240 if (ifthen_next_state)
3241 func (stream, "\t; unpredictable branch in IT block\n");
3242 break;
3244 case 'X':
3245 if (ifthen_state)
3246 func (stream, "\t; unpredictable <IT:%s>",
3247 arm_conditional[IFTHEN_COND]);
3248 break;
3250 case 'S':
3252 long reg;
3254 reg = (given >> 3) & 0x7;
3255 if (given & (1 << 6))
3256 reg += 8;
3258 func (stream, "%s", arm_regnames[reg]);
3260 break;
3262 case 'D':
3264 long reg;
3266 reg = given & 0x7;
3267 if (given & (1 << 7))
3268 reg += 8;
3270 func (stream, "%s", arm_regnames[reg]);
3272 break;
3274 case 'N':
3275 if (given & (1 << 8))
3276 domasklr = 1;
3277 /* Fall through. */
3278 case 'O':
3279 if (*c == 'O' && (given & (1 << 8)))
3280 domaskpc = 1;
3281 /* Fall through. */
3282 case 'M':
3284 int started = 0;
3285 int reg;
3287 func (stream, "{");
3289 /* It would be nice if we could spot
3290 ranges, and generate the rS-rE format: */
3291 for (reg = 0; (reg < 8); reg++)
3292 if ((given & (1 << reg)) != 0)
3294 if (started)
3295 func (stream, ", ");
3296 started = 1;
3297 func (stream, "%s", arm_regnames[reg]);
3300 if (domasklr)
3302 if (started)
3303 func (stream, ", ");
3304 started = 1;
3305 func (stream, arm_regnames[14] /* "lr" */);
3308 if (domaskpc)
3310 if (started)
3311 func (stream, ", ");
3312 func (stream, arm_regnames[15] /* "pc" */);
3315 func (stream, "}");
3317 break;
3319 case 'b':
3320 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3322 bfd_vma address = (pc + 4
3323 + ((given & 0x00f8) >> 2)
3324 + ((given & 0x0200) >> 3));
3325 info->print_address_func (address, info);
3327 break;
3329 case 's':
3330 /* Right shift immediate -- bits 6..10; 1-31 print
3331 as themselves, 0 prints as 32. */
3333 long imm = (given & 0x07c0) >> 6;
3334 if (imm == 0)
3335 imm = 32;
3336 func (stream, "#%ld", imm);
3338 break;
3340 case '0': case '1': case '2': case '3': case '4':
3341 case '5': case '6': case '7': case '8': case '9':
3343 int bitstart = *c++ - '0';
3344 int bitend = 0;
3346 while (*c >= '0' && *c <= '9')
3347 bitstart = (bitstart * 10) + *c++ - '0';
3349 switch (*c)
3351 case '-':
3353 long reg;
3355 c++;
3356 while (*c >= '0' && *c <= '9')
3357 bitend = (bitend * 10) + *c++ - '0';
3358 if (!bitend)
3359 abort ();
3360 reg = given >> bitstart;
3361 reg &= (2 << (bitend - bitstart)) - 1;
3362 switch (*c)
3364 case 'r':
3365 func (stream, "%s", arm_regnames[reg]);
3366 break;
3368 case 'd':
3369 func (stream, "%ld", reg);
3370 value_in_comment = reg;
3371 break;
3373 case 'H':
3374 func (stream, "%ld", reg << 1);
3375 value_in_comment = reg << 1;
3376 break;
3378 case 'W':
3379 func (stream, "%ld", reg << 2);
3380 value_in_comment = reg << 2;
3381 break;
3383 case 'a':
3384 /* PC-relative address -- the bottom two
3385 bits of the address are dropped
3386 before the calculation. */
3387 info->print_address_func
3388 (((pc + 4) & ~3) + (reg << 2), info);
3389 value_in_comment = 0;
3390 break;
3392 case 'x':
3393 func (stream, "0x%04lx", reg);
3394 break;
3396 case 'B':
3397 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3398 info->print_address_func (reg * 2 + pc + 4, info);
3399 value_in_comment = 0;
3400 break;
3402 case 'c':
3403 func (stream, "%s", arm_conditional [reg]);
3404 break;
3406 default:
3407 abort ();
3410 break;
3412 case '\'':
3413 c++;
3414 if ((given & (1 << bitstart)) != 0)
3415 func (stream, "%c", *c);
3416 break;
3418 case '?':
3419 ++c;
3420 if ((given & (1 << bitstart)) != 0)
3421 func (stream, "%c", *c++);
3422 else
3423 func (stream, "%c", *++c);
3424 break;
3426 default:
3427 abort ();
3430 break;
3432 default:
3433 abort ();
3437 if (value_in_comment > 32 || value_in_comment < -16)
3438 func (stream, "\t; 0x%lx", value_in_comment);
3439 return;
3442 /* No match. */
3443 abort ();
3446 /* Return the name of an V7M special register. */
3448 static const char *
3449 psr_name (int regno)
3451 switch (regno)
3453 case 0: return "APSR";
3454 case 1: return "IAPSR";
3455 case 2: return "EAPSR";
3456 case 3: return "PSR";
3457 case 5: return "IPSR";
3458 case 6: return "EPSR";
3459 case 7: return "IEPSR";
3460 case 8: return "MSP";
3461 case 9: return "PSP";
3462 case 16: return "PRIMASK";
3463 case 17: return "BASEPRI";
3464 case 18: return "BASEPRI_MASK";
3465 case 19: return "FAULTMASK";
3466 case 20: return "CONTROL";
3467 default: return "<unknown>";
3471 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3473 static void
3474 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3476 const struct opcode32 *insn;
3477 void *stream = info->stream;
3478 fprintf_ftype func = info->fprintf_func;
3480 if (print_insn_coprocessor (pc, info, given, TRUE))
3481 return;
3483 if (print_insn_neon (info, given, TRUE))
3484 return;
3486 for (insn = thumb32_opcodes; insn->assembler; insn++)
3487 if ((given & insn->mask) == insn->value)
3489 signed long value_in_comment = 0;
3490 const char *c = insn->assembler;
3492 for (; *c; c++)
3494 if (*c != '%')
3496 func (stream, "%c", *c);
3497 continue;
3500 switch (*++c)
3502 case '%':
3503 func (stream, "%%");
3504 break;
3506 case 'c':
3507 if (ifthen_state)
3508 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3509 break;
3511 case 'x':
3512 if (ifthen_next_state)
3513 func (stream, "\t; unpredictable branch in IT block\n");
3514 break;
3516 case 'X':
3517 if (ifthen_state)
3518 func (stream, "\t; unpredictable <IT:%s>",
3519 arm_conditional[IFTHEN_COND]);
3520 break;
3522 case 'I':
3524 unsigned int imm12 = 0;
3526 imm12 |= (given & 0x000000ffu);
3527 imm12 |= (given & 0x00007000u) >> 4;
3528 imm12 |= (given & 0x04000000u) >> 15;
3529 func (stream, "#%u", imm12);
3530 value_in_comment = imm12;
3532 break;
3534 case 'M':
3536 unsigned int bits = 0, imm, imm8, mod;
3538 bits |= (given & 0x000000ffu);
3539 bits |= (given & 0x00007000u) >> 4;
3540 bits |= (given & 0x04000000u) >> 15;
3541 imm8 = (bits & 0x0ff);
3542 mod = (bits & 0xf00) >> 8;
3543 switch (mod)
3545 case 0: imm = imm8; break;
3546 case 1: imm = ((imm8<<16) | imm8); break;
3547 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3548 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3549 default:
3550 mod = (bits & 0xf80) >> 7;
3551 imm8 = (bits & 0x07f) | 0x80;
3552 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3554 func (stream, "#%u", imm);
3555 value_in_comment = imm;
3557 break;
3559 case 'J':
3561 unsigned int imm = 0;
3563 imm |= (given & 0x000000ffu);
3564 imm |= (given & 0x00007000u) >> 4;
3565 imm |= (given & 0x04000000u) >> 15;
3566 imm |= (given & 0x000f0000u) >> 4;
3567 func (stream, "#%u", imm);
3568 value_in_comment = imm;
3570 break;
3572 case 'K':
3574 unsigned int imm = 0;
3576 imm |= (given & 0x000f0000u) >> 16;
3577 imm |= (given & 0x00000ff0u) >> 0;
3578 imm |= (given & 0x0000000fu) << 12;
3579 func (stream, "#%u", imm);
3580 value_in_comment = imm;
3582 break;
3584 case 'S':
3586 unsigned int reg = (given & 0x0000000fu);
3587 unsigned int stp = (given & 0x00000030u) >> 4;
3588 unsigned int imm = 0;
3589 imm |= (given & 0x000000c0u) >> 6;
3590 imm |= (given & 0x00007000u) >> 10;
3592 func (stream, "%s", arm_regnames[reg]);
3593 switch (stp)
3595 case 0:
3596 if (imm > 0)
3597 func (stream, ", lsl #%u", imm);
3598 break;
3600 case 1:
3601 if (imm == 0)
3602 imm = 32;
3603 func (stream, ", lsr #%u", imm);
3604 break;
3606 case 2:
3607 if (imm == 0)
3608 imm = 32;
3609 func (stream, ", asr #%u", imm);
3610 break;
3612 case 3:
3613 if (imm == 0)
3614 func (stream, ", rrx");
3615 else
3616 func (stream, ", ror #%u", imm);
3619 break;
3621 case 'a':
3623 unsigned int Rn = (given & 0x000f0000) >> 16;
3624 unsigned int U = (given & 0x00800000) >> 23;
3625 unsigned int op = (given & 0x00000f00) >> 8;
3626 unsigned int i12 = (given & 0x00000fff);
3627 unsigned int i8 = (given & 0x000000ff);
3628 bfd_boolean writeback = FALSE, postind = FALSE;
3629 int offset = 0;
3631 func (stream, "[%s", arm_regnames[Rn]);
3632 if (U) /* 12-bit positive immediate offset. */
3634 offset = i12;
3635 if (Rn != 15)
3636 value_in_comment = offset;
3638 else if (Rn == 15) /* 12-bit negative immediate offset. */
3639 offset = - (int) i12;
3640 else if (op == 0x0) /* Shifted register offset. */
3642 unsigned int Rm = (i8 & 0x0f);
3643 unsigned int sh = (i8 & 0x30) >> 4;
3645 func (stream, ", %s", arm_regnames[Rm]);
3646 if (sh)
3647 func (stream, ", lsl #%u", sh);
3648 func (stream, "]");
3649 break;
3651 else switch (op)
3653 case 0xE: /* 8-bit positive immediate offset. */
3654 offset = i8;
3655 break;
3657 case 0xC: /* 8-bit negative immediate offset. */
3658 offset = -i8;
3659 break;
3661 case 0xF: /* 8-bit + preindex with wb. */
3662 offset = i8;
3663 writeback = TRUE;
3664 break;
3666 case 0xD: /* 8-bit - preindex with wb. */
3667 offset = -i8;
3668 writeback = TRUE;
3669 break;
3671 case 0xB: /* 8-bit + postindex. */
3672 offset = i8;
3673 postind = TRUE;
3674 break;
3676 case 0x9: /* 8-bit - postindex. */
3677 offset = -i8;
3678 postind = TRUE;
3679 break;
3681 default:
3682 func (stream, ", <undefined>]");
3683 goto skip;
3686 if (postind)
3687 func (stream, "], #%d", offset);
3688 else
3690 if (offset)
3691 func (stream, ", #%d", offset);
3692 func (stream, writeback ? "]!" : "]");
3695 if (Rn == 15)
3697 func (stream, "\t; ");
3698 info->print_address_func (((pc + 4) & ~3) + offset, info);
3701 skip:
3702 break;
3704 case 'A':
3706 unsigned int P = (given & 0x01000000) >> 24;
3707 unsigned int U = (given & 0x00800000) >> 23;
3708 unsigned int W = (given & 0x00400000) >> 21;
3709 unsigned int Rn = (given & 0x000f0000) >> 16;
3710 unsigned int off = (given & 0x000000ff);
3712 func (stream, "[%s", arm_regnames[Rn]);
3713 if (P)
3715 if (off || !U)
3717 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3718 value_in_comment = off * 4 * U ? 1 : -1;
3720 func (stream, "]");
3721 if (W)
3722 func (stream, "!");
3724 else
3726 func (stream, "], ");
3727 if (W)
3729 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3730 value_in_comment = off * 4 * U ? 1 : -1;
3732 else
3734 func (stream, "{%u}", off);
3735 value_in_comment = off;
3739 break;
3741 case 'w':
3743 unsigned int Sbit = (given & 0x01000000) >> 24;
3744 unsigned int type = (given & 0x00600000) >> 21;
3746 switch (type)
3748 case 0: func (stream, Sbit ? "sb" : "b"); break;
3749 case 1: func (stream, Sbit ? "sh" : "h"); break;
3750 case 2:
3751 if (Sbit)
3752 func (stream, "??");
3753 break;
3754 case 3:
3755 func (stream, "??");
3756 break;
3759 break;
3761 case 'm':
3763 int started = 0;
3764 int reg;
3766 func (stream, "{");
3767 for (reg = 0; reg < 16; reg++)
3768 if ((given & (1 << reg)) != 0)
3770 if (started)
3771 func (stream, ", ");
3772 started = 1;
3773 func (stream, "%s", arm_regnames[reg]);
3775 func (stream, "}");
3777 break;
3779 case 'E':
3781 unsigned int msb = (given & 0x0000001f);
3782 unsigned int lsb = 0;
3784 lsb |= (given & 0x000000c0u) >> 6;
3785 lsb |= (given & 0x00007000u) >> 10;
3786 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3788 break;
3790 case 'F':
3792 unsigned int width = (given & 0x0000001f) + 1;
3793 unsigned int lsb = 0;
3795 lsb |= (given & 0x000000c0u) >> 6;
3796 lsb |= (given & 0x00007000u) >> 10;
3797 func (stream, "#%u, #%u", lsb, width);
3799 break;
3801 case 'b':
3803 unsigned int S = (given & 0x04000000u) >> 26;
3804 unsigned int J1 = (given & 0x00002000u) >> 13;
3805 unsigned int J2 = (given & 0x00000800u) >> 11;
3806 int offset = 0;
3808 offset |= !S << 20;
3809 offset |= J2 << 19;
3810 offset |= J1 << 18;
3811 offset |= (given & 0x003f0000) >> 4;
3812 offset |= (given & 0x000007ff) << 1;
3813 offset -= (1 << 20);
3815 info->print_address_func (pc + 4 + offset, info);
3817 break;
3819 case 'B':
3821 unsigned int S = (given & 0x04000000u) >> 26;
3822 unsigned int I1 = (given & 0x00002000u) >> 13;
3823 unsigned int I2 = (given & 0x00000800u) >> 11;
3824 int offset = 0;
3826 offset |= !S << 24;
3827 offset |= !(I1 ^ S) << 23;
3828 offset |= !(I2 ^ S) << 22;
3829 offset |= (given & 0x03ff0000u) >> 4;
3830 offset |= (given & 0x000007ffu) << 1;
3831 offset -= (1 << 24);
3832 offset += pc + 4;
3834 /* BLX target addresses are always word aligned. */
3835 if ((given & 0x00001000u) == 0)
3836 offset &= ~2u;
3838 info->print_address_func (offset, info);
3840 break;
3842 case 's':
3844 unsigned int shift = 0;
3846 shift |= (given & 0x000000c0u) >> 6;
3847 shift |= (given & 0x00007000u) >> 10;
3848 if (given & 0x00200000u)
3849 func (stream, ", asr #%u", shift);
3850 else if (shift)
3851 func (stream, ", lsl #%u", shift);
3852 /* else print nothing - lsl #0 */
3854 break;
3856 case 'R':
3858 unsigned int rot = (given & 0x00000030) >> 4;
3860 if (rot)
3861 func (stream, ", ror #%u", rot * 8);
3863 break;
3865 case 'U':
3866 switch (given & 0xf)
3868 case 0xf: func (stream, "sy"); break;
3869 case 0x7: func (stream, "un"); break;
3870 case 0xe: func (stream, "st"); break;
3871 case 0x6: func (stream, "unst"); break;
3872 default:
3873 func (stream, "#%d", (int) given & 0xf);
3874 break;
3876 break;
3878 case 'C':
3879 if ((given & 0xff) == 0)
3881 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3882 if (given & 0x800)
3883 func (stream, "f");
3884 if (given & 0x400)
3885 func (stream, "s");
3886 if (given & 0x200)
3887 func (stream, "x");
3888 if (given & 0x100)
3889 func (stream, "c");
3891 else
3893 func (stream, psr_name (given & 0xff));
3895 break;
3897 case 'D':
3898 if ((given & 0xff) == 0)
3899 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3900 else
3901 func (stream, psr_name (given & 0xff));
3902 break;
3904 case '0': case '1': case '2': case '3': case '4':
3905 case '5': case '6': case '7': case '8': case '9':
3907 int width;
3908 unsigned long val;
3910 c = arm_decode_bitfield (c, given, &val, &width);
3912 switch (*c)
3914 case 'd':
3915 func (stream, "%lu", val);
3916 value_in_comment = val;
3917 break;
3918 case 'W':
3919 func (stream, "%lu", val * 4);
3920 value_in_comment = val * 4;
3921 break;
3922 case 'r': func (stream, "%s", arm_regnames[val]); break;
3924 case 'c':
3925 func (stream, "%s", arm_conditional[val]);
3926 break;
3928 case '\'':
3929 c++;
3930 if (val == ((1ul << width) - 1))
3931 func (stream, "%c", *c);
3932 break;
3934 case '`':
3935 c++;
3936 if (val == 0)
3937 func (stream, "%c", *c);
3938 break;
3940 case '?':
3941 func (stream, "%c", c[(1 << width) - (int) val]);
3942 c += 1 << width;
3943 break;
3945 default:
3946 abort ();
3949 break;
3951 default:
3952 abort ();
3956 if (value_in_comment > 32 || value_in_comment < -16)
3957 func (stream, "\t; 0x%lx", value_in_comment);
3958 return;
3961 /* No match. */
3962 abort ();
3965 /* Print data bytes on INFO->STREAM. */
3967 static void
3968 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3969 struct disassemble_info *info,
3970 long given)
3972 switch (info->bytes_per_chunk)
3974 case 1:
3975 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3976 break;
3977 case 2:
3978 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3979 break;
3980 case 4:
3981 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3982 break;
3983 default:
3984 abort ();
3988 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3989 being displayed in symbol relative addresses. */
3991 bfd_boolean
3992 arm_symbol_is_valid (asymbol * sym,
3993 struct disassemble_info * info ATTRIBUTE_UNUSED)
3995 const char * name;
3997 if (sym == NULL)
3998 return FALSE;
4000 name = bfd_asymbol_name (sym);
4002 return (name && *name != '$');
4005 /* Parse an individual disassembler option. */
4007 void
4008 parse_arm_disassembler_option (char *option)
4010 if (option == NULL)
4011 return;
4013 if (CONST_STRNEQ (option, "reg-names-"))
4015 int i;
4017 option += 10;
4019 for (i = NUM_ARM_REGNAMES; i--;)
4020 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4022 regname_selected = i;
4023 break;
4026 if (i < 0)
4027 /* XXX - should break 'option' at following delimiter. */
4028 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4030 else if (CONST_STRNEQ (option, "force-thumb"))
4031 force_thumb = 1;
4032 else if (CONST_STRNEQ (option, "no-force-thumb"))
4033 force_thumb = 0;
4034 else
4035 /* XXX - should break 'option' at following delimiter. */
4036 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4038 return;
4041 /* Parse the string of disassembler options, spliting it at whitespaces
4042 or commas. (Whitespace separators supported for backwards compatibility). */
4044 static void
4045 parse_disassembler_options (char *options)
4047 if (options == NULL)
4048 return;
4050 while (*options)
4052 parse_arm_disassembler_option (options);
4054 /* Skip forward to next seperator. */
4055 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4056 ++ options;
4057 /* Skip forward past seperators. */
4058 while (ISSPACE (*options) || (*options == ','))
4059 ++ options;
4063 /* Search back through the insn stream to determine if this instruction is
4064 conditionally executed. */
4066 static void
4067 find_ifthen_state (bfd_vma pc,
4068 struct disassemble_info *info,
4069 bfd_boolean little)
4071 unsigned char b[2];
4072 unsigned int insn;
4073 int status;
4074 /* COUNT is twice the number of instructions seen. It will be odd if we
4075 just crossed an instruction boundary. */
4076 int count;
4077 int it_count;
4078 unsigned int seen_it;
4079 bfd_vma addr;
4081 ifthen_address = pc;
4082 ifthen_state = 0;
4084 addr = pc;
4085 count = 1;
4086 it_count = 0;
4087 seen_it = 0;
4088 /* Scan backwards looking for IT instructions, keeping track of where
4089 instruction boundaries are. We don't know if something is actually an
4090 IT instruction until we find a definite instruction boundary. */
4091 for (;;)
4093 if (addr == 0 || info->symbol_at_address_func (addr, info))
4095 /* A symbol must be on an instruction boundary, and will not
4096 be within an IT block. */
4097 if (seen_it && (count & 1))
4098 break;
4100 return;
4102 addr -= 2;
4103 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4104 if (status)
4105 return;
4107 if (little)
4108 insn = (b[0]) | (b[1] << 8);
4109 else
4110 insn = (b[1]) | (b[0] << 8);
4111 if (seen_it)
4113 if ((insn & 0xf800) < 0xe800)
4115 /* Addr + 2 is an instruction boundary. See if this matches
4116 the expected boundary based on the position of the last
4117 IT candidate. */
4118 if (count & 1)
4119 break;
4120 seen_it = 0;
4123 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4125 /* This could be an IT instruction. */
4126 seen_it = insn;
4127 it_count = count >> 1;
4129 if ((insn & 0xf800) >= 0xe800)
4130 count++;
4131 else
4132 count = (count + 2) | 1;
4133 /* IT blocks contain at most 4 instructions. */
4134 if (count >= 8 && !seen_it)
4135 return;
4137 /* We found an IT instruction. */
4138 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4139 if ((ifthen_state & 0xf) == 0)
4140 ifthen_state = 0;
4143 /* Try to infer the code type (Arm or Thumb) from a symbol.
4144 Returns nonzero if *MAP_TYPE was set. */
4146 static int
4147 get_sym_code_type (struct disassemble_info *info,
4148 int n,
4149 enum map_type *map_type)
4151 elf_symbol_type *es;
4152 unsigned int type;
4153 const char *name;
4155 es = *(elf_symbol_type **)(info->symtab + n);
4156 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4158 /* If the symbol has function type then use that. */
4159 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4161 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4162 return TRUE;
4165 /* Check for mapping symbols. */
4166 name = bfd_asymbol_name (info->symtab[n]);
4167 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4168 && (name[2] == 0 || name[2] == '.'))
4170 *map_type = ((name[1] == 'a') ? MAP_ARM
4171 : (name[1] == 't') ? MAP_THUMB
4172 : MAP_DATA);
4173 return TRUE;
4176 return FALSE;
4179 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4180 of the supplied arm_feature_set structure with bitmasks indicating
4181 the support base architectures and coprocessor extensions.
4183 FIXME: This could more efficiently implemented as a constant array,
4184 although it would also be less robust. */
4186 static void
4187 select_arm_features (unsigned long mach,
4188 arm_feature_set * features)
4190 #undef ARM_FEATURE
4191 #define ARM_FEATURE(ARCH,CEXT) \
4192 features->core = (ARCH); \
4193 features->coproc = (CEXT) | FPU_FPA; \
4194 return
4196 switch (mach)
4198 case bfd_mach_arm_2: ARM_ARCH_V2;
4199 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4200 case bfd_mach_arm_3: ARM_ARCH_V3;
4201 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4202 case bfd_mach_arm_4: ARM_ARCH_V4;
4203 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4204 case bfd_mach_arm_5: ARM_ARCH_V5;
4205 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4206 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4207 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4208 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4209 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4210 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4211 /* If the machine type is unknown allow all
4212 architecture types and all extensions. */
4213 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4214 default:
4215 abort ();
4220 /* NOTE: There are no checks in these routines that
4221 the relevant number of data bytes exist. */
4223 static int
4224 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4226 unsigned char b[4];
4227 long given;
4228 int status;
4229 int is_thumb = FALSE;
4230 int is_data = FALSE;
4231 int little_code;
4232 unsigned int size = 4;
4233 void (*printer) (bfd_vma, struct disassemble_info *, long);
4234 bfd_boolean found = FALSE;
4236 if (info->disassembler_options)
4238 parse_disassembler_options (info->disassembler_options);
4240 /* To avoid repeated parsing of these options, we remove them here. */
4241 info->disassembler_options = NULL;
4244 /* PR 10288: Control which instructions will be disassembled. */
4245 if (info->private_data == NULL)
4247 static arm_feature_set features;
4249 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4250 /* If the user did not use the -m command line switch then default to
4251 disassembling all types of ARM instruction.
4253 The info->mach value has to be ignored as this will be based on
4254 the default archictecture for the target and/or hints in the notes
4255 section, but it will never be greater than the current largest arm
4256 machine value (iWMMXt2), which is only equivalent to the V5TE
4257 architecture. ARM architectures have advanced beyond the machine
4258 value encoding, and these newer architectures would be ignored if
4259 the machine value was used.
4261 Ie the -m switch is used to restrict which instructions will be
4262 disassembled. If it is necessary to use the -m switch to tell
4263 objdump that an ARM binary is being disassembled, eg because the
4264 input is a raw binary file, but it is also desired to disassemble
4265 all ARM instructions then use "-marm". This will select the
4266 "unknown" arm architecture which is compatible with any ARM
4267 instruction. */
4268 info->mach = bfd_mach_arm_unknown;
4270 /* Compute the architecture bitmask from the machine number.
4271 Note: This assumes that the machine number will not change
4272 during disassembly.... */
4273 select_arm_features (info->mach, & features);
4275 info->private_data = & features;
4278 /* Decide if our code is going to be little-endian, despite what the
4279 function argument might say. */
4280 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4282 /* First check the full symtab for a mapping symbol, even if there
4283 are no usable non-mapping symbols for this address. */
4284 if (info->symtab_size != 0
4285 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4287 bfd_vma addr;
4288 int n;
4289 int last_sym = -1;
4290 enum map_type type = MAP_ARM;
4292 if (pc <= last_mapping_addr)
4293 last_mapping_sym = -1;
4294 is_thumb = (last_type == MAP_THUMB);
4295 found = FALSE;
4296 /* Start scanning at the start of the function, or wherever
4297 we finished last time. */
4298 n = info->symtab_pos + 1;
4299 if (n < last_mapping_sym)
4300 n = last_mapping_sym;
4302 /* Scan up to the location being disassembled. */
4303 for (; n < info->symtab_size; n++)
4305 addr = bfd_asymbol_value (info->symtab[n]);
4306 if (addr > pc)
4307 break;
4308 if ((info->section == NULL
4309 || info->section == info->symtab[n]->section)
4310 && get_sym_code_type (info, n, &type))
4312 last_sym = n;
4313 found = TRUE;
4317 if (!found)
4319 n = info->symtab_pos;
4320 if (n < last_mapping_sym - 1)
4321 n = last_mapping_sym - 1;
4323 /* No mapping symbol found at this address. Look backwards
4324 for a preceeding one. */
4325 for (; n >= 0; n--)
4327 if ((info->section == NULL
4328 || info->section == info->symtab[n]->section)
4329 && get_sym_code_type (info, n, &type))
4331 last_sym = n;
4332 found = TRUE;
4333 break;
4338 last_mapping_sym = last_sym;
4339 last_type = type;
4340 is_thumb = (last_type == MAP_THUMB);
4341 is_data = (last_type == MAP_DATA);
4343 /* Look a little bit ahead to see if we should print out
4344 two or four bytes of data. If there's a symbol,
4345 mapping or otherwise, after two bytes then don't
4346 print more. */
4347 if (is_data)
4349 size = 4 - (pc & 3);
4350 for (n = last_sym + 1; n < info->symtab_size; n++)
4352 addr = bfd_asymbol_value (info->symtab[n]);
4353 if (addr > pc)
4355 if (addr - pc < size)
4356 size = addr - pc;
4357 break;
4360 /* If the next symbol is after three bytes, we need to
4361 print only part of the data, so that we can use either
4362 .byte or .short. */
4363 if (size == 3)
4364 size = (pc & 1) ? 1 : 2;
4368 if (info->symbols != NULL)
4370 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4372 coff_symbol_type * cs;
4374 cs = coffsymbol (*info->symbols);
4375 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4376 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4377 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4378 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4379 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4381 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4382 && !found)
4384 /* If no mapping symbol has been found then fall back to the type
4385 of the function symbol. */
4386 elf_symbol_type * es;
4387 unsigned int type;
4389 es = *(elf_symbol_type **)(info->symbols);
4390 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4392 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4396 if (force_thumb)
4397 is_thumb = TRUE;
4399 if (is_data)
4400 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4401 else
4402 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4404 info->bytes_per_line = 4;
4406 /* PR 10263: Disassemble data if requested to do so by the user. */
4407 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4409 int i;
4411 /* Size was already set above. */
4412 info->bytes_per_chunk = size;
4413 printer = print_insn_data;
4415 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4416 given = 0;
4417 if (little)
4418 for (i = size - 1; i >= 0; i--)
4419 given = b[i] | (given << 8);
4420 else
4421 for (i = 0; i < (int) size; i++)
4422 given = b[i] | (given << 8);
4424 else if (!is_thumb)
4426 /* In ARM mode endianness is a straightforward issue: the instruction
4427 is four bytes long and is either ordered 0123 or 3210. */
4428 printer = print_insn_arm;
4429 info->bytes_per_chunk = 4;
4430 size = 4;
4432 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4433 if (little_code)
4434 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4435 else
4436 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4438 else
4440 /* In Thumb mode we have the additional wrinkle of two
4441 instruction lengths. Fortunately, the bits that determine
4442 the length of the current instruction are always to be found
4443 in the first two bytes. */
4444 printer = print_insn_thumb16;
4445 info->bytes_per_chunk = 2;
4446 size = 2;
4448 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4449 if (little_code)
4450 given = (b[0]) | (b[1] << 8);
4451 else
4452 given = (b[1]) | (b[0] << 8);
4454 if (!status)
4456 /* These bit patterns signal a four-byte Thumb
4457 instruction. */
4458 if ((given & 0xF800) == 0xF800
4459 || (given & 0xF800) == 0xF000
4460 || (given & 0xF800) == 0xE800)
4462 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4463 if (little_code)
4464 given = (b[0]) | (b[1] << 8) | (given << 16);
4465 else
4466 given = (b[1]) | (b[0] << 8) | (given << 16);
4468 printer = print_insn_thumb32;
4469 size = 4;
4473 if (ifthen_address != pc)
4474 find_ifthen_state (pc, info, little_code);
4476 if (ifthen_state)
4478 if ((ifthen_state & 0xf) == 0x8)
4479 ifthen_next_state = 0;
4480 else
4481 ifthen_next_state = (ifthen_state & 0xe0)
4482 | ((ifthen_state & 0xf) << 1);
4486 if (status)
4488 info->memory_error_func (status, pc, info);
4489 return -1;
4491 if (info->flags & INSN_HAS_RELOC)
4492 /* If the instruction has a reloc associated with it, then
4493 the offset field in the instruction will actually be the
4494 addend for the reloc. (We are using REL type relocs).
4495 In such cases, we can ignore the pc when computing
4496 addresses, since the addend is not currently pc-relative. */
4497 pc = 0;
4499 printer (pc, info, given);
4501 if (is_thumb)
4503 ifthen_state = ifthen_next_state;
4504 ifthen_address += size;
4506 return size;
4510 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4512 /* Detect BE8-ness and record it in the disassembler info. */
4513 if (info->flavour == bfd_target_elf_flavour
4514 && info->section != NULL
4515 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4516 info->endian_code = BFD_ENDIAN_LITTLE;
4518 return print_insn (pc, info, FALSE);
4522 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4524 return print_insn (pc, info, TRUE);
4527 void
4528 print_arm_disassembler_options (FILE *stream)
4530 int i;
4532 fprintf (stream, _("\n\
4533 The following ARM specific disassembler options are supported for use with\n\
4534 the -M switch:\n"));
4536 for (i = NUM_ARM_REGNAMES; i--;)
4537 fprintf (stream, " reg-names-%s %*c%s\n",
4538 regnames[i].name,
4539 (int)(14 - strlen (regnames[i].name)), ' ',
4540 regnames[i].description);
4542 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4543 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");