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