gdb/
[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, 0x0e130190, 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, 0x0f300ff0, "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, 0x0c500000, "strb%c\t%12-15r, %a"},
1007 {ARM_EXT_V1, 0x000000b0, 0x0e1000f0, "strh%c\t%12-15r, %s"},
1008 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%6's%5?hb%c\t%12-15r, %s"},
1009 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%20's%c\t%12-15r, %16-19r, %o"},
1010 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%20's%c\t%12-15r, %16-19r, %o"},
1011 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%20's%c\t%12-15r, %16-19r, %o"},
1012 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%20's%c\t%12-15r, %16-19r, %o"},
1013 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%20's%c\t%12-15r, %16-19r, %o"},
1014 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%20's%c\t%12-15r, %16-19r, %o"},
1015 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%20's%c\t%12-15r, %16-19r, %o"},
1016 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%20's%c\t%12-15r, %16-19r, %o"},
1017 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
1018 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
1019 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%p%c\t%16-19r, %o"},
1020 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%p%c\t%16-19r, %o"},
1021 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%p%c\t%16-19r, %o"},
1022 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%p%c\t%16-19r, %o"},
1023 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%20's%c\t%12-15r, %16-19r, %o"},
1024 {ARM_EXT_V1, 0x03a00000, 0x0fef0000, "mov%20's%c\t%12-15r, %o"},
1025 {ARM_EXT_V1, 0x01a00000, 0x0def0ff0, "mov%20's%c\t%12-15r, %0-3r"},
1026 {ARM_EXT_V1, 0x01a00000, 0x0def0060, "lsl%20's%c\t%12-15r, %q"},
1027 {ARM_EXT_V1, 0x01a00020, 0x0def0060, "lsr%20's%c\t%12-15r, %q"},
1028 {ARM_EXT_V1, 0x01a00040, 0x0def0060, "asr%20's%c\t%12-15r, %q"},
1029 {ARM_EXT_V1, 0x01a00060, 0x0def0ff0, "rrx%20's%c\t%12-15r, %0-3r"},
1030 {ARM_EXT_V1, 0x01a00060, 0x0def0060, "ror%20's%c\t%12-15r, %q"},
1031 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%20's%c\t%12-15r, %16-19r, %o"},
1032 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%20's%c\t%12-15r, %o"},
1033 {ARM_EXT_V1, 0x06000010, 0x0e000010, UNDEFINED_INSTRUCTION},
1034 {ARM_EXT_V1, 0x049d0004, 0x0fff0fff, "pop%c\t{%12-15r}\t\t; (ldr%c %12-15r, %a)"},
1035 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%22'b%t%c\t%12-15r, %a"},
1036 {ARM_EXT_V1, 0x092d0000, 0x0fff0000, "push%c\t%m"},
1037 {ARM_EXT_V1, 0x08800000, 0x0ff00000, "stm%c\t%16-19r%21'!, %m%22'^"},
1038 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1039 {ARM_EXT_V1, 0x08bd0000, 0x0fff0000, "pop%c\t%m"},
1040 {ARM_EXT_V1, 0x08900000, 0x0f900000, "ldm%c\t%16-19r%21'!, %m%22'^"},
1041 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%23?id%24?ba%c\t%16-19r%21'!, %m%22'^"},
1042 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
1043 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "svc%c\t%0-23x"},
1044
1045 /* The rest. */
1046 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1047 {0, 0x00000000, 0x00000000, 0}
1048 };
1049
1050 /* print_insn_thumb16 recognizes the following format control codes:
1051
1052 %S print Thumb register (bits 3..5 as high number if bit 6 set)
1053 %D print Thumb register (bits 0..2 as high number if bit 7 set)
1054 %<bitfield>I print bitfield as a signed decimal
1055 (top bit of range being the sign bit)
1056 %N print Thumb register mask (with LR)
1057 %O print Thumb register mask (with PC)
1058 %M print Thumb register mask
1059 %b print CZB's 6-bit unsigned branch destination
1060 %s print Thumb right-shift immediate (6..10; 0 == 32).
1061 %c print the condition code
1062 %C print the condition code, or "s" if not conditional
1063 %x print warning if conditional an not at end of IT block"
1064 %X print "\t; unpredictable <IT:code>" if conditional
1065 %I print IT instruction suffix and operands
1066 %<bitfield>r print bitfield as an ARM register
1067 %<bitfield>d print bitfield as a decimal
1068 %<bitfield>H print (bitfield * 2) as a decimal
1069 %<bitfield>W print (bitfield * 4) as a decimal
1070 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
1071 %<bitfield>B print Thumb branch destination (signed displacement)
1072 %<bitfield>c print bitfield as a condition code
1073 %<bitnum>'c print specified char iff bit is one
1074 %<bitnum>?ab print a if bit is one else print b. */
1075
1076 static const struct opcode16 thumb_opcodes[] =
1077 {
1078 /* Thumb instructions. */
1079
1080 /* ARM V6K no-argument instructions. */
1081 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop%c"},
1082 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield%c"},
1083 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe%c"},
1084 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi%c"},
1085 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev%c"},
1086 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop%c\t{%4-7d}"},
1087
1088 /* ARM V6T2 instructions. */
1089 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b%X"},
1090 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b%X"},
1091 {ARM_EXT_V6T2, 0xbf00, 0xff00, "it%I%X"},
1092
1093 /* ARM V6. */
1094 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f%X"},
1095 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f%X"},
1096 {ARM_EXT_V6, 0x4600, 0xffc0, "mov%c\t%0-2r, %3-5r"},
1097 {ARM_EXT_V6, 0xba00, 0xffc0, "rev%c\t%0-2r, %3-5r"},
1098 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16%c\t%0-2r, %3-5r"},
1099 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh%c\t%0-2r, %3-5r"},
1100 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble%X"},
1101 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth%c\t%0-2r, %3-5r"},
1102 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb%c\t%0-2r, %3-5r"},
1103 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth%c\t%0-2r, %3-5r"},
1104 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb%c\t%0-2r, %3-5r"},
1105
1106 /* ARM V5 ISA extends Thumb. */
1107 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"}, /* Is always unconditional. */
1108 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
1109 {ARM_EXT_V5T, 0x4780, 0xff87, "blx%c\t%3-6r%x"}, /* note: 4 bit register number. */
1110 /* ARM V4T ISA (Thumb v1). */
1111 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop%c\t\t\t; (mov r8, r8)"},
1112 /* Format 4. */
1113 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and%C\t%0-2r, %3-5r"},
1114 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor%C\t%0-2r, %3-5r"},
1115 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl%C\t%0-2r, %3-5r"},
1116 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr%C\t%0-2r, %3-5r"},
1117 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr%C\t%0-2r, %3-5r"},
1118 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc%C\t%0-2r, %3-5r"},
1119 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc%C\t%0-2r, %3-5r"},
1120 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror%C\t%0-2r, %3-5r"},
1121 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst%c\t%0-2r, %3-5r"},
1122 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg%C\t%0-2r, %3-5r"},
1123 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp%c\t%0-2r, %3-5r"},
1124 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn%c\t%0-2r, %3-5r"},
1125 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr%C\t%0-2r, %3-5r"},
1126 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul%C\t%0-2r, %3-5r"},
1127 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic%C\t%0-2r, %3-5r"},
1128 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn%C\t%0-2r, %3-5r"},
1129 /* format 13 */
1130 {ARM_EXT_V4T, 0xB000, 0xFF80, "add%c\tsp, #%0-6W"},
1131 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub%c\tsp, #%0-6W"},
1132 /* format 5 */
1133 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx%c\t%S%x"},
1134 {ARM_EXT_V4T, 0x4400, 0xFF00, "add%c\t%D, %S"},
1135 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp%c\t%D, %S"},
1136 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov%c\t%D, %S"},
1137 /* format 14 */
1138 {ARM_EXT_V4T, 0xB400, 0xFE00, "push%c\t%N"},
1139 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop%c\t%O"},
1140 /* format 2 */
1141 {ARM_EXT_V4T, 0x1800, 0xFE00, "add%C\t%0-2r, %3-5r, %6-8r"},
1142 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub%C\t%0-2r, %3-5r, %6-8r"},
1143 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add%C\t%0-2r, %3-5r, #%6-8d"},
1144 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub%C\t%0-2r, %3-5r, #%6-8d"},
1145 /* format 8 */
1146 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh%c\t%0-2r, [%3-5r, %6-8r]"},
1147 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh%c\t%0-2r, [%3-5r, %6-8r]"},
1148 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb%c\t%0-2r, [%3-5r, %6-8r]"},
1149 /* format 7 */
1150 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1151 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b%c\t%0-2r, [%3-5r, %6-8r]"},
1152 /* format 1 */
1153 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl%C\t%0-2r, %3-5r, #%6-10d"},
1154 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr%C\t%0-2r, %3-5r, %s"},
1155 {ARM_EXT_V4T, 0x1000, 0xF800, "asr%C\t%0-2r, %3-5r, %s"},
1156 /* format 3 */
1157 {ARM_EXT_V4T, 0x2000, 0xF800, "mov%C\t%8-10r, #%0-7d"},
1158 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp%c\t%8-10r, #%0-7d"},
1159 {ARM_EXT_V4T, 0x3000, 0xF800, "add%C\t%8-10r, #%0-7d"},
1160 {ARM_EXT_V4T, 0x3800, 0xF800, "sub%C\t%8-10r, #%0-7d"},
1161 /* format 6 */
1162 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr%c\t%8-10r, [pc, #%0-7W]\t; (%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
1163 /* format 9 */
1164 {ARM_EXT_V4T, 0x6000, 0xF800, "str%c\t%0-2r, [%3-5r, #%6-10W]"},
1165 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr%c\t%0-2r, [%3-5r, #%6-10W]"},
1166 {ARM_EXT_V4T, 0x7000, 0xF800, "strb%c\t%0-2r, [%3-5r, #%6-10d]"},
1167 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb%c\t%0-2r, [%3-5r, #%6-10d]"},
1168 /* format 10 */
1169 {ARM_EXT_V4T, 0x8000, 0xF800, "strh%c\t%0-2r, [%3-5r, #%6-10H]"},
1170 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh%c\t%0-2r, [%3-5r, #%6-10H]"},
1171 /* format 11 */
1172 {ARM_EXT_V4T, 0x9000, 0xF800, "str%c\t%8-10r, [sp, #%0-7W]"},
1173 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr%c\t%8-10r, [sp, #%0-7W]"},
1174 /* format 12 */
1175 {ARM_EXT_V4T, 0xA000, 0xF800, "add%c\t%8-10r, pc, #%0-7W\t; (adr %8-10r, %0-7a)"},
1176 {ARM_EXT_V4T, 0xA800, 0xF800, "add%c\t%8-10r, sp, #%0-7W"},
1177 /* format 15 */
1178 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia%c\t%8-10r!, %M"},
1179 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia%c\t%8-10r!, %M"},
1180 /* format 17 */
1181 {ARM_EXT_V4T, 0xDF00, 0xFF00, "svc%c\t%0-7d"},
1182 /* format 16 */
1183 {ARM_EXT_V4T, 0xDE00, 0xFE00, UNDEFINED_INSTRUCTION},
1184 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B%X"},
1185 /* format 18 */
1186 {ARM_EXT_V4T, 0xE000, 0xF800, "b%c.n\t%0-10B%x"},
1187
1188 /* The E800 .. FFFF range is unconditionally redirected to the
1189 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
1190 are processed via that table. Thus, we can never encounter a
1191 bare "second half of BL/BLX(1)" instruction here. */
1192 {ARM_EXT_V1, 0x0000, 0x0000, UNDEFINED_INSTRUCTION},
1193 {0, 0, 0, 0}
1194 };
1195
1196 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
1197 We adopt the convention that hw1 is the high 16 bits of .value and
1198 .mask, hw2 the low 16 bits.
1199
1200 print_insn_thumb32 recognizes the following format control codes:
1201
1202 %% %
1203
1204 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
1205 %M print a modified 12-bit immediate (same location)
1206 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
1207 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
1208 %S print a possibly-shifted Rm
1209
1210 %a print the address of a plain load/store
1211 %w print the width and signedness of a core load/store
1212 %m print register mask for ldm/stm
1213
1214 %E print the lsb and width fields of a bfc/bfi instruction
1215 %F print the lsb and width fields of a sbfx/ubfx instruction
1216 %b print a conditional branch offset
1217 %B print an unconditional branch offset
1218 %s print the shift field of an SSAT instruction
1219 %R print the rotation field of an SXT instruction
1220 %U print barrier type.
1221 %P print address for pli instruction.
1222 %c print the condition code
1223 %x print warning if conditional an not at end of IT block"
1224 %X print "\t; unpredictable <IT:code>" if conditional
1225
1226 %<bitfield>d print bitfield in decimal
1227 %<bitfield>W print bitfield*4 in decimal
1228 %<bitfield>r print bitfield as an ARM register
1229 %<bitfield>c print bitfield as a condition code
1230
1231 %<bitfield>'c print specified char iff bitfield is all ones
1232 %<bitfield>`c print specified char iff bitfield is all zeroes
1233 %<bitfield>?ab... select from array of values in big endian order
1234
1235 With one exception at the bottom (done because BL and BLX(1) need
1236 to come dead last), this table was machine-sorted first in
1237 decreasing order of number of bits set in the mask, then in
1238 increasing numeric order of mask, then in increasing numeric order
1239 of opcode. This order is not the clearest for a human reader, but
1240 is guaranteed never to catch a special-case bit pattern with a more
1241 general mask, which is important, because this instruction encoding
1242 makes heavy use of special-case bit patterns. */
1243 static const struct opcode32 thumb32_opcodes[] =
1244 {
1245 /* V7 instructions. */
1246 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli%c\t%a"},
1247 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg%c\t#%0-3d"},
1248 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb%c\t%U"},
1249 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb%c\t%U"},
1250 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb%c\t%U"},
1251 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv%c\t%8-11r, %16-19r, %0-3r"},
1252 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv%c\t%8-11r, %16-19r, %0-3r"},
1253
1254 /* Instructions defined in the basic V6T2 set. */
1255 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop%c.w"},
1256 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield%c.w"},
1257 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe%c.w"},
1258 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi%c.w"},
1259 {ARM_EXT_V6T2, 0xf3af8004, 0xffffffff, "sev%c.w"},
1260 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop%c.w\t{%0-7d}"},
1261
1262 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex%c"},
1263 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f%X"},
1264 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f%X"},
1265 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj%c\t%16-19r%x"},
1266 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb%c\t%16-19r%21'!"},
1267 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia%c\t%16-19r%21'!"},
1268 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs%c\t%8-11r, %D"},
1269 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d%X"},
1270 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb%c\t[%16-19r, %0-3r]%x"},
1271 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh%c\t[%16-19r, %0-3r, lsl #1]%x"},
1272 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d%X"},
1273 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d%X"},
1274 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs%c\tpc, lr, #%0-7d"},
1275 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr%c\t%C, %16-19r"},
1276 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex%c\t%12-15r, [%16-19r]"},
1277 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb%c\t%12-15r, [%16-19r]"},
1278 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb%c\t%16-19r%21'!, #%0-4d"},
1279 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia%c\t%16-19r%21'!, #%0-4d"},
1280 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth%c.w\t%8-11r, %0-3r%R"},
1281 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth%c.w\t%8-11r, %0-3r%R"},
1282 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16%c\t%8-11r, %0-3r%R"},
1283 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16%c\t%8-11r, %0-3r%R"},
1284 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb%c.w\t%8-11r, %0-3r%R"},
1285 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb%c.w\t%8-11r, %0-3r%R"},
1286 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex%c\t%8-11r, %12-15r, [%16-19r]"},
1287 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd%c\t%12-15r, %8-11r, [%16-19r]"},
1288 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8%c\t%8-11r, %16-19r, %0-3r"},
1289 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8%c\t%8-11r, %16-19r, %0-3r"},
1290 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8%c\t%8-11r, %16-19r, %0-3r"},
1291 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8%c\t%8-11r, %16-19r, %0-3r"},
1292 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8%c\t%8-11r, %16-19r, %0-3r"},
1293 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8%c\t%8-11r, %16-19r, %0-3r"},
1294 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd%c\t%8-11r, %16-19r, %0-3r"},
1295 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd%c\t%8-11r, %16-19r, %0-3r"},
1296 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub%c\t%8-11r, %16-19r, %0-3r"},
1297 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub%c\t%8-11r, %16-19r, %0-3r"},
1298 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16%c\t%8-11r, %16-19r, %0-3r"},
1299 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16%c\t%8-11r, %16-19r, %0-3r"},
1300 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16%c\t%8-11r, %16-19r, %0-3r"},
1301 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16%c\t%8-11r, %16-19r, %0-3r"},
1302 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16%c\t%8-11r, %16-19r, %0-3r"},
1303 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16%c\t%8-11r, %16-19r, %0-3r"},
1304 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev%c.w\t%8-11r, %16-19r"},
1305 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16%c.w\t%8-11r, %16-19r"},
1306 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit%c\t%8-11r, %16-19r"},
1307 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh%c.w\t%8-11r, %16-19r"},
1308 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx%c\t%8-11r, %16-19r, %0-3r"},
1309 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1310 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1311 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1312 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1313 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx%c\t%8-11r, %16-19r, %0-3r"},
1314 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel%c\t%8-11r, %16-19r, %0-3r"},
1315 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz%c\t%8-11r, %16-19r"},
1316 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8%c\t%8-11r, %16-19r, %0-3r"},
1317 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8%c\t%8-11r, %16-19r, %0-3r"},
1318 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8%c\t%8-11r, %16-19r, %0-3r"},
1319 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8%c\t%8-11r, %16-19r, %0-3r"},
1320 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8%c\t%8-11r, %16-19r, %0-3r"},
1321 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8%c\t%8-11r, %16-19r, %0-3r"},
1322 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16%c\t%8-11r, %16-19r, %0-3r"},
1323 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16%c\t%8-11r, %16-19r, %0-3r"},
1324 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16%c\t%8-11r, %16-19r, %0-3r"},
1325 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16%c\t%8-11r, %16-19r, %0-3r"},
1326 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16%c\t%8-11r, %16-19r, %0-3r"},
1327 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16%c\t%8-11r, %16-19r, %0-3r"},
1328 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx%c\t%8-11r, %16-19r, %0-3r"},
1329 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1330 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1331 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx%c\t%8-11r, %16-19r, %0-3r"},
1332 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1333 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx%c\t%8-11r, %16-19r, %0-3r"},
1334 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul%c.w\t%8-11r, %16-19r, %0-3r"},
1335 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8%c\t%8-11r, %16-19r, %0-3r"},
1336 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1337 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1338 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1339 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's%c.w\t%8-11r, %16-19r, %0-3r"},
1340 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb%c\t%0-3r, %12-15r, [%16-19r]"},
1341 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16%c\t%8-11r, #%0-4d, %16-19r"},
1342 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16%c\t%8-11r, #%0-4d, %16-19r"},
1343 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x%c\t%8-11r, %16-19r, %0-3r"},
1344 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1345 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x%c\t%8-11r, %16-19r, %0-3r"},
1346 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r%c\t%8-11r, %16-19r, %0-3r"},
1347 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1348 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah%c\t%8-11r, %16-19r, %0-3r%R"},
1349 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1350 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16%c\t%8-11r, %16-19r, %0-3r%R"},
1351 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1352 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab%c\t%8-11r, %16-19r, %0-3r%R"},
1353 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r"},
1354 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc%c\t%8-11r, %E"},
1355 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst%c.w\t%16-19r, %S"},
1356 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq%c\t%16-19r, %S"},
1357 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn%c.w\t%16-19r, %S"},
1358 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp%c.w\t%16-19r, %S"},
1359 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst%c.w\t%16-19r, %M"},
1360 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq%c\t%16-19r, %M"},
1361 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn%c.w\t%16-19r, %M"},
1362 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp%c.w\t%16-19r, %M"},
1363 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's%c.w\t%8-11r, %S"},
1364 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's%c.w\t%8-11r, %S"},
1365 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd%c\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
1366 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1367 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1368 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1369 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1370 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1371 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1372 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1373 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1374 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex%c\t%12-15r, [%16-19r, #%0-7W]"},
1375 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc%c\t%K"},
1376 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's%c.w\t%8-11r, %M"},
1377 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's%c.w\t%8-11r, %M"},
1378 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld%c\t%a"},
1379 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1380 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1381 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1382 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1383 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1384 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1385 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1386 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt%c\t%8-11r, %16-19r, %S"},
1387 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb%c\t%8-11r, %16-19r, %S"},
1388 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx%c\t%8-11r, %16-19r, %F"},
1389 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx%c\t%8-11r, %16-19r, %F"},
1390 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt%c\t%12-15r, %a"},
1391 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb%c\t%8-11r, %16-19r, %0-3r, %12-15r"},
1392 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb%c\t%12-15r, %8-11r, %16-19r, %0-3r"},
1393 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi%c\t%8-11r, %16-19r, %E"},
1394 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt%c\t%12-15r, %a"},
1395 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat%c\t%8-11r, #%0-4d, %16-19r%s"},
1396 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat%c\t%8-11r, #%0-4d, %16-19r%s"},
1397 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw%c\t%8-11r, %16-19r, %I"},
1398 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw%c\t%8-11r, %J"},
1399 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw%c\t%8-11r, %16-19r, %I"},
1400 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt%c\t%8-11r, %J"},
1401 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's%c.w\t%8-11r, %16-19r, %S"},
1402 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's%c.w\t%8-11r, %16-19r, %S"},
1403 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's%c.w\t%8-11r, %16-19r, %S"},
1404 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's%c\t%8-11r, %16-19r, %S"},
1405 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's%c.w\t%8-11r, %16-19r, %S"},
1406 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's%c.w\t%8-11r, %16-19r, %S"},
1407 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's%c.w\t%8-11r, %16-19r, %S"},
1408 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %S"},
1409 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's%c.w\t%8-11r, %16-19r, %S"},
1410 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's%c\t%8-11r, %16-19r, %S"},
1411 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex%c\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1412 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's%c.w\t%8-11r, %16-19r, %M"},
1413 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's%c.w\t%8-11r, %16-19r, %M"},
1414 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's%c.w\t%8-11r, %16-19r, %M"},
1415 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's%c\t%8-11r, %16-19r, %M"},
1416 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's%c.w\t%8-11r, %16-19r, %M"},
1417 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's%c.w\t%8-11r, %16-19r, %M"},
1418 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's%c.w\t%8-11r, %16-19r, %M"},
1419 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's%c.w\t%8-11r, %16-19r, %M"},
1420 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's%c.w\t%8-11r, %16-19r, %M"},
1421 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's%c\t%8-11r, %16-19r, %M"},
1422 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia%c.w\t%16-19r%21'!, %m"},
1423 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia%c.w\t%16-19r%21'!, %m"},
1424 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb%c\t%16-19r%21'!, %m"},
1425 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb%c\t%16-19r%21'!, %m"},
1426 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd%c\t%12-15r, %8-11r, [%16-19r]"},
1427 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd%c\t%12-15r, %8-11r, [%16-19r]"},
1428 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1429 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd%c\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]%21'!"},
1430 {ARM_EXT_V6T2, 0xe8600000, 0xff700000, "strd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1431 {ARM_EXT_V6T2, 0xe8700000, 0xff700000, "ldrd%c\t%12-15r, %8-11r, [%16-19r], #%23`-%0-7W"},
1432 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w%c.w\t%12-15r, %a"},
1433 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w%c.w\t%12-15r, %a"},
1434
1435 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1436 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1437 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1438 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b%X"},
1439 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b%c.w\t%B%x"},
1440
1441 /* These have been 32-bit since the invention of Thumb. */
1442 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx%c\t%B%x"},
1443 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl%c\t%B%x"},
1444
1445 /* Fallback. */
1446 {ARM_EXT_V1, 0x00000000, 0x00000000, UNDEFINED_INSTRUCTION},
1447 {0, 0, 0, 0}
1448 };
1449
1450 static const char *const arm_conditional[] =
1451 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1452 "hi", "ls", "ge", "lt", "gt", "le", "al", "<und>", ""};
1453
1454 static const char *const arm_fp_const[] =
1455 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1456
1457 static const char *const arm_shift[] =
1458 {"lsl", "lsr", "asr", "ror"};
1459
1460 typedef struct
1461 {
1462 const char *name;
1463 const char *description;
1464 const char *reg_names[16];
1465 }
1466 arm_regname;
1467
1468 static const arm_regname regnames[] =
1469 {
1470 { "raw" , "Select raw register names",
1471 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1472 { "gcc", "Select register names used by GCC",
1473 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1474 { "std", "Select register names used in ARM's ISA documentation",
1475 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1476 { "apcs", "Select register names used in the APCS",
1477 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1478 { "atpcs", "Select register names used in the ATPCS",
1479 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1480 { "special-atpcs", "Select special register names used in the ATPCS",
1481 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1482 };
1483
1484 static const char *const iwmmxt_wwnames[] =
1485 {"b", "h", "w", "d"};
1486
1487 static const char *const iwmmxt_wwssnames[] =
1488 {"b", "bus", "bc", "bss",
1489 "h", "hus", "hc", "hss",
1490 "w", "wus", "wc", "wss",
1491 "d", "dus", "dc", "dss"
1492 };
1493
1494 static const char *const iwmmxt_regnames[] =
1495 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1496 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1497 };
1498
1499 static const char *const iwmmxt_cregnames[] =
1500 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1501 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1502 };
1503
1504 /* Default to GCC register name set. */
1505 static unsigned int regname_selected = 1;
1506
1507 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1508 #define arm_regnames regnames[regname_selected].reg_names
1509
1510 static bfd_boolean force_thumb = FALSE;
1511
1512 /* Current IT instruction state. This contains the same state as the IT
1513 bits in the CPSR. */
1514 static unsigned int ifthen_state;
1515 /* IT state for the next instruction. */
1516 static unsigned int ifthen_next_state;
1517 /* The address of the insn for which the IT state is valid. */
1518 static bfd_vma ifthen_address;
1519 #define IFTHEN_COND ((ifthen_state >> 4) & 0xf)
1520
1521 /* Cached mapping symbol state. */
1522 enum map_type
1523 {
1524 MAP_ARM,
1525 MAP_THUMB,
1526 MAP_DATA
1527 };
1528
1529 enum map_type last_type;
1530 int last_mapping_sym = -1;
1531 bfd_vma last_mapping_addr = 0;
1532
1533 \f
1534 /* Functions. */
1535 int
1536 get_arm_regname_num_options (void)
1537 {
1538 return NUM_ARM_REGNAMES;
1539 }
1540
1541 int
1542 set_arm_regname_option (int option)
1543 {
1544 int old = regname_selected;
1545 regname_selected = option;
1546 return old;
1547 }
1548
1549 int
1550 get_arm_regnames (int option,
1551 const char **setname,
1552 const char **setdescription,
1553 const char *const **register_names)
1554 {
1555 *setname = regnames[option].name;
1556 *setdescription = regnames[option].description;
1557 *register_names = regnames[option].reg_names;
1558 return 16;
1559 }
1560
1561 /* Decode a bitfield of the form matching regexp (N(-N)?,)*N(-N)?.
1562 Returns pointer to following character of the format string and
1563 fills in *VALUEP and *WIDTHP with the extracted value and number of
1564 bits extracted. WIDTHP can be NULL. */
1565
1566 static const char *
1567 arm_decode_bitfield (const char *ptr,
1568 unsigned long insn,
1569 unsigned long *valuep,
1570 int *widthp)
1571 {
1572 unsigned long value = 0;
1573 int width = 0;
1574
1575 do
1576 {
1577 int start, end;
1578 int bits;
1579
1580 for (start = 0; *ptr >= '0' && *ptr <= '9'; ptr++)
1581 start = start * 10 + *ptr - '0';
1582 if (*ptr == '-')
1583 for (end = 0, ptr++; *ptr >= '0' && *ptr <= '9'; ptr++)
1584 end = end * 10 + *ptr - '0';
1585 else
1586 end = start;
1587 bits = end - start;
1588 if (bits < 0)
1589 abort ();
1590 value |= ((insn >> start) & ((2ul << bits) - 1)) << width;
1591 width += bits + 1;
1592 }
1593 while (*ptr++ == ',');
1594 *valuep = value;
1595 if (widthp)
1596 *widthp = width;
1597 return ptr - 1;
1598 }
1599
1600 static void
1601 arm_decode_shift (long given, fprintf_ftype func, void *stream,
1602 int print_shift)
1603 {
1604 func (stream, "%s", arm_regnames[given & 0xf]);
1605
1606 if ((given & 0xff0) != 0)
1607 {
1608 if ((given & 0x10) == 0)
1609 {
1610 int amount = (given & 0xf80) >> 7;
1611 int shift = (given & 0x60) >> 5;
1612
1613 if (amount == 0)
1614 {
1615 if (shift == 3)
1616 {
1617 func (stream, ", rrx");
1618 return;
1619 }
1620
1621 amount = 32;
1622 }
1623
1624 if (print_shift)
1625 func (stream, ", %s #%d", arm_shift[shift], amount);
1626 else
1627 func (stream, ", #%d", amount);
1628 }
1629 else if (print_shift)
1630 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1631 arm_regnames[(given & 0xf00) >> 8]);
1632 else
1633 func (stream, ", %s", arm_regnames[(given & 0xf00) >> 8]);
1634 }
1635 }
1636
1637 /* Print one coprocessor instruction on INFO->STREAM.
1638 Return TRUE if the instuction matched, FALSE if this is not a
1639 recognised coprocessor instruction. */
1640
1641 static bfd_boolean
1642 print_insn_coprocessor (bfd_vma pc,
1643 struct disassemble_info *info,
1644 long given,
1645 bfd_boolean thumb)
1646 {
1647 const struct opcode32 *insn;
1648 void *stream = info->stream;
1649 fprintf_ftype func = info->fprintf_func;
1650 unsigned long mask;
1651 unsigned long value;
1652 unsigned long allowed_arches = ((arm_feature_set *) info->private_data)->coproc;
1653 int cond;
1654
1655 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1656 {
1657 signed long value_in_comment = 0;
1658 const char *c;
1659
1660 if (insn->arch == 0)
1661 switch (insn->value)
1662 {
1663 case SENTINEL_IWMMXT_START:
1664 if (info->mach != bfd_mach_arm_XScale
1665 && info->mach != bfd_mach_arm_iWMMXt
1666 && info->mach != bfd_mach_arm_iWMMXt2)
1667 do
1668 insn++;
1669 while (insn->arch != 0 && insn->value != SENTINEL_IWMMXT_END);
1670 continue;
1671
1672 case SENTINEL_IWMMXT_END:
1673 continue;
1674
1675 case SENTINEL_GENERIC_START:
1676 allowed_arches = ((arm_feature_set *) info->private_data)->core;
1677 continue;
1678
1679 default:
1680 abort ();
1681 }
1682
1683 mask = insn->mask;
1684 value = insn->value;
1685 if (thumb)
1686 {
1687 /* The high 4 bits are 0xe for Arm conditional instructions, and
1688 0xe for arm unconditional instructions. The rest of the
1689 encoding is the same. */
1690 mask |= 0xf0000000;
1691 value |= 0xe0000000;
1692 if (ifthen_state)
1693 cond = IFTHEN_COND;
1694 else
1695 cond = 16;
1696 }
1697 else
1698 {
1699 /* Only match unconditional instuctions against unconditional
1700 patterns. */
1701 if ((given & 0xf0000000) == 0xf0000000)
1702 {
1703 mask |= 0xf0000000;
1704 cond = 16;
1705 }
1706 else
1707 {
1708 cond = (given >> 28) & 0xf;
1709 if (cond == 0xe)
1710 cond = 16;
1711 }
1712 }
1713
1714 if ((given & mask) != value)
1715 continue;
1716
1717 if ((insn->arch & allowed_arches) == 0)
1718 continue;
1719
1720 for (c = insn->assembler; *c; c++)
1721 {
1722 if (*c == '%')
1723 {
1724 switch (*++c)
1725 {
1726 case '%':
1727 func (stream, "%%");
1728 break;
1729
1730 case 'A':
1731 {
1732 int offset = given & 0xff;
1733
1734 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1735
1736 value_in_comment = offset * 4;
1737 if ((given & 0x00800000) == 0)
1738 value_in_comment = - value_in_comment;
1739
1740 if ((given & (1 << 24)) != 0)
1741 {
1742 if (offset)
1743 func (stream, ", #%d]%s",
1744 value_in_comment,
1745 ((given & 0x00200000) != 0 ? "!" : ""));
1746 else
1747 func (stream, "]");
1748 }
1749 else
1750 {
1751 func (stream, "]");
1752
1753 if (given & (1 << 21))
1754 {
1755 if (offset)
1756 func (stream, ", #%d", value_in_comment);
1757 }
1758 else
1759 {
1760 func (stream, ", {%d}", offset);
1761 value_in_comment = offset;
1762 }
1763 }
1764 }
1765 break;
1766
1767 case 'B':
1768 {
1769 int regno = ((given >> 12) & 0xf) | ((given >> (22 - 4)) & 0x10);
1770 int offset = (given >> 1) & 0x3f;
1771
1772 if (offset == 1)
1773 func (stream, "{d%d}", regno);
1774 else if (regno + offset > 32)
1775 func (stream, "{d%d-<overflow reg d%d>}", regno, regno + offset - 1);
1776 else
1777 func (stream, "{d%d-d%d}", regno, regno + offset - 1);
1778 }
1779 break;
1780
1781 case 'C':
1782 {
1783 int rn = (given >> 16) & 0xf;
1784 int offset = (given & 0xff) * 4;
1785 int add = (given >> 23) & 1;
1786
1787 func (stream, "[%s", arm_regnames[rn]);
1788
1789 if (offset)
1790 {
1791 if (!add)
1792 offset = -offset;
1793 func (stream, ", #%d", offset);
1794 if (rn != 15)
1795 value_in_comment = offset;
1796 }
1797 func (stream, "]");
1798 if (rn == 15)
1799 {
1800 func (stream, "\t; ");
1801 /* FIXME: Unsure if info->bytes_per_chunk is the
1802 right thing to use here. */
1803 info->print_address_func (offset + pc
1804 + info->bytes_per_chunk * 2, info);
1805 }
1806 }
1807 break;
1808
1809 case 'c':
1810 func (stream, "%s", arm_conditional[cond]);
1811 break;
1812
1813 case 'I':
1814 /* Print a Cirrus/DSP shift immediate. */
1815 /* Immediates are 7bit signed ints with bits 0..3 in
1816 bits 0..3 of opcode and bits 4..6 in bits 5..7
1817 of opcode. */
1818 {
1819 int imm;
1820
1821 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1822
1823 /* Is ``imm'' a negative number? */
1824 if (imm & 0x40)
1825 imm |= (-1 << 7);
1826
1827 func (stream, "%d", imm);
1828 }
1829
1830 break;
1831
1832 case 'F':
1833 switch (given & 0x00408000)
1834 {
1835 case 0:
1836 func (stream, "4");
1837 break;
1838 case 0x8000:
1839 func (stream, "1");
1840 break;
1841 case 0x00400000:
1842 func (stream, "2");
1843 break;
1844 default:
1845 func (stream, "3");
1846 }
1847 break;
1848
1849 case 'P':
1850 switch (given & 0x00080080)
1851 {
1852 case 0:
1853 func (stream, "s");
1854 break;
1855 case 0x80:
1856 func (stream, "d");
1857 break;
1858 case 0x00080000:
1859 func (stream, "e");
1860 break;
1861 default:
1862 func (stream, _("<illegal precision>"));
1863 break;
1864 }
1865 break;
1866
1867 case 'Q':
1868 switch (given & 0x00408000)
1869 {
1870 case 0:
1871 func (stream, "s");
1872 break;
1873 case 0x8000:
1874 func (stream, "d");
1875 break;
1876 case 0x00400000:
1877 func (stream, "e");
1878 break;
1879 default:
1880 func (stream, "p");
1881 break;
1882 }
1883 break;
1884
1885 case 'R':
1886 switch (given & 0x60)
1887 {
1888 case 0:
1889 break;
1890 case 0x20:
1891 func (stream, "p");
1892 break;
1893 case 0x40:
1894 func (stream, "m");
1895 break;
1896 default:
1897 func (stream, "z");
1898 break;
1899 }
1900 break;
1901
1902 case '0': case '1': case '2': case '3': case '4':
1903 case '5': case '6': case '7': case '8': case '9':
1904 {
1905 int width;
1906 unsigned long value;
1907
1908 c = arm_decode_bitfield (c, given, &value, &width);
1909
1910 switch (*c)
1911 {
1912 case 'r':
1913 func (stream, "%s", arm_regnames[value]);
1914 break;
1915 case 'D':
1916 func (stream, "d%ld", value);
1917 break;
1918 case 'Q':
1919 if (value & 1)
1920 func (stream, "<illegal reg q%ld.5>", value >> 1);
1921 else
1922 func (stream, "q%ld", value >> 1);
1923 break;
1924 case 'd':
1925 func (stream, "%ld", value);
1926 value_in_comment = value;
1927 break;
1928 case 'k':
1929 {
1930 int from = (given & (1 << 7)) ? 32 : 16;
1931 func (stream, "%ld", from - value);
1932 }
1933 break;
1934
1935 case 'f':
1936 if (value > 7)
1937 func (stream, "#%s", arm_fp_const[value & 7]);
1938 else
1939 func (stream, "f%ld", value);
1940 break;
1941
1942 case 'w':
1943 if (width == 2)
1944 func (stream, "%s", iwmmxt_wwnames[value]);
1945 else
1946 func (stream, "%s", iwmmxt_wwssnames[value]);
1947 break;
1948
1949 case 'g':
1950 func (stream, "%s", iwmmxt_regnames[value]);
1951 break;
1952 case 'G':
1953 func (stream, "%s", iwmmxt_cregnames[value]);
1954 break;
1955
1956 case 'x':
1957 func (stream, "0x%lx", value);
1958 break;
1959
1960 case '`':
1961 c++;
1962 if (value == 0)
1963 func (stream, "%c", *c);
1964 break;
1965 case '\'':
1966 c++;
1967 if (value == ((1ul << width) - 1))
1968 func (stream, "%c", *c);
1969 break;
1970 case '?':
1971 func (stream, "%c", c[(1 << width) - (int) value]);
1972 c += 1 << width;
1973 break;
1974 default:
1975 abort ();
1976 }
1977 break;
1978
1979 case 'y':
1980 case 'z':
1981 {
1982 int single = *c++ == 'y';
1983 int regno;
1984
1985 switch (*c)
1986 {
1987 case '4': /* Sm pair */
1988 case '0': /* Sm, Dm */
1989 regno = given & 0x0000000f;
1990 if (single)
1991 {
1992 regno <<= 1;
1993 regno += (given >> 5) & 1;
1994 }
1995 else
1996 regno += ((given >> 5) & 1) << 4;
1997 break;
1998
1999 case '1': /* Sd, Dd */
2000 regno = (given >> 12) & 0x0000000f;
2001 if (single)
2002 {
2003 regno <<= 1;
2004 regno += (given >> 22) & 1;
2005 }
2006 else
2007 regno += ((given >> 22) & 1) << 4;
2008 break;
2009
2010 case '2': /* Sn, Dn */
2011 regno = (given >> 16) & 0x0000000f;
2012 if (single)
2013 {
2014 regno <<= 1;
2015 regno += (given >> 7) & 1;
2016 }
2017 else
2018 regno += ((given >> 7) & 1) << 4;
2019 break;
2020
2021 case '3': /* List */
2022 func (stream, "{");
2023 regno = (given >> 12) & 0x0000000f;
2024 if (single)
2025 {
2026 regno <<= 1;
2027 regno += (given >> 22) & 1;
2028 }
2029 else
2030 regno += ((given >> 22) & 1) << 4;
2031 break;
2032
2033 default:
2034 abort ();
2035 }
2036
2037 func (stream, "%c%d", single ? 's' : 'd', regno);
2038
2039 if (*c == '3')
2040 {
2041 int count = given & 0xff;
2042
2043 if (single == 0)
2044 count >>= 1;
2045
2046 if (--count)
2047 {
2048 func (stream, "-%c%d",
2049 single ? 's' : 'd',
2050 regno + count);
2051 }
2052
2053 func (stream, "}");
2054 }
2055 else if (*c == '4')
2056 func (stream, ", %c%d", single ? 's' : 'd',
2057 regno + 1);
2058 }
2059 break;
2060
2061 case 'L':
2062 switch (given & 0x00400100)
2063 {
2064 case 0x00000000: func (stream, "b"); break;
2065 case 0x00400000: func (stream, "h"); break;
2066 case 0x00000100: func (stream, "w"); break;
2067 case 0x00400100: func (stream, "d"); break;
2068 default:
2069 break;
2070 }
2071 break;
2072
2073 case 'Z':
2074 {
2075 int value;
2076 /* given (20, 23) | given (0, 3) */
2077 value = ((given >> 16) & 0xf0) | (given & 0xf);
2078 func (stream, "%d", value);
2079 }
2080 break;
2081
2082 case 'l':
2083 /* This is like the 'A' operator, except that if
2084 the width field "M" is zero, then the offset is
2085 *not* multiplied by four. */
2086 {
2087 int offset = given & 0xff;
2088 int multiplier = (given & 0x00000100) ? 4 : 1;
2089
2090 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2091
2092 if (multiplier > 1)
2093 {
2094 value_in_comment = offset * multiplier;
2095 if ((given & 0x00800000) == 0)
2096 value_in_comment = - value_in_comment;
2097 }
2098
2099 if (offset)
2100 {
2101 if ((given & 0x01000000) != 0)
2102 func (stream, ", #%s%d]%s",
2103 ((given & 0x00800000) == 0 ? "-" : ""),
2104 offset * multiplier,
2105 ((given & 0x00200000) != 0 ? "!" : ""));
2106 else
2107 func (stream, "], #%s%d",
2108 ((given & 0x00800000) == 0 ? "-" : ""),
2109 offset * multiplier);
2110 }
2111 else
2112 func (stream, "]");
2113 }
2114 break;
2115
2116 case 'r':
2117 {
2118 int imm4 = (given >> 4) & 0xf;
2119 int puw_bits = ((given >> 22) & 6) | ((given >> 21) & 1);
2120 int ubit = (given >> 23) & 1;
2121 const char *rm = arm_regnames [given & 0xf];
2122 const char *rn = arm_regnames [(given >> 16) & 0xf];
2123
2124 switch (puw_bits)
2125 {
2126 case 1:
2127 case 3:
2128 func (stream, "[%s], %c%s", rn, ubit ? '+' : '-', rm);
2129 if (imm4)
2130 func (stream, ", lsl #%d", imm4);
2131 break;
2132
2133 case 4:
2134 case 5:
2135 case 6:
2136 case 7:
2137 func (stream, "[%s, %c%s", rn, ubit ? '+' : '-', rm);
2138 if (imm4 > 0)
2139 func (stream, ", lsl #%d", imm4);
2140 func (stream, "]");
2141 if (puw_bits == 5 || puw_bits == 7)
2142 func (stream, "!");
2143 break;
2144
2145 default:
2146 func (stream, "INVALID");
2147 }
2148 }
2149 break;
2150
2151 case 'i':
2152 {
2153 long imm5;
2154 imm5 = ((given & 0x100) >> 4) | (given & 0xf);
2155 func (stream, "%ld", (imm5 == 0) ? 32 : imm5);
2156 }
2157 break;
2158
2159 default:
2160 abort ();
2161 }
2162 }
2163 }
2164 else
2165 func (stream, "%c", *c);
2166 }
2167
2168 if (value_in_comment > 32 || value_in_comment < -16)
2169 func (stream, "\t; 0x%lx", value_in_comment);
2170
2171 return TRUE;
2172 }
2173 return FALSE;
2174 }
2175
2176 /* Decodes and prints ARM addressing modes. Returns the offset
2177 used in the address, if any, if it is worthwhile printing the
2178 offset as a hexadecimal value in a comment at the end of the
2179 line of disassembly. */
2180
2181 static signed long
2182 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
2183 {
2184 void *stream = info->stream;
2185 fprintf_ftype func = info->fprintf_func;
2186 int offset = 0;
2187
2188 if (((given & 0x000f0000) == 0x000f0000)
2189 && ((given & 0x02000000) == 0))
2190 {
2191 offset = given & 0xfff;
2192
2193 func (stream, "[pc");
2194
2195 if (given & 0x01000000)
2196 {
2197 if ((given & 0x00800000) == 0)
2198 offset = - offset;
2199
2200 /* Pre-indexed. */
2201 func (stream, ", #%d]", offset);
2202
2203 offset += pc + 8;
2204
2205 /* Cope with the possibility of write-back
2206 being used. Probably a very dangerous thing
2207 for the programmer to do, but who are we to
2208 argue ? */
2209 if (given & 0x00200000)
2210 func (stream, "!");
2211 }
2212 else
2213 {
2214 /* Post indexed. */
2215 func (stream, "], #%d", offset);
2216
2217 /* ie ignore the offset. */
2218 offset = pc + 8;
2219 }
2220
2221 func (stream, "\t; ");
2222 info->print_address_func (offset, info);
2223 offset = 0;
2224 }
2225 else
2226 {
2227 func (stream, "[%s",
2228 arm_regnames[(given >> 16) & 0xf]);
2229 if ((given & 0x01000000) != 0)
2230 {
2231 if ((given & 0x02000000) == 0)
2232 {
2233 offset = given & 0xfff;
2234 if (offset)
2235 func (stream, ", #%s%d",
2236 (((given & 0x00800000) == 0)
2237 ? "-" : ""), offset);
2238 }
2239 else
2240 {
2241 func (stream, ", %s",
2242 (((given & 0x00800000) == 0)
2243 ? "-" : ""));
2244 arm_decode_shift (given, func, stream, 1);
2245 }
2246
2247 func (stream, "]%s",
2248 ((given & 0x00200000) != 0) ? "!" : "");
2249 }
2250 else
2251 {
2252 if ((given & 0x02000000) == 0)
2253 {
2254 offset = given & 0xfff;
2255 if (offset)
2256 func (stream, "], #%s%d",
2257 (((given & 0x00800000) == 0)
2258 ? "-" : ""), offset);
2259 else
2260 func (stream, "]");
2261 }
2262 else
2263 {
2264 func (stream, "], %s",
2265 (((given & 0x00800000) == 0)
2266 ? "-" : ""));
2267 arm_decode_shift (given, func, stream, 1);
2268 }
2269 }
2270 }
2271
2272 return (signed long) offset;
2273 }
2274
2275 /* Print one neon instruction on INFO->STREAM.
2276 Return TRUE if the instuction matched, FALSE if this is not a
2277 recognised neon instruction. */
2278
2279 static bfd_boolean
2280 print_insn_neon (struct disassemble_info *info, long given, bfd_boolean thumb)
2281 {
2282 const struct opcode32 *insn;
2283 void *stream = info->stream;
2284 fprintf_ftype func = info->fprintf_func;
2285
2286 if (thumb)
2287 {
2288 if ((given & 0xef000000) == 0xef000000)
2289 {
2290 /* Move bit 28 to bit 24 to translate Thumb2 to ARM encoding. */
2291 unsigned long bit28 = given & (1 << 28);
2292
2293 given &= 0x00ffffff;
2294 if (bit28)
2295 given |= 0xf3000000;
2296 else
2297 given |= 0xf2000000;
2298 }
2299 else if ((given & 0xff000000) == 0xf9000000)
2300 given ^= 0xf9000000 ^ 0xf4000000;
2301 else
2302 return FALSE;
2303 }
2304
2305 for (insn = neon_opcodes; insn->assembler; insn++)
2306 {
2307 if ((given & insn->mask) == insn->value)
2308 {
2309 signed long value_in_comment = 0;
2310 const char *c;
2311
2312 for (c = insn->assembler; *c; c++)
2313 {
2314 if (*c == '%')
2315 {
2316 switch (*++c)
2317 {
2318 case '%':
2319 func (stream, "%%");
2320 break;
2321
2322 case 'c':
2323 if (thumb && ifthen_state)
2324 func (stream, "%s", arm_conditional[IFTHEN_COND]);
2325 break;
2326
2327 case 'A':
2328 {
2329 static const unsigned char enc[16] =
2330 {
2331 0x4, 0x14, /* st4 0,1 */
2332 0x4, /* st1 2 */
2333 0x4, /* st2 3 */
2334 0x3, /* st3 4 */
2335 0x13, /* st3 5 */
2336 0x3, /* st1 6 */
2337 0x1, /* st1 7 */
2338 0x2, /* st2 8 */
2339 0x12, /* st2 9 */
2340 0x2, /* st1 10 */
2341 0, 0, 0, 0, 0
2342 };
2343 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2344 int rn = ((given >> 16) & 0xf);
2345 int rm = ((given >> 0) & 0xf);
2346 int align = ((given >> 4) & 0x3);
2347 int type = ((given >> 8) & 0xf);
2348 int n = enc[type] & 0xf;
2349 int stride = (enc[type] >> 4) + 1;
2350 int ix;
2351
2352 func (stream, "{");
2353 if (stride > 1)
2354 for (ix = 0; ix != n; ix++)
2355 func (stream, "%sd%d", ix ? "," : "", rd + ix * stride);
2356 else if (n == 1)
2357 func (stream, "d%d", rd);
2358 else
2359 func (stream, "d%d-d%d", rd, rd + n - 1);
2360 func (stream, "}, [%s", arm_regnames[rn]);
2361 if (align)
2362 func (stream, ", :%d", 32 << align);
2363 func (stream, "]");
2364 if (rm == 0xd)
2365 func (stream, "!");
2366 else if (rm != 0xf)
2367 func (stream, ", %s", arm_regnames[rm]);
2368 }
2369 break;
2370
2371 case 'B':
2372 {
2373 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2374 int rn = ((given >> 16) & 0xf);
2375 int rm = ((given >> 0) & 0xf);
2376 int idx_align = ((given >> 4) & 0xf);
2377 int align = 0;
2378 int size = ((given >> 10) & 0x3);
2379 int idx = idx_align >> (size + 1);
2380 int length = ((given >> 8) & 3) + 1;
2381 int stride = 1;
2382 int i;
2383
2384 if (length > 1 && size > 0)
2385 stride = (idx_align & (1 << size)) ? 2 : 1;
2386
2387 switch (length)
2388 {
2389 case 1:
2390 {
2391 int amask = (1 << size) - 1;
2392 if ((idx_align & (1 << size)) != 0)
2393 return FALSE;
2394 if (size > 0)
2395 {
2396 if ((idx_align & amask) == amask)
2397 align = 8 << size;
2398 else if ((idx_align & amask) != 0)
2399 return FALSE;
2400 }
2401 }
2402 break;
2403
2404 case 2:
2405 if (size == 2 && (idx_align & 2) != 0)
2406 return FALSE;
2407 align = (idx_align & 1) ? 16 << size : 0;
2408 break;
2409
2410 case 3:
2411 if ((size == 2 && (idx_align & 3) != 0)
2412 || (idx_align & 1) != 0)
2413 return FALSE;
2414 break;
2415
2416 case 4:
2417 if (size == 2)
2418 {
2419 if ((idx_align & 3) == 3)
2420 return FALSE;
2421 align = (idx_align & 3) * 64;
2422 }
2423 else
2424 align = (idx_align & 1) ? 32 << size : 0;
2425 break;
2426
2427 default:
2428 abort ();
2429 }
2430
2431 func (stream, "{");
2432 for (i = 0; i < length; i++)
2433 func (stream, "%sd%d[%d]", (i == 0) ? "" : ",",
2434 rd + i * stride, idx);
2435 func (stream, "}, [%s", arm_regnames[rn]);
2436 if (align)
2437 func (stream, ", :%d", align);
2438 func (stream, "]");
2439 if (rm == 0xd)
2440 func (stream, "!");
2441 else if (rm != 0xf)
2442 func (stream, ", %s", arm_regnames[rm]);
2443 }
2444 break;
2445
2446 case 'C':
2447 {
2448 int rd = ((given >> 12) & 0xf) | (((given >> 22) & 1) << 4);
2449 int rn = ((given >> 16) & 0xf);
2450 int rm = ((given >> 0) & 0xf);
2451 int align = ((given >> 4) & 0x1);
2452 int size = ((given >> 6) & 0x3);
2453 int type = ((given >> 8) & 0x3);
2454 int n = type + 1;
2455 int stride = ((given >> 5) & 0x1);
2456 int ix;
2457
2458 if (stride && (n == 1))
2459 n++;
2460 else
2461 stride++;
2462
2463 func (stream, "{");
2464 if (stride > 1)
2465 for (ix = 0; ix != n; ix++)
2466 func (stream, "%sd%d[]", ix ? "," : "", rd + ix * stride);
2467 else if (n == 1)
2468 func (stream, "d%d[]", rd);
2469 else
2470 func (stream, "d%d[]-d%d[]", rd, rd + n - 1);
2471 func (stream, "}, [%s", arm_regnames[rn]);
2472 if (align)
2473 {
2474 int align = (8 * (type + 1)) << size;
2475 if (type == 3)
2476 align = (size > 1) ? align >> 1 : align;
2477 if (type == 2 || (type == 0 && !size))
2478 func (stream, ", :<bad align %d>", align);
2479 else
2480 func (stream, ", :%d", align);
2481 }
2482 func (stream, "]");
2483 if (rm == 0xd)
2484 func (stream, "!");
2485 else if (rm != 0xf)
2486 func (stream, ", %s", arm_regnames[rm]);
2487 }
2488 break;
2489
2490 case 'D':
2491 {
2492 int raw_reg = (given & 0xf) | ((given >> 1) & 0x10);
2493 int size = (given >> 20) & 3;
2494 int reg = raw_reg & ((4 << size) - 1);
2495 int ix = raw_reg >> size >> 2;
2496
2497 func (stream, "d%d[%d]", reg, ix);
2498 }
2499 break;
2500
2501 case 'E':
2502 /* Neon encoded constant for mov, mvn, vorr, vbic. */
2503 {
2504 int bits = 0;
2505 int cmode = (given >> 8) & 0xf;
2506 int op = (given >> 5) & 0x1;
2507 unsigned long value = 0, hival = 0;
2508 unsigned shift;
2509 int size = 0;
2510 int isfloat = 0;
2511
2512 bits |= ((given >> 24) & 1) << 7;
2513 bits |= ((given >> 16) & 7) << 4;
2514 bits |= ((given >> 0) & 15) << 0;
2515
2516 if (cmode < 8)
2517 {
2518 shift = (cmode >> 1) & 3;
2519 value = (unsigned long) bits << (8 * shift);
2520 size = 32;
2521 }
2522 else if (cmode < 12)
2523 {
2524 shift = (cmode >> 1) & 1;
2525 value = (unsigned long) bits << (8 * shift);
2526 size = 16;
2527 }
2528 else if (cmode < 14)
2529 {
2530 shift = (cmode & 1) + 1;
2531 value = (unsigned long) bits << (8 * shift);
2532 value |= (1ul << (8 * shift)) - 1;
2533 size = 32;
2534 }
2535 else if (cmode == 14)
2536 {
2537 if (op)
2538 {
2539 /* Bit replication into bytes. */
2540 int ix;
2541 unsigned long mask;
2542
2543 value = 0;
2544 hival = 0;
2545 for (ix = 7; ix >= 0; ix--)
2546 {
2547 mask = ((bits >> ix) & 1) ? 0xff : 0;
2548 if (ix <= 3)
2549 value = (value << 8) | mask;
2550 else
2551 hival = (hival << 8) | mask;
2552 }
2553 size = 64;
2554 }
2555 else
2556 {
2557 /* Byte replication. */
2558 value = (unsigned long) bits;
2559 size = 8;
2560 }
2561 }
2562 else if (!op)
2563 {
2564 /* Floating point encoding. */
2565 int tmp;
2566
2567 value = (unsigned long) (bits & 0x7f) << 19;
2568 value |= (unsigned long) (bits & 0x80) << 24;
2569 tmp = bits & 0x40 ? 0x3c : 0x40;
2570 value |= (unsigned long) tmp << 24;
2571 size = 32;
2572 isfloat = 1;
2573 }
2574 else
2575 {
2576 func (stream, "<illegal constant %.8x:%x:%x>",
2577 bits, cmode, op);
2578 size = 32;
2579 break;
2580 }
2581 switch (size)
2582 {
2583 case 8:
2584 func (stream, "#%ld\t; 0x%.2lx", value, value);
2585 break;
2586
2587 case 16:
2588 func (stream, "#%ld\t; 0x%.4lx", value, value);
2589 break;
2590
2591 case 32:
2592 if (isfloat)
2593 {
2594 unsigned char valbytes[4];
2595 double fvalue;
2596
2597 /* Do this a byte at a time so we don't have to
2598 worry about the host's endianness. */
2599 valbytes[0] = value & 0xff;
2600 valbytes[1] = (value >> 8) & 0xff;
2601 valbytes[2] = (value >> 16) & 0xff;
2602 valbytes[3] = (value >> 24) & 0xff;
2603
2604 floatformat_to_double
2605 (&floatformat_ieee_single_little, valbytes,
2606 &fvalue);
2607
2608 func (stream, "#%.7g\t; 0x%.8lx", fvalue,
2609 value);
2610 }
2611 else
2612 func (stream, "#%ld\t; 0x%.8lx",
2613 (long) ((value & 0x80000000)
2614 ? value | ~0xffffffffl : value), value);
2615 break;
2616
2617 case 64:
2618 func (stream, "#0x%.8lx%.8lx", hival, value);
2619 break;
2620
2621 default:
2622 abort ();
2623 }
2624 }
2625 break;
2626
2627 case 'F':
2628 {
2629 int regno = ((given >> 16) & 0xf) | ((given >> (7 - 4)) & 0x10);
2630 int num = (given >> 8) & 0x3;
2631
2632 if (!num)
2633 func (stream, "{d%d}", regno);
2634 else if (num + regno >= 32)
2635 func (stream, "{d%d-<overflow reg d%d}", regno, regno + num);
2636 else
2637 func (stream, "{d%d-d%d}", regno, regno + num);
2638 }
2639 break;
2640
2641
2642 case '0': case '1': case '2': case '3': case '4':
2643 case '5': case '6': case '7': case '8': case '9':
2644 {
2645 int width;
2646 unsigned long value;
2647
2648 c = arm_decode_bitfield (c, given, &value, &width);
2649
2650 switch (*c)
2651 {
2652 case 'r':
2653 func (stream, "%s", arm_regnames[value]);
2654 break;
2655 case 'd':
2656 func (stream, "%ld", value);
2657 value_in_comment = value;
2658 break;
2659 case 'e':
2660 func (stream, "%ld", (1ul << width) - value);
2661 break;
2662
2663 case 'S':
2664 case 'T':
2665 case 'U':
2666 /* Various width encodings. */
2667 {
2668 int base = 8 << (*c - 'S'); /* 8,16 or 32 */
2669 int limit;
2670 unsigned low, high;
2671
2672 c++;
2673 if (*c >= '0' && *c <= '9')
2674 limit = *c - '0';
2675 else if (*c >= 'a' && *c <= 'f')
2676 limit = *c - 'a' + 10;
2677 else
2678 abort ();
2679 low = limit >> 2;
2680 high = limit & 3;
2681
2682 if (value < low || value > high)
2683 func (stream, "<illegal width %d>", base << value);
2684 else
2685 func (stream, "%d", base << value);
2686 }
2687 break;
2688 case 'R':
2689 if (given & (1 << 6))
2690 goto Q;
2691 /* FALLTHROUGH */
2692 case 'D':
2693 func (stream, "d%ld", value);
2694 break;
2695 case 'Q':
2696 Q:
2697 if (value & 1)
2698 func (stream, "<illegal reg q%ld.5>", value >> 1);
2699 else
2700 func (stream, "q%ld", value >> 1);
2701 break;
2702
2703 case '`':
2704 c++;
2705 if (value == 0)
2706 func (stream, "%c", *c);
2707 break;
2708 case '\'':
2709 c++;
2710 if (value == ((1ul << width) - 1))
2711 func (stream, "%c", *c);
2712 break;
2713 case '?':
2714 func (stream, "%c", c[(1 << width) - (int) value]);
2715 c += 1 << width;
2716 break;
2717 default:
2718 abort ();
2719 }
2720 break;
2721
2722 default:
2723 abort ();
2724 }
2725 }
2726 }
2727 else
2728 func (stream, "%c", *c);
2729 }
2730
2731 if (value_in_comment > 32 || value_in_comment < -16)
2732 func (stream, "\t; 0x%lx", value_in_comment);
2733
2734 return TRUE;
2735 }
2736 }
2737 return FALSE;
2738 }
2739
2740 /* Print one ARM instruction from PC on INFO->STREAM. */
2741
2742 static void
2743 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
2744 {
2745 const struct opcode32 *insn;
2746 void *stream = info->stream;
2747 fprintf_ftype func = info->fprintf_func;
2748
2749 if (print_insn_coprocessor (pc, info, given, FALSE))
2750 return;
2751
2752 if (print_insn_neon (info, given, FALSE))
2753 return;
2754
2755 for (insn = arm_opcodes; insn->assembler; insn++)
2756 {
2757 if ((given & insn->mask) != insn->value)
2758 continue;
2759
2760 if ((insn->arch & ((arm_feature_set *) info->private_data)->core) == 0)
2761 continue;
2762
2763 /* Special case: an instruction with all bits set in the condition field
2764 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
2765 or by the catchall at the end of the table. */
2766 if ((given & 0xF0000000) != 0xF0000000
2767 || (insn->mask & 0xF0000000) == 0xF0000000
2768 || (insn->mask == 0 && insn->value == 0))
2769 {
2770 signed long value_in_comment = 0;
2771 const char *c;
2772
2773 for (c = insn->assembler; *c; c++)
2774 {
2775 if (*c == '%')
2776 {
2777 switch (*++c)
2778 {
2779 case '%':
2780 func (stream, "%%");
2781 break;
2782
2783 case 'a':
2784 value_in_comment = print_arm_address (pc, info, given);
2785 break;
2786
2787 case 'P':
2788 /* Set P address bit and use normal address
2789 printing routine. */
2790 value_in_comment = print_arm_address (pc, info, given | (1 << 24));
2791 break;
2792
2793 case 's':
2794 if ((given & 0x004f0000) == 0x004f0000)
2795 {
2796 /* PC relative with immediate offset. */
2797 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2798
2799 if ((given & 0x00800000) == 0)
2800 offset = -offset;
2801
2802 func (stream, "[pc, #%d]\t; ", offset);
2803 info->print_address_func (offset + pc + 8, info);
2804 }
2805 else
2806 {
2807 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
2808
2809 if ((given & 0x00800000) == 0)
2810 offset = -offset;
2811
2812 func (stream, "[%s",
2813 arm_regnames[(given >> 16) & 0xf]);
2814
2815 if ((given & 0x01000000) != 0)
2816 {
2817 /* Pre-indexed. */
2818 if ((given & 0x00400000) == 0x00400000)
2819 {
2820 /* Immediate. */
2821 if (offset)
2822 func (stream, ", #%d", offset);
2823 value_in_comment = offset;
2824 }
2825 else
2826 {
2827 /* Register. */
2828 func (stream, ", %s%s", offset < 0 ? "-" : "",
2829 arm_regnames[given & 0xf]);
2830 }
2831
2832 func (stream, "]%s",
2833 ((given & 0x00200000) != 0) ? "!" : "");
2834 }
2835 else
2836 {
2837 /* Post-indexed. */
2838 if ((given & 0x00400000) == 0x00400000)
2839 {
2840 /* Immediate. */
2841 if (offset)
2842 func (stream, "], #%d", offset);
2843 else
2844 func (stream, "]");
2845
2846 value_in_comment = offset;
2847 }
2848 else
2849 {
2850 /* Register. */
2851 func (stream, "], %s%s", offset < 0 ? "-" : "",
2852 arm_regnames[given & 0xf]);
2853 }
2854 }
2855 }
2856 break;
2857
2858 case 'b':
2859 {
2860 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
2861 info->print_address_func (disp * 4 + pc + 8, info);
2862 }
2863 break;
2864
2865 case 'c':
2866 if (((given >> 28) & 0xf) != 0xe)
2867 func (stream, "%s",
2868 arm_conditional [(given >> 28) & 0xf]);
2869 break;
2870
2871 case 'm':
2872 {
2873 int started = 0;
2874 int reg;
2875
2876 func (stream, "{");
2877 for (reg = 0; reg < 16; reg++)
2878 if ((given & (1 << reg)) != 0)
2879 {
2880 if (started)
2881 func (stream, ", ");
2882 started = 1;
2883 func (stream, "%s", arm_regnames[reg]);
2884 }
2885 func (stream, "}");
2886 }
2887 break;
2888
2889 case 'q':
2890 arm_decode_shift (given, func, stream, 0);
2891 break;
2892
2893 case 'o':
2894 if ((given & 0x02000000) != 0)
2895 {
2896 int rotate = (given & 0xf00) >> 7;
2897 int immed = (given & 0xff);
2898
2899 immed = (((immed << (32 - rotate))
2900 | (immed >> rotate)) & 0xffffffff);
2901 func (stream, "#%d", immed);
2902 value_in_comment = immed;
2903 }
2904 else
2905 arm_decode_shift (given, func, stream, 1);
2906 break;
2907
2908 case 'p':
2909 if ((given & 0x0000f000) == 0x0000f000)
2910 func (stream, "p");
2911 break;
2912
2913 case 't':
2914 if ((given & 0x01200000) == 0x00200000)
2915 func (stream, "t");
2916 break;
2917
2918 case 'A':
2919 {
2920 int offset = given & 0xff;
2921
2922 value_in_comment = offset * 4;
2923 if ((given & 0x00800000) == 0)
2924 value_in_comment = - value_in_comment;
2925
2926 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
2927
2928 if ((given & (1 << 24)) != 0)
2929 {
2930 if (offset)
2931 func (stream, ", #%d]%s",
2932 value_in_comment,
2933 ((given & 0x00200000) != 0 ? "!" : ""));
2934 else
2935 func (stream, "]");
2936 }
2937 else
2938 {
2939 func (stream, "]");
2940
2941 if (given & (1 << 21))
2942 {
2943 if (offset)
2944 func (stream, ", #%d", value_in_comment);
2945 }
2946 else
2947 {
2948 func (stream, ", {%d}", offset);
2949 value_in_comment = offset;
2950 }
2951 }
2952 }
2953 break;
2954
2955 case 'B':
2956 /* Print ARM V5 BLX(1) address: pc+25 bits. */
2957 {
2958 bfd_vma address;
2959 bfd_vma offset = 0;
2960
2961 if (given & 0x00800000)
2962 /* Is signed, hi bits should be ones. */
2963 offset = (-1) ^ 0x00ffffff;
2964
2965 /* Offset is (SignExtend(offset field)<<2). */
2966 offset += given & 0x00ffffff;
2967 offset <<= 2;
2968 address = offset + pc + 8;
2969
2970 if (given & 0x01000000)
2971 /* H bit allows addressing to 2-byte boundaries. */
2972 address += 2;
2973
2974 info->print_address_func (address, info);
2975 }
2976 break;
2977
2978 case 'C':
2979 func (stream, "_");
2980 if (given & 0x80000)
2981 func (stream, "f");
2982 if (given & 0x40000)
2983 func (stream, "s");
2984 if (given & 0x20000)
2985 func (stream, "x");
2986 if (given & 0x10000)
2987 func (stream, "c");
2988 break;
2989
2990 case 'U':
2991 switch (given & 0xf)
2992 {
2993 case 0xf: func (stream, "sy"); break;
2994 case 0x7: func (stream, "un"); break;
2995 case 0xe: func (stream, "st"); break;
2996 case 0x6: func (stream, "unst"); break;
2997 default:
2998 func (stream, "#%d", (int) given & 0xf);
2999 break;
3000 }
3001 break;
3002
3003 case '0': case '1': case '2': case '3': case '4':
3004 case '5': case '6': case '7': case '8': case '9':
3005 {
3006 int width;
3007 unsigned long value;
3008
3009 c = arm_decode_bitfield (c, given, &value, &width);
3010
3011 switch (*c)
3012 {
3013 case 'r':
3014 func (stream, "%s", arm_regnames[value]);
3015 break;
3016 case 'd':
3017 func (stream, "%ld", value);
3018 value_in_comment = value;
3019 break;
3020 case 'b':
3021 func (stream, "%ld", value * 8);
3022 value_in_comment = value * 8;
3023 break;
3024 case 'W':
3025 func (stream, "%ld", value + 1);
3026 value_in_comment = value + 1;
3027 break;
3028 case 'x':
3029 func (stream, "0x%08lx", value);
3030
3031 /* Some SWI instructions have special
3032 meanings. */
3033 if ((given & 0x0fffffff) == 0x0FF00000)
3034 func (stream, "\t; IMB");
3035 else if ((given & 0x0fffffff) == 0x0FF00001)
3036 func (stream, "\t; IMBRange");
3037 break;
3038 case 'X':
3039 func (stream, "%01lx", value & 0xf);
3040 value_in_comment = value;
3041 break;
3042 case '`':
3043 c++;
3044 if (value == 0)
3045 func (stream, "%c", *c);
3046 break;
3047 case '\'':
3048 c++;
3049 if (value == ((1ul << width) - 1))
3050 func (stream, "%c", *c);
3051 break;
3052 case '?':
3053 func (stream, "%c", c[(1 << width) - (int) value]);
3054 c += 1 << width;
3055 break;
3056 default:
3057 abort ();
3058 }
3059 break;
3060
3061 case 'e':
3062 {
3063 int imm;
3064
3065 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
3066 func (stream, "%d", imm);
3067 value_in_comment = imm;
3068 }
3069 break;
3070
3071 case 'E':
3072 /* LSB and WIDTH fields of BFI or BFC. The machine-
3073 language instruction encodes LSB and MSB. */
3074 {
3075 long msb = (given & 0x001f0000) >> 16;
3076 long lsb = (given & 0x00000f80) >> 7;
3077 long width = msb - lsb + 1;
3078
3079 if (width > 0)
3080 func (stream, "#%lu, #%lu", lsb, width);
3081 else
3082 func (stream, "(invalid: %lu:%lu)", lsb, msb);
3083 }
3084 break;
3085
3086 case 'V':
3087 /* 16-bit unsigned immediate from a MOVT or MOVW
3088 instruction, encoded in bits 0:11 and 15:19. */
3089 {
3090 long hi = (given & 0x000f0000) >> 4;
3091 long lo = (given & 0x00000fff);
3092 long imm16 = hi | lo;
3093
3094 func (stream, "#%lu", imm16);
3095 value_in_comment = imm16;
3096 }
3097 break;
3098
3099 default:
3100 abort ();
3101 }
3102 }
3103 }
3104 else
3105 func (stream, "%c", *c);
3106 }
3107
3108 if (value_in_comment > 32 || value_in_comment < -16)
3109 func (stream, "\t; 0x%lx", value_in_comment);
3110 return;
3111 }
3112 }
3113 abort ();
3114 }
3115
3116 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
3117
3118 static void
3119 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
3120 {
3121 const struct opcode16 *insn;
3122 void *stream = info->stream;
3123 fprintf_ftype func = info->fprintf_func;
3124
3125 for (insn = thumb_opcodes; insn->assembler; insn++)
3126 if ((given & insn->mask) == insn->value)
3127 {
3128 signed long value_in_comment = 0;
3129 const char *c = insn->assembler;
3130
3131 for (; *c; c++)
3132 {
3133 int domaskpc = 0;
3134 int domasklr = 0;
3135
3136 if (*c != '%')
3137 {
3138 func (stream, "%c", *c);
3139 continue;
3140 }
3141
3142 switch (*++c)
3143 {
3144 case '%':
3145 func (stream, "%%");
3146 break;
3147
3148 case 'c':
3149 if (ifthen_state)
3150 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3151 break;
3152
3153 case 'C':
3154 if (ifthen_state)
3155 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3156 else
3157 func (stream, "s");
3158 break;
3159
3160 case 'I':
3161 {
3162 unsigned int tmp;
3163
3164 ifthen_next_state = given & 0xff;
3165 for (tmp = given << 1; tmp & 0xf; tmp <<= 1)
3166 func (stream, ((given ^ tmp) & 0x10) ? "e" : "t");
3167 func (stream, "\t%s", arm_conditional[(given >> 4) & 0xf]);
3168 }
3169 break;
3170
3171 case 'x':
3172 if (ifthen_next_state)
3173 func (stream, "\t; unpredictable branch in IT block\n");
3174 break;
3175
3176 case 'X':
3177 if (ifthen_state)
3178 func (stream, "\t; unpredictable <IT:%s>",
3179 arm_conditional[IFTHEN_COND]);
3180 break;
3181
3182 case 'S':
3183 {
3184 long reg;
3185
3186 reg = (given >> 3) & 0x7;
3187 if (given & (1 << 6))
3188 reg += 8;
3189
3190 func (stream, "%s", arm_regnames[reg]);
3191 }
3192 break;
3193
3194 case 'D':
3195 {
3196 long reg;
3197
3198 reg = given & 0x7;
3199 if (given & (1 << 7))
3200 reg += 8;
3201
3202 func (stream, "%s", arm_regnames[reg]);
3203 }
3204 break;
3205
3206 case 'N':
3207 if (given & (1 << 8))
3208 domasklr = 1;
3209 /* Fall through. */
3210 case 'O':
3211 if (*c == 'O' && (given & (1 << 8)))
3212 domaskpc = 1;
3213 /* Fall through. */
3214 case 'M':
3215 {
3216 int started = 0;
3217 int reg;
3218
3219 func (stream, "{");
3220
3221 /* It would be nice if we could spot
3222 ranges, and generate the rS-rE format: */
3223 for (reg = 0; (reg < 8); reg++)
3224 if ((given & (1 << reg)) != 0)
3225 {
3226 if (started)
3227 func (stream, ", ");
3228 started = 1;
3229 func (stream, "%s", arm_regnames[reg]);
3230 }
3231
3232 if (domasklr)
3233 {
3234 if (started)
3235 func (stream, ", ");
3236 started = 1;
3237 func (stream, arm_regnames[14] /* "lr" */);
3238 }
3239
3240 if (domaskpc)
3241 {
3242 if (started)
3243 func (stream, ", ");
3244 func (stream, arm_regnames[15] /* "pc" */);
3245 }
3246
3247 func (stream, "}");
3248 }
3249 break;
3250
3251 case 'b':
3252 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
3253 {
3254 bfd_vma address = (pc + 4
3255 + ((given & 0x00f8) >> 2)
3256 + ((given & 0x0200) >> 3));
3257 info->print_address_func (address, info);
3258 }
3259 break;
3260
3261 case 's':
3262 /* Right shift immediate -- bits 6..10; 1-31 print
3263 as themselves, 0 prints as 32. */
3264 {
3265 long imm = (given & 0x07c0) >> 6;
3266 if (imm == 0)
3267 imm = 32;
3268 func (stream, "#%ld", imm);
3269 }
3270 break;
3271
3272 case '0': case '1': case '2': case '3': case '4':
3273 case '5': case '6': case '7': case '8': case '9':
3274 {
3275 int bitstart = *c++ - '0';
3276 int bitend = 0;
3277
3278 while (*c >= '0' && *c <= '9')
3279 bitstart = (bitstart * 10) + *c++ - '0';
3280
3281 switch (*c)
3282 {
3283 case '-':
3284 {
3285 long reg;
3286
3287 c++;
3288 while (*c >= '0' && *c <= '9')
3289 bitend = (bitend * 10) + *c++ - '0';
3290 if (!bitend)
3291 abort ();
3292 reg = given >> bitstart;
3293 reg &= (2 << (bitend - bitstart)) - 1;
3294 switch (*c)
3295 {
3296 case 'r':
3297 func (stream, "%s", arm_regnames[reg]);
3298 break;
3299
3300 case 'd':
3301 func (stream, "%ld", reg);
3302 value_in_comment = reg;
3303 break;
3304
3305 case 'H':
3306 func (stream, "%ld", reg << 1);
3307 value_in_comment = reg << 1;
3308 break;
3309
3310 case 'W':
3311 func (stream, "%ld", reg << 2);
3312 value_in_comment = reg << 2;
3313 break;
3314
3315 case 'a':
3316 /* PC-relative address -- the bottom two
3317 bits of the address are dropped
3318 before the calculation. */
3319 info->print_address_func
3320 (((pc + 4) & ~3) + (reg << 2), info);
3321 value_in_comment = 0;
3322 break;
3323
3324 case 'x':
3325 func (stream, "0x%04lx", reg);
3326 break;
3327
3328 case 'B':
3329 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
3330 info->print_address_func (reg * 2 + pc + 4, info);
3331 value_in_comment = 0;
3332 break;
3333
3334 case 'c':
3335 func (stream, "%s", arm_conditional [reg]);
3336 break;
3337
3338 default:
3339 abort ();
3340 }
3341 }
3342 break;
3343
3344 case '\'':
3345 c++;
3346 if ((given & (1 << bitstart)) != 0)
3347 func (stream, "%c", *c);
3348 break;
3349
3350 case '?':
3351 ++c;
3352 if ((given & (1 << bitstart)) != 0)
3353 func (stream, "%c", *c++);
3354 else
3355 func (stream, "%c", *++c);
3356 break;
3357
3358 default:
3359 abort ();
3360 }
3361 }
3362 break;
3363
3364 default:
3365 abort ();
3366 }
3367 }
3368
3369 if (value_in_comment > 32 || value_in_comment < -16)
3370 func (stream, "\t; 0x%lx", value_in_comment);
3371 return;
3372 }
3373
3374 /* No match. */
3375 abort ();
3376 }
3377
3378 /* Return the name of an V7M special register. */
3379
3380 static const char *
3381 psr_name (int regno)
3382 {
3383 switch (regno)
3384 {
3385 case 0: return "APSR";
3386 case 1: return "IAPSR";
3387 case 2: return "EAPSR";
3388 case 3: return "PSR";
3389 case 5: return "IPSR";
3390 case 6: return "EPSR";
3391 case 7: return "IEPSR";
3392 case 8: return "MSP";
3393 case 9: return "PSP";
3394 case 16: return "PRIMASK";
3395 case 17: return "BASEPRI";
3396 case 18: return "BASEPRI_MASK";
3397 case 19: return "FAULTMASK";
3398 case 20: return "CONTROL";
3399 default: return "<unknown>";
3400 }
3401 }
3402
3403 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
3404
3405 static void
3406 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
3407 {
3408 const struct opcode32 *insn;
3409 void *stream = info->stream;
3410 fprintf_ftype func = info->fprintf_func;
3411
3412 if (print_insn_coprocessor (pc, info, given, TRUE))
3413 return;
3414
3415 if (print_insn_neon (info, given, TRUE))
3416 return;
3417
3418 for (insn = thumb32_opcodes; insn->assembler; insn++)
3419 if ((given & insn->mask) == insn->value)
3420 {
3421 signed long value_in_comment = 0;
3422 const char *c = insn->assembler;
3423
3424 for (; *c; c++)
3425 {
3426 if (*c != '%')
3427 {
3428 func (stream, "%c", *c);
3429 continue;
3430 }
3431
3432 switch (*++c)
3433 {
3434 case '%':
3435 func (stream, "%%");
3436 break;
3437
3438 case 'c':
3439 if (ifthen_state)
3440 func (stream, "%s", arm_conditional[IFTHEN_COND]);
3441 break;
3442
3443 case 'x':
3444 if (ifthen_next_state)
3445 func (stream, "\t; unpredictable branch in IT block\n");
3446 break;
3447
3448 case 'X':
3449 if (ifthen_state)
3450 func (stream, "\t; unpredictable <IT:%s>",
3451 arm_conditional[IFTHEN_COND]);
3452 break;
3453
3454 case 'I':
3455 {
3456 unsigned int imm12 = 0;
3457
3458 imm12 |= (given & 0x000000ffu);
3459 imm12 |= (given & 0x00007000u) >> 4;
3460 imm12 |= (given & 0x04000000u) >> 15;
3461 func (stream, "#%u", imm12);
3462 value_in_comment = imm12;
3463 }
3464 break;
3465
3466 case 'M':
3467 {
3468 unsigned int bits = 0, imm, imm8, mod;
3469
3470 bits |= (given & 0x000000ffu);
3471 bits |= (given & 0x00007000u) >> 4;
3472 bits |= (given & 0x04000000u) >> 15;
3473 imm8 = (bits & 0x0ff);
3474 mod = (bits & 0xf00) >> 8;
3475 switch (mod)
3476 {
3477 case 0: imm = imm8; break;
3478 case 1: imm = ((imm8<<16) | imm8); break;
3479 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
3480 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
3481 default:
3482 mod = (bits & 0xf80) >> 7;
3483 imm8 = (bits & 0x07f) | 0x80;
3484 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
3485 }
3486 func (stream, "#%u", imm);
3487 value_in_comment = imm;
3488 }
3489 break;
3490
3491 case 'J':
3492 {
3493 unsigned int imm = 0;
3494
3495 imm |= (given & 0x000000ffu);
3496 imm |= (given & 0x00007000u) >> 4;
3497 imm |= (given & 0x04000000u) >> 15;
3498 imm |= (given & 0x000f0000u) >> 4;
3499 func (stream, "#%u", imm);
3500 value_in_comment = imm;
3501 }
3502 break;
3503
3504 case 'K':
3505 {
3506 unsigned int imm = 0;
3507
3508 imm |= (given & 0x000f0000u) >> 16;
3509 imm |= (given & 0x00000ff0u) >> 0;
3510 imm |= (given & 0x0000000fu) << 12;
3511 func (stream, "#%u", imm);
3512 value_in_comment = imm;
3513 }
3514 break;
3515
3516 case 'S':
3517 {
3518 unsigned int reg = (given & 0x0000000fu);
3519 unsigned int stp = (given & 0x00000030u) >> 4;
3520 unsigned int imm = 0;
3521 imm |= (given & 0x000000c0u) >> 6;
3522 imm |= (given & 0x00007000u) >> 10;
3523
3524 func (stream, "%s", arm_regnames[reg]);
3525 switch (stp)
3526 {
3527 case 0:
3528 if (imm > 0)
3529 func (stream, ", lsl #%u", imm);
3530 break;
3531
3532 case 1:
3533 if (imm == 0)
3534 imm = 32;
3535 func (stream, ", lsr #%u", imm);
3536 break;
3537
3538 case 2:
3539 if (imm == 0)
3540 imm = 32;
3541 func (stream, ", asr #%u", imm);
3542 break;
3543
3544 case 3:
3545 if (imm == 0)
3546 func (stream, ", rrx");
3547 else
3548 func (stream, ", ror #%u", imm);
3549 }
3550 }
3551 break;
3552
3553 case 'a':
3554 {
3555 unsigned int Rn = (given & 0x000f0000) >> 16;
3556 unsigned int U = (given & 0x00800000) >> 23;
3557 unsigned int op = (given & 0x00000f00) >> 8;
3558 unsigned int i12 = (given & 0x00000fff);
3559 unsigned int i8 = (given & 0x000000ff);
3560 bfd_boolean writeback = FALSE, postind = FALSE;
3561 int offset = 0;
3562
3563 func (stream, "[%s", arm_regnames[Rn]);
3564 if (U) /* 12-bit positive immediate offset. */
3565 {
3566 offset = i12;
3567 if (Rn != 15)
3568 value_in_comment = offset;
3569 }
3570 else if (Rn == 15) /* 12-bit negative immediate offset. */
3571 offset = - (int) i12;
3572 else if (op == 0x0) /* Shifted register offset. */
3573 {
3574 unsigned int Rm = (i8 & 0x0f);
3575 unsigned int sh = (i8 & 0x30) >> 4;
3576
3577 func (stream, ", %s", arm_regnames[Rm]);
3578 if (sh)
3579 func (stream, ", lsl #%u", sh);
3580 func (stream, "]");
3581 break;
3582 }
3583 else switch (op)
3584 {
3585 case 0xE: /* 8-bit positive immediate offset. */
3586 offset = i8;
3587 break;
3588
3589 case 0xC: /* 8-bit negative immediate offset. */
3590 offset = -i8;
3591 break;
3592
3593 case 0xF: /* 8-bit + preindex with wb. */
3594 offset = i8;
3595 writeback = TRUE;
3596 break;
3597
3598 case 0xD: /* 8-bit - preindex with wb. */
3599 offset = -i8;
3600 writeback = TRUE;
3601 break;
3602
3603 case 0xB: /* 8-bit + postindex. */
3604 offset = i8;
3605 postind = TRUE;
3606 break;
3607
3608 case 0x9: /* 8-bit - postindex. */
3609 offset = -i8;
3610 postind = TRUE;
3611 break;
3612
3613 default:
3614 func (stream, ", <undefined>]");
3615 goto skip;
3616 }
3617
3618 if (postind)
3619 func (stream, "], #%d", offset);
3620 else
3621 {
3622 if (offset)
3623 func (stream, ", #%d", offset);
3624 func (stream, writeback ? "]!" : "]");
3625 }
3626
3627 if (Rn == 15)
3628 {
3629 func (stream, "\t; ");
3630 info->print_address_func (((pc + 4) & ~3) + offset, info);
3631 }
3632 }
3633 skip:
3634 break;
3635
3636 case 'A':
3637 {
3638 unsigned int P = (given & 0x01000000) >> 24;
3639 unsigned int U = (given & 0x00800000) >> 23;
3640 unsigned int W = (given & 0x00400000) >> 21;
3641 unsigned int Rn = (given & 0x000f0000) >> 16;
3642 unsigned int off = (given & 0x000000ff);
3643
3644 func (stream, "[%s", arm_regnames[Rn]);
3645 if (P)
3646 {
3647 if (off || !U)
3648 {
3649 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
3650 value_in_comment = off * 4 * U ? 1 : -1;
3651 }
3652 func (stream, "]");
3653 if (W)
3654 func (stream, "!");
3655 }
3656 else
3657 {
3658 func (stream, "], ");
3659 if (W)
3660 {
3661 func (stream, "#%c%u", U ? '+' : '-', off * 4);
3662 value_in_comment = off * 4 * U ? 1 : -1;
3663 }
3664 else
3665 {
3666 func (stream, "{%u}", off);
3667 value_in_comment = off;
3668 }
3669 }
3670 }
3671 break;
3672
3673 case 'w':
3674 {
3675 unsigned int Sbit = (given & 0x01000000) >> 24;
3676 unsigned int type = (given & 0x00600000) >> 21;
3677
3678 switch (type)
3679 {
3680 case 0: func (stream, Sbit ? "sb" : "b"); break;
3681 case 1: func (stream, Sbit ? "sh" : "h"); break;
3682 case 2:
3683 if (Sbit)
3684 func (stream, "??");
3685 break;
3686 case 3:
3687 func (stream, "??");
3688 break;
3689 }
3690 }
3691 break;
3692
3693 case 'm':
3694 {
3695 int started = 0;
3696 int reg;
3697
3698 func (stream, "{");
3699 for (reg = 0; reg < 16; reg++)
3700 if ((given & (1 << reg)) != 0)
3701 {
3702 if (started)
3703 func (stream, ", ");
3704 started = 1;
3705 func (stream, "%s", arm_regnames[reg]);
3706 }
3707 func (stream, "}");
3708 }
3709 break;
3710
3711 case 'E':
3712 {
3713 unsigned int msb = (given & 0x0000001f);
3714 unsigned int lsb = 0;
3715
3716 lsb |= (given & 0x000000c0u) >> 6;
3717 lsb |= (given & 0x00007000u) >> 10;
3718 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
3719 }
3720 break;
3721
3722 case 'F':
3723 {
3724 unsigned int width = (given & 0x0000001f) + 1;
3725 unsigned int lsb = 0;
3726
3727 lsb |= (given & 0x000000c0u) >> 6;
3728 lsb |= (given & 0x00007000u) >> 10;
3729 func (stream, "#%u, #%u", lsb, width);
3730 }
3731 break;
3732
3733 case 'b':
3734 {
3735 unsigned int S = (given & 0x04000000u) >> 26;
3736 unsigned int J1 = (given & 0x00002000u) >> 13;
3737 unsigned int J2 = (given & 0x00000800u) >> 11;
3738 int offset = 0;
3739
3740 offset |= !S << 20;
3741 offset |= J2 << 19;
3742 offset |= J1 << 18;
3743 offset |= (given & 0x003f0000) >> 4;
3744 offset |= (given & 0x000007ff) << 1;
3745 offset -= (1 << 20);
3746
3747 info->print_address_func (pc + 4 + offset, info);
3748 }
3749 break;
3750
3751 case 'B':
3752 {
3753 unsigned int S = (given & 0x04000000u) >> 26;
3754 unsigned int I1 = (given & 0x00002000u) >> 13;
3755 unsigned int I2 = (given & 0x00000800u) >> 11;
3756 int offset = 0;
3757
3758 offset |= !S << 24;
3759 offset |= !(I1 ^ S) << 23;
3760 offset |= !(I2 ^ S) << 22;
3761 offset |= (given & 0x03ff0000u) >> 4;
3762 offset |= (given & 0x000007ffu) << 1;
3763 offset -= (1 << 24);
3764 offset += pc + 4;
3765
3766 /* BLX target addresses are always word aligned. */
3767 if ((given & 0x00001000u) == 0)
3768 offset &= ~2u;
3769
3770 info->print_address_func (offset, info);
3771 }
3772 break;
3773
3774 case 's':
3775 {
3776 unsigned int shift = 0;
3777
3778 shift |= (given & 0x000000c0u) >> 6;
3779 shift |= (given & 0x00007000u) >> 10;
3780 if (given & 0x00200000u)
3781 func (stream, ", asr #%u", shift);
3782 else if (shift)
3783 func (stream, ", lsl #%u", shift);
3784 /* else print nothing - lsl #0 */
3785 }
3786 break;
3787
3788 case 'R':
3789 {
3790 unsigned int rot = (given & 0x00000030) >> 4;
3791
3792 if (rot)
3793 func (stream, ", ror #%u", rot * 8);
3794 }
3795 break;
3796
3797 case 'U':
3798 switch (given & 0xf)
3799 {
3800 case 0xf: func (stream, "sy"); break;
3801 case 0x7: func (stream, "un"); break;
3802 case 0xe: func (stream, "st"); break;
3803 case 0x6: func (stream, "unst"); break;
3804 default:
3805 func (stream, "#%d", (int) given & 0xf);
3806 break;
3807 }
3808 break;
3809
3810 case 'C':
3811 if ((given & 0xff) == 0)
3812 {
3813 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
3814 if (given & 0x800)
3815 func (stream, "f");
3816 if (given & 0x400)
3817 func (stream, "s");
3818 if (given & 0x200)
3819 func (stream, "x");
3820 if (given & 0x100)
3821 func (stream, "c");
3822 }
3823 else
3824 {
3825 func (stream, psr_name (given & 0xff));
3826 }
3827 break;
3828
3829 case 'D':
3830 if ((given & 0xff) == 0)
3831 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
3832 else
3833 func (stream, psr_name (given & 0xff));
3834 break;
3835
3836 case '0': case '1': case '2': case '3': case '4':
3837 case '5': case '6': case '7': case '8': case '9':
3838 {
3839 int width;
3840 unsigned long val;
3841
3842 c = arm_decode_bitfield (c, given, &val, &width);
3843
3844 switch (*c)
3845 {
3846 case 'd':
3847 func (stream, "%lu", val);
3848 value_in_comment = val;
3849 break;
3850 case 'W':
3851 func (stream, "%lu", val * 4);
3852 value_in_comment = val * 4;
3853 break;
3854 case 'r': func (stream, "%s", arm_regnames[val]); break;
3855
3856 case 'c':
3857 func (stream, "%s", arm_conditional[val]);
3858 break;
3859
3860 case '\'':
3861 c++;
3862 if (val == ((1ul << width) - 1))
3863 func (stream, "%c", *c);
3864 break;
3865
3866 case '`':
3867 c++;
3868 if (val == 0)
3869 func (stream, "%c", *c);
3870 break;
3871
3872 case '?':
3873 func (stream, "%c", c[(1 << width) - (int) val]);
3874 c += 1 << width;
3875 break;
3876
3877 default:
3878 abort ();
3879 }
3880 }
3881 break;
3882
3883 default:
3884 abort ();
3885 }
3886 }
3887
3888 if (value_in_comment > 32 || value_in_comment < -16)
3889 func (stream, "\t; 0x%lx", value_in_comment);
3890 return;
3891 }
3892
3893 /* No match. */
3894 abort ();
3895 }
3896
3897 /* Print data bytes on INFO->STREAM. */
3898
3899 static void
3900 print_insn_data (bfd_vma pc ATTRIBUTE_UNUSED,
3901 struct disassemble_info *info,
3902 long given)
3903 {
3904 switch (info->bytes_per_chunk)
3905 {
3906 case 1:
3907 info->fprintf_func (info->stream, ".byte\t0x%02lx", given);
3908 break;
3909 case 2:
3910 info->fprintf_func (info->stream, ".short\t0x%04lx", given);
3911 break;
3912 case 4:
3913 info->fprintf_func (info->stream, ".word\t0x%08lx", given);
3914 break;
3915 default:
3916 abort ();
3917 }
3918 }
3919
3920 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
3921 being displayed in symbol relative addresses. */
3922
3923 bfd_boolean
3924 arm_symbol_is_valid (asymbol * sym,
3925 struct disassemble_info * info ATTRIBUTE_UNUSED)
3926 {
3927 const char * name;
3928
3929 if (sym == NULL)
3930 return FALSE;
3931
3932 name = bfd_asymbol_name (sym);
3933
3934 return (name && *name != '$');
3935 }
3936
3937 /* Parse an individual disassembler option. */
3938
3939 void
3940 parse_arm_disassembler_option (char *option)
3941 {
3942 if (option == NULL)
3943 return;
3944
3945 if (CONST_STRNEQ (option, "reg-names-"))
3946 {
3947 int i;
3948
3949 option += 10;
3950
3951 for (i = NUM_ARM_REGNAMES; i--;)
3952 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
3953 {
3954 regname_selected = i;
3955 break;
3956 }
3957
3958 if (i < 0)
3959 /* XXX - should break 'option' at following delimiter. */
3960 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
3961 }
3962 else if (CONST_STRNEQ (option, "force-thumb"))
3963 force_thumb = 1;
3964 else if (CONST_STRNEQ (option, "no-force-thumb"))
3965 force_thumb = 0;
3966 else
3967 /* XXX - should break 'option' at following delimiter. */
3968 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
3969
3970 return;
3971 }
3972
3973 /* Parse the string of disassembler options, spliting it at whitespaces
3974 or commas. (Whitespace separators supported for backwards compatibility). */
3975
3976 static void
3977 parse_disassembler_options (char *options)
3978 {
3979 if (options == NULL)
3980 return;
3981
3982 while (*options)
3983 {
3984 parse_arm_disassembler_option (options);
3985
3986 /* Skip forward to next seperator. */
3987 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
3988 ++ options;
3989 /* Skip forward past seperators. */
3990 while (ISSPACE (*options) || (*options == ','))
3991 ++ options;
3992 }
3993 }
3994
3995 /* Search back through the insn stream to determine if this instruction is
3996 conditionally executed. */
3997
3998 static void
3999 find_ifthen_state (bfd_vma pc,
4000 struct disassemble_info *info,
4001 bfd_boolean little)
4002 {
4003 unsigned char b[2];
4004 unsigned int insn;
4005 int status;
4006 /* COUNT is twice the number of instructions seen. It will be odd if we
4007 just crossed an instruction boundary. */
4008 int count;
4009 int it_count;
4010 unsigned int seen_it;
4011 bfd_vma addr;
4012
4013 ifthen_address = pc;
4014 ifthen_state = 0;
4015
4016 addr = pc;
4017 count = 1;
4018 it_count = 0;
4019 seen_it = 0;
4020 /* Scan backwards looking for IT instructions, keeping track of where
4021 instruction boundaries are. We don't know if something is actually an
4022 IT instruction until we find a definite instruction boundary. */
4023 for (;;)
4024 {
4025 if (addr == 0 || info->symbol_at_address_func (addr, info))
4026 {
4027 /* A symbol must be on an instruction boundary, and will not
4028 be within an IT block. */
4029 if (seen_it && (count & 1))
4030 break;
4031
4032 return;
4033 }
4034 addr -= 2;
4035 status = info->read_memory_func (addr, (bfd_byte *) b, 2, info);
4036 if (status)
4037 return;
4038
4039 if (little)
4040 insn = (b[0]) | (b[1] << 8);
4041 else
4042 insn = (b[1]) | (b[0] << 8);
4043 if (seen_it)
4044 {
4045 if ((insn & 0xf800) < 0xe800)
4046 {
4047 /* Addr + 2 is an instruction boundary. See if this matches
4048 the expected boundary based on the position of the last
4049 IT candidate. */
4050 if (count & 1)
4051 break;
4052 seen_it = 0;
4053 }
4054 }
4055 if ((insn & 0xff00) == 0xbf00 && (insn & 0xf) != 0)
4056 {
4057 /* This could be an IT instruction. */
4058 seen_it = insn;
4059 it_count = count >> 1;
4060 }
4061 if ((insn & 0xf800) >= 0xe800)
4062 count++;
4063 else
4064 count = (count + 2) | 1;
4065 /* IT blocks contain at most 4 instructions. */
4066 if (count >= 8 && !seen_it)
4067 return;
4068 }
4069 /* We found an IT instruction. */
4070 ifthen_state = (seen_it & 0xe0) | ((seen_it << it_count) & 0x1f);
4071 if ((ifthen_state & 0xf) == 0)
4072 ifthen_state = 0;
4073 }
4074
4075 /* Try to infer the code type (Arm or Thumb) from a symbol.
4076 Returns nonzero if *MAP_TYPE was set. */
4077
4078 static int
4079 get_sym_code_type (struct disassemble_info *info,
4080 int n,
4081 enum map_type *map_type)
4082 {
4083 elf_symbol_type *es;
4084 unsigned int type;
4085 const char *name;
4086
4087 es = *(elf_symbol_type **)(info->symtab + n);
4088 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4089
4090 /* If the symbol has function type then use that. */
4091 if (type == STT_FUNC || type == STT_ARM_TFUNC)
4092 {
4093 *map_type = (type == STT_ARM_TFUNC) ? MAP_THUMB : MAP_ARM;
4094 return TRUE;
4095 }
4096
4097 /* Check for mapping symbols. */
4098 name = bfd_asymbol_name (info->symtab[n]);
4099 if (name[0] == '$' && (name[1] == 'a' || name[1] == 't' || name[1] == 'd')
4100 && (name[2] == 0 || name[2] == '.'))
4101 {
4102 *map_type = ((name[1] == 'a') ? MAP_ARM
4103 : (name[1] == 't') ? MAP_THUMB
4104 : MAP_DATA);
4105 return TRUE;
4106 }
4107
4108 return FALSE;
4109 }
4110
4111 /* Given a bfd_mach_arm_XXX value, this function fills in the fields
4112 of the supplied arm_feature_set structure with bitmasks indicating
4113 the support base architectures and coprocessor extensions.
4114
4115 FIXME: This could more efficiently implemented as a constant array,
4116 although it would also be less robust. */
4117
4118 static void
4119 select_arm_features (unsigned long mach,
4120 arm_feature_set * features)
4121 {
4122 #undef ARM_FEATURE
4123 #define ARM_FEATURE(ARCH,CEXT) \
4124 features->core = (ARCH); \
4125 features->coproc = (CEXT) | FPU_FPA; \
4126 return
4127
4128 switch (mach)
4129 {
4130 case bfd_mach_arm_2: ARM_ARCH_V2;
4131 case bfd_mach_arm_2a: ARM_ARCH_V2S;
4132 case bfd_mach_arm_3: ARM_ARCH_V3;
4133 case bfd_mach_arm_3M: ARM_ARCH_V3M;
4134 case bfd_mach_arm_4: ARM_ARCH_V4;
4135 case bfd_mach_arm_4T: ARM_ARCH_V4T;
4136 case bfd_mach_arm_5: ARM_ARCH_V5;
4137 case bfd_mach_arm_5T: ARM_ARCH_V5T;
4138 case bfd_mach_arm_5TE: ARM_ARCH_V5TE;
4139 case bfd_mach_arm_XScale: ARM_ARCH_XSCALE;
4140 case bfd_mach_arm_ep9312: ARM_FEATURE (ARM_AEXT_V4T, ARM_CEXT_MAVERICK | FPU_MAVERICK);
4141 case bfd_mach_arm_iWMMXt: ARM_ARCH_IWMMXT;
4142 case bfd_mach_arm_iWMMXt2: ARM_ARCH_IWMMXT2;
4143 /* If the machine type is unknown allow all
4144 architecture types and all extensions. */
4145 case bfd_mach_arm_unknown: ARM_FEATURE (-1UL, -1UL);
4146 default:
4147 abort ();
4148 }
4149 }
4150
4151
4152 /* NOTE: There are no checks in these routines that
4153 the relevant number of data bytes exist. */
4154
4155 static int
4156 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
4157 {
4158 unsigned char b[4];
4159 long given;
4160 int status;
4161 int is_thumb = FALSE;
4162 int is_data = FALSE;
4163 int little_code;
4164 unsigned int size = 4;
4165 void (*printer) (bfd_vma, struct disassemble_info *, long);
4166 bfd_boolean found = FALSE;
4167
4168 if (info->disassembler_options)
4169 {
4170 parse_disassembler_options (info->disassembler_options);
4171
4172 /* To avoid repeated parsing of these options, we remove them here. */
4173 info->disassembler_options = NULL;
4174 }
4175
4176 /* PR 10288: Control which instructions will be disassembled. */
4177 if (info->private_data == NULL)
4178 {
4179 static arm_feature_set features;
4180
4181 if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
4182 /* If the user did not use the -m command line switch then default to
4183 disassembling all types of ARM instruction.
4184
4185 The info->mach value has to be ignored as this will be based on
4186 the default archictecture for the target and/or hints in the notes
4187 section, but it will never be greater than the current largest arm
4188 machine value (iWMMXt2), which is only equivalent to the V5TE
4189 architecture. ARM architectures have advanced beyond the machine
4190 value encoding, and these newer architectures would be ignored if
4191 the machine value was used.
4192
4193 Ie the -m switch is used to restrict which instructions will be
4194 disassembled. If it is necessary to use the -m switch to tell
4195 objdump that an ARM binary is being disassembled, eg because the
4196 input is a raw binary file, but it is also desired to disassemble
4197 all ARM instructions then use "-marm". This will select the
4198 "unknown" arm architecture which is compatible with any ARM
4199 instruction. */
4200 info->mach = bfd_mach_arm_unknown;
4201
4202 /* Compute the architecture bitmask from the machine number.
4203 Note: This assumes that the machine number will not change
4204 during disassembly.... */
4205 select_arm_features (info->mach, & features);
4206
4207 info->private_data = & features;
4208 }
4209
4210 /* Decide if our code is going to be little-endian, despite what the
4211 function argument might say. */
4212 little_code = ((info->endian_code == BFD_ENDIAN_LITTLE) || little);
4213
4214 /* First check the full symtab for a mapping symbol, even if there
4215 are no usable non-mapping symbols for this address. */
4216 if (info->symtab != NULL
4217 && * info->symtab
4218 && bfd_asymbol_flavour (*info->symtab) == bfd_target_elf_flavour)
4219 {
4220 bfd_vma addr;
4221 int n;
4222 int last_sym = -1;
4223 enum map_type type = MAP_ARM;
4224
4225 if (pc <= last_mapping_addr)
4226 last_mapping_sym = -1;
4227 is_thumb = (last_type == MAP_THUMB);
4228 found = FALSE;
4229 /* Start scanning at the start of the function, or wherever
4230 we finished last time. */
4231 n = info->symtab_pos + 1;
4232 if (n < last_mapping_sym)
4233 n = last_mapping_sym;
4234
4235 /* Scan up to the location being disassembled. */
4236 for (; n < info->symtab_size; n++)
4237 {
4238 addr = bfd_asymbol_value (info->symtab[n]);
4239 if (addr > pc)
4240 break;
4241 if ((info->section == NULL
4242 || info->section == info->symtab[n]->section)
4243 && get_sym_code_type (info, n, &type))
4244 {
4245 last_sym = n;
4246 found = TRUE;
4247 }
4248 }
4249
4250 if (!found)
4251 {
4252 n = info->symtab_pos;
4253 if (n < last_mapping_sym - 1)
4254 n = last_mapping_sym - 1;
4255
4256 /* No mapping symbol found at this address. Look backwards
4257 for a preceeding one. */
4258 for (; n >= 0; n--)
4259 {
4260 if ((info->section == NULL
4261 || info->section == info->symtab[n]->section)
4262 && get_sym_code_type (info, n, &type))
4263 {
4264 last_sym = n;
4265 found = TRUE;
4266 break;
4267 }
4268 }
4269 }
4270
4271 last_mapping_sym = last_sym;
4272 last_type = type;
4273 is_thumb = (last_type == MAP_THUMB);
4274 is_data = (last_type == MAP_DATA);
4275
4276 /* Look a little bit ahead to see if we should print out
4277 two or four bytes of data. If there's a symbol,
4278 mapping or otherwise, after two bytes then don't
4279 print more. */
4280 if (is_data)
4281 {
4282 size = 4 - (pc & 3);
4283 for (n = last_sym + 1; n < info->symtab_size; n++)
4284 {
4285 addr = bfd_asymbol_value (info->symtab[n]);
4286 if (addr > pc)
4287 {
4288 if (addr - pc < size)
4289 size = addr - pc;
4290 break;
4291 }
4292 }
4293 /* If the next symbol is after three bytes, we need to
4294 print only part of the data, so that we can use either
4295 .byte or .short. */
4296 if (size == 3)
4297 size = (pc & 1) ? 1 : 2;
4298 }
4299 }
4300
4301 if (info->symbols != NULL)
4302 {
4303 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
4304 {
4305 coff_symbol_type * cs;
4306
4307 cs = coffsymbol (*info->symbols);
4308 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
4309 || cs->native->u.syment.n_sclass == C_THUMBSTAT
4310 || cs->native->u.syment.n_sclass == C_THUMBLABEL
4311 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
4312 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
4313 }
4314 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour
4315 && !found)
4316 {
4317 /* If no mapping symbol has been found then fall back to the type
4318 of the function symbol. */
4319 elf_symbol_type * es;
4320 unsigned int type;
4321
4322 es = *(elf_symbol_type **)(info->symbols);
4323 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
4324
4325 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
4326 }
4327 }
4328
4329 if (force_thumb)
4330 is_thumb = TRUE;
4331
4332 if (is_data)
4333 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4334 else
4335 info->display_endian = little_code ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
4336
4337 info->bytes_per_line = 4;
4338
4339 /* PR 10263: Disassemble data if requested to do so by the user. */
4340 if (is_data && ((info->flags & DISASSEMBLE_DATA) == 0))
4341 {
4342 int i;
4343
4344 /* Size was already set above. */
4345 info->bytes_per_chunk = size;
4346 printer = print_insn_data;
4347
4348 status = info->read_memory_func (pc, (bfd_byte *) b, size, info);
4349 given = 0;
4350 if (little)
4351 for (i = size - 1; i >= 0; i--)
4352 given = b[i] | (given << 8);
4353 else
4354 for (i = 0; i < (int) size; i++)
4355 given = b[i] | (given << 8);
4356 }
4357 else if (!is_thumb)
4358 {
4359 /* In ARM mode endianness is a straightforward issue: the instruction
4360 is four bytes long and is either ordered 0123 or 3210. */
4361 printer = print_insn_arm;
4362 info->bytes_per_chunk = 4;
4363 size = 4;
4364
4365 status = info->read_memory_func (pc, (bfd_byte *) b, 4, info);
4366 if (little_code)
4367 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
4368 else
4369 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
4370 }
4371 else
4372 {
4373 /* In Thumb mode we have the additional wrinkle of two
4374 instruction lengths. Fortunately, the bits that determine
4375 the length of the current instruction are always to be found
4376 in the first two bytes. */
4377 printer = print_insn_thumb16;
4378 info->bytes_per_chunk = 2;
4379 size = 2;
4380
4381 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
4382 if (little_code)
4383 given = (b[0]) | (b[1] << 8);
4384 else
4385 given = (b[1]) | (b[0] << 8);
4386
4387 if (!status)
4388 {
4389 /* These bit patterns signal a four-byte Thumb
4390 instruction. */
4391 if ((given & 0xF800) == 0xF800
4392 || (given & 0xF800) == 0xF000
4393 || (given & 0xF800) == 0xE800)
4394 {
4395 status = info->read_memory_func (pc + 2, (bfd_byte *) b, 2, info);
4396 if (little_code)
4397 given = (b[0]) | (b[1] << 8) | (given << 16);
4398 else
4399 given = (b[1]) | (b[0] << 8) | (given << 16);
4400
4401 printer = print_insn_thumb32;
4402 size = 4;
4403 }
4404 }
4405
4406 if (ifthen_address != pc)
4407 find_ifthen_state (pc, info, little_code);
4408
4409 if (ifthen_state)
4410 {
4411 if ((ifthen_state & 0xf) == 0x8)
4412 ifthen_next_state = 0;
4413 else
4414 ifthen_next_state = (ifthen_state & 0xe0)
4415 | ((ifthen_state & 0xf) << 1);
4416 }
4417 }
4418
4419 if (status)
4420 {
4421 info->memory_error_func (status, pc, info);
4422 return -1;
4423 }
4424 if (info->flags & INSN_HAS_RELOC)
4425 /* If the instruction has a reloc associated with it, then
4426 the offset field in the instruction will actually be the
4427 addend for the reloc. (We are using REL type relocs).
4428 In such cases, we can ignore the pc when computing
4429 addresses, since the addend is not currently pc-relative. */
4430 pc = 0;
4431
4432 printer (pc, info, given);
4433
4434 if (is_thumb)
4435 {
4436 ifthen_state = ifthen_next_state;
4437 ifthen_address += size;
4438 }
4439 return size;
4440 }
4441
4442 int
4443 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
4444 {
4445 /* Detect BE8-ness and record it in the disassembler info. */
4446 if (info->flavour == bfd_target_elf_flavour
4447 && info->section != NULL
4448 && (elf_elfheader (info->section->owner)->e_flags & EF_ARM_BE8))
4449 info->endian_code = BFD_ENDIAN_LITTLE;
4450
4451 return print_insn (pc, info, FALSE);
4452 }
4453
4454 int
4455 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
4456 {
4457 return print_insn (pc, info, TRUE);
4458 }
4459
4460 void
4461 print_arm_disassembler_options (FILE *stream)
4462 {
4463 int i;
4464
4465 fprintf (stream, _("\n\
4466 The following ARM specific disassembler options are supported for use with\n\
4467 the -M switch:\n"));
4468
4469 for (i = NUM_ARM_REGNAMES; i--;)
4470 fprintf (stream, " reg-names-%s %*c%s\n",
4471 regnames[i].name,
4472 (int)(14 - strlen (regnames[i].name)), ' ',
4473 regnames[i].description);
4474
4475 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
4476 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
4477 }
This page took 0.163809 seconds and 4 git commands to generate.