daily update
[binutils.git] / opcodes / arm-dis.c
blobdbf91be9e08769541a1784ab19aecbfd249b0876
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
30 /* FIXME: This shouldn't be done here. */
31 #include "coff/internal.h"
32 #include "libcoff.h"
33 #include "elf-bfd.h"
34 #include "elf/internal.h"
35 #include "elf/arm.h"
37 /* FIXME: Belongs in global header. */
38 #ifndef strneq
39 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
40 #endif
42 #ifndef NUM_ELEM
43 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
44 #endif
46 struct opcode32
48 unsigned long arch; /* Architecture defining this insn. */
49 unsigned long value, mask; /* Recognise insn if (op&mask)==value. */
50 const char *assembler; /* How to disassemble this insn. */
53 struct opcode16
55 unsigned long arch; /* Architecture defining this insn. */
56 unsigned short value, mask; /* Recognise insn if (op&mask)==value. */
57 const char *assembler; /* How to disassemble this insn. */
60 /* Opcode tables: ARM, 16-bit Thumb, 32-bit Thumb. All three are partially
61 ordered: they must be searched linearly from the top to obtain a correct
62 match. */
64 /* print_insn_arm recognizes the following format control codes:
66 %% %
68 %a print address for ldr/str instruction
69 %s print address for ldr/str halfword/signextend instruction
70 %b print branch destination
71 %c print condition code (always bits 28-31)
72 %m print register mask for ldm/stm instruction
73 %o print operand2 (immediate or register + shift)
74 %p print 'p' iff bits 12-15 are 15
75 %t print 't' iff bit 21 set and bit 24 clear
76 %A print address for ldc/stc/ldf/stf instruction
77 %B print arm BLX(1) destination
78 %I print cirrus signed shift immediate: bits 0..3|4..6
79 %C print the PSR sub type.
80 %F print the COUNT field of a LFM/SFM instruction.
81 %P print floating point precision in arithmetic insn
82 %Q print floating point precision in ldf/stf insn
83 %R print floating point rounding mode
85 %<bitfield>r print as an ARM register
86 %<bitfield>d print the bitfield in decimal
87 %<bitfield>W print the bitfield plus one in decimal
88 %<bitfield>x print the bitfield in hex
89 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
90 %<bitfield>f print a floating point constant if >7 else a
91 floating point register
92 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
93 %<bitfield>g print as an iWMMXt 64-bit register
94 %<bitfield>G print as an iWMMXt general purpose or control register
96 %<code>y print a single precision VFP reg.
97 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
98 %<code>z print a double precision VFP reg
99 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
100 %<bitnum>'c print specified char iff bit is one
101 %<bitnum>`c print specified char iff bit is zero
102 %<bitnum>?ab print a if bit is one else print b
104 %L print as an iWMMXt N/M width field.
105 %Z print the Immediate of a WSHUFH instruction.
106 %l like 'A' except use byte offsets for 'B' & 'H' versions.
108 %e print arm SMI operand (bits 0..7,8..19).
109 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
110 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
112 static const struct opcode32 arm_opcodes[] =
114 /* ARM instructions. */
115 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
116 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
117 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
118 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
119 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
120 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
121 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
123 /* ARM V6T2 instructions. */
124 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
125 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
126 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
127 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
128 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
129 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
130 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
131 {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
132 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
134 /* ARM V6Z instructions. */
135 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
137 /* ARM V6K instructions. */
138 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
139 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
140 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
141 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
142 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
143 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
144 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
146 /* ARM V6K NOP hints. */
147 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
148 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
149 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
150 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
151 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
153 /* ARM V6 instructions. */
154 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
155 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
156 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
157 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
158 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
159 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
160 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
161 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
162 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
163 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
164 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
165 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
166 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
167 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
168 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
169 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
170 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
171 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
172 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
173 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
174 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
175 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
176 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
177 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
178 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
179 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
180 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
181 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
182 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
183 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
184 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
185 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
186 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
187 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
188 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
189 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
190 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
191 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
192 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
193 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
194 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
195 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
196 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
197 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
198 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
199 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
200 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
201 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
202 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
203 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
204 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
205 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
206 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
207 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
208 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
209 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
210 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
211 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
212 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
213 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
214 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
215 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
216 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
217 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
218 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
219 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
220 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
221 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
222 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
223 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
224 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
225 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
226 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
227 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
228 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
229 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
230 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
231 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
232 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
233 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
234 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
235 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
236 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
237 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
238 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
239 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
240 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
241 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
242 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
243 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
244 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
245 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
246 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
247 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
248 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
249 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
250 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
251 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
252 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
253 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
254 {ARM_EXT_V6, 0x068000b0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
255 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
256 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
257 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
258 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
259 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
260 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
261 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
262 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
263 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
264 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
265 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
266 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
267 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
268 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
269 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
270 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
271 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
272 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
273 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
274 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
275 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
276 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
277 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
279 /* V5J instruction. */
280 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
282 /* XScale instructions. */
283 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
284 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
285 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
286 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
287 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
289 /* Intel Wireless MMX technology instructions. */
290 #define FIRST_IWMMXT_INSN 0x0e130130
291 #define IWMMXT_INSN_COUNT 47
292 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
293 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
294 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
295 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
296 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
297 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
298 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
299 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
300 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
301 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
302 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
303 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
304 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
305 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
306 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
307 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
308 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
309 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
310 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
311 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
312 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
313 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
314 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
315 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
316 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
317 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
318 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
319 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
320 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
321 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
322 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
323 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
324 {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
325 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
326 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
327 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
328 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
329 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
330 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
331 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
332 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
333 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
334 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
335 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
336 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
337 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
338 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
339 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
340 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
342 /* V5 Instructions. */
343 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
344 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
345 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
346 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
347 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
348 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
349 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
350 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
351 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
353 /* V5E "El Segundo" Instructions. */
354 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
355 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
356 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
357 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
358 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
359 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
360 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
362 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
363 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
365 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
366 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
367 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
368 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
370 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
371 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
372 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
373 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
375 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
376 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
378 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
379 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
380 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
381 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
383 /* ARM Instructions. */
384 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
385 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
386 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
387 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
388 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
389 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
390 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
391 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
392 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
393 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
394 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
395 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
396 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
397 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
398 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
399 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
400 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
401 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
402 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
403 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
404 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
405 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
406 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
407 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
408 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
409 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
410 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
411 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
412 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
414 /* Floating point coprocessor (FPA) instructions */
415 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
416 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
417 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
418 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
419 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
420 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
421 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
422 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
423 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
424 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
425 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
426 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
427 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
428 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
429 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
430 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
431 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
432 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
433 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
434 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
435 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
436 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
437 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
438 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
439 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
440 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
441 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
442 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
443 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
444 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
445 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
446 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
447 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
448 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
449 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
450 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
451 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
452 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
453 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
454 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
455 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
456 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
457 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
459 /* Floating point coprocessor (VFP) instructions */
460 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
461 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
462 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
463 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %0y"},
464 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
465 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
466 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
467 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
468 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
469 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
470 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
471 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
472 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
473 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
474 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
475 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
476 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
477 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
478 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
479 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
480 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
481 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
482 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
483 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
484 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
485 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
486 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
487 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
488 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
489 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
490 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
491 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
492 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
493 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
494 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
495 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
496 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
497 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
498 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
499 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
500 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
501 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
502 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
503 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
504 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
505 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
506 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
507 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
508 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
509 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
510 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
511 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
512 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
513 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
514 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
515 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
516 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
517 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
518 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
519 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
520 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
521 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
522 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
523 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
524 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
525 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
526 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
527 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
528 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
529 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
530 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
531 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
532 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
534 /* Cirrus coprocessor instructions. */
535 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
536 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
537 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
538 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
539 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
540 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
541 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
542 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
543 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
544 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
545 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
546 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
547 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
548 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
549 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
550 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
551 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
552 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
553 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
554 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
555 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
556 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
557 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
558 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
559 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
560 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
561 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
562 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
563 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
564 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
565 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
566 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
567 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
568 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
569 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
570 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
571 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
572 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
573 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
574 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
575 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
576 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
577 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
578 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
579 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
580 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
581 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
582 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
583 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
584 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
585 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
586 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
587 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
588 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
589 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
590 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
591 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
592 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
593 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
594 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
595 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
596 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
597 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
598 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
599 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
600 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
601 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
602 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
603 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
604 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
605 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
606 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
607 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
608 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
609 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
610 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
611 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
612 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
613 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
614 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
615 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
616 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
617 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
618 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
620 /* Generic coprocessor instructions */
621 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
622 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
623 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
624 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
625 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
626 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
627 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
629 /* The rest. */
630 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
631 {0, 0x00000000, 0x00000000, 0}
634 /* print_insn_thumb16 recognizes the following format control codes:
636 %S print Thumb register (bits 3..5 as high number if bit 6 set)
637 %D print Thumb register (bits 0..2 as high number if bit 7 set)
638 %<bitfield>I print bitfield as a signed decimal
639 (top bit of range being the sign bit)
640 %N print Thumb register mask (with LR)
641 %O print Thumb register mask (with PC)
642 %M print Thumb register mask
643 %b print CZB's 6-bit unsigned branch destination
644 %s print Thumb right-shift immediate (6..10; 0 == 32).
645 %<bitfield>r print bitfield as an ARM register
646 %<bitfield>d print bitfield as a decimal
647 %<bitfield>H print (bitfield * 2) as a decimal
648 %<bitfield>W print (bitfield * 4) as a decimal
649 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
650 %<bitfield>B print Thumb branch destination (signed displacement)
651 %<bitfield>c print bitfield as a condition code
652 %<bitnum>'c print specified char iff bit is one
653 %<bitnum>?ab print a if bit is one else print b. */
655 static const struct opcode16 thumb_opcodes[] =
657 /* Thumb instructions. */
659 /* ARM V6K no-argument instructions. */
660 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
661 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
662 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
663 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
664 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
665 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
667 /* ARM V6T2 instructions. */
668 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"},
669 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"},
670 {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"},
671 {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"},
672 {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"},
673 {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"},
674 {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"},
675 {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"},
676 {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"},
678 /* ARM V6. */
679 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
680 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
681 {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
682 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
683 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
684 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
685 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
686 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
687 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
688 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
689 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
691 /* ARM V5 ISA extends Thumb. */
692 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
693 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
694 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
695 /* ARM V4T ISA (Thumb v1). */
696 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
697 /* Format 4. */
698 {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"},
699 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"},
700 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"},
701 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"},
702 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"},
703 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"},
704 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
705 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
706 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
707 {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
708 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
709 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
710 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
711 {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"},
712 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"},
713 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"},
714 /* format 13 */
715 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
716 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
717 /* format 5 */
718 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
719 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
720 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
721 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
722 /* format 14 */
723 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
724 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
725 /* format 2 */
726 {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
727 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
728 {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
729 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
730 /* format 8 */
731 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
732 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
733 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
734 /* format 7 */
735 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
736 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
737 /* format 1 */
738 {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"},
739 {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"},
740 {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"},
741 /* format 3 */
742 {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
743 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
744 {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
745 {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
746 /* format 6 */
747 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
748 /* format 9 */
749 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
750 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
751 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
752 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
753 /* format 10 */
754 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
755 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
756 /* format 11 */
757 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
758 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
759 /* format 12 */
760 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
761 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
762 /* format 15 */
763 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
764 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
765 /* format 17 */
766 {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
767 /* format 16 */
768 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"},
769 /* format 18 */
770 {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"},
772 /* The E800 .. FFFF range is unconditionally redirected to the
773 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
774 are processed via that table. Thus, we can never encounter a
775 bare "second half of BL/BLX(1)" instruction here. */
776 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
777 {0, 0, 0, 0}
780 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
781 We adopt the convention that hw1 is the high 16 bits of .value and
782 .mask, hw2 the low 16 bits.
784 print_insn_thumb32 recognizes the following format control codes:
786 %% %
788 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
789 %M print a modified 12-bit immediate (same location)
790 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
791 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
792 %S print a possibly-shifted Rm
794 %a print the address of a plain load/store
795 %A print the address of a coprocessor load/store
796 %w print the width and signedness of a core load/store
797 %m print register mask for ldm/stm
799 %E print the lsb and width fields of a bfc/bfi instruction
800 %F print the lsb and width fields of a sbfx/ubfx instruction
801 %b print a conditional branch offset
802 %B print an unconditional branch offset
803 %s print the shift field of an SSAT instruction
804 %R print the rotation field of an SXT instruction
806 %<bitfield>d print bitfield in decimal
807 %<bitfield>W print bitfield*4 in decimal
808 %<bitfield>r print bitfield as an ARM register
809 %<bitfield>c print bitfield as a condition code
811 %<bitnum>'c print "c" iff bit is one
812 %<bitnum>`c print "c" iff bit is zero
813 %<bitnum>?ab print "a" if bit is one, else "b"
815 With one exception at the bottom (done because BL and BLX(1) need
816 to come dead last), this table was machine-sorted first in
817 decreasing order of number of bits set in the mask, then in
818 increasing numeric order of mask, then in increasing numeric order
819 of opcode. This order is not the clearest for a human reader, but
820 is guaranteed never to catch a special-case bit pattern with a more
821 general mask, which is important, because this instruction encoding
822 makes heavy use of special-case bit patterns. */
823 static const struct opcode32 thumb32_opcodes[] =
825 /* Instructions defined in the basic V6T2 set. */
826 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
827 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
828 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
829 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
830 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
831 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
833 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
834 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
835 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
836 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
837 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
838 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
839 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff0ff, "mrs\t%8-11r, %20?CSPSR"},
840 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
841 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
842 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
843 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
844 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
845 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
846 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f0ff, "msr\t%20?CSPSR_%8'c%9'x%10's%11'f, %16-19r"},
847 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
848 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
849 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
850 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
851 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"},
852 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"},
853 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"},
854 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
855 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
856 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
857 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
858 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
859 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
860 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
861 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"},
862 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"},
863 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"},
864 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"},
865 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"},
866 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"},
867 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"},
868 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"},
869 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"},
870 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"},
871 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"},
872 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"},
873 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"},
874 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"},
875 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"},
876 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"},
877 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"},
878 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"},
879 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"},
880 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"},
881 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"},
882 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"},
883 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"},
884 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"},
885 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"},
886 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"},
887 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"},
888 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"},
889 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"},
890 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"},
891 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"},
892 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"},
893 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"},
894 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"},
895 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"},
896 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"},
897 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"},
898 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"},
899 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"},
900 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"},
901 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"},
902 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"},
903 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"},
904 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"},
905 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"},
906 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"},
907 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"},
908 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"},
909 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"},
910 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"},
911 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
912 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
913 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
914 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
915 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
916 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
917 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
918 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
919 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
920 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
921 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"},
922 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"},
923 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"},
924 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"},
925 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
926 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
927 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
928 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
929 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
930 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
931 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
932 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
933 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
934 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
935 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
936 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
937 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"},
938 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"},
939 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"},
940 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"},
941 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"},
942 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
943 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
944 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
945 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
946 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smi\t%K"},
947 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
948 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
949 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
950 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
951 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
952 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
953 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
954 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
955 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
956 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
957 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
958 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
959 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
960 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
961 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
962 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
963 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
964 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"},
965 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"},
966 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"},
967 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"},
968 {ARM_EXT_V6T2, 0xee000010, 0xef1000f0, "mcr%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d"},
969 {ARM_EXT_V6T2, 0xee100010, 0xef1000f0, "mrc%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d"},
970 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"},
971 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"},
972 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"},
973 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"},
974 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"},
975 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"},
976 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"},
977 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"},
978 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"},
979 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
980 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
981 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
982 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
983 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
984 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
985 {ARM_EXT_V6T2, 0xee000000, 0xef0000f0, "cdp%28'2\tp%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d"},
986 {ARM_EXT_V6T2, 0xec400000, 0xeff00000, "mcrr%28'2\tp%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
987 {ARM_EXT_V6T2, 0xec500000, 0xeff00000, "mrrc%28'2\tp%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
988 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"},
989 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"},
990 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"},
991 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
992 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
993 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
994 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
995 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
996 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
997 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
998 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
999 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
1000 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
1001 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
1002 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
1003 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
1004 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1005 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1006 {ARM_EXT_V6T2, 0xee000010, 0xef100010, "mcr%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, %5-7d"},
1007 {ARM_EXT_V6T2, 0xee100010, 0xef100010, "mrc%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, %5-7d"},
1008 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
1009 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"},
1010 {ARM_EXT_V6T2, 0xec000000, 0xee100000, "stc%28'2%22'l\tp%8-11d, cr%12-15d, %A"},
1011 {ARM_EXT_V6T2, 0xec100000, 0xee100000, "ldc%28'2%22'l\tp%8-11d, cr%12-15d, %A"},
1012 {ARM_EXT_V6T2, 0xee000000, 0xef000010, "cdp%28'2\tp%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, %5-7d"},
1014 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1015 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1016 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1017 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
1018 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
1020 /* These have been 32-bit since the invention of Thumb. */
1021 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx\t%B"},
1022 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl\t%B"},
1024 /* Fallback. */
1025 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1026 {0, 0, 0, 0}
1029 static const char *const arm_conditional[] =
1030 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1031 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1033 static const char *const arm_fp_const[] =
1034 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1036 static const char *const arm_shift[] =
1037 {"lsl", "lsr", "asr", "ror"};
1039 typedef struct
1041 const char *name;
1042 const char *description;
1043 const char *reg_names[16];
1045 arm_regname;
1047 static const arm_regname regnames[] =
1049 { "raw" , "Select raw register names",
1050 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1051 { "gcc", "Select register names used by GCC",
1052 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1053 { "std", "Select register names used in ARM's ISA documentation",
1054 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1055 { "apcs", "Select register names used in the APCS",
1056 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1057 { "atpcs", "Select register names used in the ATPCS",
1058 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1059 { "special-atpcs", "Select special register names used in the ATPCS",
1060 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1063 static const char *const iwmmxt_wwnames[] =
1064 {"b", "h", "w", "d"};
1066 static const char *const iwmmxt_wwssnames[] =
1067 {"b", "bus", "b", "bss",
1068 "h", "hus", "h", "hss",
1069 "w", "wus", "w", "wss",
1070 "d", "dus", "d", "dss"
1073 static const char *const iwmmxt_regnames[] =
1074 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1075 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1078 static const char *const iwmmxt_cregnames[] =
1079 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1080 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1083 /* Default to GCC register name set. */
1084 static unsigned int regname_selected = 1;
1086 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1087 #define arm_regnames regnames[regname_selected].reg_names
1089 static bfd_boolean force_thumb = FALSE;
1092 /* Functions. */
1094 get_arm_regname_num_options (void)
1096 return NUM_ARM_REGNAMES;
1100 set_arm_regname_option (int option)
1102 int old = regname_selected;
1103 regname_selected = option;
1104 return old;
1108 get_arm_regnames (int option, const char **setname, const char **setdescription,
1109 const char *const **register_names)
1111 *setname = regnames[option].name;
1112 *setdescription = regnames[option].description;
1113 *register_names = regnames[option].reg_names;
1114 return 16;
1117 static void
1118 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1120 func (stream, "%s", arm_regnames[given & 0xf]);
1122 if ((given & 0xff0) != 0)
1124 if ((given & 0x10) == 0)
1126 int amount = (given & 0xf80) >> 7;
1127 int shift = (given & 0x60) >> 5;
1129 if (amount == 0)
1131 if (shift == 3)
1133 func (stream, ", rrx");
1134 return;
1137 amount = 32;
1140 func (stream, ", %s #%d", arm_shift[shift], amount);
1142 else
1143 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1144 arm_regnames[(given & 0xf00) >> 8]);
1148 /* Print one ARM instruction from PC on INFO->STREAM. */
1150 static void
1151 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
1153 const struct opcode32 *insn;
1154 void *stream = info->stream;
1155 fprintf_ftype func = info->fprintf_func;
1157 for (insn = arm_opcodes; insn->assembler; insn++)
1159 if (insn->value == FIRST_IWMMXT_INSN
1160 && info->mach != bfd_mach_arm_XScale
1161 && info->mach != bfd_mach_arm_iWMMXt)
1162 insn = insn + IWMMXT_INSN_COUNT;
1164 if ((given & insn->mask) == insn->value
1165 /* Special case: an instruction with all bits set in the condition field
1166 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
1167 or by the catchall at the end of the table. */
1168 && ((given & 0xF0000000) != 0xF0000000
1169 || (insn->mask & 0xF0000000) == 0xF0000000
1170 || (insn->mask == 0 && insn->value == 0)))
1172 const char *c;
1174 for (c = insn->assembler; *c; c++)
1176 if (*c == '%')
1178 switch (*++c)
1180 case '%':
1181 func (stream, "%%");
1182 break;
1184 case 'a':
1185 if (((given & 0x000f0000) == 0x000f0000)
1186 && ((given & 0x02000000) == 0))
1188 int offset = given & 0xfff;
1190 func (stream, "[pc");
1192 if (given & 0x01000000)
1194 if ((given & 0x00800000) == 0)
1195 offset = - offset;
1197 /* Pre-indexed. */
1198 func (stream, ", #%d]", offset);
1200 offset += pc + 8;
1202 /* Cope with the possibility of write-back
1203 being used. Probably a very dangerous thing
1204 for the programmer to do, but who are we to
1205 argue ? */
1206 if (given & 0x00200000)
1207 func (stream, "!");
1209 else
1211 /* Post indexed. */
1212 func (stream, "], #%d", offset);
1214 /* ie ignore the offset. */
1215 offset = pc + 8;
1218 func (stream, "\t; ");
1219 info->print_address_func (offset, info);
1221 else
1223 func (stream, "[%s",
1224 arm_regnames[(given >> 16) & 0xf]);
1225 if ((given & 0x01000000) != 0)
1227 if ((given & 0x02000000) == 0)
1229 int offset = given & 0xfff;
1230 if (offset)
1231 func (stream, ", #%s%d",
1232 (((given & 0x00800000) == 0)
1233 ? "-" : ""), offset);
1235 else
1237 func (stream, ", %s",
1238 (((given & 0x00800000) == 0)
1239 ? "-" : ""));
1240 arm_decode_shift (given, func, stream);
1243 func (stream, "]%s",
1244 ((given & 0x00200000) != 0) ? "!" : "");
1246 else
1248 if ((given & 0x02000000) == 0)
1250 int offset = given & 0xfff;
1251 if (offset)
1252 func (stream, "], #%s%d",
1253 (((given & 0x00800000) == 0)
1254 ? "-" : ""), offset);
1255 else
1256 func (stream, "]");
1258 else
1260 func (stream, "], %s",
1261 (((given & 0x00800000) == 0)
1262 ? "-" : ""));
1263 arm_decode_shift (given, func, stream);
1267 break;
1269 case 's':
1270 if ((given & 0x004f0000) == 0x004f0000)
1272 /* PC relative with immediate offset. */
1273 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1275 if ((given & 0x00800000) == 0)
1276 offset = -offset;
1278 func (stream, "[pc, #%d]\t; ", offset);
1279 info->print_address_func (offset + pc + 8, info);
1281 else
1283 func (stream, "[%s",
1284 arm_regnames[(given >> 16) & 0xf]);
1285 if ((given & 0x01000000) != 0)
1287 /* Pre-indexed. */
1288 if ((given & 0x00400000) == 0x00400000)
1290 /* Immediate. */
1291 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1292 if (offset)
1293 func (stream, ", #%s%d",
1294 (((given & 0x00800000) == 0)
1295 ? "-" : ""), offset);
1297 else
1299 /* Register. */
1300 func (stream, ", %s%s",
1301 (((given & 0x00800000) == 0)
1302 ? "-" : ""),
1303 arm_regnames[given & 0xf]);
1306 func (stream, "]%s",
1307 ((given & 0x00200000) != 0) ? "!" : "");
1309 else
1311 /* Post-indexed. */
1312 if ((given & 0x00400000) == 0x00400000)
1314 /* Immediate. */
1315 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1316 if (offset)
1317 func (stream, "], #%s%d",
1318 (((given & 0x00800000) == 0)
1319 ? "-" : ""), offset);
1320 else
1321 func (stream, "]");
1323 else
1325 /* Register. */
1326 func (stream, "], %s%s",
1327 (((given & 0x00800000) == 0)
1328 ? "-" : ""),
1329 arm_regnames[given & 0xf]);
1333 break;
1335 case 'b':
1337 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
1338 info->print_address_func (disp*4 + pc + 8, info);
1340 break;
1342 case 'c':
1343 func (stream, "%s",
1344 arm_conditional [(given >> 28) & 0xf]);
1345 break;
1347 case 'm':
1349 int started = 0;
1350 int reg;
1352 func (stream, "{");
1353 for (reg = 0; reg < 16; reg++)
1354 if ((given & (1 << reg)) != 0)
1356 if (started)
1357 func (stream, ", ");
1358 started = 1;
1359 func (stream, "%s", arm_regnames[reg]);
1361 func (stream, "}");
1363 break;
1365 case 'o':
1366 if ((given & 0x02000000) != 0)
1368 int rotate = (given & 0xf00) >> 7;
1369 int immed = (given & 0xff);
1370 immed = (((immed << (32 - rotate))
1371 | (immed >> rotate)) & 0xffffffff);
1372 func (stream, "#%d\t; 0x%x", immed, immed);
1374 else
1375 arm_decode_shift (given, func, stream);
1376 break;
1378 case 'p':
1379 if ((given & 0x0000f000) == 0x0000f000)
1380 func (stream, "p");
1381 break;
1383 case 't':
1384 if ((given & 0x01200000) == 0x00200000)
1385 func (stream, "t");
1386 break;
1388 case 'A':
1389 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1391 if ((given & (1 << 24)) != 0)
1393 int offset = given & 0xff;
1395 if (offset)
1396 func (stream, ", #%s%d]%s",
1397 ((given & 0x00800000) == 0 ? "-" : ""),
1398 offset * 4,
1399 ((given & 0x00200000) != 0 ? "!" : ""));
1400 else
1401 func (stream, "]");
1403 else
1405 int offset = given & 0xff;
1407 func (stream, "]");
1409 if (given & (1 << 21))
1411 if (offset)
1412 func (stream, ", #%s%d",
1413 ((given & 0x00800000) == 0 ? "-" : ""),
1414 offset * 4);
1416 else
1417 func (stream, ", {%d}", offset);
1419 break;
1421 case 'B':
1422 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1424 bfd_vma address;
1425 bfd_vma offset = 0;
1427 if (given & 0x00800000)
1428 /* Is signed, hi bits should be ones. */
1429 offset = (-1) ^ 0x00ffffff;
1431 /* Offset is (SignExtend(offset field)<<2). */
1432 offset += given & 0x00ffffff;
1433 offset <<= 2;
1434 address = offset + pc + 8;
1436 if (given & 0x01000000)
1437 /* H bit allows addressing to 2-byte boundaries. */
1438 address += 2;
1440 info->print_address_func (address, info);
1442 break;
1444 case 'I':
1445 /* Print a Cirrus/DSP shift immediate. */
1446 /* Immediates are 7bit signed ints with bits 0..3 in
1447 bits 0..3 of opcode and bits 4..6 in bits 5..7
1448 of opcode. */
1450 int imm;
1452 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1454 /* Is ``imm'' a negative number? */
1455 if (imm & 0x40)
1456 imm |= (-1 << 7);
1458 func (stream, "%d", imm);
1461 break;
1463 case 'C':
1464 func (stream, "_");
1465 if (given & 0x80000)
1466 func (stream, "f");
1467 if (given & 0x40000)
1468 func (stream, "s");
1469 if (given & 0x20000)
1470 func (stream, "x");
1471 if (given & 0x10000)
1472 func (stream, "c");
1473 break;
1475 case 'F':
1476 switch (given & 0x00408000)
1478 case 0:
1479 func (stream, "4");
1480 break;
1481 case 0x8000:
1482 func (stream, "1");
1483 break;
1484 case 0x00400000:
1485 func (stream, "2");
1486 break;
1487 default:
1488 func (stream, "3");
1490 break;
1492 case 'P':
1493 switch (given & 0x00080080)
1495 case 0:
1496 func (stream, "s");
1497 break;
1498 case 0x80:
1499 func (stream, "d");
1500 break;
1501 case 0x00080000:
1502 func (stream, "e");
1503 break;
1504 default:
1505 func (stream, _("<illegal precision>"));
1506 break;
1508 break;
1509 case 'Q':
1510 switch (given & 0x00408000)
1512 case 0:
1513 func (stream, "s");
1514 break;
1515 case 0x8000:
1516 func (stream, "d");
1517 break;
1518 case 0x00400000:
1519 func (stream, "e");
1520 break;
1521 default:
1522 func (stream, "p");
1523 break;
1525 break;
1526 case 'R':
1527 switch (given & 0x60)
1529 case 0:
1530 break;
1531 case 0x20:
1532 func (stream, "p");
1533 break;
1534 case 0x40:
1535 func (stream, "m");
1536 break;
1537 default:
1538 func (stream, "z");
1539 break;
1541 break;
1543 case '0': case '1': case '2': case '3': case '4':
1544 case '5': case '6': case '7': case '8': case '9':
1546 int bitstart = *c++ - '0';
1547 int bitend = 0;
1548 while (*c >= '0' && *c <= '9')
1549 bitstart = (bitstart * 10) + *c++ - '0';
1551 switch (*c)
1553 case '-':
1554 c++;
1556 while (*c >= '0' && *c <= '9')
1557 bitend = (bitend * 10) + *c++ - '0';
1559 if (!bitend)
1560 abort ();
1562 switch (*c)
1564 case 'r':
1566 long reg;
1568 reg = given >> bitstart;
1569 reg &= (2 << (bitend - bitstart)) - 1;
1571 func (stream, "%s", arm_regnames[reg]);
1573 break;
1574 case 'd':
1576 long reg;
1578 reg = given >> bitstart;
1579 reg &= (2 << (bitend - bitstart)) - 1;
1581 func (stream, "%ld", reg);
1583 break;
1584 case 'W':
1586 long reg;
1588 reg = given >> bitstart;
1589 reg &= (2 << (bitend - bitstart)) - 1;
1591 func (stream, "%ld", reg + 1);
1593 break;
1594 case 'x':
1596 long reg;
1598 reg = given >> bitstart;
1599 reg &= (2 << (bitend - bitstart)) - 1;
1601 func (stream, "0x%08lx", reg);
1603 /* Some SWI instructions have special
1604 meanings. */
1605 if ((given & 0x0fffffff) == 0x0FF00000)
1606 func (stream, "\t; IMB");
1607 else if ((given & 0x0fffffff) == 0x0FF00001)
1608 func (stream, "\t; IMBRange");
1610 break;
1611 case 'X':
1613 long reg;
1615 reg = given >> bitstart;
1616 reg &= (2 << (bitend - bitstart)) - 1;
1618 func (stream, "%01lx", reg & 0xf);
1620 break;
1621 case 'f':
1623 long reg;
1625 reg = given >> bitstart;
1626 reg &= (2 << (bitend - bitstart)) - 1;
1628 if (reg > 7)
1629 func (stream, "#%s",
1630 arm_fp_const[reg & 7]);
1631 else
1632 func (stream, "f%ld", reg);
1634 break;
1636 case 'w':
1638 long reg;
1640 if (bitstart != bitend)
1642 reg = given >> bitstart;
1643 reg &= (2 << (bitend - bitstart)) - 1;
1644 if (bitend - bitstart == 1)
1645 func (stream, "%s", iwmmxt_wwnames[reg]);
1646 else
1647 func (stream, "%s", iwmmxt_wwssnames[reg]);
1649 else
1651 reg = (((given >> 8) & 0x1) |
1652 ((given >> 22) & 0x1));
1653 func (stream, "%s", iwmmxt_wwnames[reg]);
1656 break;
1658 case 'g':
1660 long reg;
1661 reg = given >> bitstart;
1662 reg &= (2 << (bitend - bitstart)) - 1;
1663 func (stream, "%s", iwmmxt_regnames[reg]);
1665 break;
1667 case 'G':
1669 long reg;
1670 reg = given >> bitstart;
1671 reg &= (2 << (bitend - bitstart)) - 1;
1672 func (stream, "%s", iwmmxt_cregnames[reg]);
1674 break;
1676 default:
1677 abort ();
1679 break;
1681 case 'y':
1682 case 'z':
1684 int single = *c == 'y';
1685 int regno;
1687 switch (bitstart)
1689 case 4: /* Sm pair */
1690 func (stream, "{");
1691 /* Fall through. */
1692 case 0: /* Sm, Dm */
1693 regno = given & 0x0000000f;
1694 if (single)
1696 regno <<= 1;
1697 regno += (given >> 5) & 1;
1699 break;
1701 case 1: /* Sd, Dd */
1702 regno = (given >> 12) & 0x0000000f;
1703 if (single)
1705 regno <<= 1;
1706 regno += (given >> 22) & 1;
1708 break;
1710 case 2: /* Sn, Dn */
1711 regno = (given >> 16) & 0x0000000f;
1712 if (single)
1714 regno <<= 1;
1715 regno += (given >> 7) & 1;
1717 break;
1719 case 3: /* List */
1720 func (stream, "{");
1721 regno = (given >> 12) & 0x0000000f;
1722 if (single)
1724 regno <<= 1;
1725 regno += (given >> 22) & 1;
1727 break;
1730 default:
1731 abort ();
1734 func (stream, "%c%d", single ? 's' : 'd', regno);
1736 if (bitstart == 3)
1738 int count = given & 0xff;
1740 if (single == 0)
1741 count >>= 1;
1743 if (--count)
1745 func (stream, "-%c%d",
1746 single ? 's' : 'd',
1747 regno + count);
1750 func (stream, "}");
1752 else if (bitstart == 4)
1753 func (stream, ", %c%d}", single ? 's' : 'd',
1754 regno + 1);
1756 break;
1759 case '`':
1760 c++;
1761 if ((given & (1 << bitstart)) == 0)
1762 func (stream, "%c", *c);
1763 break;
1764 case '\'':
1765 c++;
1766 if ((given & (1 << bitstart)) != 0)
1767 func (stream, "%c", *c);
1768 break;
1769 case '?':
1770 ++c;
1771 if ((given & (1 << bitstart)) != 0)
1772 func (stream, "%c", *c++);
1773 else
1774 func (stream, "%c", *++c);
1775 break;
1776 default:
1777 abort ();
1779 break;
1781 case 'L':
1782 switch (given & 0x00400100)
1784 case 0x00000000: func (stream, "b"); break;
1785 case 0x00400000: func (stream, "h"); break;
1786 case 0x00000100: func (stream, "w"); break;
1787 case 0x00400100: func (stream, "d"); break;
1788 default:
1789 break;
1791 break;
1793 case 'Z':
1795 int value;
1796 /* given (20, 23) | given (0, 3) */
1797 value = ((given >> 16) & 0xf0) | (given & 0xf);
1798 func (stream, "%d", value);
1800 break;
1802 case 'l':
1803 /* This is like the 'A' operator, except that if
1804 the width field "M" is zero, then the offset is
1805 *not* multiplied by four. */
1807 int offset = given & 0xff;
1808 int multiplier = (given & 0x00000100) ? 4 : 1;
1810 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1812 if (offset)
1814 if ((given & 0x01000000) != 0)
1815 func (stream, ", #%s%d]%s",
1816 ((given & 0x00800000) == 0 ? "-" : ""),
1817 offset * multiplier,
1818 ((given & 0x00200000) != 0 ? "!" : ""));
1819 else
1820 func (stream, "], #%s%d",
1821 ((given & 0x00800000) == 0 ? "-" : ""),
1822 offset * multiplier);
1824 else
1825 func (stream, "]");
1827 break;
1829 case 'e':
1831 int imm;
1833 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1834 func (stream, "%d", imm);
1836 break;
1838 case 'E':
1839 /* LSB and WIDTH fields of BFI or BFC. The machine-
1840 language instruction encodes LSB and MSB. */
1842 long msb = (given & 0x001f0000) >> 16;
1843 long lsb = (given & 0x00000f80) >> 7;
1845 long width = msb - lsb + 1;
1846 if (width > 0)
1847 func (stream, "#%lu, #%lu", lsb, width);
1848 else
1849 func (stream, "(invalid: %lu:%lu)", lsb, msb);
1851 break;
1853 case 'V':
1854 /* 16-bit unsigned immediate from a MOVT or MOVW
1855 instruction, encoded in bits 0:11 and 15:19. */
1857 long hi = (given & 0x000f0000) >> 4;
1858 long lo = (given & 0x00000fff);
1859 long imm16 = hi | lo;
1860 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
1862 break;
1864 default:
1865 abort ();
1869 else
1870 func (stream, "%c", *c);
1872 return;
1875 abort ();
1878 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
1880 static void
1881 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
1883 const struct opcode16 *insn;
1884 void *stream = info->stream;
1885 fprintf_ftype func = info->fprintf_func;
1887 for (insn = thumb_opcodes; insn->assembler; insn++)
1888 if ((given & insn->mask) == insn->value)
1890 const char *c = insn->assembler;
1891 for (; *c; c++)
1893 int domaskpc = 0;
1894 int domasklr = 0;
1896 if (*c != '%')
1898 func (stream, "%c", *c);
1899 continue;
1902 switch (*++c)
1904 case '%':
1905 func (stream, "%%");
1906 break;
1908 case 'S':
1910 long reg;
1912 reg = (given >> 3) & 0x7;
1913 if (given & (1 << 6))
1914 reg += 8;
1916 func (stream, "%s", arm_regnames[reg]);
1918 break;
1920 case 'D':
1922 long reg;
1924 reg = given & 0x7;
1925 if (given & (1 << 7))
1926 reg += 8;
1928 func (stream, "%s", arm_regnames[reg]);
1930 break;
1932 case 'N':
1933 if (given & (1 << 8))
1934 domasklr = 1;
1935 /* Fall through. */
1936 case 'O':
1937 if (*c == 'O' && (given & (1 << 8)))
1938 domaskpc = 1;
1939 /* Fall through. */
1940 case 'M':
1942 int started = 0;
1943 int reg;
1945 func (stream, "{");
1947 /* It would be nice if we could spot
1948 ranges, and generate the rS-rE format: */
1949 for (reg = 0; (reg < 8); reg++)
1950 if ((given & (1 << reg)) != 0)
1952 if (started)
1953 func (stream, ", ");
1954 started = 1;
1955 func (stream, "%s", arm_regnames[reg]);
1958 if (domasklr)
1960 if (started)
1961 func (stream, ", ");
1962 started = 1;
1963 func (stream, arm_regnames[14] /* "lr" */);
1966 if (domaskpc)
1968 if (started)
1969 func (stream, ", ");
1970 func (stream, arm_regnames[15] /* "pc" */);
1973 func (stream, "}");
1975 break;
1977 case 'b':
1978 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
1980 bfd_vma address = (pc + 4
1981 + ((given & 0x00f8) >> 2)
1982 + ((given & 0x0200) >> 3));
1983 info->print_address_func (address, info);
1985 break;
1987 case 's':
1988 /* Right shift immediate -- bits 6..10; 1-31 print
1989 as themselves, 0 prints as 32. */
1991 long imm = (given & 0x07c0) >> 6;
1992 if (imm == 0)
1993 imm = 32;
1994 func (stream, "#%ld", imm);
1996 break;
1998 case '0': case '1': case '2': case '3': case '4':
1999 case '5': case '6': case '7': case '8': case '9':
2001 int bitstart = *c++ - '0';
2002 int bitend = 0;
2004 while (*c >= '0' && *c <= '9')
2005 bitstart = (bitstart * 10) + *c++ - '0';
2007 switch (*c)
2009 case '-':
2011 long reg;
2013 c++;
2014 while (*c >= '0' && *c <= '9')
2015 bitend = (bitend * 10) + *c++ - '0';
2016 if (!bitend)
2017 abort ();
2018 reg = given >> bitstart;
2019 reg &= (2 << (bitend - bitstart)) - 1;
2020 switch (*c)
2022 case 'r':
2023 func (stream, "%s", arm_regnames[reg]);
2024 break;
2026 case 'd':
2027 func (stream, "%ld", reg);
2028 break;
2030 case 'H':
2031 func (stream, "%ld", reg << 1);
2032 break;
2034 case 'W':
2035 func (stream, "%ld", reg << 2);
2036 break;
2038 case 'a':
2039 /* PC-relative address -- the bottom two
2040 bits of the address are dropped
2041 before the calculation. */
2042 info->print_address_func
2043 (((pc + 4) & ~3) + (reg << 2), info);
2044 break;
2046 case 'x':
2047 func (stream, "0x%04lx", reg);
2048 break;
2050 case 'B':
2051 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2052 info->print_address_func (reg * 2 + pc + 4, info);
2053 break;
2055 case 'c':
2057 /* Must print 0xE as 'al' to distinguish
2058 unconditional B from conditional BAL. */
2059 if (reg == 0xE)
2060 func (stream, "al");
2061 else
2062 func (stream, "%s", arm_conditional [reg]);
2064 break;
2066 default:
2067 abort ();
2070 break;
2072 case '\'':
2073 c++;
2074 if ((given & (1 << bitstart)) != 0)
2075 func (stream, "%c", *c);
2076 break;
2078 case '?':
2079 ++c;
2080 if ((given & (1 << bitstart)) != 0)
2081 func (stream, "%c", *c++);
2082 else
2083 func (stream, "%c", *++c);
2084 break;
2086 default:
2087 abort ();
2090 break;
2092 default:
2093 abort ();
2096 return;
2099 /* No match. */
2100 abort ();
2103 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
2105 static void
2106 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
2108 const struct opcode32 *insn;
2109 void *stream = info->stream;
2110 fprintf_ftype func = info->fprintf_func;
2112 for (insn = thumb32_opcodes; insn->assembler; insn++)
2113 if ((given & insn->mask) == insn->value)
2115 const char *c = insn->assembler;
2116 for (; *c; c++)
2118 if (*c != '%')
2120 func (stream, "%c", *c);
2121 continue;
2124 switch (*++c)
2126 case '%':
2127 func (stream, "%%");
2128 break;
2130 case 'I':
2132 unsigned int imm12 = 0;
2133 imm12 |= (given & 0x000000ffu);
2134 imm12 |= (given & 0x00007000u) >> 4;
2135 imm12 |= (given & 0x04000000u) >> 15;
2136 func (stream, "#%u\t; 0x%x", imm12, imm12);
2138 break;
2140 case 'M':
2142 unsigned int bits = 0, imm, imm8, mod;
2143 bits |= (given & 0x000000ffu);
2144 bits |= (given & 0x00007000u) >> 4;
2145 bits |= (given & 0x04000000u) >> 15;
2146 imm8 = (bits & 0x0ff);
2147 mod = (bits & 0xf00) >> 8;
2148 switch (mod)
2150 case 0: imm = imm8; break;
2151 case 1: imm = ((imm8<<16) | imm8); break;
2152 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
2153 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
2154 default:
2155 mod = (bits & 0xf80) >> 7;
2156 imm8 = (bits & 0x07f) | 0x80;
2157 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
2159 func (stream, "#%u\t; 0x%x", imm, imm);
2161 break;
2163 case 'J':
2165 unsigned int imm = 0;
2166 imm |= (given & 0x000000ffu);
2167 imm |= (given & 0x00007000u) >> 4;
2168 imm |= (given & 0x04000000u) >> 15;
2169 imm |= (given & 0x000f0000u) >> 4;
2170 func (stream, "#%u\t; 0x%x", imm, imm);
2172 break;
2174 case 'K':
2176 unsigned int imm = 0;
2177 imm |= (given & 0x000f0000u) >> 16;
2178 imm |= (given & 0x00000ff0u) >> 0;
2179 imm |= (given & 0x0000000fu) << 12;
2180 func (stream, "#%u\t; 0x%x", imm, imm);
2182 break;
2184 case 'S':
2186 unsigned int reg = (given & 0x0000000fu);
2187 unsigned int stp = (given & 0x00000030u) >> 4;
2188 unsigned int imm = 0;
2189 imm |= (given & 0x000000c0u) >> 6;
2190 imm |= (given & 0x00007000u) >> 10;
2192 func (stream, "%s", arm_regnames[reg]);
2193 switch (stp)
2195 case 0:
2196 if (imm > 0)
2197 func (stream, ", lsl #%u", imm);
2198 break;
2200 case 1:
2201 if (imm == 0)
2202 imm = 32;
2203 func (stream, ", lsr #%u", imm);
2204 break;
2206 case 2:
2207 if (imm == 0)
2208 imm = 32;
2209 func (stream, ", asr #%u", imm);
2210 break;
2212 case 3:
2213 if (imm == 0)
2214 func (stream, ", rrx");
2215 else
2216 func (stream, ", ror #%u", imm);
2219 break;
2221 case 'a':
2223 unsigned int Rn = (given & 0x000f0000) >> 16;
2224 unsigned int U = (given & 0x00800000) >> 23;
2225 unsigned int op = (given & 0x00000f00) >> 8;
2226 unsigned int i12 = (given & 0x00000fff);
2227 unsigned int i8 = (given & 0x000000ff);
2228 bfd_boolean writeback = FALSE, postind = FALSE;
2229 int offset = 0;
2231 func (stream, "[%s", arm_regnames[Rn]);
2232 if (U) /* 12-bit positive immediate offset */
2233 offset = i12;
2234 else if (Rn == 15) /* 12-bit negative immediate offset */
2235 offset = -(int)i12;
2236 else if (op == 0x0) /* shifted register offset */
2238 unsigned int Rm = (i8 & 0x0f);
2239 unsigned int sh = (i8 & 0x30) >> 4;
2240 func (stream, ", %s", arm_regnames[Rm]);
2241 if (sh)
2242 func (stream, ", lsl #%u", sh);
2243 func (stream, "]");
2244 break;
2246 else switch (op)
2248 case 0xE: /* 8-bit positive immediate offset */
2249 offset = i8;
2250 break;
2252 case 0xC: /* 8-bit negative immediate offset */
2253 offset = -i8;
2254 break;
2256 case 0xF: /* 8-bit + preindex with wb */
2257 offset = i8;
2258 writeback = TRUE;
2259 break;
2261 case 0xD: /* 8-bit - preindex with wb */
2262 offset = -i8;
2263 writeback = TRUE;
2264 break;
2266 case 0xB: /* 8-bit + postindex */
2267 offset = i8;
2268 postind = TRUE;
2269 break;
2271 case 0x9: /* 8-bit - postindex */
2272 offset = -i8;
2273 postind = TRUE;
2274 break;
2276 default:
2277 func (stream, ", <undefined>]");
2278 goto skip;
2281 if (postind)
2282 func (stream, "], #%d", offset);
2283 else
2285 if (offset)
2286 func (stream, ", #%d", offset);
2287 func (stream, writeback ? "]!" : "]");
2290 if (Rn == 15)
2292 func (stream, "\t; ");
2293 info->print_address_func (((pc + 4) & ~3) + offset, info);
2296 skip:
2297 break;
2299 case 'A':
2301 unsigned int P = (given & 0x01000000) >> 24;
2302 unsigned int U = (given & 0x00800000) >> 23;
2303 unsigned int W = (given & 0x00400000) >> 21;
2304 unsigned int Rn = (given & 0x000f0000) >> 16;
2305 unsigned int off = (given & 0x000000ff);
2307 func (stream, "[%s", arm_regnames[Rn]);
2308 if (P)
2310 if (off || !U)
2311 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2312 func (stream, "]");
2313 if (W)
2314 func (stream, "!");
2316 else
2318 func (stream, "], ");
2319 if (W)
2320 func (stream, "#%c%u", U ? '+' : '-', off * 4);
2321 else
2322 func (stream, "{%u}", off);
2325 break;
2327 case 'w':
2329 unsigned int Sbit = (given & 0x01000000) >> 24;
2330 unsigned int type = (given & 0x00600000) >> 21;
2331 switch (type)
2333 case 0: func (stream, Sbit ? "sb" : "b"); break;
2334 case 1: func (stream, Sbit ? "sh" : "h"); break;
2335 case 2:
2336 if (Sbit)
2337 func (stream, "??");
2338 break;
2339 case 3:
2340 func (stream, "??");
2341 break;
2344 break;
2346 case 'm':
2348 int started = 0;
2349 int reg;
2351 func (stream, "{");
2352 for (reg = 0; reg < 16; reg++)
2353 if ((given & (1 << reg)) != 0)
2355 if (started)
2356 func (stream, ", ");
2357 started = 1;
2358 func (stream, "%s", arm_regnames[reg]);
2360 func (stream, "}");
2362 break;
2364 case 'E':
2366 unsigned int msb = (given & 0x0000001f);
2367 unsigned int lsb = 0;
2368 lsb |= (given & 0x000000c0u) >> 6;
2369 lsb |= (given & 0x00007000u) >> 10;
2370 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
2372 break;
2374 case 'F':
2376 unsigned int width = (given & 0x0000001f) + 1;
2377 unsigned int lsb = 0;
2378 lsb |= (given & 0x000000c0u) >> 6;
2379 lsb |= (given & 0x00007000u) >> 10;
2380 func (stream, "#%u, #%u", lsb, width);
2382 break;
2384 case 'b':
2386 unsigned int S = (given & 0x04000000u) >> 26;
2387 unsigned int J1 = (given & 0x00002000u) >> 13;
2388 unsigned int J2 = (given & 0x00000800u) >> 11;
2389 int offset = 0;
2391 offset |= !S << 20;
2392 offset |= J2 << 19;
2393 offset |= J1 << 18;
2394 offset |= (given & 0x003f0000) >> 4;
2395 offset |= (given & 0x000007ff) << 1;
2396 offset -= (1 << 20);
2398 info->print_address_func (pc + 4 + offset, info);
2400 break;
2402 case 'B':
2404 unsigned int S = (given & 0x04000000u) >> 26;
2405 unsigned int I1 = (given & 0x00002000u) >> 13;
2406 unsigned int I2 = (given & 0x00000800u) >> 11;
2407 int offset = 0;
2409 offset |= !S << 24;
2410 offset |= !(I1 ^ S) << 23;
2411 offset |= !(I2 ^ S) << 22;
2412 offset |= (given & 0x03ff0000u) >> 4;
2413 offset |= (given & 0x000007ffu) << 1;
2414 offset -= (1 << 24);
2416 info->print_address_func (pc + 4 + offset, info);
2418 break;
2420 case 's':
2422 unsigned int shift = 0;
2423 shift |= (given & 0x000000c0u) >> 6;
2424 shift |= (given & 0x00007000u) >> 10;
2425 if (given & 0x00200000u)
2426 func (stream, ", asr #%u", shift);
2427 else if (shift)
2428 func (stream, ", lsl #%u", shift);
2429 /* else print nothing - lsl #0 */
2431 break;
2433 case 'R':
2435 unsigned int rot = (given & 0x00000030) >> 4;
2436 if (rot)
2437 func (stream, ", ror #%u", rot * 8);
2439 break;
2441 case '0': case '1': case '2': case '3': case '4':
2442 case '5': case '6': case '7': case '8': case '9':
2444 int bitstart = *c++ - '0';
2445 int bitend = 0;
2446 unsigned int val;
2447 while (*c >= '0' && *c <= '9')
2448 bitstart = (bitstart * 10) + *c++ - '0';
2450 if (*c == '-')
2452 c++;
2453 while (*c >= '0' && *c <= '9')
2454 bitend = (bitend * 10) + *c++ - '0';
2455 if (!bitend)
2456 abort ();
2458 val = given >> bitstart;
2459 val &= (2 << (bitend - bitstart)) - 1;
2461 else
2462 val = (given >> bitstart) & 1;
2464 switch (*c)
2466 case 'd': func (stream, "%u", val); break;
2467 case 'W': func (stream, "%u", val * 4); break;
2468 case 'r': func (stream, "%s", arm_regnames[val]); break;
2470 case 'c':
2471 if (val == 0xE)
2472 func (stream, "al");
2473 else
2474 func (stream, "%s", arm_conditional[val]);
2475 break;
2477 case '\'':
2478 if (val)
2479 func (stream, "%c", c[1]);
2480 c++;
2481 break;
2483 case '`':
2484 if (!val)
2485 func (stream, "%c", c[1]);
2486 c++;
2487 break;
2489 case '?':
2490 func (stream, "%c", val ? c[1] : c[2]);
2491 c += 2;
2492 break;
2494 default:
2495 abort ();
2498 break;
2500 default:
2501 abort ();
2504 return;
2507 /* No match. */
2508 abort ();
2511 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2512 being displayed in symbol relative addresses. */
2514 bfd_boolean
2515 arm_symbol_is_valid (asymbol * sym,
2516 struct disassemble_info * info ATTRIBUTE_UNUSED)
2518 const char * name;
2520 if (sym == NULL)
2521 return FALSE;
2523 name = bfd_asymbol_name (sym);
2525 return (name && *name != '$');
2528 /* Parse an individual disassembler option. */
2530 void
2531 parse_arm_disassembler_option (char *option)
2533 if (option == NULL)
2534 return;
2536 if (strneq (option, "reg-names-", 10))
2538 int i;
2540 option += 10;
2542 for (i = NUM_ARM_REGNAMES; i--;)
2543 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2545 regname_selected = i;
2546 break;
2549 if (i < 0)
2550 /* XXX - should break 'option' at following delimiter. */
2551 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2553 else if (strneq (option, "force-thumb", 11))
2554 force_thumb = 1;
2555 else if (strneq (option, "no-force-thumb", 14))
2556 force_thumb = 0;
2557 else
2558 /* XXX - should break 'option' at following delimiter. */
2559 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2561 return;
2564 /* Parse the string of disassembler options, spliting it at whitespaces
2565 or commas. (Whitespace separators supported for backwards compatibility). */
2567 static void
2568 parse_disassembler_options (char *options)
2570 if (options == NULL)
2571 return;
2573 while (*options)
2575 parse_arm_disassembler_option (options);
2577 /* Skip forward to next seperator. */
2578 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2579 ++ options;
2580 /* Skip forward past seperators. */
2581 while (ISSPACE (*options) || (*options == ','))
2582 ++ options;
2586 /* NOTE: There are no checks in these routines that
2587 the relevant number of data bytes exist. */
2589 static int
2590 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
2592 unsigned char b[4];
2593 long given;
2594 int status;
2595 int is_thumb;
2596 int size;
2597 void (*printer) (bfd_vma, struct disassemble_info *, long);
2599 if (info->disassembler_options)
2601 parse_disassembler_options (info->disassembler_options);
2603 /* To avoid repeated parsing of these options, we remove them here. */
2604 info->disassembler_options = NULL;
2607 is_thumb = force_thumb;
2609 if (!is_thumb && info->symbols != NULL)
2611 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2613 coff_symbol_type * cs;
2615 cs = coffsymbol (*info->symbols);
2616 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
2617 || cs->native->u.syment.n_sclass == C_THUMBSTAT
2618 || cs->native->u.syment.n_sclass == C_THUMBLABEL
2619 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2620 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2622 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2624 elf_symbol_type * es;
2625 unsigned int type;
2627 es = *(elf_symbol_type **)(info->symbols);
2628 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2630 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2634 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2635 info->bytes_per_line = 4;
2637 if (!is_thumb)
2639 /* In ARM mode endianness is a straightforward issue: the instruction
2640 is four bytes long and is either ordered 0123 or 3210. */
2641 printer = print_insn_arm;
2642 info->bytes_per_chunk = 4;
2643 size = 4;
2645 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2646 if (little)
2647 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2648 else
2649 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2651 else
2653 /* In Thumb mode we have the additional wrinkle of two
2654 instruction lengths. Fortunately, the bits that determine
2655 the length of the current instruction are always to be found
2656 in the first two bytes. */
2657 printer = print_insn_thumb16;
2658 info->bytes_per_chunk = 2;
2659 size = 2;
2661 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2662 if (!status)
2664 if (little)
2665 given = (b[0]) | (b[1] << 8);
2666 else
2667 given = (b[1]) | (b[0] << 8);
2669 /* These bit patterns signal a four-byte Thumb
2670 instruction. */
2671 if ((given & 0xF800) == 0xF800
2672 || (given & 0xF800) == 0xF000
2673 || (given & 0xF800) == 0xE800)
2675 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2676 if (little)
2677 given = (b[0]) | (b[1] << 8) | (given << 16);
2678 else
2679 given = (b[1]) | (b[0] << 8) | (given << 16);
2681 printer = print_insn_thumb32;
2682 size = 4;
2687 if (status)
2689 info->memory_error_func (status, pc, info);
2690 return -1;
2692 if (info->flags & INSN_HAS_RELOC)
2693 /* If the instruction has a reloc associated with it, then
2694 the offset field in the instruction will actually be the
2695 addend for the reloc. (We are using REL type relocs).
2696 In such cases, we can ignore the pc when computing
2697 addresses, since the addend is not currently pc-relative. */
2698 pc = 0;
2700 printer (pc, info, given);
2701 return size;
2705 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
2707 return print_insn (pc, info, FALSE);
2711 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
2713 return print_insn (pc, info, TRUE);
2716 void
2717 print_arm_disassembler_options (FILE *stream)
2719 int i;
2721 fprintf (stream, _("\n\
2722 The following ARM specific disassembler options are supported for use with\n\
2723 the -M switch:\n"));
2725 for (i = NUM_ARM_REGNAMES; i--;)
2726 fprintf (stream, " reg-names-%s %*c%s\n",
2727 regnames[i].name,
2728 (int)(14 - strlen (regnames[i].name)), ' ',
2729 regnames[i].description);
2731 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
2732 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");