Move doc/ entries into doc/ChangeLog.
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
CommitLineData
252b5132 1/* Instruction printing code for the ARM
0dd132b6 2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
060d22b0 3 Free Software Foundation, Inc.
252b5132
RH
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
6
e16bb312 7 This file is part of libopcodes.
252b5132 8
e16bb312
NC
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.
252b5132 13
e16bb312
NC
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.
252b5132 18
e16bb312
NC
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
252b5132 22
cb6a5892 23#include "sysdep.h"
2fbad815 24
252b5132 25#include "dis-asm.h"
2fbad815 26#include "opcode/arm.h"
252b5132
RH
27#include "arm-opc.h"
28#include "coff/internal.h"
29#include "libcoff.h"
30#include "opintl.h"
31e0f3cd 31#include "safe-ctype.h"
252b5132 32
baf0cc5e 33/* FIXME: This shouldn't be done here. */
252b5132
RH
34#include "elf-bfd.h"
35#include "elf/internal.h"
36#include "elf/arm.h"
37
01c7f630 38#ifndef streq
58efb6c0 39#define streq(a,b) (strcmp ((a), (b)) == 0)
01c7f630 40#endif
58efb6c0 41
01c7f630 42#ifndef strneq
58efb6c0
NC
43#define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
44#endif
45
46#ifndef NUM_ELEM
47#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
01c7f630
NC
48#endif
49
b7693d02
DJ
50#define WORD_ADDRESS(pc) ((pc) & ~0x3)
51
6255809c 52/* Format of the disassembler control string :
2fbad815
RE
53
54 %% %
55 %<bitfield>d print the bitfield in decimal
56 %<bitfield>x print the bitfield in hex
57 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
58 %<bitfield>W print the bitfield plus one in decimal
59 %<bitfield>r print as an ARM register
60 %<bitfield>f print a floating point constant if >7 else a
61 floating point register
62 %<code>y print a single precision VFP reg.
63 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
64 %<code>z print a double precision VFP reg
65 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
66 %c print condition code (always bits 28-31)
67 %P print floating point precision in arithmetic insn
68 %Q print floating point precision in ldf/stf insn
69 %R print floating point rounding mode
70 %<bitnum>'c print specified char iff bit is one
71 %<bitnum>`c print specified char iff bit is zero
72 %<bitnum>?ab print a if bit is one else print b
73 %p print 'p' iff bits 12-15 are 15
74 %t print 't' iff bit 21 set and bit 24 clear
75 %o print operand2 (immediate or register + shift)
76 %a print address for ldr/str instruction
77 %s print address for ldr/str halfword/signextend instruction
78 %b print branch destination
79 %B print arm BLX(1) destination
80 %A print address for ldc/stc/ldf/stf instruction
81 %m print register mask for ldm/stm instruction
82 %C print the PSR sub type.
83 %F print the COUNT field of a LFM/SFM instruction.
0a003adc
ZW
84 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
85 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
2fbad815
RE
86IWMMXT specific format options:
87 %<bitfield>g print as an iWMMXt 64-bit register
88 %<bitfield>G print as an iWMMXt general purpose or control register
89 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
90 %Z print the Immediate of a WSHUFH instruction.
91 %L print as an iWMMXt N/M width field.
92 %l like 'A' except use byte offsets for 'B' & 'H' versions
93Thumb specific format options:
94 %D print Thumb register (bits 0..2 as high number if bit 7 set)
95 %S print Thumb register (bits 3..5 as high number if bit 6 set)
96 %<bitfield>I print bitfield as a signed decimal
97 (top bit of range being the sign bit)
98 %M print Thumb register mask
99 %N print Thumb register mask (with LR)
100 %O print Thumb register mask (with PC)
101 %T print Thumb condition code (always bits 8-11)
102 %I print cirrus signed shift immediate: bits 0..3|4..6
103 %<bitfield>B print Thumb branch destination (signed displacement)
104 %<bitfield>W print (bitfield * 4) as a decimal
105 %<bitfield>H print (bitfield * 2) as a decimal
106 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
107 %e print arm SMI operand (bits 0..7,8..19). */
108
109/* Note: There is a partial ordering in this table - it must be searched from
110 the top to obtain a correct match. */
111
112static const struct arm_opcode arm_opcodes[] =
113{
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"},
122
0a003adc
ZW
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"},
133
2fbad815
RE
134 /* ARM V6Z instructions. */
135 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
136
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]"},
145
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}"},
152
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"},
278
279 /* V5J instruction. */
280 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
281
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"},
288
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"},
341
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}"},
352
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"},
361
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"},
364
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"},
369
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"},
374
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"},
377
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"},
382
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"},
413
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"},
458
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, %1y"},
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"},
533
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"},
619
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"},
628
629 /* The rest. */
630 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
631 {0, 0x00000000, 0x00000000, 0}
632};
633
634static const struct thumb_opcode thumb_opcodes[] =
635{
636 /* Thumb instructions. */
637
885fc257
ZW
638 /* ARM V6K no-argument instructions. */
639 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
640 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
641 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
642 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
643 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
644
2fbad815
RE
645 /* ARM V6. */
646 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
647 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
648 {ARM_EXT_V6, 0x4600, 0xffc0, "cpy\t%0-2r, %3-5r"},
649 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
650 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
651 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
652 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
653 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
654 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
655 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
656 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
657
658 /* ARM V5 ISA extends Thumb. */
659 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
660 /* Note: this is BLX(2). BLX(1) is done in arm-dis.c/print_insn_thumb()
661 as an extension of the special processing there for Thumb BL.
662 BL and BLX(1) involve 2 successive 16-bit instructions, which must
663 always appear together in the correct order. So, the empty
664 string is put in this table, and the string interpreter takes <empty>
665 to mean it has a pair of BL-ish instructions. */
666 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
667 /* ARM V4T ISA (Thumb v1). */
668 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
669 /* Format 5 instructions do not update the PSR. */
670 {ARM_EXT_V4T, 0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
671 /* Format 4. */
672 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
673 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
674 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
675 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
676 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
677 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
678 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
679 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
680 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
681 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
682 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
683 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
684 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
685 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
686 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
687 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
688 /* format 13 */
689 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
690 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
691 /* format 5 */
692 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
693 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
694 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
695 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
696 /* format 14 */
697 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
698 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
699 /* format 2 */
700 {ARM_EXT_V4T, 0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
701 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
702 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
703 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
704 /* format 8 */
705 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
706 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
707 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
708 /* format 7 */
709 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
710 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
711 /* format 1 */
712 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
713 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
714 {ARM_EXT_V4T, 0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
715 /* format 3 */
716 {ARM_EXT_V4T, 0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
717 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
718 {ARM_EXT_V4T, 0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
719 {ARM_EXT_V4T, 0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
720 /* format 6 */
721 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
722 /* format 9 */
723 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
724 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
725 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
726 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
727 /* format 10 */
728 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
729 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
730 /* format 11 */
731 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
732 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
733 /* format 12 */
734 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
735 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
736 /* format 15 */
737 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!,%M"},
738 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
739 /* format 18 */
740 {ARM_EXT_V4T, 0xE000, 0xF800, "b\t%0-10B"},
741 {ARM_EXT_V4T, 0xE800, 0xF800, "undefined"},
742 /* format 19 */
743 {ARM_EXT_V4T, 0xF000, 0xF800, ""}, /* special processing required in disassembler */
744 {ARM_EXT_V4T, 0xF800, 0xF800, "second half of BL instruction %0-15x"},
745 /* format 16 */
746 {ARM_EXT_V4T, 0xD000, 0xFF00, "beq\t%0-7B"},
747 {ARM_EXT_V4T, 0xD100, 0xFF00, "bne\t%0-7B"},
748 {ARM_EXT_V4T, 0xD200, 0xFF00, "bcs\t%0-7B"},
749 {ARM_EXT_V4T, 0xD300, 0xFF00, "bcc\t%0-7B"},
750 {ARM_EXT_V4T, 0xD400, 0xFF00, "bmi\t%0-7B"},
751 {ARM_EXT_V4T, 0xD500, 0xFF00, "bpl\t%0-7B"},
752 {ARM_EXT_V4T, 0xD600, 0xFF00, "bvs\t%0-7B"},
753 {ARM_EXT_V4T, 0xD700, 0xFF00, "bvc\t%0-7B"},
754 {ARM_EXT_V4T, 0xD800, 0xFF00, "bhi\t%0-7B"},
755 {ARM_EXT_V4T, 0xD900, 0xFF00, "bls\t%0-7B"},
756 {ARM_EXT_V4T, 0xDA00, 0xFF00, "bge\t%0-7B"},
757 {ARM_EXT_V4T, 0xDB00, 0xFF00, "blt\t%0-7B"},
758 {ARM_EXT_V4T, 0xDC00, 0xFF00, "bgt\t%0-7B"},
759 {ARM_EXT_V4T, 0xDD00, 0xFF00, "ble\t%0-7B"},
760 /* format 17 */
761 {ARM_EXT_V4T, 0xDE00, 0xFF00, "bal\t%0-7B"},
762 {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
763 /* format 9 */
764 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
765 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
766 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
767 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
768 /* the rest */
769 {ARM_EXT_V1, 0x0000, 0x0000, "undefined instruction %0-15x"},
770 {0, 0x0000, 0x0000, 0}
771};
772
5876e06d 773static char * arm_conditional[] =
252b5132
RH
774{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
775 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
776
58efb6c0
NC
777typedef struct
778{
779 const char * name;
780 const char * description;
781 const char * reg_names[16];
782}
783arm_regname;
dd92f639 784
58efb6c0
NC
785static arm_regname regnames[] =
786{
787 { "raw" , "Select raw register names",
788 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
7c03c75e
SB
789 { "gcc", "Select register names used by GCC",
790 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
58efb6c0
NC
791 { "std", "Select register names used in ARM's ISA documentation",
792 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
793 { "apcs", "Select register names used in the APCS",
794 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
795 { "atpcs", "Select register names used in the ATPCS",
796 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
a7f8487e 797 { "special-atpcs", "Select special register names used in the ATPCS",
e16bb312 798 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
5a6c6817 799 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
e16bb312 800 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
5a6c6817 801 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
e16bb312
NC
802 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
803};
804
805static char * iwmmxt_wwnames[] =
806{"b", "h", "w", "d"};
807
808static char * iwmmxt_wwssnames[] =
809{"b", "bus", "b", "bss",
810 "h", "hus", "h", "hss",
811 "w", "wus", "w", "wss",
812 "d", "dus", "d", "dss"
58efb6c0
NC
813};
814
7c03c75e 815/* Default to GCC register name set. */
58efb6c0
NC
816static unsigned int regname_selected = 1;
817
818#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
819#define arm_regnames regnames[regname_selected].reg_names
252b5132 820
b34976b6 821static bfd_boolean force_thumb = FALSE;
01c7f630 822
5876e06d 823static char * arm_fp_const[] =
252b5132
RH
824{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
825
b34976b6 826static char * arm_shift[] =
252b5132 827{"lsl", "lsr", "asr", "ror"};
01c7f630
NC
828\f
829/* Forward declarations. */
b34976b6
AM
830static void arm_decode_shift
831 PARAMS ((long, fprintf_ftype, void *));
832static int print_insn_arm
833 PARAMS ((bfd_vma, struct disassemble_info *, long));
834static int print_insn_thumb
835 PARAMS ((bfd_vma, struct disassemble_info *, long));
836static void parse_disassembler_options
837 PARAMS ((char *));
838static int print_insn
839 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
e16bb312
NC
840static int set_iwmmxt_regnames
841 PARAMS ((void));
842
843int get_arm_regname_num_options
844 PARAMS ((void));
845int set_arm_regname_option
846 PARAMS ((int));
847int get_arm_regnames
848 PARAMS ((int, const char **, const char **, const char ***));
01c7f630 849\f
baf0cc5e 850/* Functions. */
a7f8487e 851int
baf0cc5e 852get_arm_regname_num_options ()
a7f8487e
FN
853{
854 return NUM_ARM_REGNAMES;
855}
856
857int
baf0cc5e
NC
858set_arm_regname_option (option)
859 int option;
a7f8487e
FN
860{
861 int old = regname_selected;
862 regname_selected = option;
863 return old;
864}
865
866int
baf0cc5e
NC
867get_arm_regnames (option, setname, setdescription, register_names)
868 int option;
869 const char **setname;
870 const char **setdescription;
871 const char ***register_names;
a7f8487e
FN
872{
873 *setname = regnames[option].name;
874 *setdescription = regnames[option].description;
875 *register_names = regnames[option].reg_names;
876 return 16;
877}
878
252b5132
RH
879static void
880arm_decode_shift (given, func, stream)
881 long given;
882 fprintf_ftype func;
5876e06d 883 void * stream;
252b5132
RH
884{
885 func (stream, "%s", arm_regnames[given & 0xf]);
b34976b6 886
252b5132
RH
887 if ((given & 0xff0) != 0)
888 {
889 if ((given & 0x10) == 0)
890 {
891 int amount = (given & 0xf80) >> 7;
892 int shift = (given & 0x60) >> 5;
b34976b6 893
252b5132
RH
894 if (amount == 0)
895 {
896 if (shift == 3)
897 {
898 func (stream, ", rrx");
899 return;
900 }
b34976b6 901
252b5132
RH
902 amount = 32;
903 }
b34976b6 904
252b5132
RH
905 func (stream, ", %s #%d", arm_shift[shift], amount);
906 }
907 else
908 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
909 arm_regnames[(given & 0xf00) >> 8]);
910 }
911}
912
e16bb312
NC
913static int
914set_iwmmxt_regnames ()
915{
916 const char * setname;
917 const char * setdesc;
918 const char ** regnames;
919 int iwmmxt_regnames = 0;
920 int num_regnames = get_arm_regname_num_options ();
921
922 get_arm_regnames (iwmmxt_regnames, &setname,
923 &setdesc, &regnames);
924 while ((strcmp ("iwmmxt_regnames", setname))
925 && (iwmmxt_regnames < num_regnames))
926 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
927
928 return iwmmxt_regnames;
929}
930
252b5132
RH
931/* Print one instruction from PC on INFO->STREAM.
932 Return the size of the instruction (always 4 on ARM). */
baf0cc5e 933
252b5132
RH
934static int
935print_insn_arm (pc, info, given)
6a51a8a8
AM
936 bfd_vma pc;
937 struct disassemble_info *info;
938 long given;
252b5132 939{
6a51a8a8
AM
940 const struct arm_opcode *insn;
941 void *stream = info->stream;
942 fprintf_ftype func = info->fprintf_func;
e16bb312 943 static int iwmmxt_regnames = 0;
252b5132
RH
944
945 for (insn = arm_opcodes; insn->assembler; insn++)
946 {
e16bb312
NC
947 if (insn->value == FIRST_IWMMXT_INSN
948 && info->mach != bfd_mach_arm_XScale
949 && info->mach != bfd_mach_arm_iWMMXt)
950 insn = insn + IWMMXT_INSN_COUNT;
951
0a003adc
ZW
952 if ((given & insn->mask) == insn->value
953 /* Special case: an instruction with all bits set in the condition field
954 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
955 or by the catchall at the end of the table. */
956 && ((given & 0xF0000000) != 0xF0000000
957 || (insn->mask & 0xF0000000) == 0xF0000000
958 || (insn->mask == 0 && insn->value == 0)))
252b5132
RH
959 {
960 char * c;
b34976b6 961
252b5132
RH
962 for (c = insn->assembler; *c; c++)
963 {
964 if (*c == '%')
965 {
966 switch (*++c)
967 {
968 case '%':
969 func (stream, "%%");
970 break;
971
972 case 'a':
973 if (((given & 0x000f0000) == 0x000f0000)
974 && ((given & 0x02000000) == 0))
975 {
976 int offset = given & 0xfff;
b34976b6 977
252b5132 978 func (stream, "[pc");
b34976b6 979
252b5132
RH
980 if (given & 0x01000000)
981 {
982 if ((given & 0x00800000) == 0)
983 offset = - offset;
b34976b6 984
baf0cc5e 985 /* Pre-indexed. */
40536497 986 func (stream, ", #%d]", offset);
252b5132
RH
987
988 offset += pc + 8;
989
58efb6c0
NC
990 /* Cope with the possibility of write-back
991 being used. Probably a very dangerous thing
992 for the programmer to do, but who are we to
993 argue ? */
252b5132
RH
994 if (given & 0x00200000)
995 func (stream, "!");
996 }
997 else
998 {
58efb6c0 999 /* Post indexed. */
40536497 1000 func (stream, "], #%d", offset);
252b5132 1001
baf0cc5e
NC
1002 /* ie ignore the offset. */
1003 offset = pc + 8;
252b5132 1004 }
b34976b6 1005
252b5132
RH
1006 func (stream, "\t; ");
1007 info->print_address_func (offset, info);
1008 }
1009 else
1010 {
b34976b6 1011 func (stream, "[%s",
252b5132
RH
1012 arm_regnames[(given >> 16) & 0xf]);
1013 if ((given & 0x01000000) != 0)
1014 {
1015 if ((given & 0x02000000) == 0)
1016 {
1017 int offset = given & 0xfff;
1018 if (offset)
8e6446ff 1019 func (stream, ", #%s%d",
252b5132
RH
1020 (((given & 0x00800000) == 0)
1021 ? "-" : ""), offset);
1022 }
1023 else
1024 {
1025 func (stream, ", %s",
1026 (((given & 0x00800000) == 0)
1027 ? "-" : ""));
1028 arm_decode_shift (given, func, stream);
1029 }
1030
b34976b6 1031 func (stream, "]%s",
252b5132
RH
1032 ((given & 0x00200000) != 0) ? "!" : "");
1033 }
1034 else
1035 {
1036 if ((given & 0x02000000) == 0)
1037 {
1038 int offset = given & 0xfff;
1039 if (offset)
8e6446ff 1040 func (stream, "], #%s%d",
252b5132
RH
1041 (((given & 0x00800000) == 0)
1042 ? "-" : ""), offset);
b34976b6 1043 else
252b5132
RH
1044 func (stream, "]");
1045 }
1046 else
1047 {
1048 func (stream, "], %s",
b34976b6 1049 (((given & 0x00800000) == 0)
252b5132
RH
1050 ? "-" : ""));
1051 arm_decode_shift (given, func, stream);
1052 }
1053 }
1054 }
1055 break;
1056
1057 case 's':
1058 if ((given & 0x004f0000) == 0x004f0000)
1059 {
58efb6c0 1060 /* PC relative with immediate offset. */
252b5132 1061 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
b34976b6 1062
252b5132
RH
1063 if ((given & 0x00800000) == 0)
1064 offset = -offset;
b34976b6 1065
40536497 1066 func (stream, "[pc, #%d]\t; ", offset);
b34976b6 1067
252b5132
RH
1068 (*info->print_address_func)
1069 (offset + pc + 8, info);
1070 }
1071 else
1072 {
b34976b6 1073 func (stream, "[%s",
252b5132
RH
1074 arm_regnames[(given >> 16) & 0xf]);
1075 if ((given & 0x01000000) != 0)
1076 {
58efb6c0 1077 /* Pre-indexed. */
252b5132
RH
1078 if ((given & 0x00400000) == 0x00400000)
1079 {
58efb6c0 1080 /* Immediate. */
252b5132
RH
1081 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1082 if (offset)
8e6446ff 1083 func (stream, ", #%s%d",
252b5132
RH
1084 (((given & 0x00800000) == 0)
1085 ? "-" : ""), offset);
1086 }
1087 else
1088 {
58efb6c0 1089 /* Register. */
252b5132
RH
1090 func (stream, ", %s%s",
1091 (((given & 0x00800000) == 0)
1092 ? "-" : ""),
1093 arm_regnames[given & 0xf]);
1094 }
1095
b34976b6 1096 func (stream, "]%s",
252b5132
RH
1097 ((given & 0x00200000) != 0) ? "!" : "");
1098 }
1099 else
1100 {
58efb6c0 1101 /* Post-indexed. */
252b5132
RH
1102 if ((given & 0x00400000) == 0x00400000)
1103 {
58efb6c0 1104 /* Immediate. */
252b5132
RH
1105 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1106 if (offset)
8e6446ff 1107 func (stream, "], #%s%d",
252b5132
RH
1108 (((given & 0x00800000) == 0)
1109 ? "-" : ""), offset);
b34976b6 1110 else
252b5132
RH
1111 func (stream, "]");
1112 }
1113 else
1114 {
58efb6c0 1115 /* Register. */
252b5132
RH
1116 func (stream, "], %s%s",
1117 (((given & 0x00800000) == 0)
1118 ? "-" : ""),
1119 arm_regnames[given & 0xf]);
1120 }
1121 }
1122 }
1123 break;
b34976b6 1124
252b5132
RH
1125 case 'b':
1126 (*info->print_address_func)
1127 (BDISP (given) * 4 + pc + 8, info);
1128 break;
1129
1130 case 'c':
1131 func (stream, "%s",
1132 arm_conditional [(given >> 28) & 0xf]);
1133 break;
1134
1135 case 'm':
1136 {
1137 int started = 0;
1138 int reg;
1139
1140 func (stream, "{");
1141 for (reg = 0; reg < 16; reg++)
1142 if ((given & (1 << reg)) != 0)
1143 {
1144 if (started)
1145 func (stream, ", ");
1146 started = 1;
1147 func (stream, "%s", arm_regnames[reg]);
1148 }
1149 func (stream, "}");
1150 }
1151 break;
1152
1153 case 'o':
1154 if ((given & 0x02000000) != 0)
1155 {
1156 int rotate = (given & 0xf00) >> 7;
1157 int immed = (given & 0xff);
9f20bbfd
NC
1158 immed = (((immed << (32 - rotate))
1159 | (immed >> rotate)) & 0xffffffff);
1160 func (stream, "#%d\t; 0x%x", immed, immed);
252b5132
RH
1161 }
1162 else
1163 arm_decode_shift (given, func, stream);
1164 break;
1165
1166 case 'p':
1167 if ((given & 0x0000f000) == 0x0000f000)
1168 func (stream, "p");
1169 break;
1170
1171 case 't':
1172 if ((given & 0x01200000) == 0x00200000)
1173 func (stream, "t");
1174 break;
1175
252b5132
RH
1176 case 'A':
1177 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
f02232aa
NC
1178
1179 if ((given & (1 << 24)) != 0)
252b5132
RH
1180 {
1181 int offset = given & 0xff;
f02232aa 1182
252b5132 1183 if (offset)
8e6446ff 1184 func (stream, ", #%s%d]%s",
252b5132
RH
1185 ((given & 0x00800000) == 0 ? "-" : ""),
1186 offset * 4,
1187 ((given & 0x00200000) != 0 ? "!" : ""));
1188 else
1189 func (stream, "]");
1190 }
1191 else
1192 {
1193 int offset = given & 0xff;
f02232aa
NC
1194
1195 func (stream, "]");
1196
1197 if (given & (1 << 21))
1198 {
1199 if (offset)
8e6446ff 1200 func (stream, ", #%s%d",
f02232aa
NC
1201 ((given & 0x00800000) == 0 ? "-" : ""),
1202 offset * 4);
1203 }
252b5132 1204 else
f02232aa 1205 func (stream, ", {%d}", offset);
252b5132
RH
1206 }
1207 break;
1208
077b8428
NC
1209 case 'B':
1210 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1211 {
1212 bfd_vma address;
1213 bfd_vma offset = 0;
b34976b6 1214
077b8428
NC
1215 if (given & 0x00800000)
1216 /* Is signed, hi bits should be ones. */
1217 offset = (-1) ^ 0x00ffffff;
1218
1219 /* Offset is (SignExtend(offset field)<<2). */
1220 offset += given & 0x00ffffff;
1221 offset <<= 2;
1222 address = offset + pc + 8;
b34976b6 1223
077b8428
NC
1224 if (given & 0x01000000)
1225 /* H bit allows addressing to 2-byte boundaries. */
1226 address += 2;
1227
1228 info->print_address_func (address, info);
1229 }
1230 break;
1231
b1ee46c5
AH
1232 case 'I':
1233 /* Print a Cirrus/DSP shift immediate. */
1234 /* Immediates are 7bit signed ints with bits 0..3 in
1235 bits 0..3 of opcode and bits 4..6 in bits 5..7
1236 of opcode. */
1237 {
1238 int imm;
1239
1240 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1241
1242 /* Is ``imm'' a negative number? */
1243 if (imm & 0x40)
1244 imm |= (-1 << 7);
1245
1246 func (stream, "%d", imm);
1247 }
1248
1249 break;
1250
252b5132 1251 case 'C':
6eeeb4b4
AO
1252 func (stream, "_");
1253 if (given & 0x80000)
1254 func (stream, "f");
1255 if (given & 0x40000)
1256 func (stream, "s");
1257 if (given & 0x20000)
1258 func (stream, "x");
1259 if (given & 0x10000)
1260 func (stream, "c");
252b5132
RH
1261 break;
1262
1263 case 'F':
1264 switch (given & 0x00408000)
1265 {
1266 case 0:
1267 func (stream, "4");
1268 break;
1269 case 0x8000:
1270 func (stream, "1");
1271 break;
1272 case 0x00400000:
1273 func (stream, "2");
1274 break;
1275 default:
1276 func (stream, "3");
1277 }
1278 break;
b34976b6 1279
252b5132
RH
1280 case 'P':
1281 switch (given & 0x00080080)
1282 {
1283 case 0:
1284 func (stream, "s");
1285 break;
1286 case 0x80:
1287 func (stream, "d");
1288 break;
1289 case 0x00080000:
1290 func (stream, "e");
1291 break;
1292 default:
1293 func (stream, _("<illegal precision>"));
1294 break;
1295 }
1296 break;
1297 case 'Q':
1298 switch (given & 0x00408000)
1299 {
1300 case 0:
1301 func (stream, "s");
1302 break;
1303 case 0x8000:
1304 func (stream, "d");
1305 break;
1306 case 0x00400000:
1307 func (stream, "e");
1308 break;
1309 default:
1310 func (stream, "p");
1311 break;
1312 }
1313 break;
1314 case 'R':
1315 switch (given & 0x60)
1316 {
1317 case 0:
1318 break;
1319 case 0x20:
1320 func (stream, "p");
1321 break;
1322 case 0x40:
1323 func (stream, "m");
1324 break;
1325 default:
1326 func (stream, "z");
1327 break;
1328 }
1329 break;
1330
b34976b6 1331 case '0': case '1': case '2': case '3': case '4':
252b5132
RH
1332 case '5': case '6': case '7': case '8': case '9':
1333 {
1334 int bitstart = *c++ - '0';
1335 int bitend = 0;
1336 while (*c >= '0' && *c <= '9')
1337 bitstart = (bitstart * 10) + *c++ - '0';
1338
1339 switch (*c)
1340 {
1341 case '-':
1342 c++;
b34976b6 1343
252b5132
RH
1344 while (*c >= '0' && *c <= '9')
1345 bitend = (bitend * 10) + *c++ - '0';
b34976b6 1346
252b5132
RH
1347 if (!bitend)
1348 abort ();
b34976b6 1349
252b5132
RH
1350 switch (*c)
1351 {
1352 case 'r':
1353 {
1354 long reg;
b34976b6 1355
252b5132
RH
1356 reg = given >> bitstart;
1357 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1358
252b5132
RH
1359 func (stream, "%s", arm_regnames[reg]);
1360 }
1361 break;
1362 case 'd':
1363 {
1364 long reg;
b34976b6 1365
252b5132
RH
1366 reg = given >> bitstart;
1367 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1368
252b5132
RH
1369 func (stream, "%d", reg);
1370 }
1371 break;
09d92015
MM
1372 case 'W':
1373 {
1374 long reg;
1375
1376 reg = given >> bitstart;
1377 reg &= (2 << (bitend - bitstart)) - 1;
1378
1379 func (stream, "%d", reg + 1);
1380 }
1381 break;
252b5132
RH
1382 case 'x':
1383 {
1384 long reg;
b34976b6 1385
252b5132
RH
1386 reg = given >> bitstart;
1387 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1388
252b5132 1389 func (stream, "0x%08x", reg);
b34976b6 1390
58efb6c0
NC
1391 /* Some SWI instructions have special
1392 meanings. */
5876e06d
NC
1393 if ((given & 0x0fffffff) == 0x0FF00000)
1394 func (stream, "\t; IMB");
1395 else if ((given & 0x0fffffff) == 0x0FF00001)
1396 func (stream, "\t; IMBRange");
252b5132
RH
1397 }
1398 break;
cfbd315c
DL
1399 case 'X':
1400 {
1401 long reg;
b34976b6 1402
cfbd315c
DL
1403 reg = given >> bitstart;
1404 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1405
cfbd315c
DL
1406 func (stream, "%01x", reg & 0xf);
1407 }
1408 break;
252b5132
RH
1409 case 'f':
1410 {
1411 long reg;
b34976b6 1412
252b5132
RH
1413 reg = given >> bitstart;
1414 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1415
252b5132
RH
1416 if (reg > 7)
1417 func (stream, "#%s",
1418 arm_fp_const[reg & 7]);
1419 else
1420 func (stream, "f%d", reg);
1421 }
1422 break;
e16bb312
NC
1423
1424 case 'w':
1425 {
1426 long reg;
1427
1428 if (bitstart != bitend)
1429 {
1430 reg = given >> bitstart;
1431 reg &= (2 << (bitend - bitstart)) - 1;
1432 if (bitend - bitstart == 1)
1433 func (stream, "%s", iwmmxt_wwnames[reg]);
1434 else
1435 func (stream, "%s", iwmmxt_wwssnames[reg]);
1436 }
1437 else
1438 {
1439 reg = (((given >> 8) & 0x1) |
1440 ((given >> 22) & 0x1));
1441 func (stream, "%s", iwmmxt_wwnames[reg]);
1442 }
1443 }
1444 break;
1445
1446 case 'g':
1447 {
1448 long reg;
1449 int current_regnames;
1450
1451 if (! iwmmxt_regnames)
1452 iwmmxt_regnames = set_iwmmxt_regnames ();
1453 current_regnames = set_arm_regname_option
1454 (iwmmxt_regnames);
1455
1456 reg = given >> bitstart;
1457 reg &= (2 << (bitend - bitstart)) - 1;
1458 func (stream, "%s", arm_regnames[reg]);
1459 set_arm_regname_option (current_regnames);
1460 }
1461 break;
1462
1463 case 'G':
1464 {
1465 long reg;
1466 int current_regnames;
1467
1468 if (! iwmmxt_regnames)
1469 iwmmxt_regnames = set_iwmmxt_regnames ();
1470 current_regnames = set_arm_regname_option
1471 (iwmmxt_regnames + 1);
1472
1473 reg = given >> bitstart;
1474 reg &= (2 << (bitend - bitstart)) - 1;
1475 func (stream, "%s", arm_regnames[reg]);
1476 set_arm_regname_option (current_regnames);
1477 }
1478 break;
1479
252b5132
RH
1480 default:
1481 abort ();
1482 }
1483 break;
a660f11e
RE
1484
1485 case 'y':
1486 case 'z':
1487 {
1488 int single = *c == 'y';
1489 int regno;
1490
1491 switch (bitstart)
1492 {
1493 case 4: /* Sm pair */
1494 func (stream, "{");
1495 /* Fall through. */
1496 case 0: /* Sm, Dm */
1497 regno = given & 0x0000000f;
1498 if (single)
1499 {
1500 regno <<= 1;
1501 regno += (given >> 5) & 1;
1502 }
1503 break;
1504
1505 case 1: /* Sd, Dd */
1506 regno = (given >> 12) & 0x0000000f;
1507 if (single)
1508 {
1509 regno <<= 1;
1510 regno += (given >> 22) & 1;
1511 }
1512 break;
1513
1514 case 2: /* Sn, Dn */
1515 regno = (given >> 16) & 0x0000000f;
1516 if (single)
1517 {
1518 regno <<= 1;
1519 regno += (given >> 7) & 1;
1520 }
1521 break;
1522
1523 case 3: /* List */
1524 func (stream, "{");
1525 regno = (given >> 12) & 0x0000000f;
1526 if (single)
1527 {
1528 regno <<= 1;
1529 regno += (given >> 22) & 1;
1530 }
1531 break;
1532
b34976b6 1533
a660f11e
RE
1534 default:
1535 abort ();
1536 }
1537
1538 func (stream, "%c%d", single ? 's' : 'd', regno);
1539
1540 if (bitstart == 3)
1541 {
1542 int count = given & 0xff;
1543
1544 if (single == 0)
1545 count >>= 1;
1546
1547 if (--count)
1548 {
1549 func (stream, "-%c%d",
1550 single ? 's' : 'd',
1551 regno + count);
1552 }
1553
1554 func (stream, "}");
1555 }
1556 else if (bitstart == 4)
1557 func (stream, ", %c%d}", single ? 's' : 'd',
1558 regno + 1);
1559
1560 break;
1561 }
1562
252b5132
RH
1563 case '`':
1564 c++;
1565 if ((given & (1 << bitstart)) == 0)
1566 func (stream, "%c", *c);
1567 break;
1568 case '\'':
1569 c++;
1570 if ((given & (1 << bitstart)) != 0)
1571 func (stream, "%c", *c);
1572 break;
1573 case '?':
1574 ++c;
1575 if ((given & (1 << bitstart)) != 0)
1576 func (stream, "%c", *c++);
1577 else
1578 func (stream, "%c", *++c);
1579 break;
1580 default:
1581 abort ();
1582 }
1583 break;
1584
e16bb312
NC
1585 case 'L':
1586 switch (given & 0x00400100)
1587 {
1588 case 0x00000000: func (stream, "b"); break;
1589 case 0x00400000: func (stream, "h"); break;
1590 case 0x00000100: func (stream, "w"); break;
1591 case 0x00400100: func (stream, "d"); break;
1592 default:
1593 break;
1594 }
1595 break;
1596
1597 case 'Z':
1598 {
1599 int value;
1600 /* given (20, 23) | given (0, 3) */
1601 value = ((given >> 16) & 0xf0) | (given & 0xf);
1602 func (stream, "%d", value);
1603 }
1604 break;
1605
1606 case 'l':
1607 /* This is like the 'A' operator, except that if
1608 the width field "M" is zero, then the offset is
1609 *not* multiplied by four. */
1610 {
1611 int offset = given & 0xff;
1612 int multiplier = (given & 0x00000100) ? 4 : 1;
1613
1614 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1615
1616 if (offset)
1617 {
1618 if ((given & 0x01000000) != 0)
8e6446ff 1619 func (stream, ", #%s%d]%s",
e16bb312
NC
1620 ((given & 0x00800000) == 0 ? "-" : ""),
1621 offset * multiplier,
1622 ((given & 0x00200000) != 0 ? "!" : ""));
1623 else
8e6446ff 1624 func (stream, "], #%s%d",
e16bb312
NC
1625 ((given & 0x00800000) == 0 ? "-" : ""),
1626 offset * multiplier);
1627 }
1628 else
1629 func (stream, "]");
1630 }
1631 break;
1632
0dd132b6
NC
1633 case 'e':
1634 {
1635 int imm;
1636
1637 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1638 func (stream, "%d", imm);
1639 }
1640 break;
1641
0a003adc
ZW
1642 case 'E':
1643 /* LSB and WIDTH fields of BFI or BFC. The machine-
1644 language instruction encodes LSB and MSB. */
1645 {
1646 long msb = (given & 0x001f0000) >> 16;
1647 long lsb = (given & 0x00000f80) >> 7;
1648
1649 long width = msb - lsb + 1;
1650 if (width > 0)
1651 func (stream, "#%lu, #%lu", lsb, width);
1652 else
1653 func (stream, "(invalid: %lu:%lu)", lsb, msb);
1654 }
1655 break;
1656
1657 case 'V':
1658 /* 16-bit unsigned immediate from a MOVT or MOVW
1659 instruction, encoded in bits 0:11 and 15:19. */
1660 {
1661 long hi = (given & 0x000f0000) >> 4;
1662 long lo = (given & 0x00000fff);
1663 long imm16 = hi | lo;
1664 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
1665 }
1666 break;
1667
252b5132
RH
1668 default:
1669 abort ();
1670 }
1671 }
1672 }
1673 else
1674 func (stream, "%c", *c);
1675 }
1676 return 4;
1677 }
1678 }
1679 abort ();
1680}
1681
1682/* Print one instruction from PC on INFO->STREAM.
1683 Return the size of the instruction. */
baf0cc5e 1684
252b5132
RH
1685static int
1686print_insn_thumb (pc, info, given)
6a51a8a8
AM
1687 bfd_vma pc;
1688 struct disassemble_info *info;
1689 long given;
252b5132 1690{
6a51a8a8
AM
1691 const struct thumb_opcode *insn;
1692 void *stream = info->stream;
1693 fprintf_ftype func = info->fprintf_func;
252b5132
RH
1694
1695 for (insn = thumb_opcodes; insn->assembler; insn++)
1696 {
1697 if ((given & insn->mask) == insn->value)
1698 {
5876e06d 1699 char * c = insn->assembler;
252b5132 1700
58efb6c0
NC
1701 /* Special processing for Thumb 2 instruction BL sequence: */
1702 if (!*c) /* Check for empty (not NULL) assembler string. */
252b5132 1703 {
4f3c3dbb 1704 long offset;
b34976b6 1705
252b5132
RH
1706 info->bytes_per_chunk = 4;
1707 info->bytes_per_line = 4;
4f3c3dbb
NC
1708
1709 offset = BDISP23 (given);
baf0cc5e
NC
1710 offset = offset * 2 + pc + 4;
1711
077b8428 1712 if ((given & 0x10000000) == 0)
4f3c3dbb
NC
1713 {
1714 func (stream, "blx\t");
baf0cc5e 1715 offset &= 0xfffffffc;
4f3c3dbb 1716 }
077b8428 1717 else
4f3c3dbb
NC
1718 func (stream, "bl\t");
1719
baf0cc5e 1720 info->print_address_func (offset, info);
252b5132
RH
1721 return 4;
1722 }
1723 else
1724 {
1725 info->bytes_per_chunk = 2;
1726 info->bytes_per_line = 4;
b34976b6 1727
252b5132 1728 given &= 0xffff;
b34976b6 1729
252b5132
RH
1730 for (; *c; c++)
1731 {
1732 if (*c == '%')
1733 {
1734 int domaskpc = 0;
1735 int domasklr = 0;
b34976b6 1736
252b5132
RH
1737 switch (*++c)
1738 {
1739 case '%':
1740 func (stream, "%%");
1741 break;
1742
1743 case 'S':
1744 {
1745 long reg;
b34976b6 1746
252b5132
RH
1747 reg = (given >> 3) & 0x7;
1748 if (given & (1 << 6))
1749 reg += 8;
b34976b6 1750
252b5132
RH
1751 func (stream, "%s", arm_regnames[reg]);
1752 }
1753 break;
1754
1755 case 'D':
1756 {
1757 long reg;
b34976b6 1758
252b5132
RH
1759 reg = given & 0x7;
1760 if (given & (1 << 7))
1761 reg += 8;
b34976b6 1762
252b5132
RH
1763 func (stream, "%s", arm_regnames[reg]);
1764 }
1765 break;
1766
1767 case 'T':
1768 func (stream, "%s",
1769 arm_conditional [(given >> 8) & 0xf]);
1770 break;
1771
1772 case 'N':
1773 if (given & (1 << 8))
1774 domasklr = 1;
58efb6c0 1775 /* Fall through. */
252b5132
RH
1776 case 'O':
1777 if (*c == 'O' && (given & (1 << 8)))
1778 domaskpc = 1;
58efb6c0 1779 /* Fall through. */
252b5132
RH
1780 case 'M':
1781 {
1782 int started = 0;
1783 int reg;
b34976b6 1784
252b5132 1785 func (stream, "{");
b34976b6 1786
252b5132
RH
1787 /* It would be nice if we could spot
1788 ranges, and generate the rS-rE format: */
1789 for (reg = 0; (reg < 8); reg++)
1790 if ((given & (1 << reg)) != 0)
1791 {
1792 if (started)
1793 func (stream, ", ");
1794 started = 1;
1795 func (stream, "%s", arm_regnames[reg]);
1796 }
1797
1798 if (domasklr)
1799 {
1800 if (started)
1801 func (stream, ", ");
1802 started = 1;
a7f8487e 1803 func (stream, arm_regnames[14] /* "lr" */);
252b5132
RH
1804 }
1805
1806 if (domaskpc)
1807 {
1808 if (started)
1809 func (stream, ", ");
a7f8487e 1810 func (stream, arm_regnames[15] /* "pc" */);
252b5132
RH
1811 }
1812
1813 func (stream, "}");
1814 }
1815 break;
1816
1817
b34976b6 1818 case '0': case '1': case '2': case '3': case '4':
252b5132
RH
1819 case '5': case '6': case '7': case '8': case '9':
1820 {
1821 int bitstart = *c++ - '0';
1822 int bitend = 0;
b34976b6 1823
252b5132
RH
1824 while (*c >= '0' && *c <= '9')
1825 bitstart = (bitstart * 10) + *c++ - '0';
1826
1827 switch (*c)
1828 {
1829 case '-':
1830 {
1831 long reg;
b34976b6 1832
252b5132
RH
1833 c++;
1834 while (*c >= '0' && *c <= '9')
1835 bitend = (bitend * 10) + *c++ - '0';
1836 if (!bitend)
1837 abort ();
1838 reg = given >> bitstart;
1839 reg &= (2 << (bitend - bitstart)) - 1;
1840 switch (*c)
1841 {
1842 case 'r':
1843 func (stream, "%s", arm_regnames[reg]);
1844 break;
1845
1846 case 'd':
1847 func (stream, "%d", reg);
1848 break;
1849
1850 case 'H':
1851 func (stream, "%d", reg << 1);
1852 break;
1853
1854 case 'W':
1855 func (stream, "%d", reg << 2);
1856 break;
1857
1858 case 'a':
1859 /* PC-relative address -- the bottom two
58efb6c0
NC
1860 bits of the address are dropped
1861 before the calculation. */
252b5132
RH
1862 info->print_address_func
1863 (((pc + 4) & ~3) + (reg << 2), info);
1864 break;
1865
1866 case 'x':
1867 func (stream, "0x%04x", reg);
1868 break;
1869
1870 case 'I':
1871 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1872 func (stream, "%d", reg);
1873 break;
1874
1875 case 'B':
1876 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1877 (*info->print_address_func)
1878 (reg * 2 + pc + 4, info);
1879 break;
1880
1881 default:
5876e06d 1882 abort ();
252b5132
RH
1883 }
1884 }
1885 break;
1886
1887 case '\'':
1888 c++;
1889 if ((given & (1 << bitstart)) != 0)
1890 func (stream, "%c", *c);
1891 break;
1892
1893 case '?':
1894 ++c;
1895 if ((given & (1 << bitstart)) != 0)
1896 func (stream, "%c", *c++);
1897 else
1898 func (stream, "%c", *++c);
1899 break;
1900
1901 default:
5876e06d 1902 abort ();
252b5132
RH
1903 }
1904 }
1905 break;
1906
1907 default:
1908 abort ();
1909 }
1910 }
1911 else
1912 func (stream, "%c", *c);
1913 }
1914 }
1915 return 2;
1916 }
1917 }
1918
58efb6c0 1919 /* No match. */
252b5132
RH
1920 abort ();
1921}
1922
22a398e1
NC
1923/* Disallow mapping symbols ($a, $b, $d, $t etc) from
1924 being displayed in symbol relative addresses. */
1925
1926bfd_boolean
1927arm_symbol_is_valid (asymbol * sym,
1928 struct disassemble_info * info ATTRIBUTE_UNUSED)
1929{
1930 const char * name;
1931
1932 if (sym == NULL)
1933 return FALSE;
1934
1935 name = bfd_asymbol_name (sym);
1936
1937 return (name && *name != '$');
1938}
1939
58efb6c0 1940/* Parse an individual disassembler option. */
baf0cc5e 1941
a3d9c82d
NC
1942void
1943parse_arm_disassembler_option (option)
01c7f630 1944 char * option;
dd92f639 1945{
01c7f630 1946 if (option == NULL)
dd92f639 1947 return;
b34976b6 1948
01c7f630 1949 if (strneq (option, "reg-names-", 10))
dd92f639 1950 {
58efb6c0 1951 int i;
b34976b6 1952
01c7f630 1953 option += 10;
58efb6c0
NC
1954
1955 for (i = NUM_ARM_REGNAMES; i--;)
31e0f3cd 1956 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
58efb6c0
NC
1957 {
1958 regname_selected = i;
1959 break;
1960 }
b34976b6 1961
58efb6c0 1962 if (i < 0)
31e0f3cd 1963 /* XXX - should break 'option' at following delimiter. */
58efb6c0 1964 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
dd92f639 1965 }
31e0f3cd 1966 else if (strneq (option, "force-thumb", 11))
01c7f630 1967 force_thumb = 1;
31e0f3cd 1968 else if (strneq (option, "no-force-thumb", 14))
01c7f630 1969 force_thumb = 0;
dd92f639 1970 else
31e0f3cd 1971 /* XXX - should break 'option' at following delimiter. */
58efb6c0 1972 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
b34976b6 1973
dd92f639
NC
1974 return;
1975}
1976
31e0f3cd
NC
1977/* Parse the string of disassembler options, spliting it at whitespaces
1978 or commas. (Whitespace separators supported for backwards compatibility). */
baf0cc5e 1979
01c7f630
NC
1980static void
1981parse_disassembler_options (options)
1982 char * options;
1983{
01c7f630
NC
1984 if (options == NULL)
1985 return;
1986
31e0f3cd 1987 while (*options)
01c7f630 1988 {
31e0f3cd
NC
1989 parse_arm_disassembler_option (options);
1990
1991 /* Skip forward to next seperator. */
1992 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1993 ++ options;
1994 /* Skip forward past seperators. */
1995 while (ISSPACE (*options) || (*options == ','))
1996 ++ options;
01c7f630 1997 }
01c7f630
NC
1998}
1999
58efb6c0
NC
2000/* NOTE: There are no checks in these routines that
2001 the relevant number of data bytes exist. */
baf0cc5e 2002
58efb6c0
NC
2003static int
2004print_insn (pc, info, little)
252b5132 2005 bfd_vma pc;
5876e06d 2006 struct disassemble_info * info;
b34976b6 2007 bfd_boolean little;
252b5132
RH
2008{
2009 unsigned char b[4];
2010 long given;
2011 int status;
b7693d02 2012 int is_thumb, second_half_valid = 1;
58efb6c0 2013
dd92f639
NC
2014 if (info->disassembler_options)
2015 {
2016 parse_disassembler_options (info->disassembler_options);
b34976b6 2017
58efb6c0 2018 /* To avoid repeated parsing of these options, we remove them here. */
dd92f639
NC
2019 info->disassembler_options = NULL;
2020 }
b34976b6 2021
01c7f630 2022 is_thumb = force_thumb;
b34976b6 2023
01c7f630 2024 if (!is_thumb && info->symbols != NULL)
252b5132 2025 {
5876e06d
NC
2026 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2027 {
2f0ca46a 2028 coff_symbol_type * cs;
b34976b6 2029
5876e06d
NC
2030 cs = coffsymbol (*info->symbols);
2031 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
2032 || cs->native->u.syment.n_sclass == C_THUMBSTAT
2033 || cs->native->u.syment.n_sclass == C_THUMBLABEL
2034 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2035 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2036 }
2037 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2038 {
2f0ca46a 2039 elf_symbol_type * es;
58efb6c0 2040 unsigned int type;
b34976b6 2041
5876e06d 2042 es = *(elf_symbol_type **)(info->symbols);
58efb6c0 2043 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
b34976b6 2044
58efb6c0 2045 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
5876e06d
NC
2046 }
2047 }
b34976b6 2048
252b5132 2049 info->bytes_per_chunk = 4;
58efb6c0 2050 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
252b5132 2051
58efb6c0 2052 if (little)
252b5132 2053 {
58efb6c0
NC
2054 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
2055 if (status != 0 && is_thumb)
2056 {
2057 info->bytes_per_chunk = 2;
b7693d02 2058 second_half_valid = 0;
b34976b6 2059
58efb6c0
NC
2060 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
2061 b[3] = b[2] = 0;
2062 }
b34976b6 2063
58efb6c0
NC
2064 if (status != 0)
2065 {
2066 info->memory_error_func (status, pc, info);
2067 return -1;
2068 }
b34976b6 2069
58efb6c0 2070 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
252b5132 2071 }
58efb6c0 2072 else
252b5132 2073 {
58efb6c0 2074 status = info->read_memory_func
b7693d02 2075 (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
58efb6c0 2076 if (status != 0)
252b5132 2077 {
b7693d02 2078 info->memory_error_func (status, WORD_ADDRESS (pc), info);
58efb6c0
NC
2079 return -1;
2080 }
b34976b6 2081
58efb6c0
NC
2082 if (is_thumb)
2083 {
2084 if (pc & 0x2)
252b5132 2085 {
58efb6c0 2086 given = (b[2] << 8) | b[3];
b34976b6 2087
58efb6c0 2088 status = info->read_memory_func
b7693d02 2089 (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info);
58efb6c0 2090 if (status != 0)
b7693d02
DJ
2091 second_half_valid = 0;
2092 else
2093 given |= (b[0] << 24) | (b[1] << 16);
252b5132 2094 }
58efb6c0
NC
2095 else
2096 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
252b5132
RH
2097 }
2098 else
58efb6c0 2099 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
252b5132 2100 }
b34976b6 2101
6a56ec7e
NC
2102 if (info->flags & INSN_HAS_RELOC)
2103 /* If the instruction has a reloc associated with it, then
2104 the offset field in the instruction will actually be the
2105 addend for the reloc. (We are using REL type relocs).
2106 In such cases, we can ignore the pc when computing
2107 addresses, since the addend is not currently pc-relative. */
2108 pc = 0;
b34976b6 2109
252b5132 2110 if (is_thumb)
5876e06d 2111 status = print_insn_thumb (pc, info, given);
252b5132 2112 else
5876e06d 2113 status = print_insn_arm (pc, info, given);
252b5132 2114
b7693d02
DJ
2115 if (is_thumb && status == 4 && second_half_valid == 0)
2116 {
2117 info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
2118 return -1;
2119 }
2120
252b5132
RH
2121 return status;
2122}
2123
2124int
58efb6c0 2125print_insn_big_arm (pc, info)
252b5132
RH
2126 bfd_vma pc;
2127 struct disassemble_info * info;
2128{
b34976b6 2129 return print_insn (pc, info, FALSE);
58efb6c0 2130}
01c7f630 2131
58efb6c0
NC
2132int
2133print_insn_little_arm (pc, info)
2134 bfd_vma pc;
2135 struct disassemble_info * info;
2136{
b34976b6 2137 return print_insn (pc, info, TRUE);
58efb6c0 2138}
252b5132 2139
58efb6c0
NC
2140void
2141print_arm_disassembler_options (FILE * stream)
2142{
2143 int i;
252b5132 2144
58efb6c0
NC
2145 fprintf (stream, _("\n\
2146The following ARM specific disassembler options are supported for use with\n\
2147the -M switch:\n"));
b34976b6 2148
58efb6c0
NC
2149 for (i = NUM_ARM_REGNAMES; i--;)
2150 fprintf (stream, " reg-names-%s %*c%s\n",
2151 regnames[i].name,
d5b2f4d6 2152 (int)(14 - strlen (regnames[i].name)), ' ',
58efb6c0
NC
2153 regnames[i].description);
2154
2155 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
2156 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
252b5132 2157}
This page took 0.357439 seconds and 4 git commands to generate.