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