daily update
[binutils.git] / opcodes / arm-dis.c
blobe623f9243228a31a9cd5610657d625ad223b133c
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "arm-opc.h"
28 #include "coff/internal.h"
29 #include "libcoff.h"
30 #include "opintl.h"
31 #include "safe-ctype.h"
33 /* FIXME: This shouldn't be done here. */
34 #include "elf-bfd.h"
35 #include "elf/internal.h"
36 #include "elf/arm.h"
38 #ifndef streq
39 #define streq(a,b) (strcmp ((a), (b)) == 0)
40 #endif
42 #ifndef strneq
43 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
44 #endif
46 #ifndef NUM_ELEM
47 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
48 #endif
50 #define WORD_ADDRESS(pc) ((pc) & ~0x3)
52 /* Format of the disassembler control string :
54 %% %
55 %<bitfield>d print the bitfield in decimal
56 %<bitfield>x print the bitfield in hex
57 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
58 %<bitfield>W print the bitfield plus one in decimal
59 %<bitfield>r print as an ARM register
60 %<bitfield>f print a floating point constant if >7 else a
61 floating point register
62 %<code>y print a single precision VFP reg.
63 Codes: 0=>Sm, 1=>Sd, 2=>Sn, 3=>multi-list, 4=>Sm pair
64 %<code>z print a double precision VFP reg
65 Codes: 0=>Dm, 1=>Dd, 2=>Dn, 3=>multi-list
66 %c print condition code (always bits 28-31)
67 %P print floating point precision in arithmetic insn
68 %Q print floating point precision in ldf/stf insn
69 %R print floating point rounding mode
70 %<bitnum>'c print specified char iff bit is one
71 %<bitnum>`c print specified char iff bit is zero
72 %<bitnum>?ab print a if bit is one else print b
73 %p print 'p' iff bits 12-15 are 15
74 %t print 't' iff bit 21 set and bit 24 clear
75 %o print operand2 (immediate or register + shift)
76 %a print address for ldr/str instruction
77 %s print address for ldr/str halfword/signextend instruction
78 %b print branch destination
79 %B print arm BLX(1) destination
80 %A print address for ldc/stc/ldf/stf instruction
81 %m print register mask for ldm/stm instruction
82 %C print the PSR sub type.
83 %F print the COUNT field of a LFM/SFM instruction.
84 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
85 %V print the 16-bit immediate field of a MOVT or MOVW instruction.
86 IWMMXT specific format options:
87 %<bitfield>g print as an iWMMXt 64-bit register
88 %<bitfield>G print as an iWMMXt general purpose or control register
89 %<bitfield>w print as an iWMMXt width field - [bhwd]ss/us
90 %Z print the Immediate of a WSHUFH instruction.
91 %L print as an iWMMXt N/M width field.
92 %l like 'A' except use byte offsets for 'B' & 'H' versions
93 Thumb specific format options:
94 %D print Thumb register (bits 0..2 as high number if bit 7 set)
95 %S print Thumb register (bits 3..5 as high number if bit 6 set)
96 %<bitfield>I print bitfield as a signed decimal
97 (top bit of range being the sign bit)
98 %M print Thumb register mask
99 %N print Thumb register mask (with LR)
100 %O print Thumb register mask (with PC)
101 %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
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). */
110 /* Note: There is a partial ordering in this table - it must be searched from
111 the top to obtain a correct match. */
113 static const struct arm_opcode arm_opcodes[] =
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"},
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"},
135 /* ARM V6Z instructions. */
136 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smi%c\t%e"},
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]"},
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}"},
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"},
280 /* V5J instruction. */
281 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
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"},
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"},
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}"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
630 /* The rest. */
631 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
632 {0, 0x00000000, 0x00000000, 0}
635 static const struct thumb_opcode thumb_opcodes[] =
637 /* Thumb instructions. */
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"},
645 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
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"},
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"},
661 {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
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"},
671 /* ARM V5 ISA extends Thumb. */
672 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
673 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
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)"},
677 /* Format 4. */
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"},
686 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
687 {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
688 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
689 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
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"},
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 */
706 {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
707 {ARM_EXT_V4T, 0x1A00, 0xFE00, "sub\t%0-2r, %3-5r, %6-8r"},
708 {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
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 */
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"},
721 /* format 3 */
722 {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
723 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
724 {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
725 {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
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 */
743 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
744 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
745 /* format 17 */
746 {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
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"},
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}
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.
764 %-escapes defined for these instructions:
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
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"
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
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
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
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. */
802 static const struct arm_opcode thumb32_opcodes[] =
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}"},
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"},
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"},
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"},
1003 /* Fallback. */
1004 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1005 {0, 0, 0, 0}
1009 static char * arm_conditional[] =
1010 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1011 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1013 typedef struct
1015 const char * name;
1016 const char * description;
1017 const char * reg_names[16];
1019 arm_regname;
1021 static arm_regname regnames[] =
1023 { "raw" , "Select raw register names",
1024 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
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" }},
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" }},
1033 { "special-atpcs", "Select special register names used in the ATPCS",
1034 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1035 { "iwmmxt_regnames", "Select register names used on the Intel Wireless MMX technology coprocessor",
1036 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7", "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"}},
1037 { "iwmmxt_Cregnames", "Select control register names used on the Intel Wireless MMX technology coprocessor",
1038 {"wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved", "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"}}
1041 static char * iwmmxt_wwnames[] =
1042 {"b", "h", "w", "d"};
1044 static char * iwmmxt_wwssnames[] =
1045 {"b", "bus", "b", "bss",
1046 "h", "hus", "h", "hss",
1047 "w", "wus", "w", "wss",
1048 "d", "dus", "d", "dss"
1051 /* Default to GCC register name set. */
1052 static unsigned int regname_selected = 1;
1054 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1055 #define arm_regnames regnames[regname_selected].reg_names
1057 static bfd_boolean force_thumb = FALSE;
1059 static char * arm_fp_const[] =
1060 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1062 static char * arm_shift[] =
1063 {"lsl", "lsr", "asr", "ror"};
1065 /* Forward declarations. */
1066 static void arm_decode_shift
1067 PARAMS ((long, fprintf_ftype, void *));
1068 static int print_insn_arm
1069 PARAMS ((bfd_vma, struct disassemble_info *, long));
1070 static int print_insn_thumb16
1071 PARAMS ((bfd_vma, struct disassemble_info *, long));
1072 static int print_insn_thumb32
1073 PARAMS ((bfd_vma, struct disassemble_info *, long));
1074 static void parse_disassembler_options
1075 PARAMS ((char *));
1076 static int print_insn
1077 PARAMS ((bfd_vma, struct disassemble_info *, bfd_boolean));
1078 static int set_iwmmxt_regnames
1079 PARAMS ((void));
1081 int get_arm_regname_num_options
1082 PARAMS ((void));
1083 int set_arm_regname_option
1084 PARAMS ((int));
1085 int get_arm_regnames
1086 PARAMS ((int, const char **, const char **, const char ***));
1088 /* Functions. */
1090 get_arm_regname_num_options ()
1092 return NUM_ARM_REGNAMES;
1096 set_arm_regname_option (option)
1097 int option;
1099 int old = regname_selected;
1100 regname_selected = option;
1101 return old;
1105 get_arm_regnames (option, setname, setdescription, register_names)
1106 int option;
1107 const char **setname;
1108 const char **setdescription;
1109 const char ***register_names;
1111 *setname = regnames[option].name;
1112 *setdescription = regnames[option].description;
1113 *register_names = regnames[option].reg_names;
1114 return 16;
1117 static void
1118 arm_decode_shift (given, func, stream)
1119 long given;
1120 fprintf_ftype func;
1121 void * stream;
1123 func (stream, "%s", arm_regnames[given & 0xf]);
1125 if ((given & 0xff0) != 0)
1127 if ((given & 0x10) == 0)
1129 int amount = (given & 0xf80) >> 7;
1130 int shift = (given & 0x60) >> 5;
1132 if (amount == 0)
1134 if (shift == 3)
1136 func (stream, ", rrx");
1137 return;
1140 amount = 32;
1143 func (stream, ", %s #%d", arm_shift[shift], amount);
1145 else
1146 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1147 arm_regnames[(given & 0xf00) >> 8]);
1151 static int
1152 set_iwmmxt_regnames ()
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 ();
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);
1166 return iwmmxt_regnames;
1169 /* Print one instruction from PC on INFO->STREAM.
1170 Return the size of the instruction (always 4 on ARM). */
1172 static int
1173 print_insn_arm (pc, info, given)
1174 bfd_vma pc;
1175 struct disassemble_info *info;
1176 long given;
1178 const struct arm_opcode *insn;
1179 void *stream = info->stream;
1180 fprintf_ftype func = info->fprintf_func;
1181 static int iwmmxt_regnames = 0;
1183 for (insn = arm_opcodes; insn->assembler; insn++)
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;
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)))
1198 char * c;
1200 for (c = insn->assembler; *c; c++)
1202 if (*c == '%')
1204 switch (*++c)
1206 case '%':
1207 func (stream, "%%");
1208 break;
1210 case 'a':
1211 if (((given & 0x000f0000) == 0x000f0000)
1212 && ((given & 0x02000000) == 0))
1214 int offset = given & 0xfff;
1216 func (stream, "[pc");
1218 if (given & 0x01000000)
1220 if ((given & 0x00800000) == 0)
1221 offset = - offset;
1223 /* Pre-indexed. */
1224 func (stream, ", #%d]", offset);
1226 offset += pc + 8;
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 ? */
1232 if (given & 0x00200000)
1233 func (stream, "!");
1235 else
1237 /* Post indexed. */
1238 func (stream, "], #%d", offset);
1240 /* ie ignore the offset. */
1241 offset = pc + 8;
1244 func (stream, "\t; ");
1245 info->print_address_func (offset, info);
1247 else
1249 func (stream, "[%s",
1250 arm_regnames[(given >> 16) & 0xf]);
1251 if ((given & 0x01000000) != 0)
1253 if ((given & 0x02000000) == 0)
1255 int offset = given & 0xfff;
1256 if (offset)
1257 func (stream, ", #%s%d",
1258 (((given & 0x00800000) == 0)
1259 ? "-" : ""), offset);
1261 else
1263 func (stream, ", %s",
1264 (((given & 0x00800000) == 0)
1265 ? "-" : ""));
1266 arm_decode_shift (given, func, stream);
1269 func (stream, "]%s",
1270 ((given & 0x00200000) != 0) ? "!" : "");
1272 else
1274 if ((given & 0x02000000) == 0)
1276 int offset = given & 0xfff;
1277 if (offset)
1278 func (stream, "], #%s%d",
1279 (((given & 0x00800000) == 0)
1280 ? "-" : ""), offset);
1281 else
1282 func (stream, "]");
1284 else
1286 func (stream, "], %s",
1287 (((given & 0x00800000) == 0)
1288 ? "-" : ""));
1289 arm_decode_shift (given, func, stream);
1293 break;
1295 case 's':
1296 if ((given & 0x004f0000) == 0x004f0000)
1298 /* PC relative with immediate offset. */
1299 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1301 if ((given & 0x00800000) == 0)
1302 offset = -offset;
1304 func (stream, "[pc, #%d]\t; ", offset);
1306 (*info->print_address_func)
1307 (offset + pc + 8, info);
1309 else
1311 func (stream, "[%s",
1312 arm_regnames[(given >> 16) & 0xf]);
1313 if ((given & 0x01000000) != 0)
1315 /* Pre-indexed. */
1316 if ((given & 0x00400000) == 0x00400000)
1318 /* Immediate. */
1319 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1320 if (offset)
1321 func (stream, ", #%s%d",
1322 (((given & 0x00800000) == 0)
1323 ? "-" : ""), offset);
1325 else
1327 /* Register. */
1328 func (stream, ", %s%s",
1329 (((given & 0x00800000) == 0)
1330 ? "-" : ""),
1331 arm_regnames[given & 0xf]);
1334 func (stream, "]%s",
1335 ((given & 0x00200000) != 0) ? "!" : "");
1337 else
1339 /* Post-indexed. */
1340 if ((given & 0x00400000) == 0x00400000)
1342 /* Immediate. */
1343 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1344 if (offset)
1345 func (stream, "], #%s%d",
1346 (((given & 0x00800000) == 0)
1347 ? "-" : ""), offset);
1348 else
1349 func (stream, "]");
1351 else
1353 /* Register. */
1354 func (stream, "], %s%s",
1355 (((given & 0x00800000) == 0)
1356 ? "-" : ""),
1357 arm_regnames[given & 0xf]);
1361 break;
1363 case 'b':
1364 (*info->print_address_func)
1365 (BDISP (given) * 4 + pc + 8, info);
1366 break;
1368 case 'c':
1369 func (stream, "%s",
1370 arm_conditional [(given >> 28) & 0xf]);
1371 break;
1373 case 'm':
1375 int started = 0;
1376 int reg;
1378 func (stream, "{");
1379 for (reg = 0; reg < 16; reg++)
1380 if ((given & (1 << reg)) != 0)
1382 if (started)
1383 func (stream, ", ");
1384 started = 1;
1385 func (stream, "%s", arm_regnames[reg]);
1387 func (stream, "}");
1389 break;
1391 case 'o':
1392 if ((given & 0x02000000) != 0)
1394 int rotate = (given & 0xf00) >> 7;
1395 int immed = (given & 0xff);
1396 immed = (((immed << (32 - rotate))
1397 | (immed >> rotate)) & 0xffffffff);
1398 func (stream, "#%d\t; 0x%x", immed, immed);
1400 else
1401 arm_decode_shift (given, func, stream);
1402 break;
1404 case 'p':
1405 if ((given & 0x0000f000) == 0x0000f000)
1406 func (stream, "p");
1407 break;
1409 case 't':
1410 if ((given & 0x01200000) == 0x00200000)
1411 func (stream, "t");
1412 break;
1414 case 'A':
1415 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1417 if ((given & (1 << 24)) != 0)
1419 int offset = given & 0xff;
1421 if (offset)
1422 func (stream, ", #%s%d]%s",
1423 ((given & 0x00800000) == 0 ? "-" : ""),
1424 offset * 4,
1425 ((given & 0x00200000) != 0 ? "!" : ""));
1426 else
1427 func (stream, "]");
1429 else
1431 int offset = given & 0xff;
1433 func (stream, "]");
1435 if (given & (1 << 21))
1437 if (offset)
1438 func (stream, ", #%s%d",
1439 ((given & 0x00800000) == 0 ? "-" : ""),
1440 offset * 4);
1442 else
1443 func (stream, ", {%d}", offset);
1445 break;
1447 case 'B':
1448 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1450 bfd_vma address;
1451 bfd_vma offset = 0;
1453 if (given & 0x00800000)
1454 /* Is signed, hi bits should be ones. */
1455 offset = (-1) ^ 0x00ffffff;
1457 /* Offset is (SignExtend(offset field)<<2). */
1458 offset += given & 0x00ffffff;
1459 offset <<= 2;
1460 address = offset + pc + 8;
1462 if (given & 0x01000000)
1463 /* H bit allows addressing to 2-byte boundaries. */
1464 address += 2;
1466 info->print_address_func (address, info);
1468 break;
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. */
1476 int imm;
1478 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1480 /* Is ``imm'' a negative number? */
1481 if (imm & 0x40)
1482 imm |= (-1 << 7);
1484 func (stream, "%d", imm);
1487 break;
1489 case 'C':
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");
1499 break;
1501 case 'F':
1502 switch (given & 0x00408000)
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");
1516 break;
1518 case 'P':
1519 switch (given & 0x00080080)
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;
1534 break;
1535 case 'Q':
1536 switch (given & 0x00408000)
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;
1551 break;
1552 case 'R':
1553 switch (given & 0x60)
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;
1567 break;
1569 case '0': case '1': case '2': case '3': case '4':
1570 case '5': case '6': case '7': case '8': case '9':
1572 int bitstart = *c++ - '0';
1573 int bitend = 0;
1574 while (*c >= '0' && *c <= '9')
1575 bitstart = (bitstart * 10) + *c++ - '0';
1577 switch (*c)
1579 case '-':
1580 c++;
1582 while (*c >= '0' && *c <= '9')
1583 bitend = (bitend * 10) + *c++ - '0';
1585 if (!bitend)
1586 abort ();
1588 switch (*c)
1590 case 'r':
1592 long reg;
1594 reg = given >> bitstart;
1595 reg &= (2 << (bitend - bitstart)) - 1;
1597 func (stream, "%s", arm_regnames[reg]);
1599 break;
1600 case 'd':
1602 long reg;
1604 reg = given >> bitstart;
1605 reg &= (2 << (bitend - bitstart)) - 1;
1607 func (stream, "%d", reg);
1609 break;
1610 case 'W':
1612 long reg;
1614 reg = given >> bitstart;
1615 reg &= (2 << (bitend - bitstart)) - 1;
1617 func (stream, "%d", reg + 1);
1619 break;
1620 case 'x':
1622 long reg;
1624 reg = given >> bitstart;
1625 reg &= (2 << (bitend - bitstart)) - 1;
1627 func (stream, "0x%08x", reg);
1629 /* Some SWI instructions have special
1630 meanings. */
1631 if ((given & 0x0fffffff) == 0x0FF00000)
1632 func (stream, "\t; IMB");
1633 else if ((given & 0x0fffffff) == 0x0FF00001)
1634 func (stream, "\t; IMBRange");
1636 break;
1637 case 'X':
1639 long reg;
1641 reg = given >> bitstart;
1642 reg &= (2 << (bitend - bitstart)) - 1;
1644 func (stream, "%01x", reg & 0xf);
1646 break;
1647 case 'f':
1649 long reg;
1651 reg = given >> bitstart;
1652 reg &= (2 << (bitend - bitstart)) - 1;
1654 if (reg > 7)
1655 func (stream, "#%s",
1656 arm_fp_const[reg & 7]);
1657 else
1658 func (stream, "f%d", reg);
1660 break;
1662 case 'w':
1664 long reg;
1666 if (bitstart != bitend)
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]);
1675 else
1677 reg = (((given >> 8) & 0x1) |
1678 ((given >> 22) & 0x1));
1679 func (stream, "%s", iwmmxt_wwnames[reg]);
1682 break;
1684 case 'g':
1686 long reg;
1687 int current_regnames;
1689 if (! iwmmxt_regnames)
1690 iwmmxt_regnames = set_iwmmxt_regnames ();
1691 current_regnames = set_arm_regname_option
1692 (iwmmxt_regnames);
1694 reg = given >> bitstart;
1695 reg &= (2 << (bitend - bitstart)) - 1;
1696 func (stream, "%s", arm_regnames[reg]);
1697 set_arm_regname_option (current_regnames);
1699 break;
1701 case 'G':
1703 long reg;
1704 int current_regnames;
1706 if (! iwmmxt_regnames)
1707 iwmmxt_regnames = set_iwmmxt_regnames ();
1708 current_regnames = set_arm_regname_option
1709 (iwmmxt_regnames + 1);
1711 reg = given >> bitstart;
1712 reg &= (2 << (bitend - bitstart)) - 1;
1713 func (stream, "%s", arm_regnames[reg]);
1714 set_arm_regname_option (current_regnames);
1716 break;
1718 default:
1719 abort ();
1721 break;
1723 case 'y':
1724 case 'z':
1726 int single = *c == 'y';
1727 int regno;
1729 switch (bitstart)
1731 case 4: /* Sm pair */
1732 func (stream, "{");
1733 /* Fall through. */
1734 case 0: /* Sm, Dm */
1735 regno = given & 0x0000000f;
1736 if (single)
1738 regno <<= 1;
1739 regno += (given >> 5) & 1;
1741 break;
1743 case 1: /* Sd, Dd */
1744 regno = (given >> 12) & 0x0000000f;
1745 if (single)
1747 regno <<= 1;
1748 regno += (given >> 22) & 1;
1750 break;
1752 case 2: /* Sn, Dn */
1753 regno = (given >> 16) & 0x0000000f;
1754 if (single)
1756 regno <<= 1;
1757 regno += (given >> 7) & 1;
1759 break;
1761 case 3: /* List */
1762 func (stream, "{");
1763 regno = (given >> 12) & 0x0000000f;
1764 if (single)
1766 regno <<= 1;
1767 regno += (given >> 22) & 1;
1769 break;
1772 default:
1773 abort ();
1776 func (stream, "%c%d", single ? 's' : 'd', regno);
1778 if (bitstart == 3)
1780 int count = given & 0xff;
1782 if (single == 0)
1783 count >>= 1;
1785 if (--count)
1787 func (stream, "-%c%d",
1788 single ? 's' : 'd',
1789 regno + count);
1792 func (stream, "}");
1794 else if (bitstart == 4)
1795 func (stream, ", %c%d}", single ? 's' : 'd',
1796 regno + 1);
1798 break;
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 ();
1821 break;
1823 case 'L':
1824 switch (given & 0x00400100)
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;
1833 break;
1835 case 'Z':
1837 int value;
1838 /* given (20, 23) | given (0, 3) */
1839 value = ((given >> 16) & 0xf0) | (given & 0xf);
1840 func (stream, "%d", value);
1842 break;
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. */
1849 int offset = given & 0xff;
1850 int multiplier = (given & 0x00000100) ? 4 : 1;
1852 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1854 if (offset)
1856 if ((given & 0x01000000) != 0)
1857 func (stream, ", #%s%d]%s",
1858 ((given & 0x00800000) == 0 ? "-" : ""),
1859 offset * multiplier,
1860 ((given & 0x00200000) != 0 ? "!" : ""));
1861 else
1862 func (stream, "], #%s%d",
1863 ((given & 0x00800000) == 0 ? "-" : ""),
1864 offset * multiplier);
1866 else
1867 func (stream, "]");
1869 break;
1871 case 'e':
1873 int imm;
1875 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
1876 func (stream, "%d", imm);
1878 break;
1880 case 'E':
1881 /* LSB and WIDTH fields of BFI or BFC. The machine-
1882 language instruction encodes LSB and MSB. */
1884 long msb = (given & 0x001f0000) >> 16;
1885 long lsb = (given & 0x00000f80) >> 7;
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);
1893 break;
1895 case 'V':
1896 /* 16-bit unsigned immediate from a MOVT or MOVW
1897 instruction, encoded in bits 0:11 and 15:19. */
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);
1904 break;
1906 default:
1907 abort ();
1911 else
1912 func (stream, "%c", *c);
1914 return 4;
1917 abort ();
1920 /* Print one instruction from PC on INFO->STREAM.
1921 Return the size of the instruction. */
1923 static int
1924 print_insn_thumb16 (pc, info, given)
1925 bfd_vma pc;
1926 struct disassemble_info *info;
1927 long given;
1929 const struct thumb_opcode *insn;
1930 void *stream = info->stream;
1931 fprintf_ftype func = info->fprintf_func;
1933 for (insn = thumb_opcodes; insn->assembler; insn++)
1934 if ((given & insn->mask) == insn->value)
1936 char * c = insn->assembler;
1937 for (; *c; c++)
1939 int domaskpc = 0;
1940 int domasklr = 0;
1942 if (*c != '%')
1944 func (stream, "%c", *c);
1945 continue;
1948 switch (*++c)
1950 case '%':
1951 func (stream, "%%");
1952 break;
1954 case 'S':
1956 long reg;
1958 reg = (given >> 3) & 0x7;
1959 if (given & (1 << 6))
1960 reg += 8;
1962 func (stream, "%s", arm_regnames[reg]);
1964 break;
1966 case 'D':
1968 long reg;
1970 reg = given & 0x7;
1971 if (given & (1 << 7))
1972 reg += 8;
1974 func (stream, "%s", arm_regnames[reg]);
1976 break;
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':
1988 int started = 0;
1989 int reg;
1991 func (stream, "{");
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)
1998 if (started)
1999 func (stream, ", ");
2000 started = 1;
2001 func (stream, "%s", arm_regnames[reg]);
2004 if (domasklr)
2006 if (started)
2007 func (stream, ", ");
2008 started = 1;
2009 func (stream, arm_regnames[14] /* "lr" */);
2012 if (domaskpc)
2014 if (started)
2015 func (stream, ", ");
2016 func (stream, arm_regnames[15] /* "pc" */);
2019 func (stream, "}");
2021 break;
2023 case 'b':
2024 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
2026 bfd_vma address = (pc + 4
2027 + ((given & 0x00f8) >> 2)
2028 + ((given & 0x0200) >> 3));
2029 info->print_address_func (address, info);
2031 break;
2033 case 's':
2034 /* Right shift immediate -- bits 6..10; 1-31 print
2035 as themselves, 0 prints as 32. */
2037 long imm = (given & 0x07c0) >> 6;
2038 if (imm == 0)
2039 imm = 32;
2040 func (stream, "#%d", imm);
2042 break;
2044 case '0': case '1': case '2': case '3': case '4':
2045 case '5': case '6': case '7': case '8': case '9':
2047 int bitstart = *c++ - '0';
2048 int bitend = 0;
2050 while (*c >= '0' && *c <= '9')
2051 bitstart = (bitstart * 10) + *c++ - '0';
2053 switch (*c)
2055 case '-':
2057 long reg;
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)
2068 case 'r':
2069 func (stream, "%s", arm_regnames[reg]);
2070 break;
2072 case 'd':
2073 func (stream, "%d", reg);
2074 break;
2076 case 'H':
2077 func (stream, "%d", reg << 1);
2078 break;
2080 case 'W':
2081 func (stream, "%d", reg << 2);
2082 break;
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;
2092 case 'x':
2093 func (stream, "0x%04x", reg);
2094 break;
2096 case 'I':
2097 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2098 func (stream, "%d", reg);
2099 break;
2101 case 'B':
2102 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2103 (*info->print_address_func)
2104 (reg * 2 + pc + 4, info);
2105 break;
2107 case 'c':
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]);
2116 break;
2118 default:
2119 abort ();
2122 break;
2124 case '\'':
2125 c++;
2126 if ((given & (1 << bitstart)) != 0)
2127 func (stream, "%c", *c);
2128 break;
2130 case '?':
2131 ++c;
2132 if ((given & (1 << bitstart)) != 0)
2133 func (stream, "%c", *c++);
2134 else
2135 func (stream, "%c", *++c);
2136 break;
2138 default:
2139 abort ();
2142 break;
2144 default:
2145 abort ();
2148 return 2;
2151 /* No match. */
2152 abort ();
2155 static int
2156 print_insn_thumb32 (pc, info, given)
2157 bfd_vma pc;
2158 struct disassemble_info *info;
2159 long given;
2161 const struct arm_opcode *insn;
2162 void *stream = info->stream;
2163 fprintf_ftype func = info->fprintf_func;
2165 for (insn = thumb32_opcodes; insn->assembler; insn++)
2166 if ((given & insn->mask) == insn->value)
2168 char * c = insn->assembler;
2169 for (; *c; c++)
2171 if (*c != '%')
2173 func (stream, "%c", *c);
2174 continue;
2177 switch (*++c)
2179 case '%':
2180 func (stream, "%%");
2181 break;
2183 case 'I':
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);
2191 break;
2193 case 'M':
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)
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);
2212 func (stream, "#%u\t; 0x%x", imm, imm);
2214 break;
2216 case 'J':
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);
2225 break;
2227 case 'K':
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);
2235 break;
2237 case 'S':
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;
2245 func (stream, "%s", arm_regnames[reg]);
2246 switch (stp)
2248 case 0:
2249 if (imm > 0)
2250 func (stream, ", lsl #%u", imm);
2251 break;
2253 case 1:
2254 if (imm == 0)
2255 imm = 32;
2256 func (stream, ", lsr #%u", imm);
2257 break;
2259 case 2:
2260 if (imm == 0)
2261 imm = 32;
2262 func (stream, ", asr #%u", imm);
2263 break;
2265 case 3:
2266 if (imm == 0)
2267 func (stream, ", rrx");
2268 else
2269 func (stream, ", ror #%u", imm);
2272 break;
2274 case 'a':
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;
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 */
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;
2299 else switch (op)
2301 case 0xE: /* 8-bit positive immediate offset */
2302 offset = i8;
2303 break;
2305 case 0xC: /* 8-bit negative immediate offset */
2306 offset = -i8;
2307 break;
2309 case 0xB: /* 8-bit + preindex with wb */
2310 offset = i8;
2311 writeback = TRUE;
2312 break;
2314 case 0x9: /* 8-bit - preindex with wb */
2315 offset = -i8;
2316 writeback = TRUE;
2317 break;
2319 case 0xF: /* 8-bit + postindex */
2320 offset = i8;
2321 postind = TRUE;
2322 break;
2324 case 0xD: /* 8-bit - postindex */
2325 offset = -i8;
2326 postind = TRUE;
2327 break;
2329 default:
2330 func (stream, ", <undefined>]");
2331 goto skip;
2334 if (postind)
2335 func (stream, "], #%d", offset);
2336 else
2338 if (offset)
2339 func (stream, ", #%d", offset);
2340 func (stream, writeback ? "]!" : "]");
2343 if (Rn == 15)
2345 func (stream, "\t; ");
2346 info->print_address_func (((pc + 4) & ~3) + offset, info);
2349 skip:
2350 break;
2352 case 'A':
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);
2360 func (stream, "[%s", arm_regnames[Rn]);
2361 if (P)
2363 if (off || !U)
2364 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2365 func (stream, "]");
2366 if (W)
2367 func (stream, "!");
2369 else
2371 func (stream, "], ");
2372 if (W)
2373 func (stream, "#%c%u", U ? '+' : '-', off * 4);
2374 else
2375 func (stream, "{%u}", off);
2378 break;
2380 case 'w':
2382 unsigned int Sbit = (given & 0x01000000) >> 24;
2383 unsigned int type = (given & 0x00600000) >> 21;
2384 switch (type)
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;
2397 break;
2399 case 'm':
2401 int started = 0;
2402 int reg;
2404 func (stream, "{");
2405 for (reg = 0; reg < 16; reg++)
2406 if ((given & (1 << reg)) != 0)
2408 if (started)
2409 func (stream, ", ");
2410 started = 1;
2411 func (stream, "%s", arm_regnames[reg]);
2413 func (stream, "}");
2415 break;
2417 case 'E':
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);
2425 break;
2427 case 'F':
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);
2435 break;
2437 case 'b':
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;
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);
2451 info->print_address_func (pc + 4 + offset, info);
2453 break;
2455 case 'B':
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;
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);
2469 info->print_address_func (pc + 4 + offset, info);
2471 break;
2473 case 's':
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 */
2484 break;
2486 case 'R':
2488 unsigned int rot = (given & 0x00000030) >> 4;
2489 if (rot)
2490 func (stream, ", ror #%u", rot * 8);
2492 break;
2494 case '0': case '1': case '2': case '3': case '4':
2495 case '5': case '6': case '7': case '8': case '9':
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';
2503 if (*c == '-')
2505 c++;
2506 while (*c >= '0' && *c <= '9')
2507 bitend = (bitend * 10) + *c++ - '0';
2508 if (!bitend)
2509 abort ();
2511 val = given >> bitstart;
2512 val &= (2 << (bitend - bitstart)) - 1;
2514 else
2515 val = (given >> bitstart) & 1;
2517 switch (*c)
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;
2523 case 'c':
2524 if (val == 0xE)
2525 func (stream, "al");
2526 else
2527 func (stream, "%s", arm_conditional[val]);
2528 break;
2530 case '\'':
2531 if (val)
2532 func (stream, "%c", c[1]);
2533 c++;
2534 break;
2536 case '`':
2537 if (!val)
2538 func (stream, "%c", c[1]);
2539 c++;
2540 break;
2542 case '?':
2543 func (stream, "%c", val ? c[1] : c[2]);
2544 c += 2;
2545 break;
2547 default:
2548 abort ();
2551 break;
2553 default:
2554 abort ();
2557 return 4;
2560 /* No match. */
2561 abort ();
2564 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2565 being displayed in symbol relative addresses. */
2567 bfd_boolean
2568 arm_symbol_is_valid (asymbol * sym,
2569 struct disassemble_info * info ATTRIBUTE_UNUSED)
2571 const char * name;
2573 if (sym == NULL)
2574 return FALSE;
2576 name = bfd_asymbol_name (sym);
2578 return (name && *name != '$');
2581 /* Parse an individual disassembler option. */
2583 void
2584 parse_arm_disassembler_option (option)
2585 char * option;
2587 if (option == NULL)
2588 return;
2590 if (strneq (option, "reg-names-", 10))
2592 int i;
2594 option += 10;
2596 for (i = NUM_ARM_REGNAMES; i--;)
2597 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2599 regname_selected = i;
2600 break;
2603 if (i < 0)
2604 /* XXX - should break 'option' at following delimiter. */
2605 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2607 else if (strneq (option, "force-thumb", 11))
2608 force_thumb = 1;
2609 else if (strneq (option, "no-force-thumb", 14))
2610 force_thumb = 0;
2611 else
2612 /* XXX - should break 'option' at following delimiter. */
2613 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2615 return;
2618 /* Parse the string of disassembler options, spliting it at whitespaces
2619 or commas. (Whitespace separators supported for backwards compatibility). */
2621 static void
2622 parse_disassembler_options (options)
2623 char * options;
2625 if (options == NULL)
2626 return;
2628 while (*options)
2630 parse_arm_disassembler_option (options);
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;
2641 /* NOTE: There are no checks in these routines that
2642 the relevant number of data bytes exist. */
2644 static int
2645 print_insn (pc, info, little)
2646 bfd_vma pc;
2647 struct disassemble_info * info;
2648 bfd_boolean little;
2650 unsigned char b[4];
2651 long given;
2652 int status;
2653 int is_thumb;
2654 int (*printer) (bfd_vma, struct disassemble_info *, long);
2656 if (info->disassembler_options)
2658 parse_disassembler_options (info->disassembler_options);
2660 /* To avoid repeated parsing of these options, we remove them here. */
2661 info->disassembler_options = NULL;
2664 is_thumb = force_thumb;
2666 if (!is_thumb && info->symbols != NULL)
2668 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2670 coff_symbol_type * cs;
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);
2679 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2681 elf_symbol_type * es;
2682 unsigned int type;
2684 es = *(elf_symbol_type **)(info->symbols);
2685 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2687 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2691 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2692 info->bytes_per_line = 4;
2694 if (!is_thumb)
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;
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);
2707 else
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. */
2714 info->bytes_per_chunk = 2;
2715 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2716 if (!status)
2718 if (little)
2719 given = (b[0]) | (b[1] << 8);
2720 else
2721 given = (b[1]) | (b[0] << 8);
2723 /* These bit patterns signal a four-byte Thumb
2724 instruction. */
2725 if ((given & 0xF800) == 0xF800
2726 || (given & 0xF800) == 0xF000
2727 || (given & 0xF800) == 0xE800)
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);
2732 else
2733 given = (b[1]) | (b[0] << 8) | (given << 16);
2735 printer = print_insn_thumb32;
2737 else
2738 printer = print_insn_thumb16;
2742 if (status)
2744 info->memory_error_func (status, pc, info);
2745 return -1;
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;
2755 return printer (pc, info, given);
2759 print_insn_big_arm (pc, info)
2760 bfd_vma pc;
2761 struct disassemble_info * info;
2763 return print_insn (pc, info, FALSE);
2767 print_insn_little_arm (pc, info)
2768 bfd_vma pc;
2769 struct disassemble_info * info;
2771 return print_insn (pc, info, TRUE);
2774 void
2775 print_arm_disassembler_options (FILE * stream)
2777 int i;
2779 fprintf (stream, _("\n\
2780 The following ARM specific disassembler options are supported for use with\n\
2781 the -M switch:\n"));
2783 for (i = NUM_ARM_REGNAMES; i--;)
2784 fprintf (stream, " reg-names-%s %*c%s\n",
2785 regnames[i].name,
2786 (int)(14 - strlen (regnames[i].name)), ' ',
2787 regnames[i].description);
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");