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