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