include/elf:
[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
f4321104 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, 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.
0a003adc
ZW
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.
2fbad815
RE
86IWMMXT 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
93Thumb 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)
2fbad815
RE
101 %I print cirrus signed shift immediate: bits 0..3|4..6
102 %<bitfield>B print Thumb branch destination (signed displacement)
103 %<bitfield>W print (bitfield * 4) as a decimal
104 %<bitfield>H print (bitfield * 2) as a decimal
105 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
c19d1205
ZW
106 %<bitfield>c print bitfield as a condition code
107 %e print arm SMI operand (bits 0..7,8..19).
108 %s print Thumb right-shift immediate (6..10; 0 == 32). */
2fbad815
RE
109
110/* Note: There is a partial ordering in this table - it must be searched from
111 the top to obtain a correct match. */
112
113static const struct arm_opcode arm_opcodes[] =
114{
115 /* ARM instructions. */
116 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
117 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
118 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
119 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
120 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
121 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
122 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
123
0a003adc
ZW
124 /* ARM V6T2 instructions. */
125 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
126 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
127 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
128 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
129 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
130 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
131 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
132 {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
133 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
134
2fbad815
RE
135 /* ARM V6Z instructions. */
136 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
137
138 /* ARM V6K instructions. */
139 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
140 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
141 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
142 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
143 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
144 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
145 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
146
147 /* ARM V6K NOP hints. */
148 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
149 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
150 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
151 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
152 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
153
154 /* ARM V6 instructions. */
155 {ARM_EXT_V6, 0xfc500000, 0xfff00000, "mrrc2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
156 {ARM_EXT_V6, 0xfc400000, 0xfff00000, "mcrr2\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
157 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
158 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
159 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
160 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
161 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
162 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
163 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
164 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
165 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
166 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
167 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
168 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
169 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
170 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
171 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
172 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
173 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
174 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
175 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
176 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
177 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
178 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
179 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
180 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
181 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
182 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
183 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
184 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
185 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
186 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
187 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
188 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
189 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
190 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
191 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
192 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
193 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
194 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
195 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
196 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
197 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
198 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
199 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
200 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
201 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
202 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
203 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
204 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
205 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
206 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
207 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
208 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
209 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
210 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
211 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
212 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
213 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
214 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
215 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
216 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
217 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
218 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
219 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
220 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
221 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
222 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
223 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
224 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
225 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
226 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
227 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
228 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
229 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
230 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
231 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
232 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
233 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
234 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
235 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
236 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
237 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
238 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
239 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
240 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
241 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
242 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
243 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
244 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
245 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
246 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
247 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
248 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
249 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
250 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
251 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
252 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
253 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
254 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
255 {ARM_EXT_V6, 0x068000b0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
256 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
257 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
258 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
259 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
260 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
261 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
262 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
263 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
264 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
265 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
266 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
267 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
268 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
269 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
270 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
271 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
272 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
273 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
274 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
275 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
276 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
277 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
278 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
279
280 /* V5J instruction. */
281 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
282
283 /* XScale instructions. */
284 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0ff0, "mia%c\tacc0, %0-3r, %12-15r"},
285 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0ff0, "miaph%c\tacc0, %0-3r, %12-15r"},
286 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0ff0, "mia%17'T%17`B%16'T%16`B%c\tacc0, %0-3r, %12-15r"},
287 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00fff, "mar%c\tacc0, %12-15r, %16-19r"},
288 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00fff, "mra%c\t%12-15r, %16-19r, acc0"},
289
290 /* Intel Wireless MMX technology instructions. */
291#define FIRST_IWMMXT_INSN 0x0e130130
292#define IWMMXT_INSN_COUNT 47
293 {ARM_CEXT_IWMMXT, 0x0e130130, 0x0f3f0fff, "tandc%22-23w%c\t%12-15r"},
294 {ARM_CEXT_XSCALE, 0x0e400010, 0x0ff00f3f, "tbcst%6-7w%c\t%16-19g, %12-15r"},
295 {ARM_CEXT_XSCALE, 0x0e130170, 0x0f3f0ff8, "textrc%22-23w%c\t%12-15r, #%0-2d"},
296 {ARM_CEXT_XSCALE, 0x0e100070, 0x0f300ff0, "textrm%3?su%22-23w%c\t%12-15r, %16-19g, #%0-2d"},
297 {ARM_CEXT_XSCALE, 0x0e600010, 0x0ff00f38, "tinsr%6-7w%c\t%16-19g, %12-15r, #%0-2d"},
298 {ARM_CEXT_XSCALE, 0x0e000110, 0x0ff00fff, "tmcr%c\t%16-19G, %12-15r"},
299 {ARM_CEXT_XSCALE, 0x0c400000, 0x0ff00ff0, "tmcrr%c\t%0-3g, %12-15r, %16-19r"},
300 {ARM_CEXT_XSCALE, 0x0e2c0010, 0x0ffc0e10, "tmia%17?tb%16?tb%c\t%5-8g, %0-3r, %12-15r"},
301 {ARM_CEXT_XSCALE, 0x0e200010, 0x0fff0e10, "tmia%c\t%5-8g, %0-3r, %12-15r"},
302 {ARM_CEXT_XSCALE, 0x0e280010, 0x0fff0e10, "tmiaph%c\t%5-8g, %0-3r, %12-15r"},
303 {ARM_CEXT_XSCALE, 0x0e100030, 0x0f300fff, "tmovmsk%22-23w%c\t%12-15r, %16-19g"},
304 {ARM_CEXT_XSCALE, 0x0e100110, 0x0ff00ff0, "tmrc%c\t%12-15r, %16-19G"},
305 {ARM_CEXT_XSCALE, 0x0c500000, 0x0ff00ff0, "tmrrc%c\t%12-15r, %16-19r, %0-3g"},
306 {ARM_CEXT_XSCALE, 0x0e130150, 0x0f3f0fff, "torc%22-23w%c\t%12-15r"},
307 {ARM_CEXT_XSCALE, 0x0e0001c0, 0x0f300fff, "wacc%22-23w%c\t%12-15g, %16-19g"},
308 {ARM_CEXT_XSCALE, 0x0e000180, 0x0f000ff0, "wadd%20-23w%c\t%12-15g, %16-19g, %0-3g"},
309 {ARM_CEXT_XSCALE, 0x0e000020, 0x0f800ff0, "waligni%c\t%12-15g, %16-19g, %0-3g, #%20-22d"},
310 {ARM_CEXT_XSCALE, 0x0e800020, 0x0fc00ff0, "walignr%20-21d%c\t%12-15g, %16-19g, %0-3g"},
311 {ARM_CEXT_XSCALE, 0x0e200000, 0x0fe00ff0, "wand%20'n%c\t%12-15g, %16-19g, %0-3g"},
312 {ARM_CEXT_XSCALE, 0x0e800000, 0x0fa00ff0, "wavg2%22?hb%20'r%c\t%12-15g, %16-19g, %0-3g"},
313 {ARM_CEXT_XSCALE, 0x0e000060, 0x0f300ff0, "wcmpeq%22-23w%c\t%12-15g, %16-19g, %0-3g"},
314 {ARM_CEXT_XSCALE, 0x0e100060, 0x0f100ff0, "wcmpgt%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
315 {ARM_CEXT_XSCALE, 0xfc100100, 0xfe500f00, "wldrw\t%12-15G, %A"},
316 {ARM_CEXT_XSCALE, 0x0c100000, 0x0e100e00, "wldr%L%c\t%12-15g, %l"},
317 {ARM_CEXT_XSCALE, 0x0e400100, 0x0fc00ff0, "wmac%21?su%20'z%c\t%12-15g, %16-19g, %0-3g"},
318 {ARM_CEXT_XSCALE, 0x0e800100, 0x0fd00ff0, "wmadd%21?su%c\t%12-15g, %16-19g, %0-3g"},
319 {ARM_CEXT_XSCALE, 0x0e000160, 0x0f100ff0, "wmax%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
320 {ARM_CEXT_XSCALE, 0x0e100160, 0x0f100ff0, "wmin%21?su%22-23w%c\t%12-15g, %16-19g, %0-3g"},
321 {ARM_CEXT_XSCALE, 0x0e000100, 0x0fc00ff0, "wmul%21?su%20?ml%c\t%12-15g, %16-19g, %0-3g"},
322 {ARM_CEXT_XSCALE, 0x0e000000, 0x0ff00ff0, "wor%c\t%12-15g, %16-19g, %0-3g"},
323 {ARM_CEXT_XSCALE, 0x0e000080, 0x0f000ff0, "wpack%20-23w%c\t%12-15g, %16-19g, %0-3g"},
324 {ARM_CEXT_XSCALE, 0x0e300040, 0x0f300ff0, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
325 {ARM_CEXT_XSCALE, 0x0e300148, 0x0f300ffc, "wror%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
326 {ARM_CEXT_XSCALE, 0x0e000120, 0x0fa00ff0, "wsad%22?hb%20'z%c\t%12-15g, %16-19g, %0-3g"},
327 {ARM_CEXT_XSCALE, 0x0e0001e0, 0x0f000ff0, "wshufh%c\t%12-15g, %16-19g, #%Z"},
328 {ARM_CEXT_XSCALE, 0x0e100040, 0x0f300ff0, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
329 {ARM_CEXT_XSCALE, 0x0e100148, 0x0f300ffc, "wsll%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
330 {ARM_CEXT_XSCALE, 0x0e000040, 0x0f300ff0, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
331 {ARM_CEXT_XSCALE, 0x0e000148, 0x0f300ffc, "wsra%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
332 {ARM_CEXT_XSCALE, 0x0e200040, 0x0f300ff0, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3g"},
333 {ARM_CEXT_XSCALE, 0x0e200148, 0x0f300ffc, "wsrl%22-23w%8'g%c\t%12-15g, %16-19g, %0-3G"},
334 {ARM_CEXT_XSCALE, 0xfc000100, 0xfe500f00, "wstrw\t%12-15G, %A"},
335 {ARM_CEXT_XSCALE, 0x0c000000, 0x0e100e00, "wstr%L%c\t%12-15g, %l"},
336 {ARM_CEXT_XSCALE, 0x0e0001a0, 0x0f000ff0, "wsub%20-23w%c\t%12-15g, %16-19g, %0-3g"},
337 {ARM_CEXT_XSCALE, 0x0e0000c0, 0x0f100fff, "wunpckeh%21?su%22-23w%c\t%12-15g, %16-19g"},
338 {ARM_CEXT_XSCALE, 0x0e0000e0, 0x0f100fff, "wunpckel%21?su%22-23w%c\t%12-15g, %16-19g"},
339 {ARM_CEXT_XSCALE, 0x0e1000c0, 0x0f300ff0, "wunpckih%22-23w%c\t%12-15g, %16-19g, %0-3g"},
340 {ARM_CEXT_XSCALE, 0x0e1000e0, 0x0f300ff0, "wunpckil%22-23w%c\t%12-15g, %16-19g, %0-3g"},
341 {ARM_CEXT_XSCALE, 0x0e100000, 0x0ff00ff0, "wxor%c\t%12-15g, %16-19g, %0-3g"},
342
343 /* V5 Instructions. */
344 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
345 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
346 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
347 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
348 {ARM_EXT_V5, 0xfc100000, 0xfe100000, "ldc2%22'l\t%8-11d, cr%12-15d, %A"},
349 {ARM_EXT_V5, 0xfc000000, 0xfe100000, "stc2%22'l\t%8-11d, cr%12-15d, %A"},
350 {ARM_EXT_V5, 0xfe000000, 0xff000010, "cdp2\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
351 {ARM_EXT_V5, 0xfe000010, 0xff100010, "mcr2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
352 {ARM_EXT_V5, 0xfe100010, 0xff100010, "mrc2\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
353
354 /* V5E "El Segundo" Instructions. */
355 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
356 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
357 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
358 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
359 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
360 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
361 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
362
363 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
364 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
365
366 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
367 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
368 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
369 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
370
371 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
372 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
373 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
374 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
375
376 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
377 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
378
379 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
380 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
381 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
382 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
383
384 /* ARM Instructions. */
385 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
386 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
387 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
388 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
389 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
390 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
391 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
392 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
393 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
394 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
395 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
396 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
397 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
398 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
399 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
400 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
401 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
402 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
403 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
404 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
405 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
406 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
407 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
408 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
409 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
410 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
411 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
412 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
413 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
414
415 /* Floating point coprocessor (FPA) instructions */
416 {FPU_FPA_EXT_V1, 0x0e000100, 0x0ff08f10, "adf%c%P%R\t%12-14f, %16-18f, %0-3f"},
417 {FPU_FPA_EXT_V1, 0x0e100100, 0x0ff08f10, "muf%c%P%R\t%12-14f, %16-18f, %0-3f"},
418 {FPU_FPA_EXT_V1, 0x0e200100, 0x0ff08f10, "suf%c%P%R\t%12-14f, %16-18f, %0-3f"},
419 {FPU_FPA_EXT_V1, 0x0e300100, 0x0ff08f10, "rsf%c%P%R\t%12-14f, %16-18f, %0-3f"},
420 {FPU_FPA_EXT_V1, 0x0e400100, 0x0ff08f10, "dvf%c%P%R\t%12-14f, %16-18f, %0-3f"},
421 {FPU_FPA_EXT_V1, 0x0e500100, 0x0ff08f10, "rdf%c%P%R\t%12-14f, %16-18f, %0-3f"},
422 {FPU_FPA_EXT_V1, 0x0e600100, 0x0ff08f10, "pow%c%P%R\t%12-14f, %16-18f, %0-3f"},
423 {FPU_FPA_EXT_V1, 0x0e700100, 0x0ff08f10, "rpw%c%P%R\t%12-14f, %16-18f, %0-3f"},
424 {FPU_FPA_EXT_V1, 0x0e800100, 0x0ff08f10, "rmf%c%P%R\t%12-14f, %16-18f, %0-3f"},
425 {FPU_FPA_EXT_V1, 0x0e900100, 0x0ff08f10, "fml%c%P%R\t%12-14f, %16-18f, %0-3f"},
426 {FPU_FPA_EXT_V1, 0x0ea00100, 0x0ff08f10, "fdv%c%P%R\t%12-14f, %16-18f, %0-3f"},
427 {FPU_FPA_EXT_V1, 0x0eb00100, 0x0ff08f10, "frd%c%P%R\t%12-14f, %16-18f, %0-3f"},
428 {FPU_FPA_EXT_V1, 0x0ec00100, 0x0ff08f10, "pol%c%P%R\t%12-14f, %16-18f, %0-3f"},
429 {FPU_FPA_EXT_V1, 0x0e008100, 0x0ff08f10, "mvf%c%P%R\t%12-14f, %0-3f"},
430 {FPU_FPA_EXT_V1, 0x0e108100, 0x0ff08f10, "mnf%c%P%R\t%12-14f, %0-3f"},
431 {FPU_FPA_EXT_V1, 0x0e208100, 0x0ff08f10, "abs%c%P%R\t%12-14f, %0-3f"},
432 {FPU_FPA_EXT_V1, 0x0e308100, 0x0ff08f10, "rnd%c%P%R\t%12-14f, %0-3f"},
433 {FPU_FPA_EXT_V1, 0x0e408100, 0x0ff08f10, "sqt%c%P%R\t%12-14f, %0-3f"},
434 {FPU_FPA_EXT_V1, 0x0e508100, 0x0ff08f10, "log%c%P%R\t%12-14f, %0-3f"},
435 {FPU_FPA_EXT_V1, 0x0e608100, 0x0ff08f10, "lgn%c%P%R\t%12-14f, %0-3f"},
436 {FPU_FPA_EXT_V1, 0x0e708100, 0x0ff08f10, "exp%c%P%R\t%12-14f, %0-3f"},
437 {FPU_FPA_EXT_V1, 0x0e808100, 0x0ff08f10, "sin%c%P%R\t%12-14f, %0-3f"},
438 {FPU_FPA_EXT_V1, 0x0e908100, 0x0ff08f10, "cos%c%P%R\t%12-14f, %0-3f"},
439 {FPU_FPA_EXT_V1, 0x0ea08100, 0x0ff08f10, "tan%c%P%R\t%12-14f, %0-3f"},
440 {FPU_FPA_EXT_V1, 0x0eb08100, 0x0ff08f10, "asn%c%P%R\t%12-14f, %0-3f"},
441 {FPU_FPA_EXT_V1, 0x0ec08100, 0x0ff08f10, "acs%c%P%R\t%12-14f, %0-3f"},
442 {FPU_FPA_EXT_V1, 0x0ed08100, 0x0ff08f10, "atn%c%P%R\t%12-14f, %0-3f"},
443 {FPU_FPA_EXT_V1, 0x0ee08100, 0x0ff08f10, "urd%c%P%R\t%12-14f, %0-3f"},
444 {FPU_FPA_EXT_V1, 0x0ef08100, 0x0ff08f10, "nrm%c%P%R\t%12-14f, %0-3f"},
445 {FPU_FPA_EXT_V1, 0x0e000110, 0x0ff00f1f, "flt%c%P%R\t%16-18f, %12-15r"},
446 {FPU_FPA_EXT_V1, 0x0e100110, 0x0fff0f98, "fix%c%R\t%12-15r, %0-2f"},
447 {FPU_FPA_EXT_V1, 0x0e200110, 0x0fff0fff, "wfs%c\t%12-15r"},
448 {FPU_FPA_EXT_V1, 0x0e300110, 0x0fff0fff, "rfs%c\t%12-15r"},
449 {FPU_FPA_EXT_V1, 0x0e400110, 0x0fff0fff, "wfc%c\t%12-15r"},
450 {FPU_FPA_EXT_V1, 0x0e500110, 0x0fff0fff, "rfc%c\t%12-15r"},
451 {FPU_FPA_EXT_V1, 0x0e90f110, 0x0ff8fff0, "cmf%c\t%16-18f, %0-3f"},
452 {FPU_FPA_EXT_V1, 0x0eb0f110, 0x0ff8fff0, "cnf%c\t%16-18f, %0-3f"},
453 {FPU_FPA_EXT_V1, 0x0ed0f110, 0x0ff8fff0, "cmfe%c\t%16-18f, %0-3f"},
454 {FPU_FPA_EXT_V1, 0x0ef0f110, 0x0ff8fff0, "cnfe%c\t%16-18f, %0-3f"},
455 {FPU_FPA_EXT_V1, 0x0c000100, 0x0e100f00, "stf%c%Q\t%12-14f, %A"},
456 {FPU_FPA_EXT_V1, 0x0c100100, 0x0e100f00, "ldf%c%Q\t%12-14f, %A"},
457 {FPU_FPA_EXT_V2, 0x0c000200, 0x0e100f00, "sfm%c\t%12-14f, %F, %A"},
458 {FPU_FPA_EXT_V2, 0x0c100200, 0x0e100f00, "lfm%c\t%12-14f, %F, %A"},
459
460 /* Floating point coprocessor (VFP) instructions */
461 {FPU_VFP_EXT_V1, 0x0eb00bc0, 0x0fff0ff0, "fabsd%c\t%1z, %0z"},
462 {FPU_VFP_EXT_V1xD, 0x0eb00ac0, 0x0fbf0fd0, "fabss%c\t%1y, %0y"},
463 {FPU_VFP_EXT_V1, 0x0e300b00, 0x0ff00ff0, "faddd%c\t%1z, %2z, %0z"},
464 {FPU_VFP_EXT_V1xD, 0x0e300a00, 0x0fb00f50, "fadds%c\t%1y, %2y, %1y"},
465 {FPU_VFP_EXT_V1, 0x0eb40b40, 0x0fff0f70, "fcmp%7'ed%c\t%1z, %0z"},
466 {FPU_VFP_EXT_V1xD, 0x0eb40a40, 0x0fbf0f50, "fcmp%7'es%c\t%1y, %0y"},
467 {FPU_VFP_EXT_V1, 0x0eb50b40, 0x0fff0f70, "fcmp%7'ezd%c\t%1z"},
468 {FPU_VFP_EXT_V1xD, 0x0eb50a40, 0x0fbf0f70, "fcmp%7'ezs%c\t%1y"},
469 {FPU_VFP_EXT_V1, 0x0eb00b40, 0x0fff0ff0, "fcpyd%c\t%1z, %0z"},
470 {FPU_VFP_EXT_V1xD, 0x0eb00a40, 0x0fbf0fd0, "fcpys%c\t%1y, %0y"},
471 {FPU_VFP_EXT_V1, 0x0eb70ac0, 0x0fff0fd0, "fcvtds%c\t%1z, %0y"},
472 {FPU_VFP_EXT_V1, 0x0eb70bc0, 0x0fbf0ff0, "fcvtsd%c\t%1y, %0z"},
473 {FPU_VFP_EXT_V1, 0x0e800b00, 0x0ff00ff0, "fdivd%c\t%1z, %2z, %0z"},
474 {FPU_VFP_EXT_V1xD, 0x0e800a00, 0x0fb00f50, "fdivs%c\t%1y, %2y, %0y"},
475 {FPU_VFP_EXT_V1, 0x0d100b00, 0x0f700f00, "fldd%c\t%1z, %A"},
476 {FPU_VFP_EXT_V1xD, 0x0c900b00, 0x0fd00f00, "fldmia%0?xd%c\t%16-19r%21'!, %3z"},
477 {FPU_VFP_EXT_V1xD, 0x0d300b00, 0x0ff00f00, "fldmdb%0?xd%c\t%16-19r!, %3z"},
478 {FPU_VFP_EXT_V1xD, 0x0d100a00, 0x0f300f00, "flds%c\t%1y, %A"},
479 {FPU_VFP_EXT_V1xD, 0x0c900a00, 0x0f900f00, "fldmias%c\t%16-19r%21'!, %3y"},
480 {FPU_VFP_EXT_V1xD, 0x0d300a00, 0x0fb00f00, "fldmdbs%c\t%16-19r!, %3y"},
481 {FPU_VFP_EXT_V1, 0x0e000b00, 0x0ff00ff0, "fmacd%c\t%1z, %2z, %0z"},
482 {FPU_VFP_EXT_V1xD, 0x0e000a00, 0x0fb00f50, "fmacs%c\t%1y, %2y, %0y"},
483 {FPU_VFP_EXT_V1, 0x0e200b10, 0x0ff00fff, "fmdhr%c\t%2z, %12-15r"},
484 {FPU_VFP_EXT_V1, 0x0e000b10, 0x0ff00fff, "fmdlr%c\t%2z, %12-15r"},
485 {FPU_VFP_EXT_V2, 0x0c400b10, 0x0ff00ff0, "fmdrr%c\t%0z, %12-15r, %16-19r"},
486 {FPU_VFP_EXT_V1, 0x0e300b10, 0x0ff00fff, "fmrdh%c\t%12-15r, %2z"},
487 {FPU_VFP_EXT_V1, 0x0e100b10, 0x0ff00fff, "fmrdl%c\t%12-15r, %2z"},
488 {FPU_VFP_EXT_V1, 0x0c500b10, 0x0ff00ff0, "fmrrd%c\t%12-15r, %16-19r, %0z"},
489 {FPU_VFP_EXT_V2, 0x0c500a10, 0x0ff00fd0, "fmrrs%c\t%12-15r, %16-19r, %4y"},
490 {FPU_VFP_EXT_V1xD, 0x0e100a10, 0x0ff00f7f, "fmrs%c\t%12-15r, %2y"},
491 {FPU_VFP_EXT_V1xD, 0x0ef1fa10, 0x0fffffff, "fmstat%c"},
492 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpsid"},
493 {FPU_VFP_EXT_V1xD, 0x0ef10a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpscr"},
494 {FPU_VFP_EXT_V1xD, 0x0ef80a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpexc"},
495 {FPU_VFP_EXT_V1xD, 0x0ef90a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst\t@ Impl def"},
496 {FPU_VFP_EXT_V1xD, 0x0efa0a10, 0x0fff0fff, "fmrx%c\t%12-15r, fpinst2\t@ Impl def"},
497 {FPU_VFP_EXT_V1xD, 0x0ef00a10, 0x0ff00fff, "fmrx%c\t%12-15r, <impl def 0x%16-19x>"},
498 {FPU_VFP_EXT_V1, 0x0e100b00, 0x0ff00ff0, "fmscd%c\t%1z, %2z, %0z"},
499 {FPU_VFP_EXT_V1xD, 0x0e100a00, 0x0fb00f50, "fmscs%c\t%1y, %2y, %0y"},
500 {FPU_VFP_EXT_V1xD, 0x0e000a10, 0x0ff00f7f, "fmsr%c\t%2y, %12-15r"},
501 {FPU_VFP_EXT_V2, 0x0c400a10, 0x0ff00fd0, "fmsrr%c\t%12-15r, %16-19r, %4y"},
502 {FPU_VFP_EXT_V1, 0x0e200b00, 0x0ff00ff0, "fmuld%c\t%1z, %2z, %0z"},
503 {FPU_VFP_EXT_V1xD, 0x0e200a00, 0x0fb00f50, "fmuls%c\t%1y, %2y, %0y"},
504 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0fff0fff, "fmxr%c\tfpsid, %12-15r"},
505 {FPU_VFP_EXT_V1xD, 0x0ee10a10, 0x0fff0fff, "fmxr%c\tfpscr, %12-15r"},
506 {FPU_VFP_EXT_V1xD, 0x0ee80a10, 0x0fff0fff, "fmxr%c\tfpexc, %12-15r"},
507 {FPU_VFP_EXT_V1xD, 0x0ee90a10, 0x0fff0fff, "fmxr%c\tfpinst, %12-15r\t@ Impl def"},
508 {FPU_VFP_EXT_V1xD, 0x0eea0a10, 0x0fff0fff, "fmxr%c\tfpinst2, %12-15r\t@ Impl def"},
509 {FPU_VFP_EXT_V1xD, 0x0ee00a10, 0x0ff00fff, "fmxr%c\t<impl def 0x%16-19x>, %12-15r"},
510 {FPU_VFP_EXT_V1, 0x0eb10b40, 0x0fff0ff0, "fnegd%c\t%1z, %0z"},
511 {FPU_VFP_EXT_V1xD, 0x0eb10a40, 0x0fbf0fd0, "fnegs%c\t%1y, %0y"},
512 {FPU_VFP_EXT_V1, 0x0e000b40, 0x0ff00ff0, "fnmacd%c\t%1z, %2z, %0z"},
513 {FPU_VFP_EXT_V1xD, 0x0e000a40, 0x0fb00f50, "fnmacs%c\t%1y, %2y, %0y"},
514 {FPU_VFP_EXT_V1, 0x0e100b40, 0x0ff00ff0, "fnmscd%c\t%1z, %2z, %0z"},
515 {FPU_VFP_EXT_V1xD, 0x0e100a40, 0x0fb00f50, "fnmscs%c\t%1y, %2y, %0y"},
516 {FPU_VFP_EXT_V1, 0x0e200b40, 0x0ff00ff0, "fnmuld%c\t%1z, %2z, %0z"},
517 {FPU_VFP_EXT_V1xD, 0x0e200a40, 0x0fb00f50, "fnmuls%c\t%1y, %2y, %0y"},
518 {FPU_VFP_EXT_V1, 0x0eb80bc0, 0x0fff0fd0, "fsitod%c\t%1z, %0y"},
519 {FPU_VFP_EXT_V1xD, 0x0eb80ac0, 0x0fbf0fd0, "fsitos%c\t%1y, %0y"},
520 {FPU_VFP_EXT_V1, 0x0eb10bc0, 0x0fff0ff0, "fsqrtd%c\t%1z, %0z"},
521 {FPU_VFP_EXT_V1xD, 0x0eb10ac0, 0x0fbf0fd0, "fsqrts%c\t%1y, %0y"},
522 {FPU_VFP_EXT_V1, 0x0d000b00, 0x0f700f00, "fstd%c\t%1z, %A"},
523 {FPU_VFP_EXT_V1xD, 0x0c800b00, 0x0fd00f00, "fstmia%0?xd%c\t%16-19r%21'!, %3z"},
524 {FPU_VFP_EXT_V1xD, 0x0d200b00, 0x0ff00f00, "fstmdb%0?xd%c\t%16-19r!, %3z"},
525 {FPU_VFP_EXT_V1xD, 0x0d000a00, 0x0f300f00, "fsts%c\t%1y, %A"},
526 {FPU_VFP_EXT_V1xD, 0x0c800a00, 0x0f900f00, "fstmias%c\t%16-19r%21'!, %3y"},
527 {FPU_VFP_EXT_V1xD, 0x0d200a00, 0x0fb00f00, "fstmdbs%c\t%16-19r!, %3y"},
528 {FPU_VFP_EXT_V1, 0x0e300b40, 0x0ff00ff0, "fsubd%c\t%1z, %2z, %0z"},
529 {FPU_VFP_EXT_V1xD, 0x0e300a40, 0x0fb00f50, "fsubs%c\t%1y, %2y, %0y"},
530 {FPU_VFP_EXT_V1, 0x0ebc0b40, 0x0fbe0f70, "fto%16?sui%7'zd%c\t%1y, %0z"},
531 {FPU_VFP_EXT_V1xD, 0x0ebc0a40, 0x0fbe0f50, "fto%16?sui%7'zs%c\t%1y, %0y"},
532 {FPU_VFP_EXT_V1, 0x0eb80b40, 0x0fff0fd0, "fuitod%c\t%1z, %0y"},
533 {FPU_VFP_EXT_V1xD, 0x0eb80a40, 0x0fbf0fd0, "fuitos%c\t%1y, %0y"},
534
535 /* Cirrus coprocessor instructions. */
536 {ARM_CEXT_MAVERICK, 0x0d100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
537 {ARM_CEXT_MAVERICK, 0x0c100400, 0x0f500f00, "cfldrs%c\tmvf%12-15d, %A"},
538 {ARM_CEXT_MAVERICK, 0x0d500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
539 {ARM_CEXT_MAVERICK, 0x0c500400, 0x0f500f00, "cfldrd%c\tmvd%12-15d, %A"},
540 {ARM_CEXT_MAVERICK, 0x0d100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
541 {ARM_CEXT_MAVERICK, 0x0c100500, 0x0f500f00, "cfldr32%c\tmvfx%12-15d, %A"},
542 {ARM_CEXT_MAVERICK, 0x0d500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
543 {ARM_CEXT_MAVERICK, 0x0c500500, 0x0f500f00, "cfldr64%c\tmvdx%12-15d, %A"},
544 {ARM_CEXT_MAVERICK, 0x0d000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
545 {ARM_CEXT_MAVERICK, 0x0c000400, 0x0f500f00, "cfstrs%c\tmvf%12-15d, %A"},
546 {ARM_CEXT_MAVERICK, 0x0d400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
547 {ARM_CEXT_MAVERICK, 0x0c400400, 0x0f500f00, "cfstrd%c\tmvd%12-15d, %A"},
548 {ARM_CEXT_MAVERICK, 0x0d000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
549 {ARM_CEXT_MAVERICK, 0x0c000500, 0x0f500f00, "cfstr32%c\tmvfx%12-15d, %A"},
550 {ARM_CEXT_MAVERICK, 0x0d400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
551 {ARM_CEXT_MAVERICK, 0x0c400500, 0x0f500f00, "cfstr64%c\tmvdx%12-15d, %A"},
552 {ARM_CEXT_MAVERICK, 0x0e000450, 0x0ff00ff0, "cfmvsr%c\tmvf%16-19d, %12-15r"},
553 {ARM_CEXT_MAVERICK, 0x0e100450, 0x0ff00ff0, "cfmvrs%c\t%12-15r, mvf%16-19d"},
554 {ARM_CEXT_MAVERICK, 0x0e000410, 0x0ff00ff0, "cfmvdlr%c\tmvd%16-19d, %12-15r"},
555 {ARM_CEXT_MAVERICK, 0x0e100410, 0x0ff00ff0, "cfmvrdl%c\t%12-15r, mvd%16-19d"},
556 {ARM_CEXT_MAVERICK, 0x0e000430, 0x0ff00ff0, "cfmvdhr%c\tmvd%16-19d, %12-15r"},
557 {ARM_CEXT_MAVERICK, 0x0e100430, 0x0ff00fff, "cfmvrdh%c\t%12-15r, mvd%16-19d"},
558 {ARM_CEXT_MAVERICK, 0x0e000510, 0x0ff00fff, "cfmv64lr%c\tmvdx%16-19d, %12-15r"},
559 {ARM_CEXT_MAVERICK, 0x0e100510, 0x0ff00fff, "cfmvr64l%c\t%12-15r, mvdx%16-19d"},
560 {ARM_CEXT_MAVERICK, 0x0e000530, 0x0ff00fff, "cfmv64hr%c\tmvdx%16-19d, %12-15r"},
561 {ARM_CEXT_MAVERICK, 0x0e100530, 0x0ff00fff, "cfmvr64h%c\t%12-15r, mvdx%16-19d"},
562 {ARM_CEXT_MAVERICK, 0x0e200440, 0x0ff00fff, "cfmval32%c\tmvax%12-15d, mvfx%16-19d"},
563 {ARM_CEXT_MAVERICK, 0x0e100440, 0x0ff00fff, "cfmv32al%c\tmvfx%12-15d, mvax%16-19d"},
564 {ARM_CEXT_MAVERICK, 0x0e200460, 0x0ff00fff, "cfmvam32%c\tmvax%12-15d, mvfx%16-19d"},
565 {ARM_CEXT_MAVERICK, 0x0e100460, 0x0ff00fff, "cfmv32am%c\tmvfx%12-15d, mvax%16-19d"},
566 {ARM_CEXT_MAVERICK, 0x0e200480, 0x0ff00fff, "cfmvah32%c\tmvax%12-15d, mvfx%16-19d"},
567 {ARM_CEXT_MAVERICK, 0x0e100480, 0x0ff00fff, "cfmv32ah%c\tmvfx%12-15d, mvax%16-19d"},
568 {ARM_CEXT_MAVERICK, 0x0e2004a0, 0x0ff00fff, "cfmva32%c\tmvax%12-15d, mvfx%16-19d"},
569 {ARM_CEXT_MAVERICK, 0x0e1004a0, 0x0ff00fff, "cfmv32a%c\tmvfx%12-15d, mvax%16-19d"},
570 {ARM_CEXT_MAVERICK, 0x0e2004c0, 0x0ff00fff, "cfmva64%c\tmvax%12-15d, mvdx%16-19d"},
571 {ARM_CEXT_MAVERICK, 0x0e1004c0, 0x0ff00fff, "cfmv64a%c\tmvdx%12-15d, mvax%16-19d"},
572 {ARM_CEXT_MAVERICK, 0x0e2004e0, 0x0fff0fff, "cfmvsc32%c\tdspsc, mvdx%12-15d"},
573 {ARM_CEXT_MAVERICK, 0x0e1004e0, 0x0fff0fff, "cfmv32sc%c\tmvdx%12-15d, dspsc"},
574 {ARM_CEXT_MAVERICK, 0x0e000400, 0x0ff00fff, "cfcpys%c\tmvf%12-15d, mvf%16-19d"},
575 {ARM_CEXT_MAVERICK, 0x0e000420, 0x0ff00fff, "cfcpyd%c\tmvd%12-15d, mvd%16-19d"},
576 {ARM_CEXT_MAVERICK, 0x0e000460, 0x0ff00fff, "cfcvtsd%c\tmvd%12-15d, mvf%16-19d"},
577 {ARM_CEXT_MAVERICK, 0x0e000440, 0x0ff00fff, "cfcvtds%c\tmvf%12-15d, mvd%16-19d"},
578 {ARM_CEXT_MAVERICK, 0x0e000480, 0x0ff00fff, "cfcvt32s%c\tmvf%12-15d, mvfx%16-19d"},
579 {ARM_CEXT_MAVERICK, 0x0e0004a0, 0x0ff00fff, "cfcvt32d%c\tmvd%12-15d, mvfx%16-19d"},
580 {ARM_CEXT_MAVERICK, 0x0e0004c0, 0x0ff00fff, "cfcvt64s%c\tmvf%12-15d, mvdx%16-19d"},
581 {ARM_CEXT_MAVERICK, 0x0e0004e0, 0x0ff00fff, "cfcvt64d%c\tmvd%12-15d, mvdx%16-19d"},
582 {ARM_CEXT_MAVERICK, 0x0e100580, 0x0ff00fff, "cfcvts32%c\tmvfx%12-15d, mvf%16-19d"},
583 {ARM_CEXT_MAVERICK, 0x0e1005a0, 0x0ff00fff, "cfcvtd32%c\tmvfx%12-15d, mvd%16-19d"},
584 {ARM_CEXT_MAVERICK, 0x0e1005c0, 0x0ff00fff, "cftruncs32%c\tmvfx%12-15d, mvf%16-19d"},
585 {ARM_CEXT_MAVERICK, 0x0e1005e0, 0x0ff00fff, "cftruncd32%c\tmvfx%12-15d, mvd%16-19d"},
586 {ARM_CEXT_MAVERICK, 0x0e000550, 0x0ff00ff0, "cfrshl32%c\tmvfx%16-19d, mvfx%0-3d, %12-15r"},
587 {ARM_CEXT_MAVERICK, 0x0e000570, 0x0ff00ff0, "cfrshl64%c\tmvdx%16-19d, mvdx%0-3d, %12-15r"},
588 {ARM_CEXT_MAVERICK, 0x0e000500, 0x0ff00f00, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
589 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f00, "cfsh64%c\tmvdx%12-15d, mvdx%16-19d, #%I"},
590 {ARM_CEXT_MAVERICK, 0x0e100490, 0x0ff00ff0, "cfcmps%c\t%12-15r, mvf%16-19d, mvf%0-3d"},
591 {ARM_CEXT_MAVERICK, 0x0e1004b0, 0x0ff00ff0, "cfcmpd%c\t%12-15r, mvd%16-19d, mvd%0-3d"},
592 {ARM_CEXT_MAVERICK, 0x0e100590, 0x0ff00ff0, "cfcmp32%c\t%12-15r, mvfx%16-19d, mvfx%0-3d"},
593 {ARM_CEXT_MAVERICK, 0x0e1005b0, 0x0ff00ff0, "cfcmp64%c\t%12-15r, mvdx%16-19d, mvdx%0-3d"},
594 {ARM_CEXT_MAVERICK, 0x0e300400, 0x0ff00fff, "cfabss%c\tmvf%12-15d, mvf%16-19d"},
595 {ARM_CEXT_MAVERICK, 0x0e300420, 0x0ff00fff, "cfabsd%c\tmvd%12-15d, mvd%16-19d"},
596 {ARM_CEXT_MAVERICK, 0x0e300440, 0x0ff00fff, "cfnegs%c\tmvf%12-15d, mvf%16-19d"},
597 {ARM_CEXT_MAVERICK, 0x0e300460, 0x0ff00fff, "cfnegd%c\tmvd%12-15d, mvd%16-19d"},
598 {ARM_CEXT_MAVERICK, 0x0e300480, 0x0ff00ff0, "cfadds%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
599 {ARM_CEXT_MAVERICK, 0x0e3004a0, 0x0ff00ff0, "cfaddd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
600 {ARM_CEXT_MAVERICK, 0x0e3004c0, 0x0ff00ff0, "cfsubs%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
601 {ARM_CEXT_MAVERICK, 0x0e3004e0, 0x0ff00ff0, "cfsubd%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
602 {ARM_CEXT_MAVERICK, 0x0e100400, 0x0ff00ff0, "cfmuls%c\tmvf%12-15d, mvf%16-19d, mvf%0-3d"},
603 {ARM_CEXT_MAVERICK, 0x0e100420, 0x0ff00ff0, "cfmuld%c\tmvd%12-15d, mvd%16-19d, mvd%0-3d"},
604 {ARM_CEXT_MAVERICK, 0x0e300500, 0x0ff00fff, "cfabs32%c\tmvfx%12-15d, mvfx%16-19d"},
605 {ARM_CEXT_MAVERICK, 0x0e300520, 0x0ff00fff, "cfabs64%c\tmvdx%12-15d, mvdx%16-19d"},
606 {ARM_CEXT_MAVERICK, 0x0e300540, 0x0ff00fff, "cfneg32%c\tmvfx%12-15d, mvfx%16-19d"},
607 {ARM_CEXT_MAVERICK, 0x0e300560, 0x0ff00fff, "cfneg64%c\tmvdx%12-15d, mvdx%16-19d"},
608 {ARM_CEXT_MAVERICK, 0x0e300580, 0x0ff00ff0, "cfadd32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
609 {ARM_CEXT_MAVERICK, 0x0e3005a0, 0x0ff00ff0, "cfadd64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
610 {ARM_CEXT_MAVERICK, 0x0e3005c0, 0x0ff00ff0, "cfsub32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
611 {ARM_CEXT_MAVERICK, 0x0e3005e0, 0x0ff00ff0, "cfsub64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
612 {ARM_CEXT_MAVERICK, 0x0e100500, 0x0ff00ff0, "cfmul32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
613 {ARM_CEXT_MAVERICK, 0x0e100520, 0x0ff00ff0, "cfmul64%c\tmvdx%12-15d, mvdx%16-19d, mvdx%0-3d"},
614 {ARM_CEXT_MAVERICK, 0x0e100540, 0x0ff00ff0, "cfmac32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
615 {ARM_CEXT_MAVERICK, 0x0e100560, 0x0ff00ff0, "cfmsc32%c\tmvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
616 {ARM_CEXT_MAVERICK, 0x0e000600, 0x0ff00f00, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
617 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f00, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
618 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f00, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
619 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f00, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
620
621 /* Generic coprocessor instructions */
622 {ARM_EXT_V2, 0x0c400000, 0x0ff00000, "mcrr%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
623 {ARM_EXT_V2, 0x0c500000, 0x0ff00000, "mrrc%c\t%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
624 {ARM_EXT_V2, 0x0e000000, 0x0f000010, "cdp%c\t%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, {%5-7d}"},
625 {ARM_EXT_V2, 0x0e100010, 0x0f100010, "mrc%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
626 {ARM_EXT_V2, 0x0e000010, 0x0f100010, "mcr%c\t%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, {%5-7d}"},
627 {ARM_EXT_V2, 0x0c000000, 0x0e100000, "stc%c%22'l\t%8-11d, cr%12-15d, %A"},
628 {ARM_EXT_V2, 0x0c100000, 0x0e100000, "ldc%c%22'l\t%8-11d, cr%12-15d, %A"},
629
630 /* The rest. */
631 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
632 {0, 0x00000000, 0x00000000, 0}
633};
634
635static const struct thumb_opcode thumb_opcodes[] =
636{
637 /* Thumb instructions. */
638
885fc257
ZW
639 /* ARM V6K no-argument instructions. */
640 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
641 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
642 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
643 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
644 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
c19d1205
ZW
645 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
646
647 /* ARM V6T2 instructions. */
648 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"},
649 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"},
650 {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"},
651 {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"},
652 {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"},
653 {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"},
654 {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"},
655 {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"},
656 {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"},
885fc257 657
2fbad815
RE
658 /* ARM V6. */
659 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
660 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
c19d1205 661 {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
2fbad815
RE
662 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
663 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
664 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
665 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
666 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
667 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
668 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
669 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
670
671 /* ARM V5 ISA extends Thumb. */
672 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
c19d1205 673 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
2fbad815
RE
674 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
675 /* ARM V4T ISA (Thumb v1). */
676 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
2fbad815 677 /* Format 4. */
c19d1205
ZW
678 {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"},
679 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"},
680 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"},
681 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"},
682 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"},
683 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"},
684 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
685 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
2fbad815 686 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
c19d1205 687 {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
2fbad815
RE
688 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
689 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
c19d1205
ZW
690 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
691 {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"},
692 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"},
693 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"},
2fbad815
RE
694 /* format 13 */
695 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
696 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
697 /* format 5 */
698 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
699 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
700 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
701 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
702 /* format 14 */
703 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
704 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
705 /* format 2 */
c19d1205 706 {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
2fbad815 707 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
c19d1205 708 {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
2fbad815
RE
709 {ARM_EXT_V4T, 0x1E00, 0xFE00, "sub\t%0-2r, %3-5r, #%6-8d"},
710 /* format 8 */
711 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
712 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
713 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
714 /* format 7 */
715 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
716 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
717 /* format 1 */
c19d1205
ZW
718 {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"},
719 {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"},
720 {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"},
2fbad815 721 /* format 3 */
c19d1205 722 {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
2fbad815 723 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
c19d1205
ZW
724 {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
725 {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
2fbad815
RE
726 /* format 6 */
727 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
728 /* format 9 */
729 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
730 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
731 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
732 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
733 /* format 10 */
734 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
735 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
736 /* format 11 */
737 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
738 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
739 /* format 12 */
740 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
741 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
742 /* format 15 */
c19d1205
ZW
743 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
744 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
2fbad815 745 /* format 17 */
2fbad815 746 {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
c19d1205
ZW
747 /* format 16 */
748 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"},
749 /* format 18 */
750 {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"},
751
752 /* The E800 .. FFFF range is unconditionally redirected to the
753 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
754 are processed via that table. Thus, we can never encounter a
755 bare "second half of BL/BLX(1)" instruction here. */
756 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
757 {0, 0, 0, 0}
758};
759
760/* Thumb32 opcodes use the same table structure as the ARM opcodes.
761 We adopt the convention that hw1 is the high 16 bits of .value and
762 .mask, hw2 the low 16 bits.
763
764 %-escapes defined for these instructions:
765
766 %% %
767 %<bitfield>d print bitfield in decimal
768 %<bitfield>W print bitfield*4 in decimal
769 %<bitfield>r print bitfield as an ARM register
770 %<bitfield>c print bitfield as a condition code
771
772 %<bitnum>'c print "c" iff bit is one
773 %<bitnum>`c print "c" iff bit is zero
774 %<bitnum>?ab print "a" if bit is one, else "b"
775
776 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
777 %M print a modified 12-bit immediate (same location)
778 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
779 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
780 %S print a possibly-shifted Rm
781
782 %a print the address of a plain load/store
783 %A print the address of a coprocessor load/store
784 %w print the width and signedness of a core load/store
785 %m print register mask for ldm/stm
786
787 %E print the lsb and width fields of a bfc/bfi instruction
788 %F print the lsb and width fields of a sbfx/ubfx instruction
789 %B print an unconditional branch offset
790 %b print a conditional branch offset
791 %s print the shift field of an SSAT instruction
792 %R print the rotation field of an SXT instruction
793
794 With one exception at the bottom (done because BL and BLX(1) need
795 to come dead last), this table was machine-sorted first in
796 decreasing order of number of bits set in the mask, then in
797 increasing numeric order of mask, then in increasing numeric order
798 of opcode. This order is not the clearest for a human reader, but
799 is guaranteed never to catch a special-case bit pattern with a more
800 general mask, which is important, because this instruction encoding
801 makes heavy use of special-case bit patterns. */
802static const struct arm_opcode thumb32_opcodes[] =
803{
804 /* Instructions defined in the basic V6T2 set. */
805 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
806 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
807 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
808 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
809 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
810 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
811
812 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
813 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
814 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
815 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
816 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
817 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
818 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff0ff, "mrs\t%8-11r, %20?CSPSR"},
819 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
820 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
821 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r]"},
822 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
823 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
824 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
825 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f0ff, "msr\t%20?CSPSR_%8'c%9'x%10's%11'f, %16-19r"},
826 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
827 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
828 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
829 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
830 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"},
831 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"},
832 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"},
833 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
834 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
835 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
836 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
837 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
838 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
839 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
840 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"},
841 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"},
842 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"},
843 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"},
844 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"},
845 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"},
846 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"},
847 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"},
848 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"},
849 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"},
850 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"},
851 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"},
852 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"},
853 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"},
854 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"},
855 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"},
856 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"},
857 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"},
858 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"},
859 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"},
860 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"},
861 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"},
862 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"},
863 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"},
864 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"},
865 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"},
866 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"},
867 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"},
868 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"},
869 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"},
870 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"},
871 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"},
872 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"},
873 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"},
874 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"},
875 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"},
876 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"},
877 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"},
878 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"},
879 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"},
880 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"},
881 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"},
882 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"},
883 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"},
884 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"},
885 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"},
886 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"},
887 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"},
888 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"},
889 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"},
890 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
891 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
892 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
893 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
894 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
895 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
896 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
897 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
898 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
899 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
900 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"},
901 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"},
902 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"},
903 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"},
904 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
905 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
906 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
907 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
908 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
909 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
910 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
911 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
912 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
913 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
914 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
915 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
916 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"},
917 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"},
918 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"},
919 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"},
920 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"},
921 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
922 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
923 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
924 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
925 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smi\t%K"},
926 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
927 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
928 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
929 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
930 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
931 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
932 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
933 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
934 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
935 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
936 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
937 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
938 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
939 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
940 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
941 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
942 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
943 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"},
944 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"},
945 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"},
946 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"},
947 {ARM_EXT_V6T2, 0xee000010, 0xef1000f0, "mcr%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d"},
948 {ARM_EXT_V6T2, 0xee100010, 0xef1000f0, "mrc%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d"},
949 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"},
950 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"},
951 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"},
952 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"},
953 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"},
954 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"},
955 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"},
956 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"},
957 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"},
958 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
959 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
960 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
961 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
962 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
963 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
964 {ARM_EXT_V6T2, 0xee000000, 0xef0000f0, "cdp%28'2\tp%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d"},
965 {ARM_EXT_V6T2, 0xec400000, 0xeff00000, "mcrr%28'2\tp%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
966 {ARM_EXT_V6T2, 0xec500000, 0xeff00000, "mrrc%28'2\tp%8-11d, %4-7d, %12-15r, %16-19r, cr%0-3d"},
967 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"},
968 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"},
969 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"},
970 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
971 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
972 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
973 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
974 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
975 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
976 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
977 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
978 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
979 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
980 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
981 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
982 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
983 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
984 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
985 {ARM_EXT_V6T2, 0xee000010, 0xef100010, "mcr%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, %5-7d"},
986 {ARM_EXT_V6T2, 0xee100010, 0xef100010, "mrc%28'2\tp%8-11d, %21-23d, %12-15r, cr%16-19d, cr%0-3d, %5-7d"},
987 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
988 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"},
989 {ARM_EXT_V6T2, 0xec000000, 0xee100000, "stc%28'2%22'l\tp%8-11d, cr%12-15d, %A"},
990 {ARM_EXT_V6T2, 0xec100000, 0xee100000, "ldc%28'2%22'l\tp%8-11d, cr%12-15d, %A"},
991 {ARM_EXT_V6T2, 0xee000000, 0xef000010, "cdp%28'2\tp%8-11d, %20-23d, cr%12-15d, cr%16-19d, cr%0-3d, %5-7d"},
992
993 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
994 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
995 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
996 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
997 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
998
999 /* These have been 32-bit since the invention of Thumb. */
1000 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx\t%B"},
1001 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl\t%B"},
1002
1003 /* Fallback. */
1004 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1005 {0, 0, 0, 0}
2fbad815 1006};
c19d1205 1007
2fbad815 1008
5876e06d 1009static char * arm_conditional[] =
252b5132 1010{"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
c19d1205 1011 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
252b5132 1012
58efb6c0
NC
1013typedef struct
1014{
1015 const char * name;
1016 const char * description;
1017 const char * reg_names[16];
1018}
1019arm_regname;
dd92f639 1020
58efb6c0
NC
1021static arm_regname regnames[] =
1022{
1023 { "raw" , "Select raw register names",
1024 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
7c03c75e
SB
1025 { "gcc", "Select register names used by GCC",
1026 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
58efb6c0
NC
1027 { "std", "Select register names used in ARM's ISA documentation",
1028 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1029 { "apcs", "Select register names used in the APCS",
1030 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1031 { "atpcs", "Select register names used in the ATPCS",
1032 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
a7f8487e 1033 { "special-atpcs", "Select special register names used in the ATPCS",
e16bb312 1034 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
5a6c6817 1035 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
e16bb312 1036 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
5a6c6817 1037 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
e16bb312
NC
1038 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
1039};
1040
1041static char * iwmmxt_wwnames[] =
1042{"b", "h", "w", "d"};
1043
1044static char * iwmmxt_wwssnames[] =
1045{"b", "bus", "b", "bss",
1046 "h", "hus", "h", "hss",
1047 "w", "wus", "w", "wss",
1048 "d", "dus", "d", "dss"
58efb6c0
NC
1049};
1050
7c03c75e 1051/* Default to GCC register name set. */
58efb6c0
NC
1052static unsigned int regname_selected = 1;
1053
1054#define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1055#define arm_regnames regnames[regname_selected].reg_names
252b5132 1056
b34976b6 1057static bfd_boolean force_thumb = FALSE;
01c7f630 1058
5876e06d 1059static char * arm_fp_const[] =
252b5132
RH
1060{"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1061
b34976b6 1062static char * arm_shift[] =
252b5132 1063{"lsl", "lsr", "asr", "ror"};
01c7f630
NC
1064\f
1065/* Forward declarations. */
b34976b6
AM
1066static void arm_decode_shift
1067 PARAMS ((long, fprintf_ftype, void *));
1068static int print_insn_arm
1069 PARAMS ((bfd_vma, struct disassemble_info *, long));
c19d1205
ZW
1070static int print_insn_thumb16
1071 PARAMS ((bfd_vma, struct disassemble_info *, long));
1072static int print_insn_thumb32
b34976b6
AM
1073 PARAMS ((bfd_vma, struct disassemble_info *, long));
1074static void parse_disassembler_options
1075 PARAMS ((char *));
1076static int print_insn
1077 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
e16bb312
NC
1078static int set_iwmmxt_regnames
1079 PARAMS ((void));
1080
1081int get_arm_regname_num_options
1082 PARAMS ((void));
1083int set_arm_regname_option
1084 PARAMS ((int));
1085int get_arm_regnames
1086 PARAMS ((int, const char **, const char **, const char ***));
01c7f630 1087\f
baf0cc5e 1088/* Functions. */
a7f8487e 1089int
baf0cc5e 1090get_arm_regname_num_options ()
a7f8487e
FN
1091{
1092 return NUM_ARM_REGNAMES;
1093}
1094
1095int
baf0cc5e
NC
1096set_arm_regname_option (option)
1097 int option;
a7f8487e
FN
1098{
1099 int old = regname_selected;
1100 regname_selected = option;
1101 return old;
1102}
1103
1104int
baf0cc5e
NC
1105get_arm_regnames (option, setname, setdescription, register_names)
1106 int option;
1107 const char **setname;
1108 const char **setdescription;
1109 const char ***register_names;
a7f8487e
FN
1110{
1111 *setname = regnames[option].name;
1112 *setdescription = regnames[option].description;
1113 *register_names = regnames[option].reg_names;
1114 return 16;
1115}
1116
252b5132
RH
1117static void
1118arm_decode_shift (given, func, stream)
1119 long given;
1120 fprintf_ftype func;
5876e06d 1121 void * stream;
252b5132
RH
1122{
1123 func (stream, "%s", arm_regnames[given & 0xf]);
b34976b6 1124
252b5132
RH
1125 if ((given & 0xff0) != 0)
1126 {
1127 if ((given & 0x10) == 0)
1128 {
1129 int amount = (given & 0xf80) >> 7;
1130 int shift = (given & 0x60) >> 5;
b34976b6 1131
252b5132
RH
1132 if (amount == 0)
1133 {
1134 if (shift == 3)
1135 {
1136 func (stream, ", rrx");
1137 return;
1138 }
b34976b6 1139
252b5132
RH
1140 amount = 32;
1141 }
b34976b6 1142
252b5132
RH
1143 func (stream, ", %s #%d", arm_shift[shift], amount);
1144 }
1145 else
1146 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1147 arm_regnames[(given & 0xf00) >> 8]);
1148 }
1149}
1150
e16bb312
NC
1151static int
1152set_iwmmxt_regnames ()
1153{
1154 const char * setname;
1155 const char * setdesc;
1156 const char ** regnames;
1157 int iwmmxt_regnames = 0;
1158 int num_regnames = get_arm_regname_num_options ();
1159
1160 get_arm_regnames (iwmmxt_regnames, &setname,
1161 &setdesc, &regnames);
1162 while ((strcmp ("iwmmxt_regnames", setname))
1163 && (iwmmxt_regnames < num_regnames))
1164 get_arm_regnames (++iwmmxt_regnames, &setname, &setdesc, &regnames);
1165
1166 return iwmmxt_regnames;
1167}
1168
252b5132
RH
1169/* Print one instruction from PC on INFO->STREAM.
1170 Return the size of the instruction (always 4 on ARM). */
baf0cc5e 1171
252b5132
RH
1172static int
1173print_insn_arm (pc, info, given)
6a51a8a8
AM
1174 bfd_vma pc;
1175 struct disassemble_info *info;
1176 long given;
252b5132 1177{
6a51a8a8
AM
1178 const struct arm_opcode *insn;
1179 void *stream = info->stream;
1180 fprintf_ftype func = info->fprintf_func;
e16bb312 1181 static int iwmmxt_regnames = 0;
252b5132
RH
1182
1183 for (insn = arm_opcodes; insn->assembler; insn++)
1184 {
e16bb312
NC
1185 if (insn->value == FIRST_IWMMXT_INSN
1186 && info->mach != bfd_mach_arm_XScale
1187 && info->mach != bfd_mach_arm_iWMMXt)
1188 insn = insn + IWMMXT_INSN_COUNT;
1189
0a003adc
ZW
1190 if ((given & insn->mask) == insn->value
1191 /* Special case: an instruction with all bits set in the condition field
1192 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
1193 or by the catchall at the end of the table. */
1194 && ((given & 0xF0000000) != 0xF0000000
1195 || (insn->mask & 0xF0000000) == 0xF0000000
1196 || (insn->mask == 0 && insn->value == 0)))
252b5132
RH
1197 {
1198 char * c;
b34976b6 1199
252b5132
RH
1200 for (c = insn->assembler; *c; c++)
1201 {
1202 if (*c == '%')
1203 {
1204 switch (*++c)
1205 {
1206 case '%':
1207 func (stream, "%%");
1208 break;
1209
1210 case 'a':
1211 if (((given & 0x000f0000) == 0x000f0000)
1212 && ((given & 0x02000000) == 0))
1213 {
1214 int offset = given & 0xfff;
b34976b6 1215
252b5132 1216 func (stream, "[pc");
b34976b6 1217
252b5132
RH
1218 if (given & 0x01000000)
1219 {
1220 if ((given & 0x00800000) == 0)
1221 offset = - offset;
b34976b6 1222
baf0cc5e 1223 /* Pre-indexed. */
40536497 1224 func (stream, ", #%d]", offset);
252b5132
RH
1225
1226 offset += pc + 8;
1227
58efb6c0
NC
1228 /* Cope with the possibility of write-back
1229 being used. Probably a very dangerous thing
1230 for the programmer to do, but who are we to
1231 argue ? */
252b5132
RH
1232 if (given & 0x00200000)
1233 func (stream, "!");
1234 }
1235 else
1236 {
58efb6c0 1237 /* Post indexed. */
40536497 1238 func (stream, "], #%d", offset);
252b5132 1239
baf0cc5e
NC
1240 /* ie ignore the offset. */
1241 offset = pc + 8;
252b5132 1242 }
b34976b6 1243
252b5132
RH
1244 func (stream, "\t; ");
1245 info->print_address_func (offset, info);
1246 }
1247 else
1248 {
b34976b6 1249 func (stream, "[%s",
252b5132
RH
1250 arm_regnames[(given >> 16) & 0xf]);
1251 if ((given & 0x01000000) != 0)
1252 {
1253 if ((given & 0x02000000) == 0)
1254 {
1255 int offset = given & 0xfff;
1256 if (offset)
8e6446ff 1257 func (stream, ", #%s%d",
252b5132
RH
1258 (((given & 0x00800000) == 0)
1259 ? "-" : ""), offset);
1260 }
1261 else
1262 {
1263 func (stream, ", %s",
1264 (((given & 0x00800000) == 0)
1265 ? "-" : ""));
1266 arm_decode_shift (given, func, stream);
1267 }
1268
b34976b6 1269 func (stream, "]%s",
252b5132
RH
1270 ((given & 0x00200000) != 0) ? "!" : "");
1271 }
1272 else
1273 {
1274 if ((given & 0x02000000) == 0)
1275 {
1276 int offset = given & 0xfff;
1277 if (offset)
8e6446ff 1278 func (stream, "], #%s%d",
252b5132
RH
1279 (((given & 0x00800000) == 0)
1280 ? "-" : ""), offset);
b34976b6 1281 else
252b5132
RH
1282 func (stream, "]");
1283 }
1284 else
1285 {
1286 func (stream, "], %s",
b34976b6 1287 (((given & 0x00800000) == 0)
252b5132
RH
1288 ? "-" : ""));
1289 arm_decode_shift (given, func, stream);
1290 }
1291 }
1292 }
1293 break;
1294
1295 case 's':
1296 if ((given & 0x004f0000) == 0x004f0000)
1297 {
58efb6c0 1298 /* PC relative with immediate offset. */
252b5132 1299 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
b34976b6 1300
252b5132
RH
1301 if ((given & 0x00800000) == 0)
1302 offset = -offset;
b34976b6 1303
40536497 1304 func (stream, "[pc, #%d]\t; ", offset);
b34976b6 1305
252b5132
RH
1306 (*info->print_address_func)
1307 (offset + pc + 8, info);
1308 }
1309 else
1310 {
b34976b6 1311 func (stream, "[%s",
252b5132
RH
1312 arm_regnames[(given >> 16) & 0xf]);
1313 if ((given & 0x01000000) != 0)
1314 {
58efb6c0 1315 /* Pre-indexed. */
252b5132
RH
1316 if ((given & 0x00400000) == 0x00400000)
1317 {
58efb6c0 1318 /* Immediate. */
252b5132
RH
1319 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1320 if (offset)
8e6446ff 1321 func (stream, ", #%s%d",
252b5132
RH
1322 (((given & 0x00800000) == 0)
1323 ? "-" : ""), offset);
1324 }
1325 else
1326 {
58efb6c0 1327 /* Register. */
252b5132
RH
1328 func (stream, ", %s%s",
1329 (((given & 0x00800000) == 0)
1330 ? "-" : ""),
1331 arm_regnames[given & 0xf]);
1332 }
1333
b34976b6 1334 func (stream, "]%s",
252b5132
RH
1335 ((given & 0x00200000) != 0) ? "!" : "");
1336 }
1337 else
1338 {
58efb6c0 1339 /* Post-indexed. */
252b5132
RH
1340 if ((given & 0x00400000) == 0x00400000)
1341 {
58efb6c0 1342 /* Immediate. */
252b5132
RH
1343 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1344 if (offset)
8e6446ff 1345 func (stream, "], #%s%d",
252b5132
RH
1346 (((given & 0x00800000) == 0)
1347 ? "-" : ""), offset);
b34976b6 1348 else
252b5132
RH
1349 func (stream, "]");
1350 }
1351 else
1352 {
58efb6c0 1353 /* Register. */
252b5132
RH
1354 func (stream, "], %s%s",
1355 (((given & 0x00800000) == 0)
1356 ? "-" : ""),
1357 arm_regnames[given & 0xf]);
1358 }
1359 }
1360 }
1361 break;
b34976b6 1362
252b5132
RH
1363 case 'b':
1364 (*info->print_address_func)
1365 (BDISP (given) * 4 + pc + 8, info);
1366 break;
1367
1368 case 'c':
1369 func (stream, "%s",
1370 arm_conditional [(given >> 28) & 0xf]);
1371 break;
1372
1373 case 'm':
1374 {
1375 int started = 0;
1376 int reg;
1377
1378 func (stream, "{");
1379 for (reg = 0; reg < 16; reg++)
1380 if ((given & (1 << reg)) != 0)
1381 {
1382 if (started)
1383 func (stream, ", ");
1384 started = 1;
1385 func (stream, "%s", arm_regnames[reg]);
1386 }
1387 func (stream, "}");
1388 }
1389 break;
1390
1391 case 'o':
1392 if ((given & 0x02000000) != 0)
1393 {
1394 int rotate = (given & 0xf00) >> 7;
1395 int immed = (given & 0xff);
9f20bbfd
NC
1396 immed = (((immed << (32 - rotate))
1397 | (immed >> rotate)) & 0xffffffff);
1398 func (stream, "#%d\t; 0x%x", immed, immed);
252b5132
RH
1399 }
1400 else
1401 arm_decode_shift (given, func, stream);
1402 break;
1403
1404 case 'p':
1405 if ((given & 0x0000f000) == 0x0000f000)
1406 func (stream, "p");
1407 break;
1408
1409 case 't':
1410 if ((given & 0x01200000) == 0x00200000)
1411 func (stream, "t");
1412 break;
1413
252b5132
RH
1414 case 'A':
1415 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
f02232aa
NC
1416
1417 if ((given & (1 << 24)) != 0)
252b5132
RH
1418 {
1419 int offset = given & 0xff;
f02232aa 1420
252b5132 1421 if (offset)
8e6446ff 1422 func (stream, ", #%s%d]%s",
252b5132
RH
1423 ((given & 0x00800000) == 0 ? "-" : ""),
1424 offset * 4,
1425 ((given & 0x00200000) != 0 ? "!" : ""));
1426 else
1427 func (stream, "]");
1428 }
1429 else
1430 {
1431 int offset = given & 0xff;
f02232aa
NC
1432
1433 func (stream, "]");
1434
1435 if (given & (1 << 21))
1436 {
1437 if (offset)
8e6446ff 1438 func (stream, ", #%s%d",
f02232aa
NC
1439 ((given & 0x00800000) == 0 ? "-" : ""),
1440 offset * 4);
1441 }
252b5132 1442 else
f02232aa 1443 func (stream, ", {%d}", offset);
252b5132
RH
1444 }
1445 break;
1446
077b8428
NC
1447 case 'B':
1448 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1449 {
1450 bfd_vma address;
1451 bfd_vma offset = 0;
b34976b6 1452
077b8428
NC
1453 if (given & 0x00800000)
1454 /* Is signed, hi bits should be ones. */
1455 offset = (-1) ^ 0x00ffffff;
1456
1457 /* Offset is (SignExtend(offset field)<<2). */
1458 offset += given & 0x00ffffff;
1459 offset <<= 2;
1460 address = offset + pc + 8;
b34976b6 1461
077b8428
NC
1462 if (given & 0x01000000)
1463 /* H bit allows addressing to 2-byte boundaries. */
1464 address += 2;
1465
1466 info->print_address_func (address, info);
1467 }
1468 break;
1469
b1ee46c5
AH
1470 case 'I':
1471 /* Print a Cirrus/DSP shift immediate. */
1472 /* Immediates are 7bit signed ints with bits 0..3 in
1473 bits 0..3 of opcode and bits 4..6 in bits 5..7
1474 of opcode. */
1475 {
1476 int imm;
1477
1478 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1479
1480 /* Is ``imm'' a negative number? */
1481 if (imm & 0x40)
1482 imm |= (-1 << 7);
1483
1484 func (stream, "%d", imm);
1485 }
1486
1487 break;
1488
252b5132 1489 case 'C':
6eeeb4b4
AO
1490 func (stream, "_");
1491 if (given & 0x80000)
1492 func (stream, "f");
1493 if (given & 0x40000)
1494 func (stream, "s");
1495 if (given & 0x20000)
1496 func (stream, "x");
1497 if (given & 0x10000)
1498 func (stream, "c");
252b5132
RH
1499 break;
1500
1501 case 'F':
1502 switch (given & 0x00408000)
1503 {
1504 case 0:
1505 func (stream, "4");
1506 break;
1507 case 0x8000:
1508 func (stream, "1");
1509 break;
1510 case 0x00400000:
1511 func (stream, "2");
1512 break;
1513 default:
1514 func (stream, "3");
1515 }
1516 break;
b34976b6 1517
252b5132
RH
1518 case 'P':
1519 switch (given & 0x00080080)
1520 {
1521 case 0:
1522 func (stream, "s");
1523 break;
1524 case 0x80:
1525 func (stream, "d");
1526 break;
1527 case 0x00080000:
1528 func (stream, "e");
1529 break;
1530 default:
1531 func (stream, _("<illegal precision>"));
1532 break;
1533 }
1534 break;
1535 case 'Q':
1536 switch (given & 0x00408000)
1537 {
1538 case 0:
1539 func (stream, "s");
1540 break;
1541 case 0x8000:
1542 func (stream, "d");
1543 break;
1544 case 0x00400000:
1545 func (stream, "e");
1546 break;
1547 default:
1548 func (stream, "p");
1549 break;
1550 }
1551 break;
1552 case 'R':
1553 switch (given & 0x60)
1554 {
1555 case 0:
1556 break;
1557 case 0x20:
1558 func (stream, "p");
1559 break;
1560 case 0x40:
1561 func (stream, "m");
1562 break;
1563 default:
1564 func (stream, "z");
1565 break;
1566 }
1567 break;
1568
b34976b6 1569 case '0': case '1': case '2': case '3': case '4':
252b5132
RH
1570 case '5': case '6': case '7': case '8': case '9':
1571 {
1572 int bitstart = *c++ - '0';
1573 int bitend = 0;
1574 while (*c >= '0' && *c <= '9')
1575 bitstart = (bitstart * 10) + *c++ - '0';
1576
1577 switch (*c)
1578 {
1579 case '-':
1580 c++;
b34976b6 1581
252b5132
RH
1582 while (*c >= '0' && *c <= '9')
1583 bitend = (bitend * 10) + *c++ - '0';
b34976b6 1584
252b5132
RH
1585 if (!bitend)
1586 abort ();
b34976b6 1587
252b5132
RH
1588 switch (*c)
1589 {
1590 case 'r':
1591 {
1592 long reg;
b34976b6 1593
252b5132
RH
1594 reg = given >> bitstart;
1595 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1596
252b5132
RH
1597 func (stream, "%s", arm_regnames[reg]);
1598 }
1599 break;
1600 case 'd':
1601 {
1602 long reg;
b34976b6 1603
252b5132
RH
1604 reg = given >> bitstart;
1605 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1606
252b5132
RH
1607 func (stream, "%d", reg);
1608 }
1609 break;
09d92015
MM
1610 case 'W':
1611 {
1612 long reg;
1613
1614 reg = given >> bitstart;
1615 reg &= (2 << (bitend - bitstart)) - 1;
1616
1617 func (stream, "%d", reg + 1);
1618 }
1619 break;
252b5132
RH
1620 case 'x':
1621 {
1622 long reg;
b34976b6 1623
252b5132
RH
1624 reg = given >> bitstart;
1625 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1626
252b5132 1627 func (stream, "0x%08x", reg);
b34976b6 1628
58efb6c0
NC
1629 /* Some SWI instructions have special
1630 meanings. */
5876e06d
NC
1631 if ((given & 0x0fffffff) == 0x0FF00000)
1632 func (stream, "\t; IMB");
1633 else if ((given & 0x0fffffff) == 0x0FF00001)
1634 func (stream, "\t; IMBRange");
252b5132
RH
1635 }
1636 break;
cfbd315c
DL
1637 case 'X':
1638 {
1639 long reg;
b34976b6 1640
cfbd315c
DL
1641 reg = given >> bitstart;
1642 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1643
cfbd315c
DL
1644 func (stream, "%01x", reg & 0xf);
1645 }
1646 break;
252b5132
RH
1647 case 'f':
1648 {
1649 long reg;
b34976b6 1650
252b5132
RH
1651 reg = given >> bitstart;
1652 reg &= (2 << (bitend - bitstart)) - 1;
b34976b6 1653
252b5132
RH
1654 if (reg > 7)
1655 func (stream, "#%s",
1656 arm_fp_const[reg & 7]);
1657 else
1658 func (stream, "f%d", reg);
1659 }
1660 break;
e16bb312
NC
1661
1662 case 'w':
1663 {
1664 long reg;
1665
1666 if (bitstart != bitend)
1667 {
1668 reg = given >> bitstart;
1669 reg &= (2 << (bitend - bitstart)) - 1;
1670 if (bitend - bitstart == 1)
1671 func (stream, "%s", iwmmxt_wwnames[reg]);
1672 else
1673 func (stream, "%s", iwmmxt_wwssnames[reg]);
1674 }
1675 else
1676 {
1677 reg = (((given >> 8) & 0x1) |
1678 ((given >> 22) & 0x1));
1679 func (stream, "%s", iwmmxt_wwnames[reg]);
1680 }
1681 }
1682 break;
1683
1684 case 'g':
1685 {
1686 long reg;
1687 int current_regnames;
1688
1689 if (! iwmmxt_regnames)
1690 iwmmxt_regnames = set_iwmmxt_regnames ();
1691 current_regnames = set_arm_regname_option
1692 (iwmmxt_regnames);
1693
1694 reg = given >> bitstart;
1695 reg &= (2 << (bitend - bitstart)) - 1;
1696 func (stream, "%s", arm_regnames[reg]);
1697 set_arm_regname_option (current_regnames);
1698 }
1699 break;
1700
1701 case 'G':
1702 {
1703 long reg;
1704 int current_regnames;
1705
1706 if (! iwmmxt_regnames)
1707 iwmmxt_regnames = set_iwmmxt_regnames ();
1708 current_regnames = set_arm_regname_option
1709 (iwmmxt_regnames + 1);
1710
1711 reg = given >> bitstart;
1712 reg &= (2 << (bitend - bitstart)) - 1;
1713 func (stream, "%s", arm_regnames[reg]);
1714 set_arm_regname_option (current_regnames);
1715 }
1716 break;
1717
252b5132
RH
1718 default:
1719 abort ();
1720 }
1721 break;
a660f11e
RE
1722
1723 case 'y':
1724 case 'z':
1725 {
1726 int single = *c == 'y';
1727 int regno;
1728
1729 switch (bitstart)
1730 {
1731 case 4: /* Sm pair */
1732 func (stream, "{");
1733 /* Fall through. */
1734 case 0: /* Sm, Dm */
1735 regno = given & 0x0000000f;
1736 if (single)
1737 {
1738 regno <<= 1;
1739 regno += (given >> 5) & 1;
1740 }
1741 break;
1742
1743 case 1: /* Sd, Dd */
1744 regno = (given >> 12) & 0x0000000f;
1745 if (single)
1746 {
1747 regno <<= 1;
1748 regno += (given >> 22) & 1;
1749 }
1750 break;
1751
1752 case 2: /* Sn, Dn */
1753 regno = (given >> 16) & 0x0000000f;
1754 if (single)
1755 {
1756 regno <<= 1;
1757 regno += (given >> 7) & 1;
1758 }
1759 break;
1760
1761 case 3: /* List */
1762 func (stream, "{");
1763 regno = (given >> 12) & 0x0000000f;
1764 if (single)
1765 {
1766 regno <<= 1;
1767 regno += (given >> 22) & 1;
1768 }
1769 break;
1770
b34976b6 1771
a660f11e
RE
1772 default:
1773 abort ();
1774 }
1775
1776 func (stream, "%c%d", single ? 's' : 'd', regno);
1777
1778 if (bitstart == 3)
1779 {
1780 int count = given & 0xff;
1781
1782 if (single == 0)
1783 count >>= 1;
1784
1785 if (--count)
1786 {
1787 func (stream, "-%c%d",
1788 single ? 's' : 'd',
1789 regno + count);
1790 }
1791
1792 func (stream, "}");
1793 }
1794 else if (bitstart == 4)
1795 func (stream, ", %c%d}", single ? 's' : 'd',
1796 regno + 1);
1797
1798 break;
1799 }
1800
252b5132
RH
1801 case '`':
1802 c++;
1803 if ((given & (1 << bitstart)) == 0)
1804 func (stream, "%c", *c);
1805 break;
1806 case '\'':
1807 c++;
1808 if ((given & (1 << bitstart)) != 0)
1809 func (stream, "%c", *c);
1810 break;
1811 case '?':
1812 ++c;
1813 if ((given & (1 << bitstart)) != 0)
1814 func (stream, "%c", *c++);
1815 else
1816 func (stream, "%c", *++c);
1817 break;
1818 default:
1819 abort ();
1820 }
1821 break;
1822
e16bb312
NC
1823 case 'L':
1824 switch (given & 0x00400100)
1825 {
1826 case 0x00000000: func (stream, "b"); break;
1827 case 0x00400000: func (stream, "h"); break;
1828 case 0x00000100: func (stream, "w"); break;
1829 case 0x00400100: func (stream, "d"); break;
1830 default:
1831 break;
1832 }
1833 break;
1834
1835 case 'Z':
1836 {
1837 int value;
1838 /* given (20, 23) | given (0, 3) */
1839 value = ((given >> 16) & 0xf0) | (given & 0xf);
1840 func (stream, "%d", value);
1841 }
1842 break;
1843
1844 case 'l':
1845 /* This is like the 'A' operator, except that if
1846 the width field "M" is zero, then the offset is
1847 *not* multiplied by four. */
1848 {
1849 int offset = given & 0xff;
1850 int multiplier = (given & 0x00000100) ? 4 : 1;
1851
1852 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1853
1854 if (offset)
1855 {
1856 if ((given & 0x01000000) != 0)
8e6446ff 1857 func (stream, ", #%s%d]%s",
e16bb312
NC
1858 ((given & 0x00800000) == 0 ? "-" : ""),
1859 offset * multiplier,
1860 ((given & 0x00200000) != 0 ? "!" : ""));
1861 else
8e6446ff 1862 func (stream, "], #%s%d",
e16bb312
NC
1863 ((given & 0x00800000) == 0 ? "-" : ""),
1864 offset * multiplier);
1865 }
1866 else
1867 func (stream, "]");
1868 }
1869 break;
1870
0dd132b6
NC
1871 case 'e':
1872 {
1873 int imm;
1874
1875 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1876 func (stream, "%d", imm);
1877 }
1878 break;
1879
0a003adc
ZW
1880 case 'E':
1881 /* LSB and WIDTH fields of BFI or BFC. The machine-
1882 language instruction encodes LSB and MSB. */
1883 {
1884 long msb = (given & 0x001f0000) >> 16;
1885 long lsb = (given & 0x00000f80) >> 7;
1886
1887 long width = msb - lsb + 1;
1888 if (width > 0)
1889 func (stream, "#%lu, #%lu", lsb, width);
1890 else
1891 func (stream, "(invalid: %lu:%lu)", lsb, msb);
1892 }
1893 break;
1894
1895 case 'V':
1896 /* 16-bit unsigned immediate from a MOVT or MOVW
1897 instruction, encoded in bits 0:11 and 15:19. */
1898 {
1899 long hi = (given & 0x000f0000) >> 4;
1900 long lo = (given & 0x00000fff);
1901 long imm16 = hi | lo;
1902 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
1903 }
1904 break;
1905
252b5132
RH
1906 default:
1907 abort ();
1908 }
1909 }
1910 }
1911 else
1912 func (stream, "%c", *c);
1913 }
1914 return 4;
1915 }
1916 }
1917 abort ();
1918}
1919
1920/* Print one instruction from PC on INFO->STREAM.
1921 Return the size of the instruction. */
baf0cc5e 1922
252b5132 1923static int
c19d1205 1924print_insn_thumb16 (pc, info, given)
6a51a8a8
AM
1925 bfd_vma pc;
1926 struct disassemble_info *info;
1927 long given;
252b5132 1928{
6a51a8a8
AM
1929 const struct thumb_opcode *insn;
1930 void *stream = info->stream;
1931 fprintf_ftype func = info->fprintf_func;
252b5132
RH
1932
1933 for (insn = thumb_opcodes; insn->assembler; insn++)
c19d1205
ZW
1934 if ((given & insn->mask) == insn->value)
1935 {
1936 char * c = insn->assembler;
1937 for (; *c; c++)
1938 {
1939 int domaskpc = 0;
1940 int domasklr = 0;
1941
1942 if (*c != '%')
1943 {
1944 func (stream, "%c", *c);
1945 continue;
1946 }
252b5132 1947
c19d1205
ZW
1948 switch (*++c)
1949 {
1950 case '%':
1951 func (stream, "%%");
1952 break;
b34976b6 1953
c19d1205
ZW
1954 case 'S':
1955 {
1956 long reg;
1957
1958 reg = (given >> 3) & 0x7;
1959 if (given & (1 << 6))
1960 reg += 8;
4f3c3dbb 1961
c19d1205
ZW
1962 func (stream, "%s", arm_regnames[reg]);
1963 }
1964 break;
baf0cc5e 1965
c19d1205 1966 case 'D':
4f3c3dbb 1967 {
c19d1205
ZW
1968 long reg;
1969
1970 reg = given & 0x7;
1971 if (given & (1 << 7))
1972 reg += 8;
1973
1974 func (stream, "%s", arm_regnames[reg]);
4f3c3dbb 1975 }
c19d1205
ZW
1976 break;
1977
1978 case 'N':
1979 if (given & (1 << 8))
1980 domasklr = 1;
1981 /* Fall through. */
1982 case 'O':
1983 if (*c == 'O' && (given & (1 << 8)))
1984 domaskpc = 1;
1985 /* Fall through. */
1986 case 'M':
1987 {
1988 int started = 0;
1989 int reg;
1990
1991 func (stream, "{");
1992
1993 /* It would be nice if we could spot
1994 ranges, and generate the rS-rE format: */
1995 for (reg = 0; (reg < 8); reg++)
1996 if ((given & (1 << reg)) != 0)
1997 {
1998 if (started)
1999 func (stream, ", ");
2000 started = 1;
2001 func (stream, "%s", arm_regnames[reg]);
2002 }
2003
2004 if (domasklr)
2005 {
2006 if (started)
2007 func (stream, ", ");
2008 started = 1;
2009 func (stream, arm_regnames[14] /* "lr" */);
2010 }
2011
2012 if (domaskpc)
2013 {
2014 if (started)
2015 func (stream, ", ");
2016 func (stream, arm_regnames[15] /* "pc" */);
2017 }
2018
2019 func (stream, "}");
2020 }
2021 break;
2022
2023 case 'b':
2024 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
2025 {
2026 bfd_vma address = (pc + 4
2027 + ((given & 0x00f8) >> 2)
2028 + ((given & 0x0200) >> 3));
2029 info->print_address_func (address, info);
2030 }
2031 break;
2032
2033 case 's':
2034 /* Right shift immediate -- bits 6..10; 1-31 print
2035 as themselves, 0 prints as 32. */
2036 {
2037 long imm = (given & 0x07c0) >> 6;
2038 if (imm == 0)
2039 imm = 32;
2040 func (stream, "#%d", imm);
2041 }
2042 break;
2043
2044 case '0': case '1': case '2': case '3': case '4':
2045 case '5': case '6': case '7': case '8': case '9':
2046 {
2047 int bitstart = *c++ - '0';
2048 int bitend = 0;
2049
2050 while (*c >= '0' && *c <= '9')
2051 bitstart = (bitstart * 10) + *c++ - '0';
2052
2053 switch (*c)
2054 {
2055 case '-':
2056 {
2057 long reg;
2058
2059 c++;
2060 while (*c >= '0' && *c <= '9')
2061 bitend = (bitend * 10) + *c++ - '0';
2062 if (!bitend)
2063 abort ();
2064 reg = given >> bitstart;
2065 reg &= (2 << (bitend - bitstart)) - 1;
2066 switch (*c)
2067 {
2068 case 'r':
2069 func (stream, "%s", arm_regnames[reg]);
2070 break;
2071
2072 case 'd':
2073 func (stream, "%d", reg);
2074 break;
2075
2076 case 'H':
2077 func (stream, "%d", reg << 1);
2078 break;
2079
2080 case 'W':
2081 func (stream, "%d", reg << 2);
2082 break;
2083
2084 case 'a':
2085 /* PC-relative address -- the bottom two
2086 bits of the address are dropped
2087 before the calculation. */
2088 info->print_address_func
2089 (((pc + 4) & ~3) + (reg << 2), info);
2090 break;
2091
2092 case 'x':
2093 func (stream, "0x%04x", reg);
2094 break;
2095
2096 case 'I':
2097 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2098 func (stream, "%d", reg);
2099 break;
2100
2101 case 'B':
2102 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2103 (*info->print_address_func)
2104 (reg * 2 + pc + 4, info);
2105 break;
2106
2107 case 'c':
2108 {
2109 /* Must print 0xE as 'al' to distinguish
2110 unconditional B from conditional BAL. */
2111 if (reg == 0xE)
2112 func (stream, "al");
2113 else
2114 func (stream, "%s", arm_conditional [reg]);
2115 }
2116 break;
2117
2118 default:
2119 abort ();
2120 }
2121 }
2122 break;
2123
2124 case '\'':
2125 c++;
2126 if ((given & (1 << bitstart)) != 0)
2127 func (stream, "%c", *c);
2128 break;
2129
2130 case '?':
2131 ++c;
2132 if ((given & (1 << bitstart)) != 0)
2133 func (stream, "%c", *c++);
2134 else
2135 func (stream, "%c", *++c);
2136 break;
2137
2138 default:
2139 abort ();
2140 }
2141 }
2142 break;
2143
2144 default:
2145 abort ();
2146 }
2147 }
2148 return 2;
2149 }
2150
2151 /* No match. */
2152 abort ();
2153}
2154
2155static int
2156print_insn_thumb32 (pc, info, given)
2157 bfd_vma pc;
2158 struct disassemble_info *info;
2159 long given;
2160{
2161 const struct arm_opcode *insn;
2162 void *stream = info->stream;
2163 fprintf_ftype func = info->fprintf_func;
2164
2165 for (insn = thumb32_opcodes; insn->assembler; insn++)
2166 if ((given & insn->mask) == insn->value)
2167 {
2168 char * c = insn->assembler;
2169 for (; *c; c++)
2170 {
2171 if (*c != '%')
2172 {
2173 func (stream, "%c", *c);
2174 continue;
2175 }
2176
2177 switch (*++c)
2178 {
2179 case '%':
2180 func (stream, "%%");
2181 break;
2182
2183 case 'I':
2184 {
2185 unsigned int imm12 = 0;
2186 imm12 |= (given & 0x000000ffu);
2187 imm12 |= (given & 0x00007000u) >> 4;
2188 imm12 |= (given & 0x04000000u) >> 12;
2189 func (stream, "#%u\t; 0x%x", imm12, imm12);
2190 }
2191 break;
2192
2193 case 'M':
2194 {
2195 unsigned int bits = 0, imm, imm8, mod;
2196 bits |= (given & 0x000000ffu);
2197 bits |= (given & 0x00007000u) >> 4;
2198 bits |= (given & 0x04000000u) >> 15;
2199 imm8 = (bits & 0x0ff);
2200 mod = (bits & 0xf00) >> 8;
2201 switch (mod)
2202 {
2203 case 0: imm = imm8; break;
2204 case 1: imm = ((imm8<<16) | imm8); break;
2205 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
2206 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
2207 default:
2208 mod = (bits & 0xf80) >> 7;
2209 imm8 = (bits & 0x07f) | 0x80;
2210 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
2211 }
2212 func (stream, "#%u\t; 0x%x", imm, imm);
2213 }
2214 break;
2215
2216 case 'J':
2217 {
2218 unsigned int imm = 0;
2219 imm |= (given & 0x000000ffu);
2220 imm |= (given & 0x00007000u) >> 4;
2221 imm |= (given & 0x04000000u) >> 15;
2222 imm |= (given & 0x000f0000u) >> 4;
2223 func (stream, "#%u\t; 0x%x", imm, imm);
2224 }
2225 break;
2226
2227 case 'K':
2228 {
2229 unsigned int imm = 0;
2230 imm |= (given & 0x000f0000u) >> 16;
2231 imm |= (given & 0x00000ff0u) >> 0;
2232 imm |= (given & 0x0000000fu) << 12;
2233 func (stream, "#%u\t; 0x%x", imm, imm);
2234 }
2235 break;
2236
2237 case 'S':
2238 {
2239 unsigned int reg = (given & 0x0000000fu);
2240 unsigned int stp = (given & 0x00000030u) >> 4;
2241 unsigned int imm = 0;
2242 imm |= (given & 0x000000c0u) >> 6;
2243 imm |= (given & 0x00007000u) >> 10;
2244
2245 func (stream, "%s", arm_regnames[reg]);
2246 switch (stp)
2247 {
2248 case 0:
2249 if (imm > 0)
2250 func (stream, ", lsl #%u", imm);
2251 break;
2252
2253 case 1:
2254 if (imm == 0)
2255 imm = 32;
2256 func (stream, ", lsr #%u", imm);
2257 break;
2258
2259 case 2:
2260 if (imm == 0)
2261 imm = 32;
2262 func (stream, ", asr #%u", imm);
2263 break;
2264
2265 case 3:
2266 if (imm == 0)
2267 func (stream, ", rrx");
2268 else
2269 func (stream, ", ror #%u", imm);
2270 }
2271 }
2272 break;
2273
2274 case 'a':
2275 {
2276 unsigned int Rn = (given & 0x000f0000) >> 16;
2277 unsigned int U = (given & 0x00800000) >> 23;
2278 unsigned int op = (given & 0x00000f00) >> 8;
2279 unsigned int i12 = (given & 0x00000fff);
2280 unsigned int i8 = (given & 0x000000ff);
2281 bfd_boolean writeback = FALSE, postind = FALSE;
2282 int offset = 0;
2283
2284 func (stream, "[%s", arm_regnames[Rn]);
2285 if (U) /* 12-bit positive immediate offset */
2286 offset = i12;
2287 else if (Rn == 15) /* 12-bit negative immediate offset */
2288 offset = -(int)i12;
2289 else if (op == 0x0) /* shifted register offset */
2290 {
2291 unsigned int Rm = (i8 & 0x0f);
2292 unsigned int sh = (i8 & 0x30) >> 4;
2293 func (stream, ", %s", arm_regnames[Rm]);
2294 if (sh)
2295 func (stream, ", lsl #%u", sh);
2296 func (stream, "]");
2297 break;
2298 }
2299 else switch (op)
2300 {
2301 case 0xE: /* 8-bit positive immediate offset */
2302 offset = i8;
2303 break;
2304
2305 case 0xC: /* 8-bit negative immediate offset */
2306 offset = -i8;
2307 break;
2308
2309 case 0xB: /* 8-bit + preindex with wb */
2310 offset = i8;
2311 writeback = TRUE;
2312 break;
2313
2314 case 0x9: /* 8-bit - preindex with wb */
2315 offset = -i8;
2316 writeback = TRUE;
2317 break;
2318
2319 case 0xF: /* 8-bit + postindex */
2320 offset = i8;
2321 postind = TRUE;
2322 break;
2323
2324 case 0xD: /* 8-bit - postindex */
2325 offset = -i8;
2326 postind = TRUE;
2327 break;
2328
2329 default:
2330 func (stream, ", <undefined>]");
2331 goto skip;
2332 }
2333
2334 if (postind)
2335 func (stream, "], #%d", offset);
2336 else
2337 {
2338 if (offset)
2339 func (stream, ", #%d", offset);
2340 func (stream, writeback ? "]!" : "]");
2341 }
2342
2343 if (Rn == 15)
2344 {
2345 func (stream, "\t; ");
2346 info->print_address_func (((pc + 4) & ~3) + offset, info);
2347 }
2348 }
2349 skip:
2350 break;
2351
2352 case 'A':
2353 {
2354 unsigned int P = (given & 0x01000000) >> 24;
2355 unsigned int U = (given & 0x00800000) >> 23;
2356 unsigned int W = (given & 0x00400000) >> 21;
2357 unsigned int Rn = (given & 0x000f0000) >> 16;
2358 unsigned int off = (given & 0x000000ff);
2359
2360 func (stream, "[%s", arm_regnames[Rn]);
2361 if (P)
2362 {
2363 if (off || !U)
2364 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2365 func (stream, "]");
2366 if (W)
2367 func (stream, "!");
2368 }
2369 else
2370 {
2371 func (stream, "], ");
2372 if (W)
2373 func (stream, "#%c%u", U ? '+' : '-', off * 4);
2374 else
2375 func (stream, "{%u}", off);
2376 }
2377 }
2378 break;
2379
2380 case 'w':
2381 {
2382 unsigned int Sbit = (given & 0x01000000) >> 24;
2383 unsigned int type = (given & 0x00600000) >> 21;
2384 switch (type)
2385 {
2386 case 0: func (stream, Sbit ? "sb" : "b"); break;
2387 case 1: func (stream, Sbit ? "sh" : "h"); break;
2388 case 2:
2389 if (Sbit)
2390 func (stream, "??");
2391 break;
2392 case 3:
2393 func (stream, "??");
2394 break;
2395 }
2396 }
2397 break;
2398
2399 case 'm':
2400 {
2401 int started = 0;
2402 int reg;
2403
2404 func (stream, "{");
2405 for (reg = 0; reg < 16; reg++)
2406 if ((given & (1 << reg)) != 0)
2407 {
2408 if (started)
2409 func (stream, ", ");
2410 started = 1;
2411 func (stream, "%s", arm_regnames[reg]);
2412 }
2413 func (stream, "}");
2414 }
2415 break;
2416
2417 case 'E':
2418 {
2419 unsigned int msb = (given & 0x0000001f);
2420 unsigned int lsb = 0;
2421 lsb |= (given & 0x000000c0u) >> 6;
2422 lsb |= (given & 0x00007000u) >> 10;
2423 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
2424 }
2425 break;
2426
2427 case 'F':
2428 {
2429 unsigned int width = (given & 0x0000001f) + 1;
2430 unsigned int lsb = 0;
2431 lsb |= (given & 0x000000c0u) >> 6;
2432 lsb |= (given & 0x00007000u) >> 10;
2433 func (stream, "#%u, #%u", lsb, width);
2434 }
2435 break;
2436
2437 case 'b':
2438 {
2439 unsigned int S = (given & 0x04000000u) >> 26;
2440 unsigned int J1 = (given & 0x00002000u) >> 13;
2441 unsigned int J2 = (given & 0x00000800u) >> 11;
2442 int offset = 0;
2443
2444 offset |= !S << 20;
2445 offset |= J2 << 19;
2446 offset |= J1 << 18;
2447 offset |= (given & 0x003f0000) >> 4;
2448 offset |= (given & 0x000007ff) << 1;
2449 offset -= (1 << 20);
2450
2451 info->print_address_func (pc + 4 + offset, info);
2452 }
2453 break;
2454
2455 case 'B':
2456 {
2457 unsigned int S = (given & 0x04000000u) >> 26;
2458 unsigned int I1 = (given & 0x00002000u) >> 13;
2459 unsigned int I2 = (given & 0x00000800u) >> 11;
2460 int offset = 0;
2461
2462 offset |= !S << 24;
2463 offset |= !(I1 ^ S) << 23;
2464 offset |= !(I2 ^ S) << 22;
2465 offset |= (given & 0x03ff0000u) >> 4;
2466 offset |= (given & 0x000007ffu) << 1;
2467 offset -= (1 << 24);
2468
2469 info->print_address_func (pc + 4 + offset, info);
2470 }
2471 break;
2472
2473 case 's':
2474 {
2475 unsigned int shift = 0;
2476 shift |= (given & 0x000000c0u) >> 6;
2477 shift |= (given & 0x00007000u) >> 10;
2478 if (given & 0x00200000u)
2479 func (stream, ", asr #%u", shift);
2480 else if (shift)
2481 func (stream, ", lsl #%u", shift);
2482 /* else print nothing - lsl #0 */
2483 }
2484 break;
2485
2486 case 'R':
2487 {
2488 unsigned int rot = (given & 0x00000030) >> 4;
2489 if (rot)
2490 func (stream, ", ror #%u", rot * 8);
2491 }
2492 break;
2493
2494 case '0': case '1': case '2': case '3': case '4':
2495 case '5': case '6': case '7': case '8': case '9':
2496 {
2497 int bitstart = *c++ - '0';
2498 int bitend = 0;
2499 unsigned int val;
2500 while (*c >= '0' && *c <= '9')
2501 bitstart = (bitstart * 10) + *c++ - '0';
2502
2503 if (*c == '-')
2504 {
2505 c++;
2506 while (*c >= '0' && *c <= '9')
2507 bitend = (bitend * 10) + *c++ - '0';
2508 if (!bitend)
2509 abort ();
2510
2511 val = given >> bitstart;
2512 val &= (2 << (bitend - bitstart)) - 1;
2513 }
2514 else
2515 val = (given >> bitstart) & 1;
2516
2517 switch (*c)
2518 {
2519 case 'd': func (stream, "%u", val); break;
2520 case 'W': func (stream, "%u", val * 4); break;
2521 case 'r': func (stream, "%s", arm_regnames[val]); break;
2522
2523 case 'c':
2524 if (val == 0xE)
2525 func (stream, "al");
2526 else
2527 func (stream, "%s", arm_conditional[val]);
2528 break;
2529
2530 case '\'':
2531 if (val)
2532 func (stream, "%c", c[1]);
2533 c++;
2534 break;
2535
2536 case '`':
2537 if (!val)
2538 func (stream, "%c", c[1]);
2539 c++;
2540 break;
2541
2542 case '?':
2543 func (stream, "%c", val ? c[1] : c[2]);
2544 c += 2;
2545 break;
2546
2547 default:
2548 abort ();
2549 }
2550 }
2551 break;
2552
2553 default:
2554 abort ();
2555 }
2556 }
2557 return 4;
2558 }
252b5132 2559
58efb6c0 2560 /* No match. */
252b5132
RH
2561 abort ();
2562}
2563
22a398e1
NC
2564/* Disallow mapping symbols ($a, $b, $d, $t etc) from
2565 being displayed in symbol relative addresses. */
2566
2567bfd_boolean
2568arm_symbol_is_valid (asymbol * sym,
2569 struct disassemble_info * info ATTRIBUTE_UNUSED)
2570{
2571 const char * name;
2572
2573 if (sym == NULL)
2574 return FALSE;
2575
2576 name = bfd_asymbol_name (sym);
2577
2578 return (name && *name != '$');
2579}
2580
58efb6c0 2581/* Parse an individual disassembler option. */
baf0cc5e 2582
a3d9c82d
NC
2583void
2584parse_arm_disassembler_option (option)
01c7f630 2585 char * option;
dd92f639 2586{
01c7f630 2587 if (option == NULL)
dd92f639 2588 return;
b34976b6 2589
01c7f630 2590 if (strneq (option, "reg-names-", 10))
dd92f639 2591 {
58efb6c0 2592 int i;
b34976b6 2593
01c7f630 2594 option += 10;
58efb6c0
NC
2595
2596 for (i = NUM_ARM_REGNAMES; i--;)
31e0f3cd 2597 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
58efb6c0
NC
2598 {
2599 regname_selected = i;
2600 break;
2601 }
b34976b6 2602
58efb6c0 2603 if (i < 0)
31e0f3cd 2604 /* XXX - should break 'option' at following delimiter. */
58efb6c0 2605 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
dd92f639 2606 }
31e0f3cd 2607 else if (strneq (option, "force-thumb", 11))
01c7f630 2608 force_thumb = 1;
31e0f3cd 2609 else if (strneq (option, "no-force-thumb", 14))
01c7f630 2610 force_thumb = 0;
dd92f639 2611 else
31e0f3cd 2612 /* XXX - should break 'option' at following delimiter. */
58efb6c0 2613 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
b34976b6 2614
dd92f639
NC
2615 return;
2616}
2617
31e0f3cd
NC
2618/* Parse the string of disassembler options, spliting it at whitespaces
2619 or commas. (Whitespace separators supported for backwards compatibility). */
baf0cc5e 2620
01c7f630
NC
2621static void
2622parse_disassembler_options (options)
2623 char * options;
2624{
01c7f630
NC
2625 if (options == NULL)
2626 return;
2627
31e0f3cd 2628 while (*options)
01c7f630 2629 {
31e0f3cd
NC
2630 parse_arm_disassembler_option (options);
2631
2632 /* Skip forward to next seperator. */
2633 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2634 ++ options;
2635 /* Skip forward past seperators. */
2636 while (ISSPACE (*options) || (*options == ','))
2637 ++ options;
01c7f630 2638 }
01c7f630
NC
2639}
2640
58efb6c0
NC
2641/* NOTE: There are no checks in these routines that
2642 the relevant number of data bytes exist. */
baf0cc5e 2643
58efb6c0
NC
2644static int
2645print_insn (pc, info, little)
252b5132 2646 bfd_vma pc;
5876e06d 2647 struct disassemble_info * info;
b34976b6 2648 bfd_boolean little;
252b5132 2649{
c19d1205
ZW
2650 unsigned char b[4];
2651 long given;
2652 int status;
2653 int is_thumb;
2654 int (*printer) (bfd_vma, struct disassemble_info *, long);
58efb6c0 2655
dd92f639
NC
2656 if (info->disassembler_options)
2657 {
2658 parse_disassembler_options (info->disassembler_options);
b34976b6 2659
58efb6c0 2660 /* To avoid repeated parsing of these options, we remove them here. */
dd92f639
NC
2661 info->disassembler_options = NULL;
2662 }
b34976b6 2663
01c7f630 2664 is_thumb = force_thumb;
b34976b6 2665
01c7f630 2666 if (!is_thumb && info->symbols != NULL)
252b5132 2667 {
5876e06d
NC
2668 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2669 {
2f0ca46a 2670 coff_symbol_type * cs;
b34976b6 2671
5876e06d
NC
2672 cs = coffsymbol (*info->symbols);
2673 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
2674 || cs->native->u.syment.n_sclass == C_THUMBSTAT
2675 || cs->native->u.syment.n_sclass == C_THUMBLABEL
2676 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2677 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2678 }
2679 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2680 {
2f0ca46a 2681 elf_symbol_type * es;
58efb6c0 2682 unsigned int type;
b34976b6 2683
5876e06d 2684 es = *(elf_symbol_type **)(info->symbols);
58efb6c0 2685 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
b34976b6 2686
58efb6c0 2687 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
5876e06d
NC
2688 }
2689 }
b34976b6 2690
58efb6c0 2691 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
c19d1205 2692 info->bytes_per_line = 4;
252b5132 2693
c19d1205 2694 if (!is_thumb)
252b5132 2695 {
c19d1205
ZW
2696 /* In ARM mode endianness is a straightforward issue: the instruction
2697 is four bytes long and is either ordered 0123 or 3210. */
2698 printer = print_insn_arm;
2699 info->bytes_per_chunk = 4;
2700
2701 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2702 if (little)
2703 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2704 else
2705 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
252b5132 2706 }
58efb6c0 2707 else
252b5132 2708 {
c19d1205
ZW
2709 /* In Thumb mode we have the additional wrinkle of two
2710 instruction lengths. Fortunately, the bits that determine
2711 the length of the current instruction are always to be found
2712 in the first two bytes. */
2713
2714 info->bytes_per_chunk = 2;
2715 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2716 if (!status)
252b5132 2717 {
c19d1205
ZW
2718 if (little)
2719 given = (b[0]) | (b[1] << 8);
2720 else
2721 given = (b[1]) | (b[0] << 8);
b34976b6 2722
c19d1205
ZW
2723 /* These bit patterns signal a four-byte Thumb
2724 instruction. */
2725 if ((given & 0xF800) == 0xF800
2726 || (given & 0xF800) == 0xF000
2727 || (given & 0xF800) == 0xE800)
252b5132 2728 {
c19d1205
ZW
2729 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2730 if (little)
2731 given = (b[0]) | (b[1] << 8) | (given << 16);
b7693d02 2732 else
c19d1205
ZW
2733 given = (b[1]) | (b[0] << 8) | (given << 16);
2734
2735 printer = print_insn_thumb32;
252b5132 2736 }
58efb6c0 2737 else
c19d1205 2738 printer = print_insn_thumb16;
252b5132 2739 }
252b5132 2740 }
b34976b6 2741
c19d1205
ZW
2742 if (status)
2743 {
2744 info->memory_error_func (status, pc, info);
2745 return -1;
2746 }
6a56ec7e
NC
2747 if (info->flags & INSN_HAS_RELOC)
2748 /* If the instruction has a reloc associated with it, then
2749 the offset field in the instruction will actually be the
2750 addend for the reloc. (We are using REL type relocs).
2751 In such cases, we can ignore the pc when computing
2752 addresses, since the addend is not currently pc-relative. */
2753 pc = 0;
b34976b6 2754
c19d1205 2755 return printer (pc, info, given);
252b5132
RH
2756}
2757
2758int
58efb6c0 2759print_insn_big_arm (pc, info)
252b5132
RH
2760 bfd_vma pc;
2761 struct disassemble_info * info;
2762{
b34976b6 2763 return print_insn (pc, info, FALSE);
58efb6c0 2764}
01c7f630 2765
58efb6c0
NC
2766int
2767print_insn_little_arm (pc, info)
2768 bfd_vma pc;
2769 struct disassemble_info * info;
2770{
b34976b6 2771 return print_insn (pc, info, TRUE);
58efb6c0 2772}
252b5132 2773
58efb6c0
NC
2774void
2775print_arm_disassembler_options (FILE * stream)
2776{
2777 int i;
252b5132 2778
58efb6c0
NC
2779 fprintf (stream, _("\n\
2780The following ARM specific disassembler options are supported for use with\n\
2781the -M switch:\n"));
b34976b6 2782
58efb6c0
NC
2783 for (i = NUM_ARM_REGNAMES; i--;)
2784 fprintf (stream, " reg-names-%s %*c%s\n",
2785 regnames[i].name,
d5b2f4d6 2786 (int)(14 - strlen (regnames[i].name)), ' ',
58efb6c0
NC
2787 regnames[i].description);
2788
2789 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
2790 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");
252b5132 2791}
This page took 0.421117 seconds and 4 git commands to generate.