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