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