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