* po/bg.po: New Bulgarian translation.
[binutils.git] / opcodes / arm-dis.c
blobba19f7c1567bd125dd2111928b3a794771e75da3
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 %I print cirrus signed shift immediate: bits 0..3|4..6
73 %F print the COUNT field of a LFM/SFM instruction.
74 %P print floating point precision in arithmetic insn
75 %Q print floating point precision in ldf/stf insn
76 %R print floating point rounding mode
78 %<bitfield>r print as an ARM register
79 %<bitfield>d print the bitfield in decimal
80 %<bitfield>k print immediate for VFPv3 conversion instruction
81 %<bitfield>x print the bitfield in hex
82 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
83 %<bitfield>f print a floating point constant if >7 else a
84 floating point register
85 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
86 %<bitfield>g print as an iWMMXt 64-bit register
87 %<bitfield>G print as an iWMMXt general purpose or control register
88 %<bitfield>D print as a NEON D register
89 %<bitfield>Q print as a NEON Q register
91 %y<code> print a single precision VFP reg.
92 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
93 %z<code> print a double precision VFP reg
94 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
96 %<bitfield>'c print specified char iff bitfield is all ones
97 %<bitfield>`c print specified char iff bitfield is all zeroes
98 %<bitfield>?ab... select from array of values in big endian order
100 %L print as an iWMMXt N/M width field.
101 %Z print the Immediate of a WSHUFH instruction.
102 %l like 'A' except use byte offsets for 'B' & 'H'
103 versions.
104 %i print 5-bit immediate in bits 8,3..0
105 (print "32" when 0)
106 %r print register offset address for wldt/wstr instruction. */
108 enum opcode_sentinel_enum
110 SENTINEL_IWMMXT_START = 1,
111 SENTINEL_IWMMXT_END,
112 SENTINEL_GENERIC_START
113 } opcode_sentinels;
115 #define UNDEFINED_INSTRUCTION "undefined instruction %0-31x"
116 #define UNPREDICTABLE_INSTRUCTION "\t; <UNPREDICTABLE>"
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"},
251 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %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, %A"},
261 {FPU_VFP_EXT_V1xD | FPU_NEON_EXT_V1, 0x0d100b00, 0x0f300f00, "vldr%c\t%12-15,22D, %A"},
262 {FPU_VFP_EXT_V1xD, 0x0d2d0a00, 0x0fbf0f00, "vpush%c\t%y3"},
263 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "vstmdb%c\t%16-19r!, %y3"},
264 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "vldmdb%c\t%16-19r!, %y3"},
265 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "vstmia%c\t%16-19r%21'!, %y3"},
266 {FPU_VFP_EXT_V1xD, 0x0cbd0a00, 0x0fbf0f00, "vpop%c\t%y3"},
267 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "vldmia%c\t%16-19r%21'!, %y3"},
268 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "vstr%c\t%y1, %A"},
269 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "vldr%c\t%y1, %A"},
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 %S like %s but allow UNPREDICTABLE addressing
780 %b print branch destination
781 %c print condition code (always bits 28-31)
782 %m print register mask for ldm/stm instruction
783 %o print operand2 (immediate or register + shift)
784 %p print 'p' iff bits 12-15 are 15
785 %t print 't' iff bit 21 set and bit 24 clear
786 %B print arm BLX(1) destination
787 %C print the PSR sub type.
788 %U print barrier type.
789 %P print address for pli instruction.
791 %<bitfield>r print as an ARM register
792 %<bitfield>d print the bitfield in decimal
793 %<bitfield>W print the bitfield plus one in decimal
794 %<bitfield>x print the bitfield in hex
795 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
797 %<bitfield>'c print specified char iff bitfield is all ones
798 %<bitfield>`c print specified char iff bitfield is all zeroes
799 %<bitfield>?ab... select from array of values in big endian order
801 %e print arm SMI operand (bits 0..7,8..19).
802 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
803 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
805 static const struct opcode32 arm_opcodes[] =
807 /* ARM instructions. */
808 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t; (mov r0, r0)"},
809 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
810 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%20's%c\t%16-19r, %0-3r, %8-11r"},
811 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%20's%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
812 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%22'b%c\t%12-15r, %0-3r, [%16-19r]"},
813 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
814 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%20's%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
816 /* V7 instructions. */
817 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
818 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
819 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
820 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
821 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
823 /* ARM V6T2 instructions. */
824 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
825 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
826 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
827 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "strht%c\t%12-15r, %S"},
828 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%6's%5?hbt%c\t%12-15r, %S"},
829 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
830 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
831 {ARM_EXT_V6T2, 0x06ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
832 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
834 /* ARM V6Z instructions. */
835 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
837 /* ARM V6K instructions. */
838 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
839 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
840 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
841 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
842 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
843 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
844 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
846 /* ARM V6K NOP hints. */
847 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
848 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
849 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
850 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
851 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
853 /* ARM V6 instructions. */
854 {ARM_EXT_V6, 0xf1080000, 0xfffffe3f, "cpsie\t%8'a%7'i%6'f"},
855 {ARM_EXT_V6, 0xf10a0000, 0xfffffe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
856 {ARM_EXT_V6, 0xf10C0000, 0xfffffe3f, "cpsid\t%8'a%7'i%6'f"},
857 {ARM_EXT_V6, 0xf10e0000, 0xfffffe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
858 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
859 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
860 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, lsl #%7-11d"},
861 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #32"},
862 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, asr #%7-11d"},
863 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
864 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
865 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
866 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
867 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
868 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
869 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
870 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
871 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
872 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
873 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
874 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
875 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
876 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
877 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
878 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
879 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
880 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
881 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
882 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
883 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
884 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
885 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
886 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
887 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
888 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
889 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
890 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
891 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
892 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
893 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
894 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
895 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
896 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
897 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
898 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
899 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
900 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t%12-15r, %0-3r"},
901 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t%12-15r, %0-3r"},
902 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t%12-15r, %0-3r"},
903 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t%16-19r%21'!"},
904 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r"},
905 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #8"},
906 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #16"},
907 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c\t%12-15r, %0-3r, ror #24"},
908 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r"},
909 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #8"},
910 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #16"},
911 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c\t%12-15r, %0-3r, ror #24"},
912 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r"},
913 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #8"},
914 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #16"},
915 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c\t%12-15r, %0-3r, ror #24"},
916 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r"},
917 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #8"},
918 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #16"},
919 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c\t%12-15r, %0-3r, ror #24"},
920 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r"},
921 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #8"},
922 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #16"},
923 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c\t%12-15r, %0-3r, ror #24"},
924 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r"},
925 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #8"},
926 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #16"},
927 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c\t%12-15r, %0-3r, ror #24"},
928 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
929 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
930 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
931 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
932 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
933 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
934 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
935 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ror #24"},
936 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
937 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
938 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
939 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
940 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
941 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #8"},
942 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #16"},
943 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ror #24"},
944 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
945 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #8"},
946 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ror #16"},
947 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
948 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
949 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #8"},
950 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #16"},
951 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ror #24"},
952 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
953 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
954 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
955 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
956 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
957 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
958 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
959 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
960 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
961 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
962 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
963 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t%16-19r%21'!, #%0-4d"},
964 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
965 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, lsl #%7-11d"},
966 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, asr #%7-11d"},
967 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
968 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
969 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
970 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
971 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
972 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
973 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, lsl #%7-11d"},
974 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, asr #%7-11d"},
975 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
977 /* V5J instruction. */
978 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
980 /* V5 Instructions. */
981 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
982 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
983 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
984 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
986 /* V5E "El Segundo" Instructions. */
987 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldrd%c\t%12-15r, %s"},
988 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "strd%c\t%12-15r, %s"},
989 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
990 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
991 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
992 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
993 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
995 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
996 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
998 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
999 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1000 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1001 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
1003 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
1004 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
1005 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
1006 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
1008 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
1009 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
1011 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
1012 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
1013 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
1014 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
1016 /* ARM Instructions. */
1017 {ARM_EXT_V1, 0x052d0004, 0x0fff0fff, "push%c\t{%12-15r}\t\t; (str%c %12-15r, %a)"},
1018 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%22'b%t%c\t%12-15r, %a"},
1019 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%22'b%t%c\t%12-15r, %a"},
1020 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%22'b%t%c\t%12-15r, %a"},
1021 {ARM_EXT_V1, 0x04400000, 0x0e500000, "strb%c\t%12-15r, %a"},
1022 {ARM_EXT_V1, 0x06400000, 0x0e500010, "strb%c\t%12-15r, %a"},
1023 {ARM_EXT_V1, 0x004000b0, 0x0e5000f0, "strh%c\t%12-15r, %s"},
1024 {ARM_EXT_V1, 0x000000b0, 0x0e500ff0, "strh%c\t%12-15r, %s"},
1025 {ARM_EXT_V1, 0x00500090, 0x0e500090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1026 {ARM_EXT_V1, 0x00100090, 0x0e500f90, "ldr%6's%5?hb%c\t%12-15r, %s"},
1028 {ARM_EXT_V1, 0x02000000, 0x0fe00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1029 {ARM_EXT_V1, 0x00000000, 0x0fe00010, "and%20's%c\t%12-15r, %16-19r, %o"},
1030 {ARM_EXT_V1, 0x00000010, 0x0fe00090, "and%20's%c\t%12-15r, %16-19r, %o"},
1032 {ARM_EXT_V1, 0x02200000, 0x0fe00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1033 {ARM_EXT_V1, 0x00200000, 0x0fe00010, "eor%20's%c\t%12-15r, %16-19r, %o"},
1034 {ARM_EXT_V1, 0x00200010, 0x0fe00090, "eor%20's%c\t%12-15r, %16-19r, %o"},
1036 {ARM_EXT_V1, 0x02400000, 0x0fe00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1037 {ARM_EXT_V1, 0x00400000, 0x0fe00010, "sub%20's%c\t%12-15r, %16-19r, %o"},
1038 {ARM_EXT_V1, 0x00400010, 0x0fe00090, "sub%20's%c\t%12-15r, %16-19r, %o"},
1040 {ARM_EXT_V1, 0x02600000, 0x0fe00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1041 {ARM_EXT_V1, 0x00600000, 0x0fe00010, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1042 {ARM_EXT_V1, 0x00600010, 0x0fe00090, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1044 {ARM_EXT_V1, 0x02800000, 0x0fe00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1045 {ARM_EXT_V1, 0x00800000, 0x0fe00010, "add%20's%c\t%12-15r, %16-19r, %o"},
1046 {ARM_EXT_V1, 0x00800010, 0x0fe00090, "add%20's%c\t%12-15r, %16-19r, %o"},
1048 {ARM_EXT_V1, 0x02a00000, 0x0fe00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1049 {ARM_EXT_V1, 0x00a00000, 0x0fe00010, "adc%20's%c\t%12-15r, %16-19r, %o"},
1050 {ARM_EXT_V1, 0x00a00010, 0x0fe00090, "adc%20's%c\t%12-15r, %16-19r, %o"},
1052 {ARM_EXT_V1, 0x02c00000, 0x0fe00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1053 {ARM_EXT_V1, 0x00c00000, 0x0fe00010, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1054 {ARM_EXT_V1, 0x00c00010, 0x0fe00090, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1056 {ARM_EXT_V1, 0x02e00000, 0x0fe00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1057 {ARM_EXT_V1, 0x00e00000, 0x0fe00010, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1058 {ARM_EXT_V1, 0x00e00010, 0x0fe00090, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1060 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1061 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1063 {ARM_EXT_V1, 0x03000000, 0x0fe00000, "tst%p%c\t%16-19r, %o"},
1064 {ARM_EXT_V1, 0x01000000, 0x0fe00010, "tst%p%c\t%16-19r, %o"},
1065 {ARM_EXT_V1, 0x01000010, 0x0fe00090, "tst%p%c\t%16-19r, %o"},
1067 {ARM_EXT_V1, 0x03200000, 0x0fe00000, "teq%p%c\t%16-19r, %o"},
1068 {ARM_EXT_V1, 0x01200000, 0x0fe00010, "teq%p%c\t%16-19r, %o"},
1069 {ARM_EXT_V1, 0x01200010, 0x0fe00090, "teq%p%c\t%16-19r, %o"},
1071 {ARM_EXT_V1, 0x03400000, 0x0fe00000, "cmp%p%c\t%16-19r, %o"},
1072 {ARM_EXT_V1, 0x01400000, 0x0fe00010, "cmp%p%c\t%16-19r, %o"},
1073 {ARM_EXT_V1, 0x01400010, 0x0fe00090, "cmp%p%c\t%16-19r, %o"},
1075 {ARM_EXT_V1, 0x03600000, 0x0fe00000, "cmn%p%c\t%16-19r, %o"},
1076 {ARM_EXT_V1, 0x01600000, 0x0fe00010, "cmn%p%c\t%16-19r, %o"},
1077 {ARM_EXT_V1, 0x01600010, 0x0fe00090, "cmn%p%c\t%16-19r, %o"},
1079 {ARM_EXT_V1, 0x03800000, 0x0fe00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1080 {ARM_EXT_V1, 0x01800000, 0x0fe00010, "orr%20's%c\t%12-15r, %16-19r, %o"},
1081 {ARM_EXT_V1, 0x01800010, 0x0fe00090, "orr%20's%c\t%12-15r, %16-19r, %o"},
1083 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1084 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1085 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1086 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1087 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1088 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1089 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1091 {ARM_EXT_V1, 0x03c00000, 0x0fe00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1092 {ARM_EXT_V1, 0x01c00000, 0x0fe00010, "bic%20's%c\t%12-15r, %16-19r, %o"},
1093 {ARM_EXT_V1, 0x01c00010, 0x0fe00090, "bic%20's%c\t%12-15r, %16-19r, %o"},
1095 {ARM_EXT_V1, 0x03e00000, 0x0fe00000, "mvn%20's%c\t%12-15r, %o"},
1096 {ARM_EXT_V1, 0x01e00000, 0x0fe00010, "mvn%20's%c\t%12-15r, %o"},
1097 {ARM_EXT_V1, 0x01e00010, 0x0fe00090, "mvn%20's%c\t%12-15r, %o"},
1099 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1100 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1101 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1102 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1103 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1104 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1105 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1106 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1107 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1108 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1109 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1111 /* The rest. */
1112 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1113 {0, 0x00000000, 0x00000000, 0}
1116 /* print_insn_thumb16 recognizes the following format control codes:
1118 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1119 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1120 %<bitfield>I print bitfield as a signed decimal
1121 (top bit of range being the sign bit)
1122 %N print Thumb register mask (with LR)
1123 %O print Thumb register mask (with PC)
1124 %M print Thumb register mask
1125 %b print CZB's 6-bit unsigned branch destination
1126 %s print Thumb right-shift immediate (6..10; 0 == 32).
1127 %c print the condition code
1128 %C print the condition code, or "s" if not conditional
1129 %x print warning if conditional an not at end of IT block"
1130 %X print "\t; unpredictable <IT:code>" if conditional
1131 %I print IT instruction suffix and operands
1132 %<bitfield>r print bitfield as an ARM register
1133 %<bitfield>d print bitfield as a decimal
1134 %<bitfield>H print (bitfield * 2) as a decimal
1135 %<bitfield>W print (bitfield * 4) as a decimal
1136 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1137 %<bitfield>B print Thumb branch destination (signed displacement)
1138 %<bitfield>c print bitfield as a condition code
1139 %<bitnum>'c print specified char iff bit is one
1140 %<bitnum>?ab print a if bit is one else print b. */
1142 static const struct opcode16 thumb_opcodes[] =
1144 /* Thumb instructions. */
1146 /* ARM V6K no-argument instructions. */
1147 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1148 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1149 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1150 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1151 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1152 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1154 /* ARM V6T2 instructions. */
1155 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1156 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1157 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1159 /* ARM V6. */
1160 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1161 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1162 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1163 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1164 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1165 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1166 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1167 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1168 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1169 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1170 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1172 /* ARM V5 ISA extends Thumb. */
1173 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1174 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1175 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1176 /* ARM V4T ISA (Thumb v1). */
1177 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1178 /* Format 4. */
1179 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1180 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1181 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1182 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1183 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1184 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1185 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1186 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1187 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1188 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1189 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1190 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1191 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1192 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1193 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1194 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1195 /* format 13 */
1196 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1197 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1198 /* format 5 */
1199 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1200 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1201 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1202 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1203 /* format 14 */
1204 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1205 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1206 /* format 2 */
1207 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1208 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1209 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1210 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1211 /* format 8 */
1212 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1213 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1214 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1215 /* format 7 */
1216 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1217 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1218 /* format 1 */
1219 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1220 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1221 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1222 /* format 3 */
1223 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1224 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1225 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1226 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1227 /* format 6 */
1228 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1229 /* format 9 */
1230 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1231 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1232 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1233 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1234 /* format 10 */
1235 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1236 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1237 /* format 11 */
1238 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1239 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1240 /* format 12 */
1241 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1242 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1243 /* format 15 */
1244 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1245 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1246 /* format 17 */
1247 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1248 /* format 16 */
1249 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1250 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1251 /* format 18 */
1252 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1254 /* The E800 .. FFFF range is unconditionally redirected to the
1255 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1256 are processed via that table. Thus, we can never encounter a
1257 bare "second half of BL/BLX(1)" instruction here. */
1258 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1259 {0, 0, 0, 0}
1262 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1263 We adopt the convention that hw1 is the high 16 bits of .value and
1264 .mask, hw2 the low 16 bits.
1266 print_insn_thumb32 recognizes the following format control codes:
1268 %% %
1270 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1271 %M print a modified 12-bit immediate (same location)
1272 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1273 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1274 %S print a possibly-shifted Rm
1276 %a print the address of a plain load/store
1277 %w print the width and signedness of a core load/store
1278 %m print register mask for ldm/stm
1280 %E print the lsb and width fields of a bfc/bfi instruction
1281 %F print the lsb and width fields of a sbfx/ubfx instruction
1282 %b print a conditional branch offset
1283 %B print an unconditional branch offset
1284 %s print the shift field of an SSAT instruction
1285 %R print the rotation field of an SXT instruction
1286 %U print barrier type.
1287 %P print address for pli instruction.
1288 %c print the condition code
1289 %x print warning if conditional an not at end of IT block"
1290 %X print "\t; unpredictable <IT:code>" if conditional
1292 %<bitfield>d print bitfield in decimal
1293 %<bitfield>W print bitfield*4 in decimal
1294 %<bitfield>r print bitfield as an ARM register
1295 %<bitfield>c print bitfield as a condition code
1297 %<bitfield>'c print specified char iff bitfield is all ones
1298 %<bitfield>`c print specified char iff bitfield is all zeroes
1299 %<bitfield>?ab... select from array of values in big endian order
1301 With one exception at the bottom (done because BL and BLX(1) need
1302 to come dead last), this table was machine-sorted first in
1303 decreasing order of number of bits set in the mask, then in
1304 increasing numeric order of mask, then in increasing numeric order
1305 of opcode. This order is not the clearest for a human reader, but
1306 is guaranteed never to catch a special-case bit pattern with a more
1307 general mask, which is important, because this instruction encoding
1308 makes heavy use of special-case bit patterns. */
1309 static const struct opcode32 thumb32_opcodes[] =
1311 /* V7 instructions. */
1312 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1313 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1314 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1315 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1316 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1317 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1318 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1320 /* Instructions defined in the basic V6T2 set. */
1321 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1322 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1323 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1324 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1325 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1326 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1328 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1329 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1330 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1331 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1332 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1333 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1334 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1335 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1336 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1337 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1338 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1339 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1340 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1341 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1342 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1343 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1344 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1345 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1346 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1347 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1348 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1349 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1350 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1351 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1352 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1353 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1354 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1355 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1356 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1357 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1358 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1359 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1360 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1361 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1362 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1363 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
1364 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1365 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1366 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1367 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1368 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1369 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1370 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1371 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1372 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1373 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1374 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1375 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1376 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1377 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1378 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1379 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1380 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1381 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1382 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1383 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1384 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1385 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1387 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1388 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1389 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1390 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1391 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1392 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1394 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1395 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1396 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1397 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1398 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1399 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1400 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1401 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1402 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1403 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1404 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1405 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1406 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1407 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1408 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1409 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1410 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1411 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1412 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1413 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1414 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1415 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1416 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1417 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1418 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1419 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1420 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1421 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1422 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1423 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1424 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1425 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1426 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1427 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1428 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1429 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1430 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1431 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1432 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1433 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1434 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1435 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1436 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1437 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1438 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1439 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1440 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1441 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1442 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1443 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1444 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1445 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1446 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1447 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1448 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1449 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1450 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1451 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1452 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1453 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1454 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1455 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1456 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1457 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1458 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1459 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1460 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1461 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1462 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1463 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1464 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1465 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1466 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1467 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1468 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1469 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1470 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1471 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1472 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1473 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1474 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1475 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1476 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1477 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1478 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1479 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1480 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1481 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1482 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1483 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1484 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1485 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1486 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1487 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1488 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1489 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1490 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1491 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1492 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1493 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1494 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1495 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1496 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1497 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1498 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1499 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1501 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1502 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1503 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1504 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1505 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1507 /* These have been 32-bit since the invention of Thumb. */
1508 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1509 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1511 /* Fallback. */
1512 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1513 {0, 0, 0, 0}
1516 static const char *const arm_conditional[] =
1517 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1518 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1520 static const char *const arm_fp_const[] =
1521 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1523 static const char *const arm_shift[] =
1524 {"lsl", "lsr", "asr", "ror"};
1526 typedef struct
1528 const char *name;
1529 const char *description;
1530 const char *reg_names[16];
1532 arm_regname;
1534 static const arm_regname regnames[] =
1536 { "raw" , "Select raw register names",
1537 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1538 { "gcc", "Select register names used by GCC",
1539 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1540 { "std", "Select register names used in ARM's ISA documentation",
1541 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1542 { "apcs", "Select register names used in the APCS",
1543 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1544 { "atpcs", "Select register names used in the ATPCS",
1545 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1546 { "special-atpcs", "Select special register names used in the ATPCS",
1547 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1550 static const char *const iwmmxt_wwnames[] =
1551 {"b", "h", "w", "d"};
1553 static const char *const iwmmxt_wwssnames[] =
1554 {"b", "bus", "bc", "bss",
1555 "h", "hus", "hc", "hss",
1556 "w", "wus", "wc", "wss",
1557 "d", "dus", "dc", "dss"
1560 static const char *const iwmmxt_regnames[] =
1561 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1562 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1565 static const char *const iwmmxt_cregnames[] =
1566 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1567 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1570 /* Default to GCC register name set. */
1571 static unsigned int regname_selected = 1;
1573 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1574 #define arm_regnames regnames[regname_selected].reg_names
1576 static bfd_boolean force_thumb = FALSE;
1578 /* Current IT instruction state. This contains the same state as the IT
1579 bits in the CPSR. */
1580 static unsigned int ifthen_state;
1581 /* IT state for the next instruction. */
1582 static unsigned int ifthen_next_state;
1583 /* The address of the insn for which the IT state is valid. */
1584 static bfd_vma ifthen_address;
1585 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1587 /* Cached mapping symbol state. */
1588 enum map_type
1590 MAP_ARM,
1591 MAP_THUMB,
1592 MAP_DATA
1595 enum map_type last_type;
1596 int last_mapping_sym = -1;
1597 bfd_vma last_mapping_addr = 0;
1600 /* Functions. */
1602 get_arm_regname_num_options (void)
1604 return NUM_ARM_REGNAMES;
1608 set_arm_regname_option (int option)
1610 int old = regname_selected;
1611 regname_selected = option;
1612 return old;
1616 get_arm_regnames (int option,
1617 const char **setname,
1618 const char **setdescription,
1619 const char *const **register_names)
1621 *setname = regnames[option].name;
1622 *setdescription = regnames[option].description;
1623 *register_names = regnames[option].reg_names;
1624 return 16;
1627 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1628 Returns pointer to following character of the format string and
1629 fills in *VALUEP and *WIDTHP with the extracted value and number of
1630 bits extracted. WIDTHP can be NULL. */
1632 static const char *
1633 arm_decode_bitfield (const char *ptr,
1634 unsigned long insn,
1635 unsigned long *valuep,
1636 int *widthp)
1638 unsigned long value = 0;
1639 int width = 0;
1643 int start, end;
1644 int bits;
1646 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1647 start = start * 10 + *ptr - '0';
1648 if (*ptr == '-')
1649 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1650 end = end * 10 + *ptr - '0';
1651 else
1652 end = start;
1653 bits = end - start;
1654 if (bits < 0)
1655 abort ();
1656 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1657 width += bits + 1;
1659 while (*ptr++ == ',');
1660 *valuep = value;
1661 if (widthp)
1662 *widthp = width;
1663 return ptr - 1;
1666 static void
1667 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1668 bfd_boolean print_shift)
1670 func (stream, "%s", arm_regnames[given & 0xf]);
1672 if ((given & 0xff0) != 0)
1674 if ((given & 0x10) == 0)
1676 int amount = (given & 0xf80) >> 7;
1677 int shift = (given & 0x60) >> 5;
1679 if (amount == 0)
1681 if (shift == 3)
1683 func (stream, ", rrx");
1684 return;
1687 amount = 32;
1690 if (print_shift)
1691 func (stream, ", %s #%d", arm_shift[shift], amount);
1692 else
1693 func (stream, ", #%d", amount);
1695 else if ((given & 0x80) == 0x80)
1696 func (stream, ", <illegal shifter operand>");
1697 else if (print_shift)
1698 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1699 arm_regnames[(given & 0xf00) >> 8]);
1700 else
1701 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1705 #define W_BIT 21
1706 #define I_BIT 22
1707 #define U_BIT 23
1708 #define P_BIT 24
1710 #define WRITEBACK_BIT_SET (given & (1 << W_BIT))
1711 #define IMMEDIATE_BIT_SET (given & (1 << I_BIT))
1712 #define NEGATIVE_BIT_SET ((given & (1 << U_BIT)) == 0)
1713 #define PRE_BIT_SET (given & (1 << P_BIT))
1715 /* Print one coprocessor instruction on INFO->STREAM.
1716 Return TRUE if the instuction matched, FALSE if this is not a
1717 recognised coprocessor instruction. */
1719 static bfd_boolean
1720 print_insn_coprocessor (bfd_vma pc,
1721 struct disassemble_info *info,
1722 long given,
1723 bfd_boolean thumb)
1725 const struct opcode32 *insn;
1726 void *stream = info->stream;
1727 fprintf_ftype func = info->fprintf_func;
1728 unsigned long mask;
1729 unsigned long value;
1730 unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
1731 int cond;
1733 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1735 signed long value_in_comment = 0;
1736 const char *c;
1738 if (insn->arch == 0)
1739 switch (insn->value)
1741 case SENTINEL_IWMMXT_START:
1742 if (info->mach != bfd_mach_arm_XScale
1743 && info->mach != bfd_mach_arm_iWMMXt
1744 && info->mach != bfd_mach_arm_iWMMXt2)
1746 insn++;
1747 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1748 continue;
1750 case SENTINEL_IWMMXT_END:
1751 continue;
1753 case SENTINEL_GENERIC_START:
1754 allowed_arches = ((arm_feature_set *) info->private_data)->core;
1755 continue;
1757 default:
1758 abort ();
1761 mask = insn->mask;
1762 value = insn->value;
1763 if (thumb)
1765 /* The high 4 bits are 0xe for Arm conditional instructions, and
1766 0xe for arm unconditional instructions. The rest of the
1767 encoding is the same. */
1768 mask |= 0xf0000000;
1769 value |= 0xe0000000;
1770 if (ifthen_state)
1771 cond = IFTHEN_COND;
1772 else
1773 cond = 16;
1775 else
1777 /* Only match unconditional instuctions against unconditional
1778 patterns. */
1779 if ((given & 0xf0000000) == 0xf0000000)
1781 mask |= 0xf0000000;
1782 cond = 16;
1784 else
1786 cond = (given >> 28) & 0xf;
1787 if (cond == 0xe)
1788 cond = 16;
1792 if ((given & mask) != value)
1793 continue;
1795 if ((insn->arch & allowed_arches) == 0)
1796 continue;
1798 for (c = insn->assembler; *c; c++)
1800 if (*c == '%')
1802 switch (*++c)
1804 case '%':
1805 func (stream, "%%");
1806 break;
1808 case 'A':
1810 int rn = (given >> 16) & 0xf;
1811 int offset = given & 0xff;
1813 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1815 if (PRE_BIT_SET || WRITEBACK_BIT_SET)
1817 /* Not unindexed. The offset is scaled. */
1818 offset = offset * 4;
1819 if (NEGATIVE_BIT_SET)
1820 offset = - offset;
1821 if (rn != 15)
1822 value_in_comment = offset;
1825 if (PRE_BIT_SET)
1827 if (offset)
1828 func (stream, ", #%d]%s",
1829 offset,
1830 WRITEBACK_BIT_SET ? "!" : "");
1831 else
1832 func (stream, "]");
1834 else
1836 func (stream, "]");
1838 if (WRITEBACK_BIT_SET)
1840 if (offset)
1841 func (stream, ", #%d", offset);
1843 else
1845 func (stream, ", {%d}", offset);
1846 value_in_comment = offset;
1849 if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
1851 func (stream, "\t; ");
1852 info->print_address_func (offset + pc
1853 + info->bytes_per_chunk * 2, info);
1856 break;
1858 case 'B':
1860 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1861 int offset = (given >> 1) & 0x3f;
1863 if (offset == 1)
1864 func (stream, "{d%d}", regno);
1865 else if (regno + offset > 32)
1866 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1867 else
1868 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1870 break;
1872 case 'c':
1873 func (stream, "%s", arm_conditional[cond]);
1874 break;
1876 case 'I':
1877 /* Print a Cirrus/DSP shift immediate. */
1878 /* Immediates are 7bit signed ints with bits 0..3 in
1879 bits 0..3 of opcode and bits 4..6 in bits 5..7
1880 of opcode. */
1882 int imm;
1884 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1886 /* Is ``imm'' a negative number? */
1887 if (imm & 0x40)
1888 imm |= (-1 << 7);
1890 func (stream, "%d", imm);
1893 break;
1895 case 'F':
1896 switch (given & 0x00408000)
1898 case 0:
1899 func (stream, "4");
1900 break;
1901 case 0x8000:
1902 func (stream, "1");
1903 break;
1904 case 0x00400000:
1905 func (stream, "2");
1906 break;
1907 default:
1908 func (stream, "3");
1910 break;
1912 case 'P':
1913 switch (given & 0x00080080)
1915 case 0:
1916 func (stream, "s");
1917 break;
1918 case 0x80:
1919 func (stream, "d");
1920 break;
1921 case 0x00080000:
1922 func (stream, "e");
1923 break;
1924 default:
1925 func (stream, _("<illegal precision>"));
1926 break;
1928 break;
1930 case 'Q':
1931 switch (given & 0x00408000)
1933 case 0:
1934 func (stream, "s");
1935 break;
1936 case 0x8000:
1937 func (stream, "d");
1938 break;
1939 case 0x00400000:
1940 func (stream, "e");
1941 break;
1942 default:
1943 func (stream, "p");
1944 break;
1946 break;
1948 case 'R':
1949 switch (given & 0x60)
1951 case 0:
1952 break;
1953 case 0x20:
1954 func (stream, "p");
1955 break;
1956 case 0x40:
1957 func (stream, "m");
1958 break;
1959 default:
1960 func (stream, "z");
1961 break;
1963 break;
1965 case '0': case '1': case '2': case '3': case '4':
1966 case '5': case '6': case '7': case '8': case '9':
1968 int width;
1969 unsigned long value;
1971 c = arm_decode_bitfield (c, given, &value, &width);
1973 switch (*c)
1975 case 'r':
1976 func (stream, "%s", arm_regnames[value]);
1977 break;
1978 case 'D':
1979 func (stream, "d%ld", value);
1980 break;
1981 case 'Q':
1982 if (value & 1)
1983 func (stream, "<illegal reg q%ld.5>", value >> 1);
1984 else
1985 func (stream, "q%ld", value >> 1);
1986 break;
1987 case 'd':
1988 func (stream, "%ld", value);
1989 value_in_comment = value;
1990 break;
1991 case 'k':
1993 int from = (given & (1 << 7)) ? 32 : 16;
1994 func (stream, "%ld", from - value);
1996 break;
1998 case 'f':
1999 if (value > 7)
2000 func (stream, "#%s", arm_fp_const[value & 7]);
2001 else
2002 func (stream, "f%ld", value);
2003 break;
2005 case 'w':
2006 if (width == 2)
2007 func (stream, "%s", iwmmxt_wwnames[value]);
2008 else
2009 func (stream, "%s", iwmmxt_wwssnames[value]);
2010 break;
2012 case 'g':
2013 func (stream, "%s", iwmmxt_regnames[value]);
2014 break;
2015 case 'G':
2016 func (stream, "%s", iwmmxt_cregnames[value]);
2017 break;
2019 case 'x':
2020 func (stream, "0x%lx", (value & 0xffffffffUL));
2021 break;
2023 case '`':
2024 c++;
2025 if (value == 0)
2026 func (stream, "%c", *c);
2027 break;
2028 case '\'':
2029 c++;
2030 if (value == ((1ul << width) - 1))
2031 func (stream, "%c", *c);
2032 break;
2033 case '?':
2034 func (stream, "%c", c[(1 << width) - (int) value]);
2035 c += 1 << width;
2036 break;
2037 default:
2038 abort ();
2040 break;
2042 case 'y':
2043 case 'z':
2045 int single = *c++ == 'y';
2046 int regno;
2048 switch (*c)
2050 case '4': /* Sm pair */
2051 case '0': /* Sm, Dm */
2052 regno = given & 0x0000000f;
2053 if (single)
2055 regno <<= 1;
2056 regno += (given >> 5) & 1;
2058 else
2059 regno += ((given >> 5) & 1) << 4;
2060 break;
2062 case '1': /* Sd, Dd */
2063 regno = (given >> 12) & 0x0000000f;
2064 if (single)
2066 regno <<= 1;
2067 regno += (given >> 22) & 1;
2069 else
2070 regno += ((given >> 22) & 1) << 4;
2071 break;
2073 case '2': /* Sn, Dn */
2074 regno = (given >> 16) & 0x0000000f;
2075 if (single)
2077 regno <<= 1;
2078 regno += (given >> 7) & 1;
2080 else
2081 regno += ((given >> 7) & 1) << 4;
2082 break;
2084 case '3': /* List */
2085 func (stream, "{");
2086 regno = (given >> 12) & 0x0000000f;
2087 if (single)
2089 regno <<= 1;
2090 regno += (given >> 22) & 1;
2092 else
2093 regno += ((given >> 22) & 1) << 4;
2094 break;
2096 default:
2097 abort ();
2100 func (stream, "%c%d", single ? 's' : 'd', regno);
2102 if (*c == '3')
2104 int count = given & 0xff;
2106 if (single == 0)
2107 count >>= 1;
2109 if (--count)
2111 func (stream, "-%c%d",
2112 single ? 's' : 'd',
2113 regno + count);
2116 func (stream, "}");
2118 else if (*c == '4')
2119 func (stream, ", %c%d", single ? 's' : 'd',
2120 regno + 1);
2122 break;
2124 case 'L':
2125 switch (given & 0x00400100)
2127 case 0x00000000: func (stream, "b"); break;
2128 case 0x00400000: func (stream, "h"); break;
2129 case 0x00000100: func (stream, "w"); break;
2130 case 0x00400100: func (stream, "d"); break;
2131 default:
2132 break;
2134 break;
2136 case 'Z':
2138 int value;
2139 /* given (20, 23) | given (0, 3) */
2140 value = ((given >> 16) & 0xf0) | (given & 0xf);
2141 func (stream, "%d", value);
2143 break;
2145 case 'l':
2146 /* This is like the 'A' operator, except that if
2147 the width field "M" is zero, then the offset is
2148 *not* multiplied by four. */
2150 int offset = given & 0xff;
2151 int multiplier = (given & 0x00000100) ? 4 : 1;
2153 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2155 if (multiplier > 1)
2157 value_in_comment = offset * multiplier;
2158 if (NEGATIVE_BIT_SET)
2159 value_in_comment = - value_in_comment;
2162 if (offset)
2164 if (PRE_BIT_SET)
2165 func (stream, ", #%s%d]%s",
2166 NEGATIVE_BIT_SET ? "-" : "",
2167 offset * multiplier,
2168 WRITEBACK_BIT_SET ? "!" : "");
2169 else
2170 func (stream, "], #%s%d",
2171 NEGATIVE_BIT_SET ? "-" : "",
2172 offset * multiplier);
2174 else
2175 func (stream, "]");
2177 break;
2179 case 'r':
2181 int imm4 = (given >> 4) & 0xf;
2182 int puw_bits = ((given >> 22) & 6) | ((given >> W_BIT) & 1);
2183 int ubit = ! NEGATIVE_BIT_SET;
2184 const char *rm = arm_regnames [given & 0xf];
2185 const char *rn = arm_regnames [(given >> 16) & 0xf];
2187 switch (puw_bits)
2189 case 1:
2190 case 3:
2191 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2192 if (imm4)
2193 func (stream, ", lsl #%d", imm4);
2194 break;
2196 case 4:
2197 case 5:
2198 case 6:
2199 case 7:
2200 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2201 if (imm4 > 0)
2202 func (stream, ", lsl #%d", imm4);
2203 func (stream, "]");
2204 if (puw_bits == 5 || puw_bits == 7)
2205 func (stream, "!");
2206 break;
2208 default:
2209 func (stream, "INVALID");
2212 break;
2214 case 'i':
2216 long imm5;
2217 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2218 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2220 break;
2222 default:
2223 abort ();
2227 else
2228 func (stream, "%c", *c);
2231 if (value_in_comment > 32 || value_in_comment < -16)
2232 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
2234 return TRUE;
2236 return FALSE;
2239 /* Decodes and prints ARM addressing modes. Returns the offset
2240 used in the address, if any, if it is worthwhile printing the
2241 offset as a hexadecimal value in a comment at the end of the
2242 line of disassembly. */
2244 static signed long
2245 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2247 void *stream = info->stream;
2248 fprintf_ftype func = info->fprintf_func;
2249 int offset = 0;
2251 if (((given & 0x000f0000) == 0x000f0000)
2252 && ((given & 0x02000000) == 0))
2254 offset = given & 0xfff;
2256 func (stream, "[pc");
2258 if (PRE_BIT_SET)
2260 if (NEGATIVE_BIT_SET)
2261 offset = - offset;
2263 /* Pre-indexed. */
2264 func (stream, ", #%d]", offset);
2266 offset += pc + 8;
2268 /* Cope with the possibility of write-back
2269 being used. Probably a very dangerous thing
2270 for the programmer to do, but who are we to
2271 argue ? */
2272 if (WRITEBACK_BIT_SET)
2273 func (stream, "!");
2275 else /* Post indexed. */
2277 func (stream, "], #%d", offset);
2279 /* Ie ignore the offset. */
2280 offset = pc + 8;
2283 func (stream, "\t; ");
2284 info->print_address_func (offset, info);
2285 offset = 0;
2287 else
2289 func (stream, "[%s",
2290 arm_regnames[(given >> 16) & 0xf]);
2292 if (PRE_BIT_SET)
2294 if ((given & 0x02000000) == 0)
2296 offset = given & 0xfff;
2297 if (offset)
2298 func (stream, ", #%s%d",
2299 NEGATIVE_BIT_SET ? "-" : "", offset);
2301 else
2303 func (stream, ", %s",
2304 NEGATIVE_BIT_SET ? "-" : "");
2305 arm_decode_shift (given, func, stream, TRUE);
2308 func (stream, "]%s",
2309 WRITEBACK_BIT_SET ? "!" : "");
2311 else
2313 if ((given & 0x02000000) == 0)
2315 offset = given & 0xfff;
2316 if (offset)
2317 func (stream, "], #%s%d",
2318 NEGATIVE_BIT_SET ? "-" : "", offset);
2319 else
2320 func (stream, "]");
2322 else
2324 func (stream, "], %s",
2325 NEGATIVE_BIT_SET ? "-" : "");
2326 arm_decode_shift (given, func, stream, TRUE);
2331 return (signed long) offset;
2334 /* Print one neon instruction on INFO->STREAM.
2335 Return TRUE if the instuction matched, FALSE if this is not a
2336 recognised neon instruction. */
2338 static bfd_boolean
2339 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2341 const struct opcode32 *insn;
2342 void *stream = info->stream;
2343 fprintf_ftype func = info->fprintf_func;
2345 if (thumb)
2347 if ((given & 0xef000000) == 0xef000000)
2349 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2350 unsigned long bit28 = given & (1 << 28);
2352 given &= 0x00ffffff;
2353 if (bit28)
2354 given |= 0xf3000000;
2355 else
2356 given |= 0xf2000000;
2358 else if ((given & 0xff000000) == 0xf9000000)
2359 given ^= 0xf9000000 ^ 0xf4000000;
2360 else
2361 return FALSE;
2364 for (insn = neon_opcodes; insn->assembler; insn++)
2366 if ((given & insn->mask) == insn->value)
2368 signed long value_in_comment = 0;
2369 const char *c;
2371 for (c = insn->assembler; *c; c++)
2373 if (*c == '%')
2375 switch (*++c)
2377 case '%':
2378 func (stream, "%%");
2379 break;
2381 case 'c':
2382 if (thumb && ifthen_state)
2383 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2384 break;
2386 case 'A':
2388 static const unsigned char enc[16] =
2390 0x4, 0x14, /* st4 0,1 */
2391 0x4, /* st1 2 */
2392 0x4, /* st2 3 */
2393 0x3, /* st3 4 */
2394 0x13, /* st3 5 */
2395 0x3, /* st1 6 */
2396 0x1, /* st1 7 */
2397 0x2, /* st2 8 */
2398 0x12, /* st2 9 */
2399 0x2, /* st1 10 */
2400 0, 0, 0, 0, 0
2402 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2403 int rn = ((given >> 16) & 0xf);
2404 int rm = ((given >> 0) & 0xf);
2405 int align = ((given >> 4) & 0x3);
2406 int type = ((given >> 8) & 0xf);
2407 int n = enc[type] & 0xf;
2408 int stride = (enc[type] >> 4) + 1;
2409 int ix;
2411 func (stream, "{");
2412 if (stride > 1)
2413 for (ix = 0; ix != n; ix++)
2414 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2415 else if (n == 1)
2416 func (stream, "d%d", rd);
2417 else
2418 func (stream, "d%d-d%d", rd, rd + n - 1);
2419 func (stream, "}, [%s", arm_regnames[rn]);
2420 if (align)
2421 func (stream, ", :%d", 32 << align);
2422 func (stream, "]");
2423 if (rm == 0xd)
2424 func (stream, "!");
2425 else if (rm != 0xf)
2426 func (stream, ", %s", arm_regnames[rm]);
2428 break;
2430 case 'B':
2432 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2433 int rn = ((given >> 16) & 0xf);
2434 int rm = ((given >> 0) & 0xf);
2435 int idx_align = ((given >> 4) & 0xf);
2436 int align = 0;
2437 int size = ((given >> 10) & 0x3);
2438 int idx = idx_align >> (size + 1);
2439 int length = ((given >> 8) & 3) + 1;
2440 int stride = 1;
2441 int i;
2443 if (length > 1 && size > 0)
2444 stride = (idx_align & (1 << size)) ? 2 : 1;
2446 switch (length)
2448 case 1:
2450 int amask = (1 << size) - 1;
2451 if ((idx_align & (1 << size)) != 0)
2452 return FALSE;
2453 if (size > 0)
2455 if ((idx_align & amask) == amask)
2456 align = 8 << size;
2457 else if ((idx_align & amask) != 0)
2458 return FALSE;
2461 break;
2463 case 2:
2464 if (size == 2 && (idx_align & 2) != 0)
2465 return FALSE;
2466 align = (idx_align & 1) ? 16 << size : 0;
2467 break;
2469 case 3:
2470 if ((size == 2 && (idx_align & 3) != 0)
2471 || (idx_align & 1) != 0)
2472 return FALSE;
2473 break;
2475 case 4:
2476 if (size == 2)
2478 if ((idx_align & 3) == 3)
2479 return FALSE;
2480 align = (idx_align & 3) * 64;
2482 else
2483 align = (idx_align & 1) ? 32 << size : 0;
2484 break;
2486 default:
2487 abort ();
2490 func (stream, "{");
2491 for (i = 0; i < length; i++)
2492 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2493 rd + i * stride, idx);
2494 func (stream, "}, [%s", arm_regnames[rn]);
2495 if (align)
2496 func (stream, ", :%d", align);
2497 func (stream, "]");
2498 if (rm == 0xd)
2499 func (stream, "!");
2500 else if (rm != 0xf)
2501 func (stream, ", %s", arm_regnames[rm]);
2503 break;
2505 case 'C':
2507 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2508 int rn = ((given >> 16) & 0xf);
2509 int rm = ((given >> 0) & 0xf);
2510 int align = ((given >> 4) & 0x1);
2511 int size = ((given >> 6) & 0x3);
2512 int type = ((given >> 8) & 0x3);
2513 int n = type + 1;
2514 int stride = ((given >> 5) & 0x1);
2515 int ix;
2517 if (stride && (n == 1))
2518 n++;
2519 else
2520 stride++;
2522 func (stream, "{");
2523 if (stride > 1)
2524 for (ix = 0; ix != n; ix++)
2525 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2526 else if (n == 1)
2527 func (stream, "d%d[]", rd);
2528 else
2529 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2530 func (stream, "}, [%s", arm_regnames[rn]);
2531 if (align)
2533 int align = (8 * (type + 1)) << size;
2534 if (type == 3)
2535 align = (size > 1) ? align >> 1 : align;
2536 if (type == 2 || (type == 0 && !size))
2537 func (stream, ", :<bad align %d>", align);
2538 else
2539 func (stream, ", :%d", align);
2541 func (stream, "]");
2542 if (rm == 0xd)
2543 func (stream, "!");
2544 else if (rm != 0xf)
2545 func (stream, ", %s", arm_regnames[rm]);
2547 break;
2549 case 'D':
2551 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2552 int size = (given >> 20) & 3;
2553 int reg = raw_reg & ((4 << size) - 1);
2554 int ix = raw_reg >> size >> 2;
2556 func (stream, "d%d[%d]", reg, ix);
2558 break;
2560 case 'E':
2561 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2563 int bits = 0;
2564 int cmode = (given >> 8) & 0xf;
2565 int op = (given >> 5) & 0x1;
2566 unsigned long value = 0, hival = 0;
2567 unsigned shift;
2568 int size = 0;
2569 int isfloat = 0;
2571 bits |= ((given >> 24) & 1) << 7;
2572 bits |= ((given >> 16) & 7) << 4;
2573 bits |= ((given >> 0) & 15) << 0;
2575 if (cmode < 8)
2577 shift = (cmode >> 1) & 3;
2578 value = (unsigned long) bits << (8 * shift);
2579 size = 32;
2581 else if (cmode < 12)
2583 shift = (cmode >> 1) & 1;
2584 value = (unsigned long) bits << (8 * shift);
2585 size = 16;
2587 else if (cmode < 14)
2589 shift = (cmode & 1) + 1;
2590 value = (unsigned long) bits << (8 * shift);
2591 value |= (1ul << (8 * shift)) - 1;
2592 size = 32;
2594 else if (cmode == 14)
2596 if (op)
2598 /* Bit replication into bytes. */
2599 int ix;
2600 unsigned long mask;
2602 value = 0;
2603 hival = 0;
2604 for (ix = 7; ix >= 0; ix--)
2606 mask = ((bits >> ix) & 1) ? 0xff : 0;
2607 if (ix <= 3)
2608 value = (value << 8) | mask;
2609 else
2610 hival = (hival << 8) | mask;
2612 size = 64;
2614 else
2616 /* Byte replication. */
2617 value = (unsigned long) bits;
2618 size = 8;
2621 else if (!op)
2623 /* Floating point encoding. */
2624 int tmp;
2626 value = (unsigned long) (bits & 0x7f) << 19;
2627 value |= (unsigned long) (bits & 0x80) << 24;
2628 tmp = bits & 0x40 ? 0x3c : 0x40;
2629 value |= (unsigned long) tmp << 24;
2630 size = 32;
2631 isfloat = 1;
2633 else
2635 func (stream, "<illegal constant %.8x:%x:%x>",
2636 bits, cmode, op);
2637 size = 32;
2638 break;
2640 switch (size)
2642 case 8:
2643 func (stream, "#%ld\t; 0x%.2lx", value, value);
2644 break;
2646 case 16:
2647 func (stream, "#%ld\t; 0x%.4lx", value, value);
2648 break;
2650 case 32:
2651 if (isfloat)
2653 unsigned char valbytes[4];
2654 double fvalue;
2656 /* Do this a byte at a time so we don't have to
2657 worry about the host's endianness. */
2658 valbytes[0] = value & 0xff;
2659 valbytes[1] = (value >> 8) & 0xff;
2660 valbytes[2] = (value >> 16) & 0xff;
2661 valbytes[3] = (value >> 24) & 0xff;
2663 floatformat_to_double
2664 (& floatformat_ieee_single_little, valbytes,
2665 & fvalue);
2667 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2668 value);
2670 else
2671 func (stream, "#%ld\t; 0x%.8lx",
2672 (long) (NEGATIVE_BIT_SET ? value | ~0xffffffffL : value),
2673 value);
2674 break;
2676 case 64:
2677 func (stream, "#0x%.8lx%.8lx", hival, value);
2678 break;
2680 default:
2681 abort ();
2684 break;
2686 case 'F':
2688 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2689 int num = (given >> 8) & 0x3;
2691 if (!num)
2692 func (stream, "{d%d}", regno);
2693 else if (num + regno >= 32)
2694 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2695 else
2696 func (stream, "{d%d-d%d}", regno, regno + num);
2698 break;
2701 case '0': case '1': case '2': case '3': case '4':
2702 case '5': case '6': case '7': case '8': case '9':
2704 int width;
2705 unsigned long value;
2707 c = arm_decode_bitfield (c, given, &value, &width);
2709 switch (*c)
2711 case 'r':
2712 func (stream, "%s", arm_regnames[value]);
2713 break;
2714 case 'd':
2715 func (stream, "%ld", value);
2716 value_in_comment = value;
2717 break;
2718 case 'e':
2719 func (stream, "%ld", (1ul << width) - value);
2720 break;
2722 case 'S':
2723 case 'T':
2724 case 'U':
2725 /* Various width encodings. */
2727 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2728 int limit;
2729 unsigned low, high;
2731 c++;
2732 if (*c >= '0' && *c <= '9')
2733 limit = *c - '0';
2734 else if (*c >= 'a' && *c <= 'f')
2735 limit = *c - 'a' + 10;
2736 else
2737 abort ();
2738 low = limit >> 2;
2739 high = limit & 3;
2741 if (value < low || value > high)
2742 func (stream, "<illegal width %d>", base << value);
2743 else
2744 func (stream, "%d", base << value);
2746 break;
2747 case 'R':
2748 if (given & (1 << 6))
2749 goto Q;
2750 /* FALLTHROUGH */
2751 case 'D':
2752 func (stream, "d%ld", value);
2753 break;
2754 case 'Q':
2756 if (value & 1)
2757 func (stream, "<illegal reg q%ld.5>", value >> 1);
2758 else
2759 func (stream, "q%ld", value >> 1);
2760 break;
2762 case '`':
2763 c++;
2764 if (value == 0)
2765 func (stream, "%c", *c);
2766 break;
2767 case '\'':
2768 c++;
2769 if (value == ((1ul << width) - 1))
2770 func (stream, "%c", *c);
2771 break;
2772 case '?':
2773 func (stream, "%c", c[(1 << width) - (int) value]);
2774 c += 1 << width;
2775 break;
2776 default:
2777 abort ();
2779 break;
2781 default:
2782 abort ();
2786 else
2787 func (stream, "%c", *c);
2790 if (value_in_comment > 32 || value_in_comment < -16)
2791 func (stream, "\t; 0x%lx", value_in_comment);
2793 return TRUE;
2796 return FALSE;
2799 /* Print one ARM instruction from PC on INFO->STREAM. */
2801 static void
2802 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2804 const struct opcode32 *insn;
2805 void *stream = info->stream;
2806 fprintf_ftype func = info->fprintf_func;
2808 if (print_insn_coprocessor (pc, info, given, FALSE))
2809 return;
2811 if (print_insn_neon (info, given, FALSE))
2812 return;
2814 for (insn = arm_opcodes; insn->assembler; insn++)
2816 if ((given & insn->mask) != insn->value)
2817 continue;
2819 if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
2820 continue;
2822 /* Special case: an instruction with all bits set in the condition field
2823 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2824 or by the catchall at the end of the table. */
2825 if ((given & 0xF0000000) != 0xF0000000
2826 || (insn->mask & 0xF0000000) == 0xF0000000
2827 || (insn->mask == 0 && insn->value == 0))
2829 signed long value_in_comment = 0;
2830 const char *c;
2832 for (c = insn->assembler; *c; c++)
2834 if (*c == '%')
2836 bfd_boolean allow_unpredictable = FALSE;
2838 switch (*++c)
2840 case '%':
2841 func (stream, "%%");
2842 break;
2844 case 'a':
2845 value_in_comment = print_arm_address (pc, info, given);
2846 break;
2848 case 'P':
2849 /* Set P address bit and use normal address
2850 printing routine. */
2851 value_in_comment = print_arm_address (pc, info, given | (1 << P_BIT));
2852 break;
2854 case 'S':
2855 allow_unpredictable = TRUE;
2856 case 's':
2857 if ((given & 0x004f0000) == 0x004f0000)
2859 /* PC relative with immediate offset. */
2860 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2862 if (NEGATIVE_BIT_SET)
2863 offset = - offset;
2865 func (stream, "[pc, #%d]\t; ", offset);
2866 info->print_address_func (offset + pc + 8, info);
2868 else
2870 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2872 if (NEGATIVE_BIT_SET)
2873 offset = - offset;
2875 func (stream, "[%s",
2876 arm_regnames[(given >> 16) & 0xf]);
2878 if (PRE_BIT_SET)
2880 /* Pre-indexed. */
2881 if (IMMEDIATE_BIT_SET)
2883 if (offset)
2884 func (stream, ", #%d", offset);
2885 value_in_comment = offset;
2887 else /* Register. */
2888 func (stream, ", %s%s",
2889 NEGATIVE_BIT_SET ? "-" : "",
2890 arm_regnames[given & 0xf]);
2892 func (stream, "]%s",
2893 WRITEBACK_BIT_SET ? "!" : "");
2895 else /* Post-indexed. */
2897 if (IMMEDIATE_BIT_SET)
2899 if (offset)
2900 func (stream, "], #%d", offset);
2901 else
2902 func (stream, "]");
2904 value_in_comment = offset;
2906 else /* Register. */
2907 func (stream, "], %s%s",
2908 NEGATIVE_BIT_SET ? "-" : "",
2909 arm_regnames[given & 0xf]);
2911 if (WRITEBACK_BIT_SET && ! allow_unpredictable)
2912 func (stream, UNPREDICTABLE_INSTRUCTION);
2915 break;
2917 case 'b':
2919 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2920 info->print_address_func (disp * 4 + pc + 8, info);
2922 break;
2924 case 'c':
2925 if (((given >> 28) & 0xf) != 0xe)
2926 func (stream, "%s",
2927 arm_conditional [(given >> 28) & 0xf]);
2928 break;
2930 case 'm':
2932 int started = 0;
2933 int reg;
2935 func (stream, "{");
2936 for (reg = 0; reg < 16; reg++)
2937 if ((given & (1 << reg)) != 0)
2939 if (started)
2940 func (stream, ", ");
2941 started = 1;
2942 func (stream, "%s", arm_regnames[reg]);
2944 func (stream, "}");
2946 break;
2948 case 'q':
2949 arm_decode_shift (given, func, stream, FALSE);
2950 break;
2952 case 'o':
2953 if ((given & 0x02000000) != 0)
2955 int rotate = (given & 0xf00) >> 7;
2956 int immed = (given & 0xff);
2958 immed = (((immed << (32 - rotate))
2959 | (immed >> rotate)) & 0xffffffff);
2960 func (stream, "#%d", immed);
2961 value_in_comment = immed;
2963 else
2964 arm_decode_shift (given, func, stream, TRUE);
2965 break;
2967 case 'p':
2968 if ((given & 0x0000f000) == 0x0000f000)
2969 func (stream, "p");
2970 break;
2972 case 't':
2973 if ((given & 0x01200000) == 0x00200000)
2974 func (stream, "t");
2975 break;
2977 case 'A':
2979 int offset = given & 0xff;
2981 value_in_comment = offset * 4;
2982 if (NEGATIVE_BIT_SET)
2983 value_in_comment = - value_in_comment;
2985 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2987 if (PRE_BIT_SET)
2989 if (offset)
2990 func (stream, ", #%d]%s",
2991 value_in_comment,
2992 WRITEBACK_BIT_SET ? "!" : "");
2993 else
2994 func (stream, "]");
2996 else
2998 func (stream, "]");
3000 if (WRITEBACK_BIT_SET)
3002 if (offset)
3003 func (stream, ", #%d", value_in_comment);
3005 else
3007 func (stream, ", {%d}", offset);
3008 value_in_comment = offset;
3012 break;
3014 case 'B':
3015 /* Print ARM V5 BLX(1) address: pc+25 bits. */
3017 bfd_vma address;
3018 bfd_vma offset = 0;
3020 if (! NEGATIVE_BIT_SET)
3021 /* Is signed, hi bits should be ones. */
3022 offset = (-1) ^ 0x00ffffff;
3024 /* Offset is (SignExtend(offset field)<<2). */
3025 offset += given & 0x00ffffff;
3026 offset <<= 2;
3027 address = offset + pc + 8;
3029 if (given & 0x01000000)
3030 /* H bit allows addressing to 2-byte boundaries. */
3031 address += 2;
3033 info->print_address_func (address, info);
3035 break;
3037 case 'C':
3038 func (stream, "_");
3039 if (given & 0x80000)
3040 func (stream, "f");
3041 if (given & 0x40000)
3042 func (stream, "s");
3043 if (given & 0x20000)
3044 func (stream, "x");
3045 if (given & 0x10000)
3046 func (stream, "c");
3047 break;
3049 case 'U':
3050 switch (given & 0xf)
3052 case 0xf: func (stream, "sy"); break;
3053 case 0x7: func (stream, "un"); break;
3054 case 0xe: func (stream, "st"); break;
3055 case 0x6: func (stream, "unst"); break;
3056 default:
3057 func (stream, "#%d", (int) given & 0xf);
3058 break;
3060 break;
3062 case '0': case '1': case '2': case '3': case '4':
3063 case '5': case '6': case '7': case '8': case '9':
3065 int width;
3066 unsigned long value;
3068 c = arm_decode_bitfield (c, given, &value, &width);
3070 switch (*c)
3072 case 'r':
3073 func (stream, "%s", arm_regnames[value]);
3074 break;
3075 case 'd':
3076 func (stream, "%ld", value);
3077 value_in_comment = value;
3078 break;
3079 case 'b':
3080 func (stream, "%ld", value * 8);
3081 value_in_comment = value * 8;
3082 break;
3083 case 'W':
3084 func (stream, "%ld", value + 1);
3085 value_in_comment = value + 1;
3086 break;
3087 case 'x':
3088 func (stream, "0x%08lx", value);
3090 /* Some SWI instructions have special
3091 meanings. */
3092 if ((given & 0x0fffffff) == 0x0FF00000)
3093 func (stream, "\t; IMB");
3094 else if ((given & 0x0fffffff) == 0x0FF00001)
3095 func (stream, "\t; IMBRange");
3096 break;
3097 case 'X':
3098 func (stream, "%01lx", value & 0xf);
3099 value_in_comment = value;
3100 break;
3101 case '`':
3102 c++;
3103 if (value == 0)
3104 func (stream, "%c", *c);
3105 break;
3106 case '\'':
3107 c++;
3108 if (value == ((1ul << width) - 1))
3109 func (stream, "%c", *c);
3110 break;
3111 case '?':
3112 func (stream, "%c", c[(1 << width) - (int) value]);
3113 c += 1 << width;
3114 break;
3115 default:
3116 abort ();
3118 break;
3120 case 'e':
3122 int imm;
3124 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3125 func (stream, "%d", imm);
3126 value_in_comment = imm;
3128 break;
3130 case 'E':
3131 /* LSB and WIDTH fields of BFI or BFC. The machine-
3132 language instruction encodes LSB and MSB. */
3134 long msb = (given & 0x001f0000) >> 16;
3135 long lsb = (given & 0x00000f80) >> 7;
3136 long width = msb - lsb + 1;
3138 if (width > 0)
3139 func (stream, "#%lu, #%lu", lsb, width);
3140 else
3141 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3143 break;
3145 case 'V':
3146 /* 16-bit unsigned immediate from a MOVT or MOVW
3147 instruction, encoded in bits 0:11 and 15:19. */
3149 long hi = (given & 0x000f0000) >> 4;
3150 long lo = (given & 0x00000fff);
3151 long imm16 = hi | lo;
3153 func (stream, "#%lu", imm16);
3154 value_in_comment = imm16;
3156 break;
3158 default:
3159 abort ();
3163 else
3164 func (stream, "%c", *c);
3167 if (value_in_comment > 32 || value_in_comment < -16)
3168 func (stream, "\t; 0x%lx", (value_in_comment & 0xffffffffUL));
3169 return;
3172 abort ();
3175 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3177 static void
3178 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3180 const struct opcode16 *insn;
3181 void *stream = info->stream;
3182 fprintf_ftype func = info->fprintf_func;
3184 for (insn = thumb_opcodes; insn->assembler; insn++)
3185 if ((given & insn->mask) == insn->value)
3187 signed long value_in_comment = 0;
3188 const char *c = insn->assembler;
3190 for (; *c; c++)
3192 int domaskpc = 0;
3193 int domasklr = 0;
3195 if (*c != '%')
3197 func (stream, "%c", *c);
3198 continue;
3201 switch (*++c)
3203 case '%':
3204 func (stream, "%%");
3205 break;
3207 case 'c':
3208 if (ifthen_state)
3209 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3210 break;
3212 case 'C':
3213 if (ifthen_state)
3214 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3215 else
3216 func (stream, "s");
3217 break;
3219 case 'I':
3221 unsigned int tmp;
3223 ifthen_next_state = given & 0xff;
3224 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3225 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3226 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3228 break;
3230 case 'x':
3231 if (ifthen_next_state)
3232 func (stream, "\t; unpredictable branch in IT block\n");
3233 break;
3235 case 'X':
3236 if (ifthen_state)
3237 func (stream, "\t; unpredictable <IT:%s>",
3238 arm_conditional[IFTHEN_COND]);
3239 break;
3241 case 'S':
3243 long reg;
3245 reg = (given >> 3) & 0x7;
3246 if (given & (1 << 6))
3247 reg += 8;
3249 func (stream, "%s", arm_regnames[reg]);
3251 break;
3253 case 'D':
3255 long reg;
3257 reg = given & 0x7;
3258 if (given & (1 << 7))
3259 reg += 8;
3261 func (stream, "%s", arm_regnames[reg]);
3263 break;
3265 case 'N':
3266 if (given & (1 << 8))
3267 domasklr = 1;
3268 /* Fall through. */
3269 case 'O':
3270 if (*c == 'O' && (given & (1 << 8)))
3271 domaskpc = 1;
3272 /* Fall through. */
3273 case 'M':
3275 int started = 0;
3276 int reg;
3278 func (stream, "{");
3280 /* It would be nice if we could spot
3281 ranges, and generate the rS-rE format: */
3282 for (reg = 0; (reg < 8); reg++)
3283 if ((given & (1 << reg)) != 0)
3285 if (started)
3286 func (stream, ", ");
3287 started = 1;
3288 func (stream, "%s", arm_regnames[reg]);
3291 if (domasklr)
3293 if (started)
3294 func (stream, ", ");
3295 started = 1;
3296 func (stream, arm_regnames[14] /* "lr" */);
3299 if (domaskpc)
3301 if (started)
3302 func (stream, ", ");
3303 func (stream, arm_regnames[15] /* "pc" */);
3306 func (stream, "}");
3308 break;
3310 case 'b':
3311 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3313 bfd_vma address = (pc + 4
3314 + ((given & 0x00f8) >> 2)
3315 + ((given & 0x0200) >> 3));
3316 info->print_address_func (address, info);
3318 break;
3320 case 's':
3321 /* Right shift immediate -- bits 6..10; 1-31 print
3322 as themselves, 0 prints as 32. */
3324 long imm = (given & 0x07c0) >> 6;
3325 if (imm == 0)
3326 imm = 32;
3327 func (stream, "#%ld", imm);
3329 break;
3331 case '0': case '1': case '2': case '3': case '4':
3332 case '5': case '6': case '7': case '8': case '9':
3334 int bitstart = *c++ - '0';
3335 int bitend = 0;
3337 while (*c >= '0' && *c <= '9')
3338 bitstart = (bitstart * 10) + *c++ - '0';
3340 switch (*c)
3342 case '-':
3344 long reg;
3346 c++;
3347 while (*c >= '0' && *c <= '9')
3348 bitend = (bitend * 10) + *c++ - '0';
3349 if (!bitend)
3350 abort ();
3351 reg = given >> bitstart;
3352 reg &= (2 << (bitend - bitstart)) - 1;
3353 switch (*c)
3355 case 'r':
3356 func (stream, "%s", arm_regnames[reg]);
3357 break;
3359 case 'd':
3360 func (stream, "%ld", reg);
3361 value_in_comment = reg;
3362 break;
3364 case 'H':
3365 func (stream, "%ld", reg << 1);
3366 value_in_comment = reg << 1;
3367 break;
3369 case 'W':
3370 func (stream, "%ld", reg << 2);
3371 value_in_comment = reg << 2;
3372 break;
3374 case 'a':
3375 /* PC-relative address -- the bottom two
3376 bits of the address are dropped
3377 before the calculation. */
3378 info->print_address_func
3379 (((pc + 4) & ~3) + (reg << 2), info);
3380 value_in_comment = 0;
3381 break;
3383 case 'x':
3384 func (stream, "0x%04lx", reg);
3385 break;
3387 case 'B':
3388 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3389 info->print_address_func (reg * 2 + pc + 4, info);
3390 value_in_comment = 0;
3391 break;
3393 case 'c':
3394 func (stream, "%s", arm_conditional [reg]);
3395 break;
3397 default:
3398 abort ();
3401 break;
3403 case '\'':
3404 c++;
3405 if ((given & (1 << bitstart)) != 0)
3406 func (stream, "%c", *c);
3407 break;
3409 case '?':
3410 ++c;
3411 if ((given & (1 << bitstart)) != 0)
3412 func (stream, "%c", *c++);
3413 else
3414 func (stream, "%c", *++c);
3415 break;
3417 default:
3418 abort ();
3421 break;
3423 default:
3424 abort ();
3428 if (value_in_comment > 32 || value_in_comment < -16)
3429 func (stream, "\t; 0x%lx", value_in_comment);
3430 return;
3433 /* No match. */
3434 abort ();
3437 /* Return the name of an V7M special register. */
3439 static const char *
3440 psr_name (int regno)
3442 switch (regno)
3444 case 0: return "APSR";
3445 case 1: return "IAPSR";
3446 case 2: return "EAPSR";
3447 case 3: return "PSR";
3448 case 5: return "IPSR";
3449 case 6: return "EPSR";
3450 case 7: return "IEPSR";
3451 case 8: return "MSP";
3452 case 9: return "PSP";
3453 case 16: return "PRIMASK";
3454 case 17: return "BASEPRI";
3455 case 18: return "BASEPRI_MASK";
3456 case 19: return "FAULTMASK";
3457 case 20: return "CONTROL";
3458 default: return "<unknown>";
3462 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3464 static void
3465 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3467 const struct opcode32 *insn;
3468 void *stream = info->stream;
3469 fprintf_ftype func = info->fprintf_func;
3471 if (print_insn_coprocessor (pc, info, given, TRUE))
3472 return;
3474 if (print_insn_neon (info, given, TRUE))
3475 return;
3477 for (insn = thumb32_opcodes; insn->assembler; insn++)
3478 if ((given & insn->mask) == insn->value)
3480 signed long value_in_comment = 0;
3481 const char *c = insn->assembler;
3483 for (; *c; c++)
3485 if (*c != '%')
3487 func (stream, "%c", *c);
3488 continue;
3491 switch (*++c)
3493 case '%':
3494 func (stream, "%%");
3495 break;
3497 case 'c':
3498 if (ifthen_state)
3499 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3500 break;
3502 case 'x':
3503 if (ifthen_next_state)
3504 func (stream, "\t; unpredictable branch in IT block\n");
3505 break;
3507 case 'X':
3508 if (ifthen_state)
3509 func (stream, "\t; unpredictable <IT:%s>",
3510 arm_conditional[IFTHEN_COND]);
3511 break;
3513 case 'I':
3515 unsigned int imm12 = 0;
3517 imm12 |= (given & 0x000000ffu);
3518 imm12 |= (given & 0x00007000u) >> 4;
3519 imm12 |= (given & 0x04000000u) >> 15;
3520 func (stream, "#%u", imm12);
3521 value_in_comment = imm12;
3523 break;
3525 case 'M':
3527 unsigned int bits = 0, imm, imm8, mod;
3529 bits |= (given & 0x000000ffu);
3530 bits |= (given & 0x00007000u) >> 4;
3531 bits |= (given & 0x04000000u) >> 15;
3532 imm8 = (bits & 0x0ff);
3533 mod = (bits & 0xf00) >> 8;
3534 switch (mod)
3536 case 0: imm = imm8; break;
3537 case 1: imm = ((imm8 << 16) | imm8); break;
3538 case 2: imm = ((imm8 << 24) | (imm8 << 8)); break;
3539 case 3: imm = ((imm8 << 24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3540 default:
3541 mod = (bits & 0xf80) >> 7;
3542 imm8 = (bits & 0x07f) | 0x80;
3543 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3545 func (stream, "#%u", imm);
3546 value_in_comment = imm;
3548 break;
3550 case 'J':
3552 unsigned int imm = 0;
3554 imm |= (given & 0x000000ffu);
3555 imm |= (given & 0x00007000u) >> 4;
3556 imm |= (given & 0x04000000u) >> 15;
3557 imm |= (given & 0x000f0000u) >> 4;
3558 func (stream, "#%u", imm);
3559 value_in_comment = imm;
3561 break;
3563 case 'K':
3565 unsigned int imm = 0;
3567 imm |= (given & 0x000f0000u) >> 16;
3568 imm |= (given & 0x00000ff0u) >> 0;
3569 imm |= (given & 0x0000000fu) << 12;
3570 func (stream, "#%u", imm);
3571 value_in_comment = imm;
3573 break;
3575 case 'S':
3577 unsigned int reg = (given & 0x0000000fu);
3578 unsigned int stp = (given & 0x00000030u) >> 4;
3579 unsigned int imm = 0;
3580 imm |= (given & 0x000000c0u) >> 6;
3581 imm |= (given & 0x00007000u) >> 10;
3583 func (stream, "%s", arm_regnames[reg]);
3584 switch (stp)
3586 case 0:
3587 if (imm > 0)
3588 func (stream, ", lsl #%u", imm);
3589 break;
3591 case 1:
3592 if (imm == 0)
3593 imm = 32;
3594 func (stream, ", lsr #%u", imm);
3595 break;
3597 case 2:
3598 if (imm == 0)
3599 imm = 32;
3600 func (stream, ", asr #%u", imm);
3601 break;
3603 case 3:
3604 if (imm == 0)
3605 func (stream, ", rrx");
3606 else
3607 func (stream, ", ror #%u", imm);
3610 break;
3612 case 'a':
3614 unsigned int Rn = (given & 0x000f0000) >> 16;
3615 unsigned int U = ! NEGATIVE_BIT_SET;
3616 unsigned int op = (given & 0x00000f00) >> 8;
3617 unsigned int i12 = (given & 0x00000fff);
3618 unsigned int i8 = (given & 0x000000ff);
3619 bfd_boolean writeback = FALSE, postind = FALSE;
3620 int offset = 0;
3622 func (stream, "[%s", arm_regnames[Rn]);
3623 if (U) /* 12-bit positive immediate offset. */
3625 offset = i12;
3626 if (Rn != 15)
3627 value_in_comment = offset;
3629 else if (Rn == 15) /* 12-bit negative immediate offset. */
3630 offset = - (int) i12;
3631 else if (op == 0x0) /* Shifted register offset. */
3633 unsigned int Rm = (i8 & 0x0f);
3634 unsigned int sh = (i8 & 0x30) >> 4;
3636 func (stream, ", %s", arm_regnames[Rm]);
3637 if (sh)
3638 func (stream, ", lsl #%u", sh);
3639 func (stream, "]");
3640 break;
3642 else switch (op)
3644 case 0xE: /* 8-bit positive immediate offset. */
3645 offset = i8;
3646 break;
3648 case 0xC: /* 8-bit negative immediate offset. */
3649 offset = -i8;
3650 break;
3652 case 0xF: /* 8-bit + preindex with wb. */
3653 offset = i8;
3654 writeback = TRUE;
3655 break;
3657 case 0xD: /* 8-bit - preindex with wb. */
3658 offset = -i8;
3659 writeback = TRUE;
3660 break;
3662 case 0xB: /* 8-bit + postindex. */
3663 offset = i8;
3664 postind = TRUE;
3665 break;
3667 case 0x9: /* 8-bit - postindex. */
3668 offset = -i8;
3669 postind = TRUE;
3670 break;
3672 default:
3673 func (stream, ", <undefined>]");
3674 goto skip;
3677 if (postind)
3678 func (stream, "], #%d", offset);
3679 else
3681 if (offset)
3682 func (stream, ", #%d", offset);
3683 func (stream, writeback ? "]!" : "]");
3686 if (Rn == 15)
3688 func (stream, "\t; ");
3689 info->print_address_func (((pc + 4) & ~3) + offset, info);
3692 skip:
3693 break;
3695 case 'A':
3697 unsigned int U = ! NEGATIVE_BIT_SET;
3698 unsigned int W = WRITEBACK_BIT_SET;
3699 unsigned int Rn = (given & 0x000f0000) >> 16;
3700 unsigned int off = (given & 0x000000ff);
3702 func (stream, "[%s", arm_regnames[Rn]);
3704 if (PRE_BIT_SET)
3706 if (off || !U)
3708 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3709 value_in_comment = off * 4 * U ? 1 : -1;
3711 func (stream, "]");
3712 if (W)
3713 func (stream, "!");
3715 else
3717 func (stream, "], ");
3718 if (W)
3720 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3721 value_in_comment = off * 4 * U ? 1 : -1;
3723 else
3725 func (stream, "{%u}", off);
3726 value_in_comment = off;
3730 break;
3732 case 'w':
3734 unsigned int Sbit = (given & 0x01000000) >> 24;
3735 unsigned int type = (given & 0x00600000) >> 21;
3737 switch (type)
3739 case 0: func (stream, Sbit ? "sb" : "b"); break;
3740 case 1: func (stream, Sbit ? "sh" : "h"); break;
3741 case 2:
3742 if (Sbit)
3743 func (stream, "??");
3744 break;
3745 case 3:
3746 func (stream, "??");
3747 break;
3750 break;
3752 case 'm':
3754 int started = 0;
3755 int reg;
3757 func (stream, "{");
3758 for (reg = 0; reg < 16; reg++)
3759 if ((given & (1 << reg)) != 0)
3761 if (started)
3762 func (stream, ", ");
3763 started = 1;
3764 func (stream, "%s", arm_regnames[reg]);
3766 func (stream, "}");
3768 break;
3770 case 'E':
3772 unsigned int msb = (given & 0x0000001f);
3773 unsigned int lsb = 0;
3775 lsb |= (given & 0x000000c0u) >> 6;
3776 lsb |= (given & 0x00007000u) >> 10;
3777 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3779 break;
3781 case 'F':
3783 unsigned int width = (given & 0x0000001f) + 1;
3784 unsigned int lsb = 0;
3786 lsb |= (given & 0x000000c0u) >> 6;
3787 lsb |= (given & 0x00007000u) >> 10;
3788 func (stream, "#%u, #%u", lsb, width);
3790 break;
3792 case 'b':
3794 unsigned int S = (given & 0x04000000u) >> 26;
3795 unsigned int J1 = (given & 0x00002000u) >> 13;
3796 unsigned int J2 = (given & 0x00000800u) >> 11;
3797 int offset = 0;
3799 offset |= !S << 20;
3800 offset |= J2 << 19;
3801 offset |= J1 << 18;
3802 offset |= (given & 0x003f0000) >> 4;
3803 offset |= (given & 0x000007ff) << 1;
3804 offset -= (1 << 20);
3806 info->print_address_func (pc + 4 + offset, info);
3808 break;
3810 case 'B':
3812 unsigned int S = (given & 0x04000000u) >> 26;
3813 unsigned int I1 = (given & 0x00002000u) >> 13;
3814 unsigned int I2 = (given & 0x00000800u) >> 11;
3815 int offset = 0;
3817 offset |= !S << 24;
3818 offset |= !(I1 ^ S) << 23;
3819 offset |= !(I2 ^ S) << 22;
3820 offset |= (given & 0x03ff0000u) >> 4;
3821 offset |= (given & 0x000007ffu) << 1;
3822 offset -= (1 << 24);
3823 offset += pc + 4;
3825 /* BLX target addresses are always word aligned. */
3826 if ((given & 0x00001000u) == 0)
3827 offset &= ~2u;
3829 info->print_address_func (offset, info);
3831 break;
3833 case 's':
3835 unsigned int shift = 0;
3837 shift |= (given & 0x000000c0u) >> 6;
3838 shift |= (given & 0x00007000u) >> 10;
3839 if (WRITEBACK_BIT_SET)
3840 func (stream, ", asr #%u", shift);
3841 else if (shift)
3842 func (stream, ", lsl #%u", shift);
3843 /* else print nothing - lsl #0 */
3845 break;
3847 case 'R':
3849 unsigned int rot = (given & 0x00000030) >> 4;
3851 if (rot)
3852 func (stream, ", ror #%u", rot * 8);
3854 break;
3856 case 'U':
3857 switch (given & 0xf)
3859 case 0xf: func (stream, "sy"); break;
3860 case 0x7: func (stream, "un"); break;
3861 case 0xe: func (stream, "st"); break;
3862 case 0x6: func (stream, "unst"); break;
3863 default:
3864 func (stream, "#%d", (int) given & 0xf);
3865 break;
3867 break;
3869 case 'C':
3870 if ((given & 0xff) == 0)
3872 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3873 if (given & 0x800)
3874 func (stream, "f");
3875 if (given & 0x400)
3876 func (stream, "s");
3877 if (given & 0x200)
3878 func (stream, "x");
3879 if (given & 0x100)
3880 func (stream, "c");
3882 else
3884 func (stream, psr_name (given & 0xff));
3886 break;
3888 case 'D':
3889 if ((given & 0xff) == 0)
3890 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3891 else
3892 func (stream, psr_name (given & 0xff));
3893 break;
3895 case '0': case '1': case '2': case '3': case '4':
3896 case '5': case '6': case '7': case '8': case '9':
3898 int width;
3899 unsigned long val;
3901 c = arm_decode_bitfield (c, given, &val, &width);
3903 switch (*c)
3905 case 'd':
3906 func (stream, "%lu", val);
3907 value_in_comment = val;
3908 break;
3909 case 'W':
3910 func (stream, "%lu", val * 4);
3911 value_in_comment = val * 4;
3912 break;
3913 case 'r': func (stream, "%s", arm_regnames[val]); break;
3915 case 'c':
3916 func (stream, "%s", arm_conditional[val]);
3917 break;
3919 case '\'':
3920 c++;
3921 if (val == ((1ul << width) - 1))
3922 func (stream, "%c", *c);
3923 break;
3925 case '`':
3926 c++;
3927 if (val == 0)
3928 func (stream, "%c", *c);
3929 break;
3931 case '?':
3932 func (stream, "%c", c[(1 << width) - (int) val]);
3933 c += 1 << width;
3934 break;
3936 case 'x':
3937 func (stream, "0x%lx", val & 0xffffffffUL);
3938 break;
3940 default:
3941 abort ();
3944 break;
3946 default:
3947 abort ();
3951 if (value_in_comment > 32 || value_in_comment < -16)
3952 func (stream, "\t; 0x%lx", value_in_comment);
3953 return;
3956 /* No match. */
3957 abort ();
3960 /* Print data bytes on INFO->STREAM. */
3962 static void
3963 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3964 struct disassemble_info *info,
3965 long given)
3967 switch (info->bytes_per_chunk)
3969 case 1:
3970 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3971 break;
3972 case 2:
3973 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3974 break;
3975 case 4:
3976 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3977 break;
3978 default:
3979 abort ();
3983 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3984 being displayed in symbol relative addresses. */
3986 bfd_boolean
3987 arm_symbol_is_valid (asymbol * sym,
3988 struct disassemble_info * info ATTRIBUTE_UNUSED)
3990 const char * name;
3992 if (sym == NULL)
3993 return FALSE;
3995 name = bfd_asymbol_name (sym);
3997 return (name && *name != '$');
4000 /* Parse an individual disassembler option. */
4002 void
4003 parse_arm_disassembler_option (char *option)
4005 if (option == NULL)
4006 return;
4008 if (CONST_STRNEQ (option, "reg-names-"))
4010 int i;
4012 option += 10;
4014 for (i = NUM_ARM_REGNAMES; i--;)
4015 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
4017 regname_selected = i;
4018 break;
4021 if (i < 0)
4022 /* XXX - should break 'option' at following delimiter. */
4023 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
4025 else if (CONST_STRNEQ (option, "force-thumb"))
4026 force_thumb = 1;
4027 else if (CONST_STRNEQ (option, "no-force-thumb"))
4028 force_thumb = 0;
4029 else
4030 /* XXX - should break 'option' at following delimiter. */
4031 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
4033 return;
4036 /* Parse the string of disassembler options, spliting it at whitespaces
4037 or commas. (Whitespace separators supported for backwards compatibility). */
4039 static void
4040 parse_disassembler_options (char *options)
4042 if (options == NULL)
4043 return;
4045 while (*options)
4047 parse_arm_disassembler_option (options);
4049 /* Skip forward to next seperator. */
4050 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
4051 ++ options;
4052 /* Skip forward past seperators. */
4053 while (ISSPACE (*options) || (*options == ','))
4054 ++ options;
4058 /* Search back through the insn stream to determine if this instruction is
4059 conditionally executed. */
4061 static void
4062 find_ifthen_state (bfd_vma pc,
4063 struct disassemble_info *info,
4064 bfd_boolean little)
4066 unsigned char b[2];
4067 unsigned int insn;
4068 int status;
4069 /* COUNT is twice the number of instructions seen. It will be odd if we
4070 just crossed an instruction boundary. */
4071 int count;
4072 int it_count;
4073 unsigned int seen_it;
4074 bfd_vma addr;
4076 ifthen_address = pc;
4077 ifthen_state = 0;
4079 addr = pc;
4080 count = 1;
4081 it_count = 0;
4082 seen_it = 0;
4083 /* Scan backwards looking for IT instructions, keeping track of where
4084 instruction boundaries are. We don't know if something is actually an
4085 IT instruction until we find a definite instruction boundary. */
4086 for (;;)
4088 if (addr == 0 || info->symbol_at_address_func (addr, info))
4090 /* A symbol must be on an instruction boundary, and will not
4091 be within an IT block. */
4092 if (seen_it && (count & 1))
4093 break;
4095 return;
4097 addr -= 2;
4098 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4099 if (status)
4100 return;
4102 if (little)
4103 insn = (b[0]) | (b[1] << 8);
4104 else
4105 insn = (b[1]) | (b[0] << 8);
4106 if (seen_it)
4108 if ((insn & 0xf800) < 0xe800)
4110 /* Addr + 2 is an instruction boundary. See if this matches
4111 the expected boundary based on the position of the last
4112 IT candidate. */
4113 if (count & 1)
4114 break;
4115 seen_it = 0;
4118 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4120 /* This could be an IT instruction. */
4121 seen_it = insn;
4122 it_count = count >> 1;
4124 if ((insn & 0xf800) >= 0xe800)
4125 count++;
4126 else
4127 count = (count + 2) | 1;
4128 /* IT blocks contain at most 4 instructions. */
4129 if (count >= 8 && !seen_it)
4130 return;
4132 /* We found an IT instruction. */
4133 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4134 if ((ifthen_state & 0xf) == 0)
4135 ifthen_state = 0;
4138 /* Try to infer the code type (Arm or Thumb) from a symbol.
4139 Returns nonzero if *MAP_TYPE was set. */
4141 static int
4142 get_sym_code_type (struct disassemble_info *info,
4143 int n,
4144 enum map_type *map_type)
4146 elf_symbol_type *es;
4147 unsigned int type;
4148 const char *name;
4150 es = *(elf_symbol_type **)(info->symtab + n);
4151 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4153 /* If the symbol has function type then use that. */
4154 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4156 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4157 return TRUE;
4160 /* Check for mapping symbols. */
4161 name = bfd_asymbol_name (info->symtab[n]);
4162 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4163 && (name[2] == 0 || name[2] == '.'))
4165 *map_type = ((name[1] == 'a') ? MAP_ARM
4166 : (name[1] == 't') ? MAP_THUMB
4167 : MAP_DATA);
4168 return TRUE;
4171 return FALSE;
4174 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4175 of the supplied arm_feature_set structure with bitmasks indicating
4176 the support base architectures and coprocessor extensions.
4178 FIXME: This could more efficiently implemented as a constant array,
4179 although it would also be less robust. */
4181 static void
4182 select_arm_features (unsigned long mach,
4183 arm_feature_set * features)
4185 #undef ARM_FEATURE
4186 #define ARM_FEATURE(ARCH,CEXT) \
4187 features->core = (ARCH); \
4188 features->coproc = (CEXT) | FPU_FPA; \
4189 return
4191 switch (mach)
4193 case bfd_mach_arm_2: ARM_ARCH_V2;
4194 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4195 case bfd_mach_arm_3: ARM_ARCH_V3;
4196 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4197 case bfd_mach_arm_4: ARM_ARCH_V4;
4198 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4199 case bfd_mach_arm_5: ARM_ARCH_V5;
4200 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4201 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4202 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4203 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4204 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4205 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4206 /* If the machine type is unknown allow all
4207 architecture types and all extensions. */
4208 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4209 default:
4210 abort ();
4215 /* NOTE: There are no checks in these routines that
4216 the relevant number of data bytes exist. */
4218 static int
4219 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4221 unsigned char b[4];
4222 long given;
4223 int status;
4224 int is_thumb = FALSE;
4225 int is_data = FALSE;
4226 int little_code;
4227 unsigned int size = 4;
4228 void (*printer) (bfd_vma, struct disassemble_info *, long);
4229 bfd_boolean found = FALSE;
4231 if (info->disassembler_options)
4233 parse_disassembler_options (info->disassembler_options);
4235 /* To avoid repeated parsing of these options, we remove them here. */
4236 info->disassembler_options = NULL;
4239 /* PR 10288: Control which instructions will be disassembled. */
4240 if (info->private_data == NULL)
4242 static arm_feature_set features;
4244 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4245 /* If the user did not use the -m command line switch then default to
4246 disassembling all types of ARM instruction.
4248 The info->mach value has to be ignored as this will be based on
4249 the default archictecture for the target and/or hints in the notes
4250 section, but it will never be greater than the current largest arm
4251 machine value (iWMMXt2), which is only equivalent to the V5TE
4252 architecture. ARM architectures have advanced beyond the machine
4253 value encoding, and these newer architectures would be ignored if
4254 the machine value was used.
4256 Ie the -m switch is used to restrict which instructions will be
4257 disassembled. If it is necessary to use the -m switch to tell
4258 objdump that an ARM binary is being disassembled, eg because the
4259 input is a raw binary file, but it is also desired to disassemble
4260 all ARM instructions then use "-marm". This will select the
4261 "unknown" arm architecture which is compatible with any ARM
4262 instruction. */
4263 info->mach = bfd_mach_arm_unknown;
4265 /* Compute the architecture bitmask from the machine number.
4266 Note: This assumes that the machine number will not change
4267 during disassembly.... */
4268 select_arm_features (info->mach, & features);
4270 info->private_data = & features;
4273 /* Decide if our code is going to be little-endian, despite what the
4274 function argument might say. */
4275 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4277 /* First check the full symtab for a mapping symbol, even if there
4278 are no usable non-mapping symbols for this address. */
4279 if (info->symtab_size != 0
4280 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4282 bfd_vma addr;
4283 int n;
4284 int last_sym = -1;
4285 enum map_type type = MAP_ARM;
4287 if (pc <= last_mapping_addr)
4288 last_mapping_sym = -1;
4289 is_thumb = (last_type == MAP_THUMB);
4290 found = FALSE;
4291 /* Start scanning at the start of the function, or wherever
4292 we finished last time. */
4293 n = info->symtab_pos + 1;
4294 if (n < last_mapping_sym)
4295 n = last_mapping_sym;
4297 /* Scan up to the location being disassembled. */
4298 for (; n < info->symtab_size; n++)
4300 addr = bfd_asymbol_value (info->symtab[n]);
4301 if (addr > pc)
4302 break;
4303 if ((info->section == NULL
4304 || info->section == info->symtab[n]->section)
4305 && get_sym_code_type (info, n, &type))
4307 last_sym = n;
4308 found = TRUE;
4312 if (!found)
4314 n = info->symtab_pos;
4315 if (n < last_mapping_sym - 1)
4316 n = last_mapping_sym - 1;
4318 /* No mapping symbol found at this address. Look backwards
4319 for a preceeding one. */
4320 for (; n >= 0; n--)
4322 if ((info->section == NULL
4323 || info->section == info->symtab[n]->section)
4324 && get_sym_code_type (info, n, &type))
4326 last_sym = n;
4327 found = TRUE;
4328 break;
4333 last_mapping_sym = last_sym;
4334 last_type = type;
4335 is_thumb = (last_type == MAP_THUMB);
4336 is_data = (last_type == MAP_DATA);
4338 /* Look a little bit ahead to see if we should print out
4339 two or four bytes of data. If there's a symbol,
4340 mapping or otherwise, after two bytes then don't
4341 print more. */
4342 if (is_data)
4344 size = 4 - (pc & 3);
4345 for (n = last_sym + 1; n < info->symtab_size; n++)
4347 addr = bfd_asymbol_value (info->symtab[n]);
4348 if (addr > pc)
4350 if (addr - pc < size)
4351 size = addr - pc;
4352 break;
4355 /* If the next symbol is after three bytes, we need to
4356 print only part of the data, so that we can use either
4357 .byte or .short. */
4358 if (size == 3)
4359 size = (pc & 1) ? 1 : 2;
4363 if (info->symbols != NULL)
4365 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4367 coff_symbol_type * cs;
4369 cs = coffsymbol (*info->symbols);
4370 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4371 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4372 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4373 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4374 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4376 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4377 && !found)
4379 /* If no mapping symbol has been found then fall back to the type
4380 of the function symbol. */
4381 elf_symbol_type * es;
4382 unsigned int type;
4384 es = *(elf_symbol_type **)(info->symbols);
4385 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4387 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4391 if (force_thumb)
4392 is_thumb = TRUE;
4394 if (is_data)
4395 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4396 else
4397 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4399 info->bytes_per_line = 4;
4401 /* PR 10263: Disassemble data if requested to do so by the user. */
4402 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4404 int i;
4406 /* Size was already set above. */
4407 info->bytes_per_chunk = size;
4408 printer = print_insn_data;
4410 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4411 given = 0;
4412 if (little)
4413 for (i = size - 1; i >= 0; i--)
4414 given = b[i] | (given << 8);
4415 else
4416 for (i = 0; i < (int) size; i++)
4417 given = b[i] | (given << 8);
4419 else if (!is_thumb)
4421 /* In ARM mode endianness is a straightforward issue: the instruction
4422 is four bytes long and is either ordered 0123 or 3210. */
4423 printer = print_insn_arm;
4424 info->bytes_per_chunk = 4;
4425 size = 4;
4427 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4428 if (little_code)
4429 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4430 else
4431 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4433 else
4435 /* In Thumb mode we have the additional wrinkle of two
4436 instruction lengths. Fortunately, the bits that determine
4437 the length of the current instruction are always to be found
4438 in the first two bytes. */
4439 printer = print_insn_thumb16;
4440 info->bytes_per_chunk = 2;
4441 size = 2;
4443 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4444 if (little_code)
4445 given = (b[0]) | (b[1] << 8);
4446 else
4447 given = (b[1]) | (b[0] << 8);
4449 if (!status)
4451 /* These bit patterns signal a four-byte Thumb
4452 instruction. */
4453 if ((given & 0xF800) == 0xF800
4454 || (given & 0xF800) == 0xF000
4455 || (given & 0xF800) == 0xE800)
4457 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4458 if (little_code)
4459 given = (b[0]) | (b[1] << 8) | (given << 16);
4460 else
4461 given = (b[1]) | (b[0] << 8) | (given << 16);
4463 printer = print_insn_thumb32;
4464 size = 4;
4468 if (ifthen_address != pc)
4469 find_ifthen_state (pc, info, little_code);
4471 if (ifthen_state)
4473 if ((ifthen_state & 0xf) == 0x8)
4474 ifthen_next_state = 0;
4475 else
4476 ifthen_next_state = (ifthen_state & 0xe0)
4477 | ((ifthen_state & 0xf) << 1);
4481 if (status)
4483 info->memory_error_func (status, pc, info);
4484 return -1;
4486 if (info->flags & INSN_HAS_RELOC)
4487 /* If the instruction has a reloc associated with it, then
4488 the offset field in the instruction will actually be the
4489 addend for the reloc. (We are using REL type relocs).
4490 In such cases, we can ignore the pc when computing
4491 addresses, since the addend is not currently pc-relative. */
4492 pc = 0;
4494 printer (pc, info, given);
4496 if (is_thumb)
4498 ifthen_state = ifthen_next_state;
4499 ifthen_address += size;
4501 return size;
4505 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4507 /* Detect BE8-ness and record it in the disassembler info. */
4508 if (info->flavour == bfd_target_elf_flavour
4509 && info->section != NULL
4510 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4511 info->endian_code = BFD_ENDIAN_LITTLE;
4513 return print_insn (pc, info, FALSE);
4517 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4519 return print_insn (pc, info, TRUE);
4522 void
4523 print_arm_disassembler_options (FILE *stream)
4525 int i;
4527 fprintf (stream, _("\n\
4528 The following ARM specific disassembler options are supported for use with\n\
4529 the -M switch:\n"));
4531 for (i = NUM_ARM_REGNAMES; i--;)
4532 fprintf (stream, " reg-names-%s %*c%s\n",
4533 regnames[i].name,
4534 (int)(14 - strlen (regnames[i].name)), ' ',
4535 regnames[i].description);
4537 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4538 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");