daily update
[binutils.git] / opcodes / arm-dis.c
blobfb3cb77bc4a1ee080edb4a28d1375bd067448b08
1 /* Instruction printing code for the ARM
2 Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
3 Free Software Foundation, Inc.
4 Contributed by Richard Earnshaw (rwe@pegasus.esprit.ec.org)
5 Modification by James G. Smith (jsmith@cygnus.co.uk)
7 This file is part of libopcodes.
9 This program is free software; you can redistribute it and/or modify it under
10 the terms of the GNU General Public License as published by the Free
11 Software Foundation; either version 2 of the License, or (at your option)
12 any later version.
14 This program is distributed in the hope that it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
23 #include "sysdep.h"
25 #include "dis-asm.h"
26 #include "opcode/arm.h"
27 #include "opintl.h"
28 #include "safe-ctype.h"
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"
37 /* FIXME: Belongs in global header. */
38 #ifndef strneq
39 #define strneq(a,b,n) (strncmp ((a), (b), (n)) == 0)
40 #endif
42 #ifndef NUM_ELEM
43 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
44 #endif
46 struct opcode32
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. */
53 struct opcode16
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. */
60 /* print_insn_coprocessor recognizes the following format control codes:
62 %% %
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
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
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
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. */
95 /* Common coprocessor opcodes shared between Arm and Thumb-2. */
97 static const struct opcode32 coprocessor_opcodes[] =
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"},
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"},
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"},
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"},
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, 0x0ff00f10, "cfsh32%c\tmvfx%12-15d, mvfx%16-19d, #%I"},
333 {ARM_CEXT_MAVERICK, 0x0e200500, 0x0ff00f10, "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, 0x0ff00f10, "cfmadd32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
361 {ARM_CEXT_MAVERICK, 0x0e100600, 0x0ff00f10, "cfmsub32%c\tmvax%5-7d, mvfx%12-15d, mvfx%16-19d, mvfx%0-3d"},
362 {ARM_CEXT_MAVERICK, 0x0e200600, 0x0ff00f10, "cfmadda32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
363 {ARM_CEXT_MAVERICK, 0x0e300600, 0x0ff00f10, "cfmsuba32%c\tmvax%5-7d, mvax%12-15d, mvfx%16-19d, mvfx%0-3d"},
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"},
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"},
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}
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. */
391 /* print_insn_arm recognizes the following format control codes:
393 %% %
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.
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"
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
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. */
420 static const struct opcode32 arm_opcodes[] =
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"},
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"},
442 /* ARM V6Z instructions. */
443 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
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]"},
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}"},
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, 0x06800fb0, 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"},
585 /* V5J instruction. */
586 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
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"},
655 /* The rest. */
656 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
657 {0, 0x00000000, 0x00000000, 0}
660 /* print_insn_thumb16 recognizes the following format control codes:
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. */
681 static const struct opcode16 thumb_opcodes[] =
683 /* Thumb instructions. */
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}"},
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"},
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"},
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"},
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}
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.
810 print_insn_thumb32 recognizes the following format control codes:
812 %% %
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
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
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
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
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"
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[] =
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}"},
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"},
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"},
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"},
1039 /* Fallback. */
1040 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1041 {0, 0, 0, 0}
1044 static const char *const arm_conditional[] =
1045 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1046 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
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"};
1051 static const char *const arm_shift[] =
1052 {"lsl", "lsr", "asr", "ror"};
1054 typedef struct
1056 const char *name;
1057 const char *description;
1058 const char *reg_names[16];
1060 arm_regname;
1062 static const arm_regname regnames[] =
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" }},
1078 static const char *const iwmmxt_wwnames[] =
1079 {"b", "h", "w", "d"};
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"
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"
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"
1098 /* Default to GCC register name set. */
1099 static unsigned int regname_selected = 1;
1101 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1102 #define arm_regnames regnames[regname_selected].reg_names
1104 static bfd_boolean force_thumb = FALSE;
1107 /* Functions. */
1109 get_arm_regname_num_options (void)
1111 return NUM_ARM_REGNAMES;
1115 set_arm_regname_option (int option)
1117 int old = regname_selected;
1118 regname_selected = option;
1119 return old;
1123 get_arm_regnames (int option, const char **setname, const char **setdescription,
1124 const char *const **register_names)
1126 *setname = regnames[option].name;
1127 *setdescription = regnames[option].description;
1128 *register_names = regnames[option].reg_names;
1129 return 16;
1132 static void
1133 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1135 func (stream, "%s", arm_regnames[given & 0xf]);
1137 if ((given & 0xff0) != 0)
1139 if ((given & 0x10) == 0)
1141 int amount = (given & 0xf80) >> 7;
1142 int shift = (given & 0x60) >> 5;
1144 if (amount == 0)
1146 if (shift == 3)
1148 func (stream, ", rrx");
1149 return;
1152 amount = 32;
1155 func (stream, ", %s #%d", arm_shift[shift], amount);
1157 else
1158 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1159 arm_regnames[(given & 0xf00) >> 8]);
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. */
1167 static bfd_boolean
1168 print_insn_coprocessor (struct disassemble_info *info, long given,
1169 bfd_boolean thumb)
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;
1177 for (insn = coprocessor_opcodes; insn->assembler; insn++)
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;
1184 mask = insn->mask;
1185 value = insn->value;
1186 if (thumb)
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;
1194 else
1196 /* Only match unconditional instuctions against unconditional
1197 patterns. */
1198 if ((given & 0xf0000000) == 0xf0000000)
1199 mask |= 0xf0000000;
1201 if ((given & mask) == value)
1203 const char *c;
1205 for (c = insn->assembler; *c; c++)
1207 if (*c == '%')
1209 switch (*++c)
1211 case '%':
1212 func (stream, "%%");
1213 break;
1215 case 'A':
1216 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1218 if ((given & (1 << 24)) != 0)
1220 int offset = given & 0xff;
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, "]");
1230 else
1232 int offset = given & 0xff;
1234 func (stream, "]");
1236 if (given & (1 << 21))
1238 if (offset)
1239 func (stream, ", #%s%d",
1240 ((given & 0x00800000) == 0 ? "-" : ""),
1241 offset * 4);
1243 else
1244 func (stream, ", {%d}", offset);
1246 break;
1248 case 'c':
1249 func (stream, "%s",
1250 arm_conditional [(given >> 28) & 0xf]);
1251 break;
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. */
1259 int imm;
1261 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1263 /* Is ``imm'' a negative number? */
1264 if (imm & 0x40)
1265 imm |= (-1 << 7);
1267 func (stream, "%d", imm);
1270 break;
1272 case 'F':
1273 switch (given & 0x00408000)
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");
1287 break;
1289 case 'P':
1290 switch (given & 0x00080080)
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;
1305 break;
1306 case 'Q':
1307 switch (given & 0x00408000)
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;
1322 break;
1323 case 'R':
1324 switch (given & 0x60)
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;
1338 break;
1340 case '0': case '1': case '2': case '3': case '4':
1341 case '5': case '6': case '7': case '8': case '9':
1343 int bitstart = *c++ - '0';
1344 int bitend = 0;
1345 while (*c >= '0' && *c <= '9')
1346 bitstart = (bitstart * 10) + *c++ - '0';
1348 switch (*c)
1350 case '-':
1351 c++;
1353 while (*c >= '0' && *c <= '9')
1354 bitend = (bitend * 10) + *c++ - '0';
1356 if (!bitend)
1357 abort ();
1359 switch (*c)
1361 case 'r':
1363 long reg;
1365 reg = given >> bitstart;
1366 reg &= (2 << (bitend - bitstart)) - 1;
1368 func (stream, "%s", arm_regnames[reg]);
1370 break;
1371 case 'd':
1373 long reg;
1375 reg = given >> bitstart;
1376 reg &= (2 << (bitend - bitstart)) - 1;
1378 func (stream, "%ld", reg);
1380 break;
1381 case 'f':
1383 long reg;
1385 reg = given >> bitstart;
1386 reg &= (2 << (bitend - bitstart)) - 1;
1388 if (reg > 7)
1389 func (stream, "#%s",
1390 arm_fp_const[reg & 7]);
1391 else
1392 func (stream, "f%ld", reg);
1394 break;
1396 case 'w':
1398 long reg;
1400 if (bitstart != bitend)
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]);
1409 else
1411 reg = (((given >> 8) & 0x1) |
1412 ((given >> 22) & 0x1));
1413 func (stream, "%s", iwmmxt_wwnames[reg]);
1416 break;
1418 case 'g':
1420 long reg;
1421 reg = given >> bitstart;
1422 reg &= (2 << (bitend - bitstart)) - 1;
1423 func (stream, "%s", iwmmxt_regnames[reg]);
1425 break;
1427 case 'G':
1429 long reg;
1430 reg = given >> bitstart;
1431 reg &= (2 << (bitend - bitstart)) - 1;
1432 func (stream, "%s", iwmmxt_cregnames[reg]);
1434 break;
1436 default:
1437 abort ();
1439 break;
1441 case 'y':
1442 case 'z':
1444 int single = *c == 'y';
1445 int regno;
1447 switch (bitstart)
1449 case 4: /* Sm pair */
1450 func (stream, "{");
1451 /* Fall through. */
1452 case 0: /* Sm, Dm */
1453 regno = given & 0x0000000f;
1454 if (single)
1456 regno <<= 1;
1457 regno += (given >> 5) & 1;
1459 break;
1461 case 1: /* Sd, Dd */
1462 regno = (given >> 12) & 0x0000000f;
1463 if (single)
1465 regno <<= 1;
1466 regno += (given >> 22) & 1;
1468 break;
1470 case 2: /* Sn, Dn */
1471 regno = (given >> 16) & 0x0000000f;
1472 if (single)
1474 regno <<= 1;
1475 regno += (given >> 7) & 1;
1477 break;
1479 case 3: /* List */
1480 func (stream, "{");
1481 regno = (given >> 12) & 0x0000000f;
1482 if (single)
1484 regno <<= 1;
1485 regno += (given >> 22) & 1;
1487 break;
1490 default:
1491 abort ();
1494 func (stream, "%c%d", single ? 's' : 'd', regno);
1496 if (bitstart == 3)
1498 int count = given & 0xff;
1500 if (single == 0)
1501 count >>= 1;
1503 if (--count)
1505 func (stream, "-%c%d",
1506 single ? 's' : 'd',
1507 regno + count);
1510 func (stream, "}");
1512 else if (bitstart == 4)
1513 func (stream, ", %c%d}", single ? 's' : 'd',
1514 regno + 1);
1516 break;
1519 break;
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 ();
1541 break;
1543 case 'L':
1544 switch (given & 0x00400100)
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;
1553 break;
1555 case 'Z':
1557 int value;
1558 /* given (20, 23) | given (0, 3) */
1559 value = ((given >> 16) & 0xf0) | (given & 0xf);
1560 func (stream, "%d", value);
1562 break;
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. */
1569 int offset = given & 0xff;
1570 int multiplier = (given & 0x00000100) ? 4 : 1;
1572 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1574 if (offset)
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);
1586 else
1587 func (stream, "]");
1589 break;
1591 default:
1592 abort ();
1596 else
1597 func (stream, "%c", *c);
1599 return TRUE;
1602 return FALSE;
1605 /* Print one ARM instruction from PC on INFO->STREAM. */
1607 static void
1608 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
1610 const struct opcode32 *insn;
1611 void *stream = info->stream;
1612 fprintf_ftype func = info->fprintf_func;
1614 if (print_insn_coprocessor (info, given, FALSE))
1615 return;
1617 for (insn = arm_opcodes; insn->assembler; insn++)
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;
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)))
1632 const char *c;
1634 for (c = insn->assembler; *c; c++)
1636 if (*c == '%')
1638 switch (*++c)
1640 case '%':
1641 func (stream, "%%");
1642 break;
1644 case 'a':
1645 if (((given & 0x000f0000) == 0x000f0000)
1646 && ((given & 0x02000000) == 0))
1648 int offset = given & 0xfff;
1650 func (stream, "[pc");
1652 if (given & 0x01000000)
1654 if ((given & 0x00800000) == 0)
1655 offset = - offset;
1657 /* Pre-indexed. */
1658 func (stream, ", #%d]", offset);
1660 offset += pc + 8;
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, "!");
1669 else
1671 /* Post indexed. */
1672 func (stream, "], #%d", offset);
1674 /* ie ignore the offset. */
1675 offset = pc + 8;
1678 func (stream, "\t; ");
1679 info->print_address_func (offset, info);
1681 else
1683 func (stream, "[%s",
1684 arm_regnames[(given >> 16) & 0xf]);
1685 if ((given & 0x01000000) != 0)
1687 if ((given & 0x02000000) == 0)
1689 int offset = given & 0xfff;
1690 if (offset)
1691 func (stream, ", #%s%d",
1692 (((given & 0x00800000) == 0)
1693 ? "-" : ""), offset);
1695 else
1697 func (stream, ", %s",
1698 (((given & 0x00800000) == 0)
1699 ? "-" : ""));
1700 arm_decode_shift (given, func, stream);
1703 func (stream, "]%s",
1704 ((given & 0x00200000) != 0) ? "!" : "");
1706 else
1708 if ((given & 0x02000000) == 0)
1710 int offset = given & 0xfff;
1711 if (offset)
1712 func (stream, "], #%s%d",
1713 (((given & 0x00800000) == 0)
1714 ? "-" : ""), offset);
1715 else
1716 func (stream, "]");
1718 else
1720 func (stream, "], %s",
1721 (((given & 0x00800000) == 0)
1722 ? "-" : ""));
1723 arm_decode_shift (given, func, stream);
1727 break;
1729 case 's':
1730 if ((given & 0x004f0000) == 0x004f0000)
1732 /* PC relative with immediate offset. */
1733 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1735 if ((given & 0x00800000) == 0)
1736 offset = -offset;
1738 func (stream, "[pc, #%d]\t; ", offset);
1739 info->print_address_func (offset + pc + 8, info);
1741 else
1743 func (stream, "[%s",
1744 arm_regnames[(given >> 16) & 0xf]);
1745 if ((given & 0x01000000) != 0)
1747 /* Pre-indexed. */
1748 if ((given & 0x00400000) == 0x00400000)
1750 /* Immediate. */
1751 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1752 if (offset)
1753 func (stream, ", #%s%d",
1754 (((given & 0x00800000) == 0)
1755 ? "-" : ""), offset);
1757 else
1759 /* Register. */
1760 func (stream, ", %s%s",
1761 (((given & 0x00800000) == 0)
1762 ? "-" : ""),
1763 arm_regnames[given & 0xf]);
1766 func (stream, "]%s",
1767 ((given & 0x00200000) != 0) ? "!" : "");
1769 else
1771 /* Post-indexed. */
1772 if ((given & 0x00400000) == 0x00400000)
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, "]");
1783 else
1785 /* Register. */
1786 func (stream, "], %s%s",
1787 (((given & 0x00800000) == 0)
1788 ? "-" : ""),
1789 arm_regnames[given & 0xf]);
1793 break;
1795 case 'b':
1797 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
1798 info->print_address_func (disp*4 + pc + 8, info);
1800 break;
1802 case 'c':
1803 func (stream, "%s",
1804 arm_conditional [(given >> 28) & 0xf]);
1805 break;
1807 case 'm':
1809 int started = 0;
1810 int reg;
1812 func (stream, "{");
1813 for (reg = 0; reg < 16; reg++)
1814 if ((given & (1 << reg)) != 0)
1816 if (started)
1817 func (stream, ", ");
1818 started = 1;
1819 func (stream, "%s", arm_regnames[reg]);
1821 func (stream, "}");
1823 break;
1825 case 'o':
1826 if ((given & 0x02000000) != 0)
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);
1834 else
1835 arm_decode_shift (given, func, stream);
1836 break;
1838 case 'p':
1839 if ((given & 0x0000f000) == 0x0000f000)
1840 func (stream, "p");
1841 break;
1843 case 't':
1844 if ((given & 0x01200000) == 0x00200000)
1845 func (stream, "t");
1846 break;
1848 case 'A':
1849 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1851 if ((given & (1 << 24)) != 0)
1853 int offset = given & 0xff;
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, "]");
1863 else
1865 int offset = given & 0xff;
1867 func (stream, "]");
1869 if (given & (1 << 21))
1871 if (offset)
1872 func (stream, ", #%s%d",
1873 ((given & 0x00800000) == 0 ? "-" : ""),
1874 offset * 4);
1876 else
1877 func (stream, ", {%d}", offset);
1879 break;
1881 case 'B':
1882 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1884 bfd_vma address;
1885 bfd_vma offset = 0;
1887 if (given & 0x00800000)
1888 /* Is signed, hi bits should be ones. */
1889 offset = (-1) ^ 0x00ffffff;
1891 /* Offset is (SignExtend(offset field)<<2). */
1892 offset += given & 0x00ffffff;
1893 offset <<= 2;
1894 address = offset + pc + 8;
1896 if (given & 0x01000000)
1897 /* H bit allows addressing to 2-byte boundaries. */
1898 address += 2;
1900 info->print_address_func (address, info);
1902 break;
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;
1916 case '0': case '1': case '2': case '3': case '4':
1917 case '5': case '6': case '7': case '8': case '9':
1919 int bitstart = *c++ - '0';
1920 int bitend = 0;
1921 while (*c >= '0' && *c <= '9')
1922 bitstart = (bitstart * 10) + *c++ - '0';
1924 switch (*c)
1926 case '-':
1927 c++;
1929 while (*c >= '0' && *c <= '9')
1930 bitend = (bitend * 10) + *c++ - '0';
1932 if (!bitend)
1933 abort ();
1935 switch (*c)
1937 case 'r':
1939 long reg;
1941 reg = given >> bitstart;
1942 reg &= (2 << (bitend - bitstart)) - 1;
1944 func (stream, "%s", arm_regnames[reg]);
1946 break;
1947 case 'd':
1949 long reg;
1951 reg = given >> bitstart;
1952 reg &= (2 << (bitend - bitstart)) - 1;
1954 func (stream, "%ld", reg);
1956 break;
1957 case 'W':
1959 long reg;
1961 reg = given >> bitstart;
1962 reg &= (2 << (bitend - bitstart)) - 1;
1964 func (stream, "%ld", reg + 1);
1966 break;
1967 case 'x':
1969 long reg;
1971 reg = given >> bitstart;
1972 reg &= (2 << (bitend - bitstart)) - 1;
1974 func (stream, "0x%08lx", reg);
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");
1983 break;
1984 case 'X':
1986 long reg;
1988 reg = given >> bitstart;
1989 reg &= (2 << (bitend - bitstart)) - 1;
1991 func (stream, "%01lx", reg & 0xf);
1993 break;
1994 default:
1995 abort ();
1997 break;
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 ();
2019 break;
2021 case 'e':
2023 int imm;
2025 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2026 func (stream, "%d", imm);
2028 break;
2030 case 'E':
2031 /* LSB and WIDTH fields of BFI or BFC. The machine-
2032 language instruction encodes LSB and MSB. */
2034 long msb = (given & 0x001f0000) >> 16;
2035 long lsb = (given & 0x00000f80) >> 7;
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);
2043 break;
2045 case 'V':
2046 /* 16-bit unsigned immediate from a MOVT or MOVW
2047 instruction, encoded in bits 0:11 and 15:19. */
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);
2054 break;
2056 default:
2057 abort ();
2061 else
2062 func (stream, "%c", *c);
2064 return;
2067 abort ();
2070 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2072 static void
2073 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2075 const struct opcode16 *insn;
2076 void *stream = info->stream;
2077 fprintf_ftype func = info->fprintf_func;
2079 for (insn = thumb_opcodes; insn->assembler; insn++)
2080 if ((given & insn->mask) == insn->value)
2082 const char *c = insn->assembler;
2083 for (; *c; c++)
2085 int domaskpc = 0;
2086 int domasklr = 0;
2088 if (*c != '%')
2090 func (stream, "%c", *c);
2091 continue;
2094 switch (*++c)
2096 case '%':
2097 func (stream, "%%");
2098 break;
2100 case 'S':
2102 long reg;
2104 reg = (given >> 3) & 0x7;
2105 if (given & (1 << 6))
2106 reg += 8;
2108 func (stream, "%s", arm_regnames[reg]);
2110 break;
2112 case 'D':
2114 long reg;
2116 reg = given & 0x7;
2117 if (given & (1 << 7))
2118 reg += 8;
2120 func (stream, "%s", arm_regnames[reg]);
2122 break;
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':
2134 int started = 0;
2135 int reg;
2137 func (stream, "{");
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)
2144 if (started)
2145 func (stream, ", ");
2146 started = 1;
2147 func (stream, "%s", arm_regnames[reg]);
2150 if (domasklr)
2152 if (started)
2153 func (stream, ", ");
2154 started = 1;
2155 func (stream, arm_regnames[14] /* "lr" */);
2158 if (domaskpc)
2160 if (started)
2161 func (stream, ", ");
2162 func (stream, arm_regnames[15] /* "pc" */);
2165 func (stream, "}");
2167 break;
2169 case 'b':
2170 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
2172 bfd_vma address = (pc + 4
2173 + ((given & 0x00f8) >> 2)
2174 + ((given & 0x0200) >> 3));
2175 info->print_address_func (address, info);
2177 break;
2179 case 's':
2180 /* Right shift immediate -- bits 6..10; 1-31 print
2181 as themselves, 0 prints as 32. */
2183 long imm = (given & 0x07c0) >> 6;
2184 if (imm == 0)
2185 imm = 32;
2186 func (stream, "#%ld", imm);
2188 break;
2190 case '0': case '1': case '2': case '3': case '4':
2191 case '5': case '6': case '7': case '8': case '9':
2193 int bitstart = *c++ - '0';
2194 int bitend = 0;
2196 while (*c >= '0' && *c <= '9')
2197 bitstart = (bitstart * 10) + *c++ - '0';
2199 switch (*c)
2201 case '-':
2203 long reg;
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)
2214 case 'r':
2215 func (stream, "%s", arm_regnames[reg]);
2216 break;
2218 case 'd':
2219 func (stream, "%ld", reg);
2220 break;
2222 case 'H':
2223 func (stream, "%ld", reg << 1);
2224 break;
2226 case 'W':
2227 func (stream, "%ld", reg << 2);
2228 break;
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;
2238 case 'x':
2239 func (stream, "0x%04lx", reg);
2240 break;
2242 case 'B':
2243 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2244 info->print_address_func (reg * 2 + pc + 4, info);
2245 break;
2247 case 'c':
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]);
2256 break;
2258 default:
2259 abort ();
2262 break;
2264 case '\'':
2265 c++;
2266 if ((given & (1 << bitstart)) != 0)
2267 func (stream, "%c", *c);
2268 break;
2270 case '?':
2271 ++c;
2272 if ((given & (1 << bitstart)) != 0)
2273 func (stream, "%c", *c++);
2274 else
2275 func (stream, "%c", *++c);
2276 break;
2278 default:
2279 abort ();
2282 break;
2284 default:
2285 abort ();
2288 return;
2291 /* No match. */
2292 abort ();
2295 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
2297 static void
2298 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
2300 const struct opcode32 *insn;
2301 void *stream = info->stream;
2302 fprintf_ftype func = info->fprintf_func;
2304 if (print_insn_coprocessor (info, given, TRUE))
2305 return;
2307 for (insn = thumb32_opcodes; insn->assembler; insn++)
2308 if ((given & insn->mask) == insn->value)
2310 const char *c = insn->assembler;
2311 for (; *c; c++)
2313 if (*c != '%')
2315 func (stream, "%c", *c);
2316 continue;
2319 switch (*++c)
2321 case '%':
2322 func (stream, "%%");
2323 break;
2325 case 'I':
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);
2333 break;
2335 case 'M':
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)
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);
2354 func (stream, "#%u\t; 0x%x", imm, imm);
2356 break;
2358 case 'J':
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);
2367 break;
2369 case 'K':
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);
2377 break;
2379 case 'S':
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;
2387 func (stream, "%s", arm_regnames[reg]);
2388 switch (stp)
2390 case 0:
2391 if (imm > 0)
2392 func (stream, ", lsl #%u", imm);
2393 break;
2395 case 1:
2396 if (imm == 0)
2397 imm = 32;
2398 func (stream, ", lsr #%u", imm);
2399 break;
2401 case 2:
2402 if (imm == 0)
2403 imm = 32;
2404 func (stream, ", asr #%u", imm);
2405 break;
2407 case 3:
2408 if (imm == 0)
2409 func (stream, ", rrx");
2410 else
2411 func (stream, ", ror #%u", imm);
2414 break;
2416 case 'a':
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;
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 */
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;
2441 else switch (op)
2443 case 0xE: /* 8-bit positive immediate offset */
2444 offset = i8;
2445 break;
2447 case 0xC: /* 8-bit negative immediate offset */
2448 offset = -i8;
2449 break;
2451 case 0xF: /* 8-bit + preindex with wb */
2452 offset = i8;
2453 writeback = TRUE;
2454 break;
2456 case 0xD: /* 8-bit - preindex with wb */
2457 offset = -i8;
2458 writeback = TRUE;
2459 break;
2461 case 0xB: /* 8-bit + postindex */
2462 offset = i8;
2463 postind = TRUE;
2464 break;
2466 case 0x9: /* 8-bit - postindex */
2467 offset = -i8;
2468 postind = TRUE;
2469 break;
2471 default:
2472 func (stream, ", <undefined>]");
2473 goto skip;
2476 if (postind)
2477 func (stream, "], #%d", offset);
2478 else
2480 if (offset)
2481 func (stream, ", #%d", offset);
2482 func (stream, writeback ? "]!" : "]");
2485 if (Rn == 15)
2487 func (stream, "\t; ");
2488 info->print_address_func (((pc + 4) & ~3) + offset, info);
2491 skip:
2492 break;
2494 case 'A':
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);
2502 func (stream, "[%s", arm_regnames[Rn]);
2503 if (P)
2505 if (off || !U)
2506 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2507 func (stream, "]");
2508 if (W)
2509 func (stream, "!");
2511 else
2513 func (stream, "], ");
2514 if (W)
2515 func (stream, "#%c%u", U ? '+' : '-', off * 4);
2516 else
2517 func (stream, "{%u}", off);
2520 break;
2522 case 'w':
2524 unsigned int Sbit = (given & 0x01000000) >> 24;
2525 unsigned int type = (given & 0x00600000) >> 21;
2526 switch (type)
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;
2539 break;
2541 case 'm':
2543 int started = 0;
2544 int reg;
2546 func (stream, "{");
2547 for (reg = 0; reg < 16; reg++)
2548 if ((given & (1 << reg)) != 0)
2550 if (started)
2551 func (stream, ", ");
2552 started = 1;
2553 func (stream, "%s", arm_regnames[reg]);
2555 func (stream, "}");
2557 break;
2559 case 'E':
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);
2567 break;
2569 case 'F':
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);
2577 break;
2579 case 'b':
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;
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);
2593 info->print_address_func (pc + 4 + offset, info);
2595 break;
2597 case 'B':
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;
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 offset += pc + 4;
2612 /* BLX target addresses are always word aligned. */
2613 if ((given & 0x00001000u) == 0)
2614 offset &= ~2u;
2616 info->print_address_func (offset, info);
2618 break;
2620 case 's':
2622 unsigned int shift = 0;
2623 shift |= (given & 0x000000c0u) >> 6;
2624 shift |= (given & 0x00007000u) >> 10;
2625 if (given & 0x00200000u)
2626 func (stream, ", asr #%u", shift);
2627 else if (shift)
2628 func (stream, ", lsl #%u", shift);
2629 /* else print nothing - lsl #0 */
2631 break;
2633 case 'R':
2635 unsigned int rot = (given & 0x00000030) >> 4;
2636 if (rot)
2637 func (stream, ", ror #%u", rot * 8);
2639 break;
2641 case '0': case '1': case '2': case '3': case '4':
2642 case '5': case '6': case '7': case '8': case '9':
2644 int bitstart = *c++ - '0';
2645 int bitend = 0;
2646 unsigned int val;
2647 while (*c >= '0' && *c <= '9')
2648 bitstart = (bitstart * 10) + *c++ - '0';
2650 if (*c == '-')
2652 c++;
2653 while (*c >= '0' && *c <= '9')
2654 bitend = (bitend * 10) + *c++ - '0';
2655 if (!bitend)
2656 abort ();
2658 val = given >> bitstart;
2659 val &= (2 << (bitend - bitstart)) - 1;
2661 else
2662 val = (given >> bitstart) & 1;
2664 switch (*c)
2666 case 'd': func (stream, "%u", val); break;
2667 case 'W': func (stream, "%u", val * 4); break;
2668 case 'r': func (stream, "%s", arm_regnames[val]); break;
2670 case 'c':
2671 if (val == 0xE)
2672 func (stream, "al");
2673 else
2674 func (stream, "%s", arm_conditional[val]);
2675 break;
2677 case '\'':
2678 if (val)
2679 func (stream, "%c", c[1]);
2680 c++;
2681 break;
2683 case '`':
2684 if (!val)
2685 func (stream, "%c", c[1]);
2686 c++;
2687 break;
2689 case '?':
2690 func (stream, "%c", val ? c[1] : c[2]);
2691 c += 2;
2692 break;
2694 default:
2695 abort ();
2698 break;
2700 default:
2701 abort ();
2704 return;
2707 /* No match. */
2708 abort ();
2711 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2712 being displayed in symbol relative addresses. */
2714 bfd_boolean
2715 arm_symbol_is_valid (asymbol * sym,
2716 struct disassemble_info * info ATTRIBUTE_UNUSED)
2718 const char * name;
2720 if (sym == NULL)
2721 return FALSE;
2723 name = bfd_asymbol_name (sym);
2725 return (name && *name != '$');
2728 /* Parse an individual disassembler option. */
2730 void
2731 parse_arm_disassembler_option (char *option)
2733 if (option == NULL)
2734 return;
2736 if (strneq (option, "reg-names-", 10))
2738 int i;
2740 option += 10;
2742 for (i = NUM_ARM_REGNAMES; i--;)
2743 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2745 regname_selected = i;
2746 break;
2749 if (i < 0)
2750 /* XXX - should break 'option' at following delimiter. */
2751 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2753 else if (strneq (option, "force-thumb", 11))
2754 force_thumb = 1;
2755 else if (strneq (option, "no-force-thumb", 14))
2756 force_thumb = 0;
2757 else
2758 /* XXX - should break 'option' at following delimiter. */
2759 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2761 return;
2764 /* Parse the string of disassembler options, spliting it at whitespaces
2765 or commas. (Whitespace separators supported for backwards compatibility). */
2767 static void
2768 parse_disassembler_options (char *options)
2770 if (options == NULL)
2771 return;
2773 while (*options)
2775 parse_arm_disassembler_option (options);
2777 /* Skip forward to next seperator. */
2778 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2779 ++ options;
2780 /* Skip forward past seperators. */
2781 while (ISSPACE (*options) || (*options == ','))
2782 ++ options;
2786 /* NOTE: There are no checks in these routines that
2787 the relevant number of data bytes exist. */
2789 static int
2790 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
2792 unsigned char b[4];
2793 long given;
2794 int status;
2795 int is_thumb;
2796 int size;
2797 void (*printer) (bfd_vma, struct disassemble_info *, long);
2799 if (info->disassembler_options)
2801 parse_disassembler_options (info->disassembler_options);
2803 /* To avoid repeated parsing of these options, we remove them here. */
2804 info->disassembler_options = NULL;
2807 is_thumb = force_thumb;
2809 if (!is_thumb && info->symbols != NULL)
2811 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2813 coff_symbol_type * cs;
2815 cs = coffsymbol (*info->symbols);
2816 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
2817 || cs->native->u.syment.n_sclass == C_THUMBSTAT
2818 || cs->native->u.syment.n_sclass == C_THUMBLABEL
2819 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2820 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2822 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2824 elf_symbol_type * es;
2825 unsigned int type;
2827 es = *(elf_symbol_type **)(info->symbols);
2828 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2830 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2834 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2835 info->bytes_per_line = 4;
2837 if (!is_thumb)
2839 /* In ARM mode endianness is a straightforward issue: the instruction
2840 is four bytes long and is either ordered 0123 or 3210. */
2841 printer = print_insn_arm;
2842 info->bytes_per_chunk = 4;
2843 size = 4;
2845 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2846 if (little)
2847 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2848 else
2849 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2851 else
2853 /* In Thumb mode we have the additional wrinkle of two
2854 instruction lengths. Fortunately, the bits that determine
2855 the length of the current instruction are always to be found
2856 in the first two bytes. */
2857 printer = print_insn_thumb16;
2858 info->bytes_per_chunk = 2;
2859 size = 2;
2861 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2862 if (little)
2863 given = (b[0]) | (b[1] << 8);
2864 else
2865 given = (b[1]) | (b[0] << 8);
2867 if (!status)
2869 /* These bit patterns signal a four-byte Thumb
2870 instruction. */
2871 if ((given & 0xF800) == 0xF800
2872 || (given & 0xF800) == 0xF000
2873 || (given & 0xF800) == 0xE800)
2875 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2876 if (little)
2877 given = (b[0]) | (b[1] << 8) | (given << 16);
2878 else
2879 given = (b[1]) | (b[0] << 8) | (given << 16);
2881 printer = print_insn_thumb32;
2882 size = 4;
2887 if (status)
2889 info->memory_error_func (status, pc, info);
2890 return -1;
2892 if (info->flags & INSN_HAS_RELOC)
2893 /* If the instruction has a reloc associated with it, then
2894 the offset field in the instruction will actually be the
2895 addend for the reloc. (We are using REL type relocs).
2896 In such cases, we can ignore the pc when computing
2897 addresses, since the addend is not currently pc-relative. */
2898 pc = 0;
2900 printer (pc, info, given);
2901 return size;
2905 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
2907 return print_insn (pc, info, FALSE);
2911 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
2913 return print_insn (pc, info, TRUE);
2916 void
2917 print_arm_disassembler_options (FILE *stream)
2919 int i;
2921 fprintf (stream, _("\n\
2922 The following ARM specific disassembler options are supported for use with\n\
2923 the -M switch:\n"));
2925 for (i = NUM_ARM_REGNAMES; i--;)
2926 fprintf (stream, " reg-names-%s %*c%s\n",
2927 regnames[i].name,
2928 (int)(14 - strlen (regnames[i].name)), ' ',
2929 regnames[i].description);
2931 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
2932 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");