2004-12-14 Randolph Chung <tausq@debian.org>
[deliverable/binutils-gdb.git] / opcodes / arm-dis.c
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 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)
6
7 This file is part of libopcodes.
8
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.
13
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.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
22
23 #include "sysdep.h"
24
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "arm-opc.h"
28 #include "coff/internal.h"
29 #include "libcoff.h"
30 #include "opintl.h"
31 #include "safe-ctype.h"
32
33 /* FIXME: This shouldn't be done here. */
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
37
38 #ifndef streq
39 #define streq(a,b) (strcmp ((a), (b)) == 0)
40 #endif
41
42 #ifndef strneq
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])
48 #endif
49
50 #define WORD_ADDRESS(pc) ((pc) & ~0x3)
51
52 /* Format of the disassembler control string :
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.
84 IWMMXT specific format options:
85 %<bitfield>g print as an iWMMXt 64-bit register
86 %<bitfield>G print as an iWMMXt general purpose or control register
87 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
88 %Z print the Immediate of a WSHUFH instruction.
89 %L print as an iWMMXt N/M width field.
90 %l like 'A' except use byte offsets for 'B' & 'H' versions
91 Thumb specific format options:
92 %D print Thumb register (bits 0..2 as high number if bit 7 set)
93 %S print Thumb register (bits 3..5 as high number if bit 6 set)
94 %<bitfield>I print bitfield as a signed decimal
95 (top bit of range being the sign bit)
96 %M print Thumb register mask
97 %N print Thumb register mask (with LR)
98 %O print Thumb register mask (with PC)
99 %T print Thumb condition code (always bits 8-11)
100 %I print cirrus signed shift immediate: bits 0..3|4..6
101 %<bitfield>B print Thumb branch destination (signed displacement)
102 %<bitfield>W print (bitfield * 4) as a decimal
103 %<bitfield>H print (bitfield * 2) as a decimal
104 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
105 %e print arm SMI operand (bits 0..7,8..19). */
106
107 /* Note: There is a partial ordering in this table - it must be searched from
108 the top to obtain a correct match. */
109
110 static const struct arm_opcode arm_opcodes[] =
111 {
112 /* ARM instructions. */
113 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
114 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
115 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
116 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
117 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
118 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
119 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
120
121 /* ARM V6Z instructions. */
122 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
123
124 /* ARM V6K instructions. */
125 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
126 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
127 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
128 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
129 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
130 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
131 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
132
133 /* ARM V6K NOP hints. */
134 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
135 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
136 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
137 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
138 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
139
140 /* ARM V6 instructions. */
141 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
142 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
143 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
144 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
145 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
146 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
147 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
148 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
149 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
150 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
151 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
152 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
153 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
154 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
155 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
156 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
157 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
158 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
159 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
160 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
161 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
162 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
163 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
164 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
165 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
166 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
167 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
168 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
169 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
170 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
171 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
172 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
173 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
174 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
175 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
176 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
177 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
178 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
179 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
180 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
181 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
182 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
183 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
184 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
185 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
186 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
187 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
188 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
189 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
190 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
191 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
192 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
193 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
194 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
195 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
196 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
197 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
198 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
199 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
200 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
201 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
202 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
203 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
204 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
205 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
206 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
207 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
208 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
209 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
210 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
211 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
212 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
213 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
214 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
215 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
216 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
217 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
218 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
219 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
220 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
221 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
222 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
223 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
224 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
225 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
226 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
227 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
228 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
229 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
230 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
231 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
232 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
233 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
234 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
235 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
236 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
237 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
238 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
239 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
240 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
241 {ARM_EXT_V6, 0x068000b0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
242 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
243 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
244 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
245 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
246 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
247 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
248 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
249 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
250 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
251 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
252 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
253 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
254 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
255 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
256 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
257 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
258 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
259 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
260 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
261 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
262 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
263 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
264 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
265
266 /* V5J instruction. */
267 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
268
269 /* XScale instructions. */
270 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
271 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
272 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
273 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
274 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
275
276 /* Intel Wireless MMX technology instructions. */
277 #define FIRST_IWMMXT_INSN 0x0e130130
278 #define IWMMXT_INSN_COUNT 47
279 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
280 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
281 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
282 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
283 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
284 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
285 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
286 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
287 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
288 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
289 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
290 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
291 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
292 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
293 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
294 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
295 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
296 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
297 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
298 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
299 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
300 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
301 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
302 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
303 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
304 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
305 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
306 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
307 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
308 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
309 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
310 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
311 {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
312 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
313 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
314 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
315 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
316 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
317 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
318 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
319 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
320 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
321 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
322 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
323 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
324 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
325 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
326 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
327 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
328
329 /* V5 Instructions. */
330 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
331 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
332 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
333 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
334 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
335 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
336 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
337 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
338 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
339
340 /* V5E "El Segundo" Instructions. */
341 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
342 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
343 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
344 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
345 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
346 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
347 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
348
349 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
350 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
351
352 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
353 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
354 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
355 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
356
357 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
358 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
359 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
360 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
361
362 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
363 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
364
365 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
366 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
367 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
368 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
369
370 /* ARM Instructions. */
371 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
372 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
373 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
374 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
375 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
376 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
377 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
378 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
379 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
380 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
381 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
382 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
383 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
384 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
385 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
386 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
387 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
388 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
389 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
390 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
391 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
392 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
393 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
394 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
395 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
396 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
397 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
398 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
399 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
400
401 /* Floating point coprocessor (FPA) instructions */
402 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
403 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
404 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
405 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
406 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
407 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
408 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
409 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
410 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
411 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
412 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
413 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
414 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
415 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
416 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
417 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
418 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
419 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
420 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
421 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
422 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
423 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
424 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
425 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
426 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
427 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
428 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
429 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
430 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
431 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
432 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
433 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
434 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
435 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
436 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
437 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
438 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
439 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
440 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
441 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
442 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
443 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
444 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
445
446 /* Floating point coprocessor (VFP) instructions */
447 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
448 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
449 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
450 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"},
451 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
452 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
453 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
454 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
455 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
456 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
457 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
458 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
459 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
460 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
461 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
462 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
463 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
464 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
465 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
466 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
467 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
468 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
469 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
470 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
471 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
472 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
473 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
474 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
475 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
476 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
477 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
478 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
479 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
480 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
481 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
482 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
483 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
484 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
485 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
486 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
487 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
488 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
489 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
490 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
491 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
492 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
493 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
494 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
495 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
496 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
497 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
498 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
499 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
500 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
501 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
502 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
503 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
504 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
505 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
506 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
507 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
508 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
509 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
510 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
511 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
512 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
513 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
514 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
515 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
516 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
517 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
518 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
519 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
520
521 /* Cirrus coprocessor instructions. */
522 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
523 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
524 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
525 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
526 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
527 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
528 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
529 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
530 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
531 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
532 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
533 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
534 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
535 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
536 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
537 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
538 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
539 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
540 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
541 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
542 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
543 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
544 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
545 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
546 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
547 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
548 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
549 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
550 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
551 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
552 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
553 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
554 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
555 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
556 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
557 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
558 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
559 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
560 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
561 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
562 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
563 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
564 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
565 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
566 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
567 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
568 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
569 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
570 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
571 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
572 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
573 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
574 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
575 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
576 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
577 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
578 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
579 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
580 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
581 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
582 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
583 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
584 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
585 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
586 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
587 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
588 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
589 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
590 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
591 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
592 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
593 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
594 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
595 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
596 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
597 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
598 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
599 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
600 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
601 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
602 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
603 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
604 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
605 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
606
607 /* Generic coprocessor instructions */
608 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
609 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
610 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
611 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
612 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
613 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
614 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
615
616 /* The rest. */
617 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
618 {0, 0x00000000, 0x00000000, 0}
619 };
620
621 static const struct thumb_opcode thumb_opcodes[] =
622 {
623 /* Thumb instructions. */
624
625 /* ARM V6. */
626 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
627 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
628 {ARM_EXT_V6, 0x4600, 0xffc0, "cpy\t%0-2r, %3-5r"},
629 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
630 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
631 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
632 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
633 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
634 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
635 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
636 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
637
638 /* ARM V5 ISA extends Thumb. */
639 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
640 /* Note: this is BLX(2). BLX(1) is done in arm-dis.c/print_insn_thumb()
641 as an extension of the special processing there for Thumb BL.
642 BL and BLX(1) involve 2 successive 16-bit instructions, which must
643 always appear together in the correct order. So, the empty
644 string is put in this table, and the string interpreter takes <empty>
645 to mean it has a pair of BL-ish instructions. */
646 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
647 /* ARM V4T ISA (Thumb v1). */
648 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
649 /* Format 5 instructions do not update the PSR. */
650 {ARM_EXT_V4T, 0x1C00, 0xFFC0, "mov\t%0-2r, %3-5r\t\t(add %0-2r, %3-5r, #%6-8d)"},
651 /* Format 4. */
652 {ARM_EXT_V4T, 0x4000, 0xFFC0, "and\t%0-2r, %3-5r"},
653 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eor\t%0-2r, %3-5r"},
654 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsl\t%0-2r, %3-5r"},
655 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsr\t%0-2r, %3-5r"},
656 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asr\t%0-2r, %3-5r"},
657 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adc\t%0-2r, %3-5r"},
658 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbc\t%0-2r, %3-5r"},
659 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "ror\t%0-2r, %3-5r"},
660 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
661 {ARM_EXT_V4T, 0x4240, 0xFFC0, "neg\t%0-2r, %3-5r"},
662 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
663 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
664 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orr\t%0-2r, %3-5r"},
665 {ARM_EXT_V4T, 0x4340, 0xFFC0, "mul\t%0-2r, %3-5r"},
666 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bic\t%0-2r, %3-5r"},
667 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvn\t%0-2r, %3-5r"},
668 /* format 13 */
669 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
670 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
671 /* format 5 */
672 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
673 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
674 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
675 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
676 /* format 14 */
677 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
678 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
679 /* format 2 */
680 {ARM_EXT_V4T, 0x1800, 0xFE00, "add\t%0-2r, %3-5r, %6-8r"},
681 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
682 {ARM_EXT_V4T, 0x1C00, 0xFE00, "add\t%0-2r, %3-5r, #%6-8d"},
683 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
684 /* format 8 */
685 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
686 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
687 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
688 /* format 7 */
689 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
690 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
691 /* format 1 */
692 {ARM_EXT_V4T, 0x0000, 0xF800, "lsl\t%0-2r, %3-5r, #%6-10d"},
693 {ARM_EXT_V4T, 0x0800, 0xF800, "lsr\t%0-2r, %3-5r, #%6-10d"},
694 {ARM_EXT_V4T, 0x1000, 0xF800, "asr\t%0-2r, %3-5r, #%6-10d"},
695 /* format 3 */
696 {ARM_EXT_V4T, 0x2000, 0xF800, "mov\t%8-10r, #%0-7d"},
697 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
698 {ARM_EXT_V4T, 0x3000, 0xF800, "add\t%8-10r, #%0-7d"},
699 {ARM_EXT_V4T, 0x3800, 0xF800, "sub\t%8-10r, #%0-7d"},
700 /* format 6 */
701 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
702 /* format 9 */
703 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
704 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
705 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
706 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
707 /* format 10 */
708 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
709 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
710 /* format 11 */
711 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
712 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
713 /* format 12 */
714 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
715 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
716 /* format 15 */
717 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!,%M"},
718 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!,%M"},
719 /* format 18 */
720 {ARM_EXT_V4T, 0xE000, 0xF800, "b\t%0-10B"},
721 {ARM_EXT_V4T, 0xE800, 0xF800, "undefined"},
722 /* format 19 */
723 {ARM_EXT_V4T, 0xF000, 0xF800, ""}, /* special processing required in disassembler */
724 {ARM_EXT_V4T, 0xF800, 0xF800, "second half of BL instruction %0-15x"},
725 /* format 16 */
726 {ARM_EXT_V4T, 0xD000, 0xFF00, "beq\t%0-7B"},
727 {ARM_EXT_V4T, 0xD100, 0xFF00, "bne\t%0-7B"},
728 {ARM_EXT_V4T, 0xD200, 0xFF00, "bcs\t%0-7B"},
729 {ARM_EXT_V4T, 0xD300, 0xFF00, "bcc\t%0-7B"},
730 {ARM_EXT_V4T, 0xD400, 0xFF00, "bmi\t%0-7B"},
731 {ARM_EXT_V4T, 0xD500, 0xFF00, "bpl\t%0-7B"},
732 {ARM_EXT_V4T, 0xD600, 0xFF00, "bvs\t%0-7B"},
733 {ARM_EXT_V4T, 0xD700, 0xFF00, "bvc\t%0-7B"},
734 {ARM_EXT_V4T, 0xD800, 0xFF00, "bhi\t%0-7B"},
735 {ARM_EXT_V4T, 0xD900, 0xFF00, "bls\t%0-7B"},
736 {ARM_EXT_V4T, 0xDA00, 0xFF00, "bge\t%0-7B"},
737 {ARM_EXT_V4T, 0xDB00, 0xFF00, "blt\t%0-7B"},
738 {ARM_EXT_V4T, 0xDC00, 0xFF00, "bgt\t%0-7B"},
739 {ARM_EXT_V4T, 0xDD00, 0xFF00, "ble\t%0-7B"},
740 /* format 17 */
741 {ARM_EXT_V4T, 0xDE00, 0xFF00, "bal\t%0-7B"},
742 {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
743 /* format 9 */
744 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
745 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
746 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
747 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
748 /* the rest */
749 {ARM_EXT_V1, 0x0000, 0x0000, "undefined instruction %0-15x"},
750 {0, 0x0000, 0x0000, 0}
751 };
752
753 static char * arm_conditional[] =
754 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
755 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
756
757 typedef struct
758 {
759 const char * name;
760 const char * description;
761 const char * reg_names[16];
762 }
763 arm_regname;
764
765 static arm_regname regnames[] =
766 {
767 { "raw" , "Select raw register names",
768 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
769 { "gcc", "Select register names used by GCC",
770 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
771 { "std", "Select register names used in ARM's ISA documentation",
772 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
773 { "apcs", "Select register names used in the APCS",
774 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
775 { "atpcs", "Select register names used in the ATPCS",
776 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
777 { "special-atpcs", "Select special register names used in the ATPCS",
778 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
779 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
780 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
781 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
782 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
783 };
784
785 static char * iwmmxt_wwnames[] =
786 {"b", "h", "w", "d"};
787
788 static char * iwmmxt_wwssnames[] =
789 {"b", "bus", "b", "bss",
790 "h", "hus", "h", "hss",
791 "w", "wus", "w", "wss",
792 "d", "dus", "d", "dss"
793 };
794
795 /* Default to GCC register name set. */
796 static unsigned int regname_selected = 1;
797
798 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
799 #define arm_regnames regnames[regname_selected].reg_names
800
801 static bfd_boolean force_thumb = FALSE;
802
803 static char * arm_fp_const[] =
804 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
805
806 static char * arm_shift[] =
807 {"lsl", "lsr", "asr", "ror"};
808 \f
809 /* Forward declarations. */
810 static void arm_decode_shift
811 PARAMS ((long, fprintf_ftype, void *));
812 static int print_insn_arm
813 PARAMS ((bfd_vma, struct disassemble_info *, long));
814 static int print_insn_thumb
815 PARAMS ((bfd_vma, struct disassemble_info *, long));
816 static void parse_disassembler_options
817 PARAMS ((char *));
818 static int print_insn
819 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
820 static int set_iwmmxt_regnames
821 PARAMS ((void));
822
823 int get_arm_regname_num_options
824 PARAMS ((void));
825 int set_arm_regname_option
826 PARAMS ((int));
827 int get_arm_regnames
828 PARAMS ((int, const char **, const char **, const char ***));
829 \f
830 /* Functions. */
831 int
832 get_arm_regname_num_options ()
833 {
834 return NUM_ARM_REGNAMES;
835 }
836
837 int
838 set_arm_regname_option (option)
839 int option;
840 {
841 int old = regname_selected;
842 regname_selected = option;
843 return old;
844 }
845
846 int
847 get_arm_regnames (option, setname, setdescription, register_names)
848 int option;
849 const char **setname;
850 const char **setdescription;
851 const char ***register_names;
852 {
853 *setname = regnames[option].name;
854 *setdescription = regnames[option].description;
855 *register_names = regnames[option].reg_names;
856 return 16;
857 }
858
859 static void
860 arm_decode_shift (given, func, stream)
861 long given;
862 fprintf_ftype func;
863 void * stream;
864 {
865 func (stream, "%s", arm_regnames[given & 0xf]);
866
867 if ((given & 0xff0) != 0)
868 {
869 if ((given & 0x10) == 0)
870 {
871 int amount = (given & 0xf80) >> 7;
872 int shift = (given & 0x60) >> 5;
873
874 if (amount == 0)
875 {
876 if (shift == 3)
877 {
878 func (stream, ", rrx");
879 return;
880 }
881
882 amount = 32;
883 }
884
885 func (stream, ", %s #%d", arm_shift[shift], amount);
886 }
887 else
888 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
889 arm_regnames[(given & 0xf00) >> 8]);
890 }
891 }
892
893 static int
894 set_iwmmxt_regnames ()
895 {
896 const char * setname;
897 const char * setdesc;
898 const char ** regnames;
899 int iwmmxt_regnames = 0;
900 int num_regnames = get_arm_regname_num_options ();
901
902 get_arm_regnames (iwmmxt_regnames, &setname,
903 &setdesc, &regnames);
904 while ((strcmp ("iwmmxt_regnames", setname))
905 && (iwmmxt_regnames < num_regnames))
906 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
907
908 return iwmmxt_regnames;
909 }
910
911 /* Print one instruction from PC on INFO->STREAM.
912 Return the size of the instruction (always 4 on ARM). */
913
914 static int
915 print_insn_arm (pc, info, given)
916 bfd_vma pc;
917 struct disassemble_info *info;
918 long given;
919 {
920 const struct arm_opcode *insn;
921 void *stream = info->stream;
922 fprintf_ftype func = info->fprintf_func;
923 static int iwmmxt_regnames = 0;
924
925 for (insn = arm_opcodes; insn->assembler; insn++)
926 {
927 if (insn->value == FIRST_IWMMXT_INSN
928 && info->mach != bfd_mach_arm_XScale
929 && info->mach != bfd_mach_arm_iWMMXt)
930 insn = insn + IWMMXT_INSN_COUNT;
931
932 if ((given & insn->mask) == insn->value)
933 {
934 char * c;
935
936 for (c = insn->assembler; *c; c++)
937 {
938 if (*c == '%')
939 {
940 switch (*++c)
941 {
942 case '%':
943 func (stream, "%%");
944 break;
945
946 case 'a':
947 if (((given & 0x000f0000) == 0x000f0000)
948 && ((given & 0x02000000) == 0))
949 {
950 int offset = given & 0xfff;
951
952 func (stream, "[pc");
953
954 if (given & 0x01000000)
955 {
956 if ((given & 0x00800000) == 0)
957 offset = - offset;
958
959 /* Pre-indexed. */
960 func (stream, ", #%d]", offset);
961
962 offset += pc + 8;
963
964 /* Cope with the possibility of write-back
965 being used. Probably a very dangerous thing
966 for the programmer to do, but who are we to
967 argue ? */
968 if (given & 0x00200000)
969 func (stream, "!");
970 }
971 else
972 {
973 /* Post indexed. */
974 func (stream, "], #%d", offset);
975
976 /* ie ignore the offset. */
977 offset = pc + 8;
978 }
979
980 func (stream, "\t; ");
981 info->print_address_func (offset, info);
982 }
983 else
984 {
985 func (stream, "[%s",
986 arm_regnames[(given >> 16) & 0xf]);
987 if ((given & 0x01000000) != 0)
988 {
989 if ((given & 0x02000000) == 0)
990 {
991 int offset = given & 0xfff;
992 if (offset)
993 func (stream, ", #%s%d",
994 (((given & 0x00800000) == 0)
995 ? "-" : ""), offset);
996 }
997 else
998 {
999 func (stream, ", %s",
1000 (((given & 0x00800000) == 0)
1001 ? "-" : ""));
1002 arm_decode_shift (given, func, stream);
1003 }
1004
1005 func (stream, "]%s",
1006 ((given & 0x00200000) != 0) ? "!" : "");
1007 }
1008 else
1009 {
1010 if ((given & 0x02000000) == 0)
1011 {
1012 int offset = given & 0xfff;
1013 if (offset)
1014 func (stream, "], #%s%d",
1015 (((given & 0x00800000) == 0)
1016 ? "-" : ""), offset);
1017 else
1018 func (stream, "]");
1019 }
1020 else
1021 {
1022 func (stream, "], %s",
1023 (((given & 0x00800000) == 0)
1024 ? "-" : ""));
1025 arm_decode_shift (given, func, stream);
1026 }
1027 }
1028 }
1029 break;
1030
1031 case 's':
1032 if ((given & 0x004f0000) == 0x004f0000)
1033 {
1034 /* PC relative with immediate offset. */
1035 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1036
1037 if ((given & 0x00800000) == 0)
1038 offset = -offset;
1039
1040 func (stream, "[pc, #%d]\t; ", offset);
1041
1042 (*info->print_address_func)
1043 (offset + pc + 8, info);
1044 }
1045 else
1046 {
1047 func (stream, "[%s",
1048 arm_regnames[(given >> 16) & 0xf]);
1049 if ((given & 0x01000000) != 0)
1050 {
1051 /* Pre-indexed. */
1052 if ((given & 0x00400000) == 0x00400000)
1053 {
1054 /* Immediate. */
1055 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1056 if (offset)
1057 func (stream, ", #%s%d",
1058 (((given & 0x00800000) == 0)
1059 ? "-" : ""), offset);
1060 }
1061 else
1062 {
1063 /* Register. */
1064 func (stream, ", %s%s",
1065 (((given & 0x00800000) == 0)
1066 ? "-" : ""),
1067 arm_regnames[given & 0xf]);
1068 }
1069
1070 func (stream, "]%s",
1071 ((given & 0x00200000) != 0) ? "!" : "");
1072 }
1073 else
1074 {
1075 /* Post-indexed. */
1076 if ((given & 0x00400000) == 0x00400000)
1077 {
1078 /* Immediate. */
1079 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1080 if (offset)
1081 func (stream, "], #%s%d",
1082 (((given & 0x00800000) == 0)
1083 ? "-" : ""), offset);
1084 else
1085 func (stream, "]");
1086 }
1087 else
1088 {
1089 /* Register. */
1090 func (stream, "], %s%s",
1091 (((given & 0x00800000) == 0)
1092 ? "-" : ""),
1093 arm_regnames[given & 0xf]);
1094 }
1095 }
1096 }
1097 break;
1098
1099 case 'b':
1100 (*info->print_address_func)
1101 (BDISP (given) * 4 + pc + 8, info);
1102 break;
1103
1104 case 'c':
1105 func (stream, "%s",
1106 arm_conditional [(given >> 28) & 0xf]);
1107 break;
1108
1109 case 'm':
1110 {
1111 int started = 0;
1112 int reg;
1113
1114 func (stream, "{");
1115 for (reg = 0; reg < 16; reg++)
1116 if ((given & (1 << reg)) != 0)
1117 {
1118 if (started)
1119 func (stream, ", ");
1120 started = 1;
1121 func (stream, "%s", arm_regnames[reg]);
1122 }
1123 func (stream, "}");
1124 }
1125 break;
1126
1127 case 'o':
1128 if ((given & 0x02000000) != 0)
1129 {
1130 int rotate = (given & 0xf00) >> 7;
1131 int immed = (given & 0xff);
1132 immed = (((immed << (32 - rotate))
1133 | (immed >> rotate)) & 0xffffffff);
1134 func (stream, "#%d\t; 0x%x", immed, immed);
1135 }
1136 else
1137 arm_decode_shift (given, func, stream);
1138 break;
1139
1140 case 'p':
1141 if ((given & 0x0000f000) == 0x0000f000)
1142 func (stream, "p");
1143 break;
1144
1145 case 't':
1146 if ((given & 0x01200000) == 0x00200000)
1147 func (stream, "t");
1148 break;
1149
1150 case 'A':
1151 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1152
1153 if ((given & (1 << 24)) != 0)
1154 {
1155 int offset = given & 0xff;
1156
1157 if (offset)
1158 func (stream, ", #%s%d]%s",
1159 ((given & 0x00800000) == 0 ? "-" : ""),
1160 offset * 4,
1161 ((given & 0x00200000) != 0 ? "!" : ""));
1162 else
1163 func (stream, "]");
1164 }
1165 else
1166 {
1167 int offset = given & 0xff;
1168
1169 func (stream, "]");
1170
1171 if (given & (1 << 21))
1172 {
1173 if (offset)
1174 func (stream, ", #%s%d",
1175 ((given & 0x00800000) == 0 ? "-" : ""),
1176 offset * 4);
1177 }
1178 else
1179 func (stream, ", {%d}", offset);
1180 }
1181 break;
1182
1183 case 'B':
1184 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1185 {
1186 bfd_vma address;
1187 bfd_vma offset = 0;
1188
1189 if (given & 0x00800000)
1190 /* Is signed, hi bits should be ones. */
1191 offset = (-1) ^ 0x00ffffff;
1192
1193 /* Offset is (SignExtend(offset field)<<2). */
1194 offset += given & 0x00ffffff;
1195 offset <<= 2;
1196 address = offset + pc + 8;
1197
1198 if (given & 0x01000000)
1199 /* H bit allows addressing to 2-byte boundaries. */
1200 address += 2;
1201
1202 info->print_address_func (address, info);
1203 }
1204 break;
1205
1206 case 'I':
1207 /* Print a Cirrus/DSP shift immediate. */
1208 /* Immediates are 7bit signed ints with bits 0..3 in
1209 bits 0..3 of opcode and bits 4..6 in bits 5..7
1210 of opcode. */
1211 {
1212 int imm;
1213
1214 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1215
1216 /* Is ``imm'' a negative number? */
1217 if (imm & 0x40)
1218 imm |= (-1 << 7);
1219
1220 func (stream, "%d", imm);
1221 }
1222
1223 break;
1224
1225 case 'C':
1226 func (stream, "_");
1227 if (given & 0x80000)
1228 func (stream, "f");
1229 if (given & 0x40000)
1230 func (stream, "s");
1231 if (given & 0x20000)
1232 func (stream, "x");
1233 if (given & 0x10000)
1234 func (stream, "c");
1235 break;
1236
1237 case 'F':
1238 switch (given & 0x00408000)
1239 {
1240 case 0:
1241 func (stream, "4");
1242 break;
1243 case 0x8000:
1244 func (stream, "1");
1245 break;
1246 case 0x00400000:
1247 func (stream, "2");
1248 break;
1249 default:
1250 func (stream, "3");
1251 }
1252 break;
1253
1254 case 'P':
1255 switch (given & 0x00080080)
1256 {
1257 case 0:
1258 func (stream, "s");
1259 break;
1260 case 0x80:
1261 func (stream, "d");
1262 break;
1263 case 0x00080000:
1264 func (stream, "e");
1265 break;
1266 default:
1267 func (stream, _("<illegal precision>"));
1268 break;
1269 }
1270 break;
1271 case 'Q':
1272 switch (given & 0x00408000)
1273 {
1274 case 0:
1275 func (stream, "s");
1276 break;
1277 case 0x8000:
1278 func (stream, "d");
1279 break;
1280 case 0x00400000:
1281 func (stream, "e");
1282 break;
1283 default:
1284 func (stream, "p");
1285 break;
1286 }
1287 break;
1288 case 'R':
1289 switch (given & 0x60)
1290 {
1291 case 0:
1292 break;
1293 case 0x20:
1294 func (stream, "p");
1295 break;
1296 case 0x40:
1297 func (stream, "m");
1298 break;
1299 default:
1300 func (stream, "z");
1301 break;
1302 }
1303 break;
1304
1305 case '0': case '1': case '2': case '3': case '4':
1306 case '5': case '6': case '7': case '8': case '9':
1307 {
1308 int bitstart = *c++ - '0';
1309 int bitend = 0;
1310 while (*c >= '0' && *c <= '9')
1311 bitstart = (bitstart * 10) + *c++ - '0';
1312
1313 switch (*c)
1314 {
1315 case '-':
1316 c++;
1317
1318 while (*c >= '0' && *c <= '9')
1319 bitend = (bitend * 10) + *c++ - '0';
1320
1321 if (!bitend)
1322 abort ();
1323
1324 switch (*c)
1325 {
1326 case 'r':
1327 {
1328 long reg;
1329
1330 reg = given >> bitstart;
1331 reg &= (2 << (bitend - bitstart)) - 1;
1332
1333 func (stream, "%s", arm_regnames[reg]);
1334 }
1335 break;
1336 case 'd':
1337 {
1338 long reg;
1339
1340 reg = given >> bitstart;
1341 reg &= (2 << (bitend - bitstart)) - 1;
1342
1343 func (stream, "%d", reg);
1344 }
1345 break;
1346 case 'W':
1347 {
1348 long reg;
1349
1350 reg = given >> bitstart;
1351 reg &= (2 << (bitend - bitstart)) - 1;
1352
1353 func (stream, "%d", reg + 1);
1354 }
1355 break;
1356 case 'x':
1357 {
1358 long reg;
1359
1360 reg = given >> bitstart;
1361 reg &= (2 << (bitend - bitstart)) - 1;
1362
1363 func (stream, "0x%08x", reg);
1364
1365 /* Some SWI instructions have special
1366 meanings. */
1367 if ((given & 0x0fffffff) == 0x0FF00000)
1368 func (stream, "\t; IMB");
1369 else if ((given & 0x0fffffff) == 0x0FF00001)
1370 func (stream, "\t; IMBRange");
1371 }
1372 break;
1373 case 'X':
1374 {
1375 long reg;
1376
1377 reg = given >> bitstart;
1378 reg &= (2 << (bitend - bitstart)) - 1;
1379
1380 func (stream, "%01x", reg & 0xf);
1381 }
1382 break;
1383 case 'f':
1384 {
1385 long reg;
1386
1387 reg = given >> bitstart;
1388 reg &= (2 << (bitend - bitstart)) - 1;
1389
1390 if (reg > 7)
1391 func (stream, "#%s",
1392 arm_fp_const[reg & 7]);
1393 else
1394 func (stream, "f%d", reg);
1395 }
1396 break;
1397
1398 case 'w':
1399 {
1400 long reg;
1401
1402 if (bitstart != bitend)
1403 {
1404 reg = given >> bitstart;
1405 reg &= (2 << (bitend - bitstart)) - 1;
1406 if (bitend - bitstart == 1)
1407 func (stream, "%s", iwmmxt_wwnames[reg]);
1408 else
1409 func (stream, "%s", iwmmxt_wwssnames[reg]);
1410 }
1411 else
1412 {
1413 reg = (((given >> 8) & 0x1) |
1414 ((given >> 22) & 0x1));
1415 func (stream, "%s", iwmmxt_wwnames[reg]);
1416 }
1417 }
1418 break;
1419
1420 case 'g':
1421 {
1422 long reg;
1423 int current_regnames;
1424
1425 if (! iwmmxt_regnames)
1426 iwmmxt_regnames = set_iwmmxt_regnames ();
1427 current_regnames = set_arm_regname_option
1428 (iwmmxt_regnames);
1429
1430 reg = given >> bitstart;
1431 reg &= (2 << (bitend - bitstart)) - 1;
1432 func (stream, "%s", arm_regnames[reg]);
1433 set_arm_regname_option (current_regnames);
1434 }
1435 break;
1436
1437 case 'G':
1438 {
1439 long reg;
1440 int current_regnames;
1441
1442 if (! iwmmxt_regnames)
1443 iwmmxt_regnames = set_iwmmxt_regnames ();
1444 current_regnames = set_arm_regname_option
1445 (iwmmxt_regnames + 1);
1446
1447 reg = given >> bitstart;
1448 reg &= (2 << (bitend - bitstart)) - 1;
1449 func (stream, "%s", arm_regnames[reg]);
1450 set_arm_regname_option (current_regnames);
1451 }
1452 break;
1453
1454 default:
1455 abort ();
1456 }
1457 break;
1458
1459 case 'y':
1460 case 'z':
1461 {
1462 int single = *c == 'y';
1463 int regno;
1464
1465 switch (bitstart)
1466 {
1467 case 4: /* Sm pair */
1468 func (stream, "{");
1469 /* Fall through. */
1470 case 0: /* Sm, Dm */
1471 regno = given & 0x0000000f;
1472 if (single)
1473 {
1474 regno <<= 1;
1475 regno += (given >> 5) & 1;
1476 }
1477 break;
1478
1479 case 1: /* Sd, Dd */
1480 regno = (given >> 12) & 0x0000000f;
1481 if (single)
1482 {
1483 regno <<= 1;
1484 regno += (given >> 22) & 1;
1485 }
1486 break;
1487
1488 case 2: /* Sn, Dn */
1489 regno = (given >> 16) & 0x0000000f;
1490 if (single)
1491 {
1492 regno <<= 1;
1493 regno += (given >> 7) & 1;
1494 }
1495 break;
1496
1497 case 3: /* List */
1498 func (stream, "{");
1499 regno = (given >> 12) & 0x0000000f;
1500 if (single)
1501 {
1502 regno <<= 1;
1503 regno += (given >> 22) & 1;
1504 }
1505 break;
1506
1507
1508 default:
1509 abort ();
1510 }
1511
1512 func (stream, "%c%d", single ? 's' : 'd', regno);
1513
1514 if (bitstart == 3)
1515 {
1516 int count = given & 0xff;
1517
1518 if (single == 0)
1519 count >>= 1;
1520
1521 if (--count)
1522 {
1523 func (stream, "-%c%d",
1524 single ? 's' : 'd',
1525 regno + count);
1526 }
1527
1528 func (stream, "}");
1529 }
1530 else if (bitstart == 4)
1531 func (stream, ", %c%d}", single ? 's' : 'd',
1532 regno + 1);
1533
1534 break;
1535 }
1536
1537 case '`':
1538 c++;
1539 if ((given & (1 << bitstart)) == 0)
1540 func (stream, "%c", *c);
1541 break;
1542 case '\'':
1543 c++;
1544 if ((given & (1 << bitstart)) != 0)
1545 func (stream, "%c", *c);
1546 break;
1547 case '?':
1548 ++c;
1549 if ((given & (1 << bitstart)) != 0)
1550 func (stream, "%c", *c++);
1551 else
1552 func (stream, "%c", *++c);
1553 break;
1554 default:
1555 abort ();
1556 }
1557 break;
1558
1559 case 'L':
1560 switch (given & 0x00400100)
1561 {
1562 case 0x00000000: func (stream, "b"); break;
1563 case 0x00400000: func (stream, "h"); break;
1564 case 0x00000100: func (stream, "w"); break;
1565 case 0x00400100: func (stream, "d"); break;
1566 default:
1567 break;
1568 }
1569 break;
1570
1571 case 'Z':
1572 {
1573 int value;
1574 /* given (20, 23) | given (0, 3) */
1575 value = ((given >> 16) & 0xf0) | (given & 0xf);
1576 func (stream, "%d", value);
1577 }
1578 break;
1579
1580 case 'l':
1581 /* This is like the 'A' operator, except that if
1582 the width field "M" is zero, then the offset is
1583 *not* multiplied by four. */
1584 {
1585 int offset = given & 0xff;
1586 int multiplier = (given & 0x00000100) ? 4 : 1;
1587
1588 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1589
1590 if (offset)
1591 {
1592 if ((given & 0x01000000) != 0)
1593 func (stream, ", #%s%d]%s",
1594 ((given & 0x00800000) == 0 ? "-" : ""),
1595 offset * multiplier,
1596 ((given & 0x00200000) != 0 ? "!" : ""));
1597 else
1598 func (stream, "], #%s%d",
1599 ((given & 0x00800000) == 0 ? "-" : ""),
1600 offset * multiplier);
1601 }
1602 else
1603 func (stream, "]");
1604 }
1605 break;
1606
1607 case 'e':
1608 {
1609 int imm;
1610
1611 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1612 func (stream, "%d", imm);
1613 }
1614 break;
1615
1616 default:
1617 abort ();
1618 }
1619 }
1620 }
1621 else
1622 func (stream, "%c", *c);
1623 }
1624 return 4;
1625 }
1626 }
1627 abort ();
1628 }
1629
1630 /* Print one instruction from PC on INFO->STREAM.
1631 Return the size of the instruction. */
1632
1633 static int
1634 print_insn_thumb (pc, info, given)
1635 bfd_vma pc;
1636 struct disassemble_info *info;
1637 long given;
1638 {
1639 const struct thumb_opcode *insn;
1640 void *stream = info->stream;
1641 fprintf_ftype func = info->fprintf_func;
1642
1643 for (insn = thumb_opcodes; insn->assembler; insn++)
1644 {
1645 if ((given & insn->mask) == insn->value)
1646 {
1647 char * c = insn->assembler;
1648
1649 /* Special processing for Thumb 2 instruction BL sequence: */
1650 if (!*c) /* Check for empty (not NULL) assembler string. */
1651 {
1652 long offset;
1653
1654 info->bytes_per_chunk = 4;
1655 info->bytes_per_line = 4;
1656
1657 offset = BDISP23 (given);
1658 offset = offset * 2 + pc + 4;
1659
1660 if ((given & 0x10000000) == 0)
1661 {
1662 func (stream, "blx\t");
1663 offset &= 0xfffffffc;
1664 }
1665 else
1666 func (stream, "bl\t");
1667
1668 info->print_address_func (offset, info);
1669 return 4;
1670 }
1671 else
1672 {
1673 info->bytes_per_chunk = 2;
1674 info->bytes_per_line = 4;
1675
1676 given &= 0xffff;
1677
1678 for (; *c; c++)
1679 {
1680 if (*c == '%')
1681 {
1682 int domaskpc = 0;
1683 int domasklr = 0;
1684
1685 switch (*++c)
1686 {
1687 case '%':
1688 func (stream, "%%");
1689 break;
1690
1691 case 'S':
1692 {
1693 long reg;
1694
1695 reg = (given >> 3) & 0x7;
1696 if (given & (1 << 6))
1697 reg += 8;
1698
1699 func (stream, "%s", arm_regnames[reg]);
1700 }
1701 break;
1702
1703 case 'D':
1704 {
1705 long reg;
1706
1707 reg = given & 0x7;
1708 if (given & (1 << 7))
1709 reg += 8;
1710
1711 func (stream, "%s", arm_regnames[reg]);
1712 }
1713 break;
1714
1715 case 'T':
1716 func (stream, "%s",
1717 arm_conditional [(given >> 8) & 0xf]);
1718 break;
1719
1720 case 'N':
1721 if (given & (1 << 8))
1722 domasklr = 1;
1723 /* Fall through. */
1724 case 'O':
1725 if (*c == 'O' && (given & (1 << 8)))
1726 domaskpc = 1;
1727 /* Fall through. */
1728 case 'M':
1729 {
1730 int started = 0;
1731 int reg;
1732
1733 func (stream, "{");
1734
1735 /* It would be nice if we could spot
1736 ranges, and generate the rS-rE format: */
1737 for (reg = 0; (reg < 8); reg++)
1738 if ((given & (1 << reg)) != 0)
1739 {
1740 if (started)
1741 func (stream, ", ");
1742 started = 1;
1743 func (stream, "%s", arm_regnames[reg]);
1744 }
1745
1746 if (domasklr)
1747 {
1748 if (started)
1749 func (stream, ", ");
1750 started = 1;
1751 func (stream, arm_regnames[14] /* "lr" */);
1752 }
1753
1754 if (domaskpc)
1755 {
1756 if (started)
1757 func (stream, ", ");
1758 func (stream, arm_regnames[15] /* "pc" */);
1759 }
1760
1761 func (stream, "}");
1762 }
1763 break;
1764
1765
1766 case '0': case '1': case '2': case '3': case '4':
1767 case '5': case '6': case '7': case '8': case '9':
1768 {
1769 int bitstart = *c++ - '0';
1770 int bitend = 0;
1771
1772 while (*c >= '0' && *c <= '9')
1773 bitstart = (bitstart * 10) + *c++ - '0';
1774
1775 switch (*c)
1776 {
1777 case '-':
1778 {
1779 long reg;
1780
1781 c++;
1782 while (*c >= '0' && *c <= '9')
1783 bitend = (bitend * 10) + *c++ - '0';
1784 if (!bitend)
1785 abort ();
1786 reg = given >> bitstart;
1787 reg &= (2 << (bitend - bitstart)) - 1;
1788 switch (*c)
1789 {
1790 case 'r':
1791 func (stream, "%s", arm_regnames[reg]);
1792 break;
1793
1794 case 'd':
1795 func (stream, "%d", reg);
1796 break;
1797
1798 case 'H':
1799 func (stream, "%d", reg << 1);
1800 break;
1801
1802 case 'W':
1803 func (stream, "%d", reg << 2);
1804 break;
1805
1806 case 'a':
1807 /* PC-relative address -- the bottom two
1808 bits of the address are dropped
1809 before the calculation. */
1810 info->print_address_func
1811 (((pc + 4) & ~3) + (reg << 2), info);
1812 break;
1813
1814 case 'x':
1815 func (stream, "0x%04x", reg);
1816 break;
1817
1818 case 'I':
1819 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1820 func (stream, "%d", reg);
1821 break;
1822
1823 case 'B':
1824 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1825 (*info->print_address_func)
1826 (reg * 2 + pc + 4, info);
1827 break;
1828
1829 default:
1830 abort ();
1831 }
1832 }
1833 break;
1834
1835 case '\'':
1836 c++;
1837 if ((given & (1 << bitstart)) != 0)
1838 func (stream, "%c", *c);
1839 break;
1840
1841 case '?':
1842 ++c;
1843 if ((given & (1 << bitstart)) != 0)
1844 func (stream, "%c", *c++);
1845 else
1846 func (stream, "%c", *++c);
1847 break;
1848
1849 default:
1850 abort ();
1851 }
1852 }
1853 break;
1854
1855 default:
1856 abort ();
1857 }
1858 }
1859 else
1860 func (stream, "%c", *c);
1861 }
1862 }
1863 return 2;
1864 }
1865 }
1866
1867 /* No match. */
1868 abort ();
1869 }
1870
1871 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1872 being displayed in symbol relative addresses. */
1873
1874 bfd_boolean
1875 arm_symbol_is_valid (asymbol * sym,
1876 struct disassemble_info * info ATTRIBUTE_UNUSED)
1877 {
1878 const char * name;
1879
1880 if (sym == NULL)
1881 return FALSE;
1882
1883 name = bfd_asymbol_name (sym);
1884
1885 return (name && *name != '$');
1886 }
1887
1888 /* Parse an individual disassembler option. */
1889
1890 void
1891 parse_arm_disassembler_option (option)
1892 char * option;
1893 {
1894 if (option == NULL)
1895 return;
1896
1897 if (strneq (option, "reg-names-", 10))
1898 {
1899 int i;
1900
1901 option += 10;
1902
1903 for (i = NUM_ARM_REGNAMES; i--;)
1904 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1905 {
1906 regname_selected = i;
1907 break;
1908 }
1909
1910 if (i < 0)
1911 /* XXX - should break 'option' at following delimiter. */
1912 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
1913 }
1914 else if (strneq (option, "force-thumb", 11))
1915 force_thumb = 1;
1916 else if (strneq (option, "no-force-thumb", 14))
1917 force_thumb = 0;
1918 else
1919 /* XXX - should break 'option' at following delimiter. */
1920 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
1921
1922 return;
1923 }
1924
1925 /* Parse the string of disassembler options, spliting it at whitespaces
1926 or commas. (Whitespace separators supported for backwards compatibility). */
1927
1928 static void
1929 parse_disassembler_options (options)
1930 char * options;
1931 {
1932 if (options == NULL)
1933 return;
1934
1935 while (*options)
1936 {
1937 parse_arm_disassembler_option (options);
1938
1939 /* Skip forward to next seperator. */
1940 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
1941 ++ options;
1942 /* Skip forward past seperators. */
1943 while (ISSPACE (*options) || (*options == ','))
1944 ++ options;
1945 }
1946 }
1947
1948 /* NOTE: There are no checks in these routines that
1949 the relevant number of data bytes exist. */
1950
1951 static int
1952 print_insn (pc, info, little)
1953 bfd_vma pc;
1954 struct disassemble_info * info;
1955 bfd_boolean little;
1956 {
1957 unsigned char b[4];
1958 long given;
1959 int status;
1960 int is_thumb, second_half_valid = 1;
1961
1962 if (info->disassembler_options)
1963 {
1964 parse_disassembler_options (info->disassembler_options);
1965
1966 /* To avoid repeated parsing of these options, we remove them here. */
1967 info->disassembler_options = NULL;
1968 }
1969
1970 is_thumb = force_thumb;
1971
1972 if (!is_thumb && info->symbols != NULL)
1973 {
1974 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
1975 {
1976 coff_symbol_type * cs;
1977
1978 cs = coffsymbol (*info->symbols);
1979 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
1980 || cs->native->u.syment.n_sclass == C_THUMBSTAT
1981 || cs->native->u.syment.n_sclass == C_THUMBLABEL
1982 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
1983 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
1984 }
1985 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
1986 {
1987 elf_symbol_type * es;
1988 unsigned int type;
1989
1990 es = *(elf_symbol_type **)(info->symbols);
1991 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
1992
1993 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
1994 }
1995 }
1996
1997 info->bytes_per_chunk = 4;
1998 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
1999
2000 if (little)
2001 {
2002 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
2003 if (status != 0 && is_thumb)
2004 {
2005 info->bytes_per_chunk = 2;
2006 second_half_valid = 0;
2007
2008 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
2009 b[3] = b[2] = 0;
2010 }
2011
2012 if (status != 0)
2013 {
2014 info->memory_error_func (status, pc, info);
2015 return -1;
2016 }
2017
2018 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2019 }
2020 else
2021 {
2022 status = info->read_memory_func
2023 (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
2024 if (status != 0)
2025 {
2026 info->memory_error_func (status, WORD_ADDRESS (pc), info);
2027 return -1;
2028 }
2029
2030 if (is_thumb)
2031 {
2032 if (pc & 0x2)
2033 {
2034 given = (b[2] << 8) | b[3];
2035
2036 status = info->read_memory_func
2037 (WORD_ADDRESS (pc + 4), (bfd_byte *) b, 4, info);
2038 if (status != 0)
2039 second_half_valid = 0;
2040 else
2041 given |= (b[0] << 24) | (b[1] << 16);
2042 }
2043 else
2044 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
2045 }
2046 else
2047 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
2048 }
2049
2050 if (info->flags & INSN_HAS_RELOC)
2051 /* If the instruction has a reloc associated with it, then
2052 the offset field in the instruction will actually be the
2053 addend for the reloc. (We are using REL type relocs).
2054 In such cases, we can ignore the pc when computing
2055 addresses, since the addend is not currently pc-relative. */
2056 pc = 0;
2057
2058 if (is_thumb)
2059 status = print_insn_thumb (pc, info, given);
2060 else
2061 status = print_insn_arm (pc, info, given);
2062
2063 if (is_thumb && status == 4 && second_half_valid == 0)
2064 {
2065 info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
2066 return -1;
2067 }
2068
2069 return status;
2070 }
2071
2072 int
2073 print_insn_big_arm (pc, info)
2074 bfd_vma pc;
2075 struct disassemble_info * info;
2076 {
2077 return print_insn (pc, info, FALSE);
2078 }
2079
2080 int
2081 print_insn_little_arm (pc, info)
2082 bfd_vma pc;
2083 struct disassemble_info * info;
2084 {
2085 return print_insn (pc, info, TRUE);
2086 }
2087
2088 void
2089 print_arm_disassembler_options (FILE * stream)
2090 {
2091 int i;
2092
2093 fprintf (stream, _("\n\
2094 The following ARM specific disassembler options are supported for use with\n\
2095 the -M switch:\n"));
2096
2097 for (i = NUM_ARM_REGNAMES; i--;)
2098 fprintf (stream, " reg-names-%s %*c%s\n",
2099 regnames[i].name,
2100 (int)(14 - strlen (regnames[i].name)), ' ',
2101 regnames[i].description);
2102
2103 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
2104 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
2105 }
This page took 0.09636 seconds and 4 git commands to generate.