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