Add cutoff for changes in 2.16 release
[binutils.git] / opcodes / arm-dis.c
bloba87bcc0b2f839f56041c663c3ab26891edcac537
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)
7 This file is part of libopcodes.
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.
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.
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. */
23 #include "sysdep.h"
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"
33 /* FIXME: This shouldn't be done here. */
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
38 #ifndef streq
39 #define streq(a,b) (strcmp ((a), (b)) == 0)
40 #endif
42 #ifndef strneq
43 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
44 #endif
46 #ifndef NUM_ELEM
47 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
48 #endif
50 #define WORD_ADDRESS(pc) ((pc) & ~0x3)
52 /* Format of the disassembler control string :
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). */
109 /* Note: There is a partial ordering in this table - it must be searched from
110 the top to obtain a correct match. */
112 static const struct arm_opcode arm_opcodes[] =
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"},
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"},
134 /* ARM V6Z instructions. */
135 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
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]"},
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}"},
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"},
279 /* V5J instruction. */
280 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
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"},
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"},
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}"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
629 /* The rest. */
630 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
631 {0, 0x00000000, 0x00000000, 0}
634 static const struct thumb_opcode thumb_opcodes[] =
636 /* Thumb instructions. */
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"},
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"},
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}
773 static char * arm_conditional[] =
774 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
775 "hi", "ls", "ge", "lt", "gt", "le", "", "nv"};
777 typedef struct
779 const char * name;
780 const char * description;
781 const char * reg_names[16];
783 arm_regname;
785 static arm_regname regnames[] =
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"}}
805 static char * iwmmxt_wwnames[] =
806 {"b", "h", "w", "d"};
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"
815 /* Default to GCC register name set. */
816 static unsigned int regname_selected = 1;
818 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
819 #define arm_regnames regnames[regname_selected].reg_names
821 static bfd_boolean force_thumb = FALSE;
823 static char * arm_fp_const[] =
824 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
826 static char * arm_shift[] =
827 {"lsl", "lsr", "asr", "ror"};
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));
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 ***));
850 /* Functions. */
852 get_arm_regname_num_options ()
854 return NUM_ARM_REGNAMES;
858 set_arm_regname_option (option)
859 int option;
861 int old = regname_selected;
862 regname_selected = option;
863 return old;
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;
873 *setname = regnames[option].name;
874 *setdescription = regnames[option].description;
875 *register_names = regnames[option].reg_names;
876 return 16;
879 static void
880 arm_decode_shift (given, func, stream)
881 long given;
882 fprintf_ftype func;
883 void * stream;
885 func (stream, "%s", arm_regnames[given & 0xf]);
887 if ((given & 0xff0) != 0)
889 if ((given & 0x10) == 0)
891 int amount = (given & 0xf80) >> 7;
892 int shift = (given & 0x60) >> 5;
894 if (amount == 0)
896 if (shift == 3)
898 func (stream, ", rrx");
899 return;
902 amount = 32;
905 func (stream, ", %s #%d", arm_shift[shift], amount);
907 else
908 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
909 arm_regnames[(given & 0xf00) >> 8]);
913 static int
914 set_iwmmxt_regnames ()
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 ();
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);
928 return iwmmxt_regnames;
931 /* Print one instruction from PC on INFO->STREAM.
932 Return the size of the instruction (always 4 on ARM). */
934 static int
935 print_insn_arm (pc, info, given)
936 bfd_vma pc;
937 struct disassemble_info *info;
938 long given;
940 const struct arm_opcode *insn;
941 void *stream = info->stream;
942 fprintf_ftype func = info->fprintf_func;
943 static int iwmmxt_regnames = 0;
945 for (insn = arm_opcodes; insn->assembler; insn++)
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;
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)))
960 char * c;
962 for (c = insn->assembler; *c; c++)
964 if (*c == '%')
966 switch (*++c)
968 case '%':
969 func (stream, "%%");
970 break;
972 case 'a':
973 if (((given & 0x000f0000) == 0x000f0000)
974 && ((given & 0x02000000) == 0))
976 int offset = given & 0xfff;
978 func (stream, "[pc");
980 if (given & 0x01000000)
982 if ((given & 0x00800000) == 0)
983 offset = - offset;
985 /* Pre-indexed. */
986 func (stream, ", #%d]", offset);
988 offset += pc + 8;
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, "!");
997 else
999 /* Post indexed. */
1000 func (stream, "], #%d", offset);
1002 /* ie ignore the offset. */
1003 offset = pc + 8;
1006 func (stream, "\t; ");
1007 info->print_address_func (offset, info);
1009 else
1011 func (stream, "[%s",
1012 arm_regnames[(given >> 16) & 0xf]);
1013 if ((given & 0x01000000) != 0)
1015 if ((given & 0x02000000) == 0)
1017 int offset = given & 0xfff;
1018 if (offset)
1019 func (stream, ", #%s%d",
1020 (((given & 0x00800000) == 0)
1021 ? "-" : ""), offset);
1023 else
1025 func (stream, ", %s",
1026 (((given & 0x00800000) == 0)
1027 ? "-" : ""));
1028 arm_decode_shift (given, func, stream);
1031 func (stream, "]%s",
1032 ((given & 0x00200000) != 0) ? "!" : "");
1034 else
1036 if ((given & 0x02000000) == 0)
1038 int offset = given & 0xfff;
1039 if (offset)
1040 func (stream, "], #%s%d",
1041 (((given & 0x00800000) == 0)
1042 ? "-" : ""), offset);
1043 else
1044 func (stream, "]");
1046 else
1048 func (stream, "], %s",
1049 (((given & 0x00800000) == 0)
1050 ? "-" : ""));
1051 arm_decode_shift (given, func, stream);
1055 break;
1057 case 's':
1058 if ((given & 0x004f0000) == 0x004f0000)
1060 /* PC relative with immediate offset. */
1061 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1063 if ((given & 0x00800000) == 0)
1064 offset = -offset;
1066 func (stream, "[pc, #%d]\t; ", offset);
1068 (*info->print_address_func)
1069 (offset + pc + 8, info);
1071 else
1073 func (stream, "[%s",
1074 arm_regnames[(given >> 16) & 0xf]);
1075 if ((given & 0x01000000) != 0)
1077 /* Pre-indexed. */
1078 if ((given & 0x00400000) == 0x00400000)
1080 /* Immediate. */
1081 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1082 if (offset)
1083 func (stream, ", #%s%d",
1084 (((given & 0x00800000) == 0)
1085 ? "-" : ""), offset);
1087 else
1089 /* Register. */
1090 func (stream, ", %s%s",
1091 (((given & 0x00800000) == 0)
1092 ? "-" : ""),
1093 arm_regnames[given & 0xf]);
1096 func (stream, "]%s",
1097 ((given & 0x00200000) != 0) ? "!" : "");
1099 else
1101 /* Post-indexed. */
1102 if ((given & 0x00400000) == 0x00400000)
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, "]");
1113 else
1115 /* Register. */
1116 func (stream, "], %s%s",
1117 (((given & 0x00800000) == 0)
1118 ? "-" : ""),
1119 arm_regnames[given & 0xf]);
1123 break;
1125 case 'b':
1126 (*info->print_address_func)
1127 (BDISP (given) * 4 + pc + 8, info);
1128 break;
1130 case 'c':
1131 func (stream, "%s",
1132 arm_conditional [(given >> 28) & 0xf]);
1133 break;
1135 case 'm':
1137 int started = 0;
1138 int reg;
1140 func (stream, "{");
1141 for (reg = 0; reg < 16; reg++)
1142 if ((given & (1 << reg)) != 0)
1144 if (started)
1145 func (stream, ", ");
1146 started = 1;
1147 func (stream, "%s", arm_regnames[reg]);
1149 func (stream, "}");
1151 break;
1153 case 'o':
1154 if ((given & 0x02000000) != 0)
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);
1162 else
1163 arm_decode_shift (given, func, stream);
1164 break;
1166 case 'p':
1167 if ((given & 0x0000f000) == 0x0000f000)
1168 func (stream, "p");
1169 break;
1171 case 't':
1172 if ((given & 0x01200000) == 0x00200000)
1173 func (stream, "t");
1174 break;
1176 case 'A':
1177 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1179 if ((given & (1 << 24)) != 0)
1181 int offset = given & 0xff;
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, "]");
1191 else
1193 int offset = given & 0xff;
1195 func (stream, "]");
1197 if (given & (1 << 21))
1199 if (offset)
1200 func (stream, ", #%s%d",
1201 ((given & 0x00800000) == 0 ? "-" : ""),
1202 offset * 4);
1204 else
1205 func (stream, ", {%d}", offset);
1207 break;
1209 case 'B':
1210 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1212 bfd_vma address;
1213 bfd_vma offset = 0;
1215 if (given & 0x00800000)
1216 /* Is signed, hi bits should be ones. */
1217 offset = (-1) ^ 0x00ffffff;
1219 /* Offset is (SignExtend(offset field)<<2). */
1220 offset += given & 0x00ffffff;
1221 offset <<= 2;
1222 address = offset + pc + 8;
1224 if (given & 0x01000000)
1225 /* H bit allows addressing to 2-byte boundaries. */
1226 address += 2;
1228 info->print_address_func (address, info);
1230 break;
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. */
1238 int imm;
1240 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1242 /* Is ``imm'' a negative number? */
1243 if (imm & 0x40)
1244 imm |= (-1 << 7);
1246 func (stream, "%d", imm);
1249 break;
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;
1263 case 'F':
1264 switch (given & 0x00408000)
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");
1278 break;
1280 case 'P':
1281 switch (given & 0x00080080)
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;
1296 break;
1297 case 'Q':
1298 switch (given & 0x00408000)
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;
1313 break;
1314 case 'R':
1315 switch (given & 0x60)
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;
1329 break;
1331 case '0': case '1': case '2': case '3': case '4':
1332 case '5': case '6': case '7': case '8': case '9':
1334 int bitstart = *c++ - '0';
1335 int bitend = 0;
1336 while (*c >= '0' && *c <= '9')
1337 bitstart = (bitstart * 10) + *c++ - '0';
1339 switch (*c)
1341 case '-':
1342 c++;
1344 while (*c >= '0' && *c <= '9')
1345 bitend = (bitend * 10) + *c++ - '0';
1347 if (!bitend)
1348 abort ();
1350 switch (*c)
1352 case 'r':
1354 long reg;
1356 reg = given >> bitstart;
1357 reg &= (2 << (bitend - bitstart)) - 1;
1359 func (stream, "%s", arm_regnames[reg]);
1361 break;
1362 case 'd':
1364 long reg;
1366 reg = given >> bitstart;
1367 reg &= (2 << (bitend - bitstart)) - 1;
1369 func (stream, "%d", reg);
1371 break;
1372 case 'W':
1374 long reg;
1376 reg = given >> bitstart;
1377 reg &= (2 << (bitend - bitstart)) - 1;
1379 func (stream, "%d", reg + 1);
1381 break;
1382 case 'x':
1384 long reg;
1386 reg = given >> bitstart;
1387 reg &= (2 << (bitend - bitstart)) - 1;
1389 func (stream, "0x%08x", reg);
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");
1398 break;
1399 case 'X':
1401 long reg;
1403 reg = given >> bitstart;
1404 reg &= (2 << (bitend - bitstart)) - 1;
1406 func (stream, "%01x", reg & 0xf);
1408 break;
1409 case 'f':
1411 long reg;
1413 reg = given >> bitstart;
1414 reg &= (2 << (bitend - bitstart)) - 1;
1416 if (reg > 7)
1417 func (stream, "#%s",
1418 arm_fp_const[reg & 7]);
1419 else
1420 func (stream, "f%d", reg);
1422 break;
1424 case 'w':
1426 long reg;
1428 if (bitstart != bitend)
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]);
1437 else
1439 reg = (((given >> 8) & 0x1) |
1440 ((given >> 22) & 0x1));
1441 func (stream, "%s", iwmmxt_wwnames[reg]);
1444 break;
1446 case 'g':
1448 long reg;
1449 int current_regnames;
1451 if (! iwmmxt_regnames)
1452 iwmmxt_regnames = set_iwmmxt_regnames ();
1453 current_regnames = set_arm_regname_option
1454 (iwmmxt_regnames);
1456 reg = given >> bitstart;
1457 reg &= (2 << (bitend - bitstart)) - 1;
1458 func (stream, "%s", arm_regnames[reg]);
1459 set_arm_regname_option (current_regnames);
1461 break;
1463 case 'G':
1465 long reg;
1466 int current_regnames;
1468 if (! iwmmxt_regnames)
1469 iwmmxt_regnames = set_iwmmxt_regnames ();
1470 current_regnames = set_arm_regname_option
1471 (iwmmxt_regnames + 1);
1473 reg = given >> bitstart;
1474 reg &= (2 << (bitend - bitstart)) - 1;
1475 func (stream, "%s", arm_regnames[reg]);
1476 set_arm_regname_option (current_regnames);
1478 break;
1480 default:
1481 abort ();
1483 break;
1485 case 'y':
1486 case 'z':
1488 int single = *c == 'y';
1489 int regno;
1491 switch (bitstart)
1493 case 4: /* Sm pair */
1494 func (stream, "{");
1495 /* Fall through. */
1496 case 0: /* Sm, Dm */
1497 regno = given & 0x0000000f;
1498 if (single)
1500 regno <<= 1;
1501 regno += (given >> 5) & 1;
1503 break;
1505 case 1: /* Sd, Dd */
1506 regno = (given >> 12) & 0x0000000f;
1507 if (single)
1509 regno <<= 1;
1510 regno += (given >> 22) & 1;
1512 break;
1514 case 2: /* Sn, Dn */
1515 regno = (given >> 16) & 0x0000000f;
1516 if (single)
1518 regno <<= 1;
1519 regno += (given >> 7) & 1;
1521 break;
1523 case 3: /* List */
1524 func (stream, "{");
1525 regno = (given >> 12) & 0x0000000f;
1526 if (single)
1528 regno <<= 1;
1529 regno += (given >> 22) & 1;
1531 break;
1534 default:
1535 abort ();
1538 func (stream, "%c%d", single ? 's' : 'd', regno);
1540 if (bitstart == 3)
1542 int count = given & 0xff;
1544 if (single == 0)
1545 count >>= 1;
1547 if (--count)
1549 func (stream, "-%c%d",
1550 single ? 's' : 'd',
1551 regno + count);
1554 func (stream, "}");
1556 else if (bitstart == 4)
1557 func (stream, ", %c%d}", single ? 's' : 'd',
1558 regno + 1);
1560 break;
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 ();
1583 break;
1585 case 'L':
1586 switch (given & 0x00400100)
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;
1595 break;
1597 case 'Z':
1599 int value;
1600 /* given (20, 23) | given (0, 3) */
1601 value = ((given >> 16) & 0xf0) | (given & 0xf);
1602 func (stream, "%d", value);
1604 break;
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. */
1611 int offset = given & 0xff;
1612 int multiplier = (given & 0x00000100) ? 4 : 1;
1614 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1616 if (offset)
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);
1628 else
1629 func (stream, "]");
1631 break;
1633 case 'e':
1635 int imm;
1637 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1638 func (stream, "%d", imm);
1640 break;
1642 case 'E':
1643 /* LSB and WIDTH fields of BFI or BFC. The machine-
1644 language instruction encodes LSB and MSB. */
1646 long msb = (given & 0x001f0000) >> 16;
1647 long lsb = (given & 0x00000f80) >> 7;
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);
1655 break;
1657 case 'V':
1658 /* 16-bit unsigned immediate from a MOVT or MOVW
1659 instruction, encoded in bits 0:11 and 15:19. */
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);
1666 break;
1668 default:
1669 abort ();
1673 else
1674 func (stream, "%c", *c);
1676 return 4;
1679 abort ();
1682 /* Print one instruction from PC on INFO->STREAM.
1683 Return the size of the instruction. */
1685 static int
1686 print_insn_thumb (pc, info, given)
1687 bfd_vma pc;
1688 struct disassemble_info *info;
1689 long given;
1691 const struct thumb_opcode *insn;
1692 void *stream = info->stream;
1693 fprintf_ftype func = info->fprintf_func;
1695 for (insn = thumb_opcodes; insn->assembler; insn++)
1697 if ((given & insn->mask) == insn->value)
1699 char * c = insn->assembler;
1701 /* Special processing for Thumb 2 instruction BL sequence: */
1702 if (!*c) /* Check for empty (not NULL) assembler string. */
1704 long offset;
1706 info->bytes_per_chunk = 4;
1707 info->bytes_per_line = 4;
1709 offset = BDISP23 (given);
1710 offset = offset * 2 + pc + 4;
1712 if ((given & 0x10000000) == 0)
1714 func (stream, "blx\t");
1715 offset &= 0xfffffffc;
1717 else
1718 func (stream, "bl\t");
1720 info->print_address_func (offset, info);
1721 return 4;
1723 else
1725 info->bytes_per_chunk = 2;
1726 info->bytes_per_line = 4;
1728 given &= 0xffff;
1730 for (; *c; c++)
1732 if (*c == '%')
1734 int domaskpc = 0;
1735 int domasklr = 0;
1737 switch (*++c)
1739 case '%':
1740 func (stream, "%%");
1741 break;
1743 case 'S':
1745 long reg;
1747 reg = (given >> 3) & 0x7;
1748 if (given & (1 << 6))
1749 reg += 8;
1751 func (stream, "%s", arm_regnames[reg]);
1753 break;
1755 case 'D':
1757 long reg;
1759 reg = given & 0x7;
1760 if (given & (1 << 7))
1761 reg += 8;
1763 func (stream, "%s", arm_regnames[reg]);
1765 break;
1767 case 'T':
1768 func (stream, "%s",
1769 arm_conditional [(given >> 8) & 0xf]);
1770 break;
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':
1782 int started = 0;
1783 int reg;
1785 func (stream, "{");
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)
1792 if (started)
1793 func (stream, ", ");
1794 started = 1;
1795 func (stream, "%s", arm_regnames[reg]);
1798 if (domasklr)
1800 if (started)
1801 func (stream, ", ");
1802 started = 1;
1803 func (stream, arm_regnames[14] /* "lr" */);
1806 if (domaskpc)
1808 if (started)
1809 func (stream, ", ");
1810 func (stream, arm_regnames[15] /* "pc" */);
1813 func (stream, "}");
1815 break;
1818 case '0': case '1': case '2': case '3': case '4':
1819 case '5': case '6': case '7': case '8': case '9':
1821 int bitstart = *c++ - '0';
1822 int bitend = 0;
1824 while (*c >= '0' && *c <= '9')
1825 bitstart = (bitstart * 10) + *c++ - '0';
1827 switch (*c)
1829 case '-':
1831 long reg;
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)
1842 case 'r':
1843 func (stream, "%s", arm_regnames[reg]);
1844 break;
1846 case 'd':
1847 func (stream, "%d", reg);
1848 break;
1850 case 'H':
1851 func (stream, "%d", reg << 1);
1852 break;
1854 case 'W':
1855 func (stream, "%d", reg << 2);
1856 break;
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;
1866 case 'x':
1867 func (stream, "0x%04x", reg);
1868 break;
1870 case 'I':
1871 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1872 func (stream, "%d", reg);
1873 break;
1875 case 'B':
1876 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
1877 (*info->print_address_func)
1878 (reg * 2 + pc + 4, info);
1879 break;
1881 default:
1882 abort ();
1885 break;
1887 case '\'':
1888 c++;
1889 if ((given & (1 << bitstart)) != 0)
1890 func (stream, "%c", *c);
1891 break;
1893 case '?':
1894 ++c;
1895 if ((given & (1 << bitstart)) != 0)
1896 func (stream, "%c", *c++);
1897 else
1898 func (stream, "%c", *++c);
1899 break;
1901 default:
1902 abort ();
1905 break;
1907 default:
1908 abort ();
1911 else
1912 func (stream, "%c", *c);
1915 return 2;
1919 /* No match. */
1920 abort ();
1923 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
1924 being displayed in symbol relative addresses. */
1926 bfd_boolean
1927 arm_symbol_is_valid (asymbol * sym,
1928 struct disassemble_info * info ATTRIBUTE_UNUSED)
1930 const char * name;
1932 if (sym == NULL)
1933 return FALSE;
1935 name = bfd_asymbol_name (sym);
1937 return (name && *name != '$');
1940 /* Parse an individual disassembler option. */
1942 void
1943 parse_arm_disassembler_option (option)
1944 char * option;
1946 if (option == NULL)
1947 return;
1949 if (strneq (option, "reg-names-", 10))
1951 int i;
1953 option += 10;
1955 for (i = NUM_ARM_REGNAMES; i--;)
1956 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
1958 regname_selected = i;
1959 break;
1962 if (i < 0)
1963 /* XXX - should break 'option' at following delimiter. */
1964 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
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);
1974 return;
1977 /* Parse the string of disassembler options, spliting it at whitespaces
1978 or commas. (Whitespace separators supported for backwards compatibility). */
1980 static void
1981 parse_disassembler_options (options)
1982 char * options;
1984 if (options == NULL)
1985 return;
1987 while (*options)
1989 parse_arm_disassembler_option (options);
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;
2000 /* NOTE: There are no checks in these routines that
2001 the relevant number of data bytes exist. */
2003 static int
2004 print_insn (pc, info, little)
2005 bfd_vma pc;
2006 struct disassemble_info * info;
2007 bfd_boolean little;
2009 unsigned char b[4];
2010 long given;
2011 int status;
2012 int is_thumb, second_half_valid = 1;
2014 if (info->disassembler_options)
2016 parse_disassembler_options (info->disassembler_options);
2018 /* To avoid repeated parsing of these options, we remove them here. */
2019 info->disassembler_options = NULL;
2022 is_thumb = force_thumb;
2024 if (!is_thumb && info->symbols != NULL)
2026 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2028 coff_symbol_type * cs;
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);
2037 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2039 elf_symbol_type * es;
2040 unsigned int type;
2042 es = *(elf_symbol_type **)(info->symbols);
2043 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2045 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2049 info->bytes_per_chunk = 4;
2050 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2052 if (little)
2054 status = info->read_memory_func (pc, (bfd_byte *) &b[0], 4, info);
2055 if (status != 0 && is_thumb)
2057 info->bytes_per_chunk = 2;
2058 second_half_valid = 0;
2060 status = info->read_memory_func (pc, (bfd_byte *) b, 2, info);
2061 b[3] = b[2] = 0;
2064 if (status != 0)
2066 info->memory_error_func (status, pc, info);
2067 return -1;
2070 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2072 else
2074 status = info->read_memory_func
2075 (WORD_ADDRESS (pc), (bfd_byte *) &b[0], 4, info);
2076 if (status != 0)
2078 info->memory_error_func (status, WORD_ADDRESS (pc), info);
2079 return -1;
2082 if (is_thumb)
2084 if (pc & 0x2)
2086 given = (b[2] << 8) | b[3];
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);
2095 else
2096 given = (b[0] << 8) | b[1] | (b[2] << 24) | (b[3] << 16);
2098 else
2099 given = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3]);
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;
2110 if (is_thumb)
2111 status = print_insn_thumb (pc, info, given);
2112 else
2113 status = print_insn_arm (pc, info, given);
2115 if (is_thumb && status == 4 && second_half_valid == 0)
2117 info->memory_error_func (status, WORD_ADDRESS (pc + 4), info);
2118 return -1;
2121 return status;
2125 print_insn_big_arm (pc, info)
2126 bfd_vma pc;
2127 struct disassemble_info * info;
2129 return print_insn (pc, info, FALSE);
2133 print_insn_little_arm (pc, info)
2134 bfd_vma pc;
2135 struct disassemble_info * info;
2137 return print_insn (pc, info, TRUE);
2140 void
2141 print_arm_disassembler_options (FILE * stream)
2143 int i;
2145 fprintf (stream, _("\n\
2146 The following ARM specific disassembler options are supported for use with\n\
2147 the -M switch:\n"));
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);
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");