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