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