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