ld/testsuite/
[binutils.git] / opcodes / arm-dis.c
blobb5167e9b6f2a191a38fa7bd0d8f11349c96ec729
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.
405 %U print barrier type.
406 %P print address for pli instruction.
408 %<bitfield>r print as an ARM register
409 %<bitfield>d print the bitfield in decimal
410 %<bitfield>W print the bitfield plus one in decimal
411 %<bitfield>x print the bitfield in hex
412 %<bitfield>X print the bitfield as 1 hex digit without leading "0x"
414 %<bitnum>'c print specified char iff bit is one
415 %<bitnum>`c print specified char iff bit is zero
416 %<bitnum>?ab print a if bit is one else print b
418 %e print arm SMI operand (bits 0..7,8..19).
419 %E print the LSB and WIDTH fields of a BFI or BFC instruction.
420 %V print the 16-bit immediate field of a MOVT or MOVW instruction. */
422 static const struct opcode32 arm_opcodes[] =
424 /* ARM instructions. */
425 {ARM_EXT_V1, 0xe1a00000, 0xffffffff, "nop\t\t\t(mov r0,r0)"},
426 {ARM_EXT_V4T | ARM_EXT_V5, 0x012FFF10, 0x0ffffff0, "bx%c\t%0-3r"},
427 {ARM_EXT_V2, 0x00000090, 0x0fe000f0, "mul%c%20's\t%16-19r, %0-3r, %8-11r"},
428 {ARM_EXT_V2, 0x00200090, 0x0fe000f0, "mla%c%20's\t%16-19r, %0-3r, %8-11r, %12-15r"},
429 {ARM_EXT_V2S, 0x01000090, 0x0fb00ff0, "swp%c%22'b\t%12-15r, %0-3r, [%16-19r]"},
430 {ARM_EXT_V3M, 0x00800090, 0x0fa000f0, "%22?sumull%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
431 {ARM_EXT_V3M, 0x00a00090, 0x0fa000f0, "%22?sumlal%c%20's\t%12-15r, %16-19r, %0-3r, %8-11r"},
433 /* V7 instructions. */
434 {ARM_EXT_V7, 0xf450f000, 0xfd70f000, "pli\t%P"},
435 {ARM_EXT_V7, 0x0320f0f0, 0x0ffffff0, "dbg%c\t#%0-3d"},
436 {ARM_EXT_V7, 0xf57ff050, 0xfffffff0, "dmb\t%U"},
437 {ARM_EXT_V7, 0xf57ff040, 0xfffffff0, "dsb\t%U"},
438 {ARM_EXT_V7, 0xf57ff060, 0xfffffff0, "isb\t%U"},
440 /* ARM V6T2 instructions. */
441 {ARM_EXT_V6T2, 0x07c0001f, 0x0fe0007f, "bfc%c\t%12-15r, %E"},
442 {ARM_EXT_V6T2, 0x07c00010, 0x0fe00070, "bfi%c\t%12-15r, %0-3r, %E"},
443 {ARM_EXT_V6T2, 0x00600090, 0x0ff000f0, "mls%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
444 {ARM_EXT_V6T2, 0x006000b0, 0x0f7000f0, "str%cht\t%12-15r, %s"},
445 {ARM_EXT_V6T2, 0x00300090, 0x0f300090, "ldr%c%6's%5?hbt\t%12-15r, %s"},
446 {ARM_EXT_V6T2, 0x03000000, 0x0ff00000, "movw%c\t%12-15r, %V"},
447 {ARM_EXT_V6T2, 0x03400000, 0x0ff00000, "movt%c\t%12-15r, %V"},
448 {ARM_EXT_V6T2, 0x03ff0f30, 0x0fff0ff0, "rbit%c\t%12-15r, %0-3r"},
449 {ARM_EXT_V6T2, 0x07a00050, 0x0fa00070, "%22?usbfx%c\t%12-15r, %0-3r, #%7-11d, #%16-20W"},
451 /* ARM V6Z instructions. */
452 {ARM_EXT_V6Z, 0x01600070, 0x0ff000f0, "smc%c\t%e"},
454 /* ARM V6K instructions. */
455 {ARM_EXT_V6K, 0xf57ff01f, 0xffffffff, "clrex"},
456 {ARM_EXT_V6K, 0x01d00f9f, 0x0ff00fff, "ldrexb%c\t%12-15r, [%16-19r]"},
457 {ARM_EXT_V6K, 0x01b00f9f, 0x0ff00fff, "ldrexd%c\t%12-15r, [%16-19r]"},
458 {ARM_EXT_V6K, 0x01f00f9f, 0x0ff00fff, "ldrexh%c\t%12-15r, [%16-19r]"},
459 {ARM_EXT_V6K, 0x01c00f90, 0x0ff00ff0, "strexb%c\t%12-15r, %0-3r, [%16-19r]"},
460 {ARM_EXT_V6K, 0x01a00f90, 0x0ff00ff0, "strexd%c\t%12-15r, %0-3r, [%16-19r]"},
461 {ARM_EXT_V6K, 0x01e00f90, 0x0ff00ff0, "strexh%c\t%12-15r, %0-3r, [%16-19r]"},
463 /* ARM V6K NOP hints. */
464 {ARM_EXT_V6K, 0x0320f001, 0x0fffffff, "yield%c"},
465 {ARM_EXT_V6K, 0x0320f002, 0x0fffffff, "wfe%c"},
466 {ARM_EXT_V6K, 0x0320f003, 0x0fffffff, "wfi%c"},
467 {ARM_EXT_V6K, 0x0320f004, 0x0fffffff, "sev%c"},
468 {ARM_EXT_V6K, 0x0320f000, 0x0fffff00, "nop%c\t{%0-7d}"},
470 /* ARM V6 instructions. */
471 {ARM_EXT_V6, 0xf1080000, 0xfffdfe3f, "cpsie\t%8'a%7'i%6'f"},
472 {ARM_EXT_V6, 0xf1080000, 0xfffdfe20, "cpsie\t%8'a%7'i%6'f,#%0-4d"},
473 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe3f, "cpsid\t%8'a%7'i%6'f"},
474 {ARM_EXT_V6, 0xf10C0000, 0xfffdfe20, "cpsid\t%8'a%7'i%6'f,#%0-4d"},
475 {ARM_EXT_V6, 0xf1000000, 0xfff1fe20, "cps\t#%0-4d"},
476 {ARM_EXT_V6, 0x06800010, 0x0ff00ff0, "pkhbt%c\t%12-15r, %16-19r, %0-3r"},
477 {ARM_EXT_V6, 0x06800010, 0x0ff00070, "pkhbt%c\t%12-15r, %16-19r, %0-3r, LSL #%7-11d"},
478 {ARM_EXT_V6, 0x06800050, 0x0ff00ff0, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #32"},
479 {ARM_EXT_V6, 0x06800050, 0x0ff00070, "pkhtb%c\t%12-15r, %16-19r, %0-3r, ASR #%7-11d"},
480 {ARM_EXT_V6, 0x01900f9f, 0x0ff00fff, "ldrex%c\tr%12-15d, [%16-19r]"},
481 {ARM_EXT_V6, 0x06200f10, 0x0ff00ff0, "qadd16%c\t%12-15r, %16-19r, %0-3r"},
482 {ARM_EXT_V6, 0x06200f90, 0x0ff00ff0, "qadd8%c\t%12-15r, %16-19r, %0-3r"},
483 {ARM_EXT_V6, 0x06200f30, 0x0ff00ff0, "qaddsubx%c\t%12-15r, %16-19r, %0-3r"},
484 {ARM_EXT_V6, 0x06200f70, 0x0ff00ff0, "qsub16%c\t%12-15r, %16-19r, %0-3r"},
485 {ARM_EXT_V6, 0x06200ff0, 0x0ff00ff0, "qsub8%c\t%12-15r, %16-19r, %0-3r"},
486 {ARM_EXT_V6, 0x06200f50, 0x0ff00ff0, "qsubaddx%c\t%12-15r, %16-19r, %0-3r"},
487 {ARM_EXT_V6, 0x06100f10, 0x0ff00ff0, "sadd16%c\t%12-15r, %16-19r, %0-3r"},
488 {ARM_EXT_V6, 0x06100f90, 0x0ff00ff0, "sadd8%c\t%12-15r, %16-19r, %0-3r"},
489 {ARM_EXT_V6, 0x06100f30, 0x0ff00ff0, "saddaddx%c\t%12-15r, %16-19r, %0-3r"},
490 {ARM_EXT_V6, 0x06300f10, 0x0ff00ff0, "shadd16%c\t%12-15r, %16-19r, %0-3r"},
491 {ARM_EXT_V6, 0x06300f90, 0x0ff00ff0, "shadd8%c\t%12-15r, %16-19r, %0-3r"},
492 {ARM_EXT_V6, 0x06300f30, 0x0ff00ff0, "shaddsubx%c\t%12-15r, %16-19r, %0-3r"},
493 {ARM_EXT_V6, 0x06300f70, 0x0ff00ff0, "shsub16%c\t%12-15r, %16-19r, %0-3r"},
494 {ARM_EXT_V6, 0x06300ff0, 0x0ff00ff0, "shsub8%c\t%12-15r, %16-19r, %0-3r"},
495 {ARM_EXT_V6, 0x06300f50, 0x0ff00ff0, "shsubaddx%c\t%12-15r, %16-19r, %0-3r"},
496 {ARM_EXT_V6, 0x06100f70, 0x0ff00ff0, "ssub16%c\t%12-15r, %16-19r, %0-3r"},
497 {ARM_EXT_V6, 0x06100ff0, 0x0ff00ff0, "ssub8%c\t%12-15r, %16-19r, %0-3r"},
498 {ARM_EXT_V6, 0x06100f50, 0x0ff00ff0, "ssubaddx%c\t%12-15r, %16-19r, %0-3r"},
499 {ARM_EXT_V6, 0x06500f10, 0x0ff00ff0, "uadd16%c\t%12-15r, %16-19r, %0-3r"},
500 {ARM_EXT_V6, 0x06500f90, 0x0ff00ff0, "uadd8%c\t%12-15r, %16-19r, %0-3r"},
501 {ARM_EXT_V6, 0x06500f30, 0x0ff00ff0, "uaddsubx%c\t%12-15r, %16-19r, %0-3r"},
502 {ARM_EXT_V6, 0x06700f10, 0x0ff00ff0, "uhadd16%c\t%12-15r, %16-19r, %0-3r"},
503 {ARM_EXT_V6, 0x06700f90, 0x0ff00ff0, "uhadd8%c\t%12-15r, %16-19r, %0-3r"},
504 {ARM_EXT_V6, 0x06700f30, 0x0ff00ff0, "uhaddsubx%c\t%12-15r, %16-19r, %0-3r"},
505 {ARM_EXT_V6, 0x06700f70, 0x0ff00ff0, "uhsub16%c\t%12-15r, %16-19r, %0-3r"},
506 {ARM_EXT_V6, 0x06700ff0, 0x0ff00ff0, "uhsub8%c\t%12-15r, %16-19r, %0-3r"},
507 {ARM_EXT_V6, 0x06700f50, 0x0ff00ff0, "uhsubaddx%c\t%12-15r, %16-19r, %0-3r"},
508 {ARM_EXT_V6, 0x06600f10, 0x0ff00ff0, "uqadd16%c\t%12-15r, %16-19r, %0-3r"},
509 {ARM_EXT_V6, 0x06600f90, 0x0ff00ff0, "uqadd8%c\t%12-15r, %16-19r, %0-3r"},
510 {ARM_EXT_V6, 0x06600f30, 0x0ff00ff0, "uqaddsubx%c\t%12-15r, %16-19r, %0-3r"},
511 {ARM_EXT_V6, 0x06600f70, 0x0ff00ff0, "uqsub16%c\t%12-15r, %16-19r, %0-3r"},
512 {ARM_EXT_V6, 0x06600ff0, 0x0ff00ff0, "uqsub8%c\t%12-15r, %16-19r, %0-3r"},
513 {ARM_EXT_V6, 0x06600f50, 0x0ff00ff0, "uqsubaddx%c\t%12-15r, %16-19r, %0-3r"},
514 {ARM_EXT_V6, 0x06500f70, 0x0ff00ff0, "usub16%c\t%12-15r, %16-19r, %0-3r"},
515 {ARM_EXT_V6, 0x06500ff0, 0x0ff00ff0, "usub8%c\t%12-15r, %16-19r, %0-3r"},
516 {ARM_EXT_V6, 0x06500f50, 0x0ff00ff0, "usubaddx%c\t%12-15r, %16-19r, %0-3r"},
517 {ARM_EXT_V6, 0x06bf0f30, 0x0fff0ff0, "rev%c\t\%12-15r, %0-3r"},
518 {ARM_EXT_V6, 0x06bf0fb0, 0x0fff0ff0, "rev16%c\t\%12-15r, %0-3r"},
519 {ARM_EXT_V6, 0x06ff0fb0, 0x0fff0ff0, "revsh%c\t\%12-15r, %0-3r"},
520 {ARM_EXT_V6, 0xf8100a00, 0xfe50ffff, "rfe%23?id%24?ba\t\%16-19r%21'!"},
521 {ARM_EXT_V6, 0x06bf0070, 0x0fff0ff0, "sxth%c %12-15r,%0-3r"},
522 {ARM_EXT_V6, 0x06bf0470, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #8"},
523 {ARM_EXT_V6, 0x06bf0870, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #16"},
524 {ARM_EXT_V6, 0x06bf0c70, 0x0fff0ff0, "sxth%c %12-15r,%0-3r, ROR #24"},
525 {ARM_EXT_V6, 0x068f0070, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r"},
526 {ARM_EXT_V6, 0x068f0470, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #8"},
527 {ARM_EXT_V6, 0x068f0870, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #16"},
528 {ARM_EXT_V6, 0x068f0c70, 0x0fff0ff0, "sxtb16%c %12-15r,%0-3r, ROR #24"},
529 {ARM_EXT_V6, 0x06af0070, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r"},
530 {ARM_EXT_V6, 0x06af0470, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #8"},
531 {ARM_EXT_V6, 0x06af0870, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #16"},
532 {ARM_EXT_V6, 0x06af0c70, 0x0fff0ff0, "sxtb%c %12-15r,%0-3r, ROR #24"},
533 {ARM_EXT_V6, 0x06ff0070, 0x0fff0ff0, "uxth%c %12-15r,%0-3r"},
534 {ARM_EXT_V6, 0x06ff0470, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #8"},
535 {ARM_EXT_V6, 0x06ff0870, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #16"},
536 {ARM_EXT_V6, 0x06ff0c70, 0x0fff0ff0, "uxth%c %12-15r,%0-3r, ROR #24"},
537 {ARM_EXT_V6, 0x06cf0070, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r"},
538 {ARM_EXT_V6, 0x06cf0470, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #8"},
539 {ARM_EXT_V6, 0x06cf0870, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #16"},
540 {ARM_EXT_V6, 0x06cf0c70, 0x0fff0ff0, "uxtb16%c %12-15r,%0-3r, ROR #24"},
541 {ARM_EXT_V6, 0x06ef0070, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r"},
542 {ARM_EXT_V6, 0x06ef0470, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #8"},
543 {ARM_EXT_V6, 0x06ef0870, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #16"},
544 {ARM_EXT_V6, 0x06ef0c70, 0x0fff0ff0, "uxtb%c %12-15r,%0-3r, ROR #24"},
545 {ARM_EXT_V6, 0x06b00070, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r"},
546 {ARM_EXT_V6, 0x06b00470, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
547 {ARM_EXT_V6, 0x06b00870, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
548 {ARM_EXT_V6, 0x06b00c70, 0x0ff00ff0, "sxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
549 {ARM_EXT_V6, 0x06800070, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r"},
550 {ARM_EXT_V6, 0x06800470, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
551 {ARM_EXT_V6, 0x06800870, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
552 {ARM_EXT_V6, 0x06800c70, 0x0ff00ff0, "sxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
553 {ARM_EXT_V6, 0x06a00070, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r"},
554 {ARM_EXT_V6, 0x06a00470, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
555 {ARM_EXT_V6, 0x06a00870, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
556 {ARM_EXT_V6, 0x06a00c70, 0x0ff00ff0, "sxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
557 {ARM_EXT_V6, 0x06f00070, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r"},
558 {ARM_EXT_V6, 0x06f00470, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
559 {ARM_EXT_V6, 0x06f00870, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
560 {ARM_EXT_V6, 0x06f00c70, 0x0ff00ff0, "uxtah%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
561 {ARM_EXT_V6, 0x06c00070, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r"},
562 {ARM_EXT_V6, 0x06c00470, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
563 {ARM_EXT_V6, 0x06c00870, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
564 {ARM_EXT_V6, 0x06c00c70, 0x0ff00ff0, "uxtab16%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
565 {ARM_EXT_V6, 0x06e00070, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r"},
566 {ARM_EXT_V6, 0x06e00470, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #8"},
567 {ARM_EXT_V6, 0x06e00870, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #16"},
568 {ARM_EXT_V6, 0x06e00c70, 0x0ff00ff0, "uxtab%c\t%12-15r, %16-19r, %0-3r, ROR #24"},
569 {ARM_EXT_V6, 0x06800fb0, 0x0ff00ff0, "sel%c\t%12-15r, %16-19r, %0-3r"},
570 {ARM_EXT_V6, 0xf1010000, 0xfffffc00, "setend\t%9?ble"},
571 {ARM_EXT_V6, 0x0700f010, 0x0ff0f0d0, "smuad%5'x%c\t%16-19r, %0-3r, %8-11r"},
572 {ARM_EXT_V6, 0x0700f050, 0x0ff0f0d0, "smusd%5'x%c\t%16-19r, %0-3r, %8-11r"},
573 {ARM_EXT_V6, 0x07000010, 0x0ff000d0, "smlad%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
574 {ARM_EXT_V6, 0x07400010, 0x0ff000d0, "smlald%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
575 {ARM_EXT_V6, 0x07000050, 0x0ff000d0, "smlsd%5'x%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
576 {ARM_EXT_V6, 0x07400050, 0x0ff000d0, "smlsld%5'x%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
577 {ARM_EXT_V6, 0x0750f010, 0x0ff0f0d0, "smmul%5'r%c\t%16-19r, %0-3r, %8-11r"},
578 {ARM_EXT_V6, 0x07500010, 0x0ff000d0, "smmla%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
579 {ARM_EXT_V6, 0x075000d0, 0x0ff000d0, "smmls%5'r%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
580 {ARM_EXT_V6, 0xf84d0500, 0xfe5fffe0, "srs%23?id%24?ba\t#%0-4d%21'!"},
581 {ARM_EXT_V6, 0x06a00010, 0x0fe00ff0, "ssat%c\t%12-15r, #%16-20W, %0-3r"},
582 {ARM_EXT_V6, 0x06a00010, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, LSL #%7-11d"},
583 {ARM_EXT_V6, 0x06a00050, 0x0fe00070, "ssat%c\t%12-15r, #%16-20W, %0-3r, ASR #%7-11d"},
584 {ARM_EXT_V6, 0x06a00f30, 0x0ff00ff0, "ssat16%c\t%12-15r, #%16-19W, %0-3r"},
585 {ARM_EXT_V6, 0x01800f90, 0x0ff00ff0, "strex%c\t%12-15r, %0-3r, [%16-19r]"},
586 {ARM_EXT_V6, 0x00400090, 0x0ff000f0, "umaal%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
587 {ARM_EXT_V6, 0x0780f010, 0x0ff0f0f0, "usad8%c\t%16-19r, %0-3r, %8-11r"},
588 {ARM_EXT_V6, 0x07800010, 0x0ff000f0, "usada8%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
589 {ARM_EXT_V6, 0x06e00010, 0x0fe00ff0, "usat%c\t%12-15r, #%16-20d, %0-3r"},
590 {ARM_EXT_V6, 0x06e00010, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, LSL #%7-11d"},
591 {ARM_EXT_V6, 0x06e00050, 0x0fe00070, "usat%c\t%12-15r, #%16-20d, %0-3r, ASR #%7-11d"},
592 {ARM_EXT_V6, 0x06e00f30, 0x0ff00ff0, "usat16%c\t%12-15r, #%16-19d, %0-3r"},
594 /* V5J instruction. */
595 {ARM_EXT_V5J, 0x012fff20, 0x0ffffff0, "bxj%c\t%0-3r"},
597 /* V5 Instructions. */
598 {ARM_EXT_V5, 0xe1200070, 0xfff000f0, "bkpt\t0x%16-19X%12-15X%8-11X%0-3X"},
599 {ARM_EXT_V5, 0xfa000000, 0xfe000000, "blx\t%B"},
600 {ARM_EXT_V5, 0x012fff30, 0x0ffffff0, "blx%c\t%0-3r"},
601 {ARM_EXT_V5, 0x016f0f10, 0x0fff0ff0, "clz%c\t%12-15r, %0-3r"},
603 /* V5E "El Segundo" Instructions. */
604 {ARM_EXT_V5E, 0x000000d0, 0x0e1000f0, "ldr%cd\t%12-15r, %s"},
605 {ARM_EXT_V5E, 0x000000f0, 0x0e1000f0, "str%cd\t%12-15r, %s"},
606 {ARM_EXT_V5E, 0xf450f000, 0xfc70f000, "pld\t%a"},
607 {ARM_EXT_V5ExP, 0x01000080, 0x0ff000f0, "smlabb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
608 {ARM_EXT_V5ExP, 0x010000a0, 0x0ff000f0, "smlatb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
609 {ARM_EXT_V5ExP, 0x010000c0, 0x0ff000f0, "smlabt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
610 {ARM_EXT_V5ExP, 0x010000e0, 0x0ff000f0, "smlatt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
612 {ARM_EXT_V5ExP, 0x01200080, 0x0ff000f0, "smlawb%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
613 {ARM_EXT_V5ExP, 0x012000c0, 0x0ff000f0, "smlawt%c\t%16-19r, %0-3r, %8-11r, %12-15r"},
615 {ARM_EXT_V5ExP, 0x01400080, 0x0ff000f0, "smlalbb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
616 {ARM_EXT_V5ExP, 0x014000a0, 0x0ff000f0, "smlaltb%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
617 {ARM_EXT_V5ExP, 0x014000c0, 0x0ff000f0, "smlalbt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
618 {ARM_EXT_V5ExP, 0x014000e0, 0x0ff000f0, "smlaltt%c\t%12-15r, %16-19r, %0-3r, %8-11r"},
620 {ARM_EXT_V5ExP, 0x01600080, 0x0ff0f0f0, "smulbb%c\t%16-19r, %0-3r, %8-11r"},
621 {ARM_EXT_V5ExP, 0x016000a0, 0x0ff0f0f0, "smultb%c\t%16-19r, %0-3r, %8-11r"},
622 {ARM_EXT_V5ExP, 0x016000c0, 0x0ff0f0f0, "smulbt%c\t%16-19r, %0-3r, %8-11r"},
623 {ARM_EXT_V5ExP, 0x016000e0, 0x0ff0f0f0, "smultt%c\t%16-19r, %0-3r, %8-11r"},
625 {ARM_EXT_V5ExP, 0x012000a0, 0x0ff0f0f0, "smulwb%c\t%16-19r, %0-3r, %8-11r"},
626 {ARM_EXT_V5ExP, 0x012000e0, 0x0ff0f0f0, "smulwt%c\t%16-19r, %0-3r, %8-11r"},
628 {ARM_EXT_V5ExP, 0x01000050, 0x0ff00ff0, "qadd%c\t%12-15r, %0-3r, %16-19r"},
629 {ARM_EXT_V5ExP, 0x01400050, 0x0ff00ff0, "qdadd%c\t%12-15r, %0-3r, %16-19r"},
630 {ARM_EXT_V5ExP, 0x01200050, 0x0ff00ff0, "qsub%c\t%12-15r, %0-3r, %16-19r"},
631 {ARM_EXT_V5ExP, 0x01600050, 0x0ff00ff0, "qdsub%c\t%12-15r, %0-3r, %16-19r"},
633 /* ARM Instructions. */
634 {ARM_EXT_V1, 0x00000090, 0x0e100090, "str%c%6's%5?hb\t%12-15r, %s"},
635 {ARM_EXT_V1, 0x00100090, 0x0e100090, "ldr%c%6's%5?hb\t%12-15r, %s"},
636 {ARM_EXT_V1, 0x00000000, 0x0de00000, "and%c%20's\t%12-15r, %16-19r, %o"},
637 {ARM_EXT_V1, 0x00200000, 0x0de00000, "eor%c%20's\t%12-15r, %16-19r, %o"},
638 {ARM_EXT_V1, 0x00400000, 0x0de00000, "sub%c%20's\t%12-15r, %16-19r, %o"},
639 {ARM_EXT_V1, 0x00600000, 0x0de00000, "rsb%c%20's\t%12-15r, %16-19r, %o"},
640 {ARM_EXT_V1, 0x00800000, 0x0de00000, "add%c%20's\t%12-15r, %16-19r, %o"},
641 {ARM_EXT_V1, 0x00a00000, 0x0de00000, "adc%c%20's\t%12-15r, %16-19r, %o"},
642 {ARM_EXT_V1, 0x00c00000, 0x0de00000, "sbc%c%20's\t%12-15r, %16-19r, %o"},
643 {ARM_EXT_V1, 0x00e00000, 0x0de00000, "rsc%c%20's\t%12-15r, %16-19r, %o"},
644 {ARM_EXT_V3, 0x0120f000, 0x0db0f000, "msr%c\t%22?SCPSR%C, %o"},
645 {ARM_EXT_V3, 0x010f0000, 0x0fbf0fff, "mrs%c\t%12-15r, %22?SCPSR"},
646 {ARM_EXT_V1, 0x01000000, 0x0de00000, "tst%c%p\t%16-19r, %o"},
647 {ARM_EXT_V1, 0x01200000, 0x0de00000, "teq%c%p\t%16-19r, %o"},
648 {ARM_EXT_V1, 0x01400000, 0x0de00000, "cmp%c%p\t%16-19r, %o"},
649 {ARM_EXT_V1, 0x01600000, 0x0de00000, "cmn%c%p\t%16-19r, %o"},
650 {ARM_EXT_V1, 0x01800000, 0x0de00000, "orr%c%20's\t%12-15r, %16-19r, %o"},
651 {ARM_EXT_V1, 0x01a00000, 0x0de00000, "mov%c%20's\t%12-15r, %o"},
652 {ARM_EXT_V1, 0x01c00000, 0x0de00000, "bic%c%20's\t%12-15r, %16-19r, %o"},
653 {ARM_EXT_V1, 0x01e00000, 0x0de00000, "mvn%c%20's\t%12-15r, %o"},
654 {ARM_EXT_V1, 0x04000000, 0x0e100000, "str%c%22'b%t\t%12-15r, %a"},
655 {ARM_EXT_V1, 0x06000000, 0x0e100ff0, "str%c%22'b%t\t%12-15r, %a"},
656 {ARM_EXT_V1, 0x04000000, 0x0c100010, "str%c%22'b%t\t%12-15r, %a"},
657 {ARM_EXT_V1, 0x06000010, 0x0e000010, "undefined"},
658 {ARM_EXT_V1, 0x04100000, 0x0c100000, "ldr%c%22'b%t\t%12-15r, %a"},
659 {ARM_EXT_V1, 0x08000000, 0x0e100000, "stm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
660 {ARM_EXT_V1, 0x08100000, 0x0e100000, "ldm%c%23?id%24?ba\t%16-19r%21'!, %m%22'^"},
661 {ARM_EXT_V1, 0x0a000000, 0x0e000000, "b%24'l%c\t%b"},
662 {ARM_EXT_V1, 0x0f000000, 0x0f000000, "swi%c\t%0-23x"},
664 /* The rest. */
665 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined instruction %0-31x"},
666 {0, 0x00000000, 0x00000000, 0}
669 /* print_insn_thumb16 recognizes the following format control codes:
671 %S print Thumb register (bits 3..5 as high number if bit 6 set)
672 %D print Thumb register (bits 0..2 as high number if bit 7 set)
673 %<bitfield>I print bitfield as a signed decimal
674 (top bit of range being the sign bit)
675 %N print Thumb register mask (with LR)
676 %O print Thumb register mask (with PC)
677 %M print Thumb register mask
678 %b print CZB's 6-bit unsigned branch destination
679 %s print Thumb right-shift immediate (6..10; 0 == 32).
680 %<bitfield>r print bitfield as an ARM register
681 %<bitfield>d print bitfield as a decimal
682 %<bitfield>H print (bitfield * 2) as a decimal
683 %<bitfield>W print (bitfield * 4) as a decimal
684 %<bitfield>a print (bitfield * 4) as a pc-rel offset + decoded symbol
685 %<bitfield>B print Thumb branch destination (signed displacement)
686 %<bitfield>c print bitfield as a condition code
687 %<bitnum>'c print specified char iff bit is one
688 %<bitnum>?ab print a if bit is one else print b. */
690 static const struct opcode16 thumb_opcodes[] =
692 /* Thumb instructions. */
694 /* ARM V6K no-argument instructions. */
695 {ARM_EXT_V6K, 0xbf00, 0xffff, "nop"},
696 {ARM_EXT_V6K, 0xbf10, 0xffff, "yield"},
697 {ARM_EXT_V6K, 0xbf20, 0xffff, "wfe"},
698 {ARM_EXT_V6K, 0xbf30, 0xffff, "wfi"},
699 {ARM_EXT_V6K, 0xbf40, 0xffff, "sev"},
700 {ARM_EXT_V6K, 0xbf00, 0xff0f, "nop\t{%4-7d}"},
702 /* ARM V6T2 instructions. */
703 {ARM_EXT_V6T2, 0xb900, 0xfd00, "cbnz\t%0-2r, %b"},
704 {ARM_EXT_V6T2, 0xb100, 0xfd00, "cbz\t%0-2r, %b"},
705 {ARM_EXT_V6T2, 0xbf08, 0xff0f, "it\t%4-7c"},
706 {ARM_EXT_V6T2, 0xbf14, 0xff17, "it%3?te\t%4-7c"},
707 {ARM_EXT_V6T2, 0xbf04, 0xff17, "it%3?et\t%4-7c"},
708 {ARM_EXT_V6T2, 0xbf12, 0xff13, "it%3?te%2?te\t%4-7c"},
709 {ARM_EXT_V6T2, 0xbf02, 0xff13, "it%3?et%2?et\t%4-7c"},
710 {ARM_EXT_V6T2, 0xbf11, 0xff11, "it%3?te%2?te%1?te\t%4-7c"},
711 {ARM_EXT_V6T2, 0xbf01, 0xff11, "it%3?et%2?et%1?et\t%4-7c"},
713 /* ARM V6. */
714 {ARM_EXT_V6, 0xb660, 0xfff8, "cpsie\t%2'a%1'i%0'f"},
715 {ARM_EXT_V6, 0xb670, 0xfff8, "cpsid\t%2'a%1'i%0'f"},
716 {ARM_EXT_V6, 0x4600, 0xffc0, "mov\t%0-2r, %3-5r"},
717 {ARM_EXT_V6, 0xba00, 0xffc0, "rev\t%0-2r, %3-5r"},
718 {ARM_EXT_V6, 0xba40, 0xffc0, "rev16\t%0-2r, %3-5r"},
719 {ARM_EXT_V6, 0xbac0, 0xffc0, "revsh\t%0-2r, %3-5r"},
720 {ARM_EXT_V6, 0xb650, 0xfff7, "setend\t%3?ble"},
721 {ARM_EXT_V6, 0xb200, 0xffc0, "sxth\t%0-2r, %3-5r"},
722 {ARM_EXT_V6, 0xb240, 0xffc0, "sxtb\t%0-2r, %3-5r"},
723 {ARM_EXT_V6, 0xb280, 0xffc0, "uxth\t%0-2r, %3-5r"},
724 {ARM_EXT_V6, 0xb2c0, 0xffc0, "uxtb\t%0-2r, %3-5r"},
726 /* ARM V5 ISA extends Thumb. */
727 {ARM_EXT_V5T, 0xbe00, 0xff00, "bkpt\t%0-7x"},
728 /* This is BLX(2). BLX(1) is a 32-bit instruction. */
729 {ARM_EXT_V5T, 0x4780, 0xff87, "blx\t%3-6r"}, /* note: 4 bit register number. */
730 /* ARM V4T ISA (Thumb v1). */
731 {ARM_EXT_V4T, 0x46C0, 0xFFFF, "nop\t\t\t(mov r8, r8)"},
732 /* Format 4. */
733 {ARM_EXT_V4T, 0x4000, 0xFFC0, "ands\t%0-2r, %3-5r"},
734 {ARM_EXT_V4T, 0x4040, 0xFFC0, "eors\t%0-2r, %3-5r"},
735 {ARM_EXT_V4T, 0x4080, 0xFFC0, "lsls\t%0-2r, %3-5r"},
736 {ARM_EXT_V4T, 0x40C0, 0xFFC0, "lsrs\t%0-2r, %3-5r"},
737 {ARM_EXT_V4T, 0x4100, 0xFFC0, "asrs\t%0-2r, %3-5r"},
738 {ARM_EXT_V4T, 0x4140, 0xFFC0, "adcs\t%0-2r, %3-5r"},
739 {ARM_EXT_V4T, 0x4180, 0xFFC0, "sbcs\t%0-2r, %3-5r"},
740 {ARM_EXT_V4T, 0x41C0, 0xFFC0, "rors\t%0-2r, %3-5r"},
741 {ARM_EXT_V4T, 0x4200, 0xFFC0, "tst\t%0-2r, %3-5r"},
742 {ARM_EXT_V4T, 0x4240, 0xFFC0, "negs\t%0-2r, %3-5r"},
743 {ARM_EXT_V4T, 0x4280, 0xFFC0, "cmp\t%0-2r, %3-5r"},
744 {ARM_EXT_V4T, 0x42C0, 0xFFC0, "cmn\t%0-2r, %3-5r"},
745 {ARM_EXT_V4T, 0x4300, 0xFFC0, "orrs\t%0-2r, %3-5r"},
746 {ARM_EXT_V4T, 0x4340, 0xFFC0, "muls\t%0-2r, %3-5r"},
747 {ARM_EXT_V4T, 0x4380, 0xFFC0, "bics\t%0-2r, %3-5r"},
748 {ARM_EXT_V4T, 0x43C0, 0xFFC0, "mvns\t%0-2r, %3-5r"},
749 /* format 13 */
750 {ARM_EXT_V4T, 0xB000, 0xFF80, "add\tsp, #%0-6W"},
751 {ARM_EXT_V4T, 0xB080, 0xFF80, "sub\tsp, #%0-6W"},
752 /* format 5 */
753 {ARM_EXT_V4T, 0x4700, 0xFF80, "bx\t%S"},
754 {ARM_EXT_V4T, 0x4400, 0xFF00, "add\t%D, %S"},
755 {ARM_EXT_V4T, 0x4500, 0xFF00, "cmp\t%D, %S"},
756 {ARM_EXT_V4T, 0x4600, 0xFF00, "mov\t%D, %S"},
757 /* format 14 */
758 {ARM_EXT_V4T, 0xB400, 0xFE00, "push\t%N"},
759 {ARM_EXT_V4T, 0xBC00, 0xFE00, "pop\t%O"},
760 /* format 2 */
761 {ARM_EXT_V4T, 0x1800, 0xFE00, "adds\t%0-2r, %3-5r, %6-8r"},
762 {ARM_EXT_V4T, 0x1A00, 0xFE00, "subs\t%0-2r, %3-5r, %6-8r"},
763 {ARM_EXT_V4T, 0x1C00, 0xFE00, "adds\t%0-2r, %3-5r, #%6-8d"},
764 {ARM_EXT_V4T, 0x1E00, 0xFE00, "subs\t%0-2r, %3-5r, #%6-8d"},
765 /* format 8 */
766 {ARM_EXT_V4T, 0x5200, 0xFE00, "strh\t%0-2r, [%3-5r, %6-8r]"},
767 {ARM_EXT_V4T, 0x5A00, 0xFE00, "ldrh\t%0-2r, [%3-5r, %6-8r]"},
768 {ARM_EXT_V4T, 0x5600, 0xF600, "ldrs%11?hb\t%0-2r, [%3-5r, %6-8r]"},
769 /* format 7 */
770 {ARM_EXT_V4T, 0x5000, 0xFA00, "str%10'b\t%0-2r, [%3-5r, %6-8r]"},
771 {ARM_EXT_V4T, 0x5800, 0xFA00, "ldr%10'b\t%0-2r, [%3-5r, %6-8r]"},
772 /* format 1 */
773 {ARM_EXT_V4T, 0x0000, 0xF800, "lsls\t%0-2r, %3-5r, #%6-10d"},
774 {ARM_EXT_V4T, 0x0800, 0xF800, "lsrs\t%0-2r, %3-5r, %s"},
775 {ARM_EXT_V4T, 0x1000, 0xF800, "asrs\t%0-2r, %3-5r, %s"},
776 /* format 3 */
777 {ARM_EXT_V4T, 0x2000, 0xF800, "movs\t%8-10r, #%0-7d"},
778 {ARM_EXT_V4T, 0x2800, 0xF800, "cmp\t%8-10r, #%0-7d"},
779 {ARM_EXT_V4T, 0x3000, 0xF800, "adds\t%8-10r, #%0-7d"},
780 {ARM_EXT_V4T, 0x3800, 0xF800, "subs\t%8-10r, #%0-7d"},
781 /* format 6 */
782 {ARM_EXT_V4T, 0x4800, 0xF800, "ldr\t%8-10r, [pc, #%0-7W]\t(%0-7a)"}, /* TODO: Disassemble PC relative "LDR rD,=<symbolic>" */
783 /* format 9 */
784 {ARM_EXT_V4T, 0x6000, 0xF800, "str\t%0-2r, [%3-5r, #%6-10W]"},
785 {ARM_EXT_V4T, 0x6800, 0xF800, "ldr\t%0-2r, [%3-5r, #%6-10W]"},
786 {ARM_EXT_V4T, 0x7000, 0xF800, "strb\t%0-2r, [%3-5r, #%6-10d]"},
787 {ARM_EXT_V4T, 0x7800, 0xF800, "ldrb\t%0-2r, [%3-5r, #%6-10d]"},
788 /* format 10 */
789 {ARM_EXT_V4T, 0x8000, 0xF800, "strh\t%0-2r, [%3-5r, #%6-10H]"},
790 {ARM_EXT_V4T, 0x8800, 0xF800, "ldrh\t%0-2r, [%3-5r, #%6-10H]"},
791 /* format 11 */
792 {ARM_EXT_V4T, 0x9000, 0xF800, "str\t%8-10r, [sp, #%0-7W]"},
793 {ARM_EXT_V4T, 0x9800, 0xF800, "ldr\t%8-10r, [sp, #%0-7W]"},
794 /* format 12 */
795 {ARM_EXT_V4T, 0xA000, 0xF800, "add\t%8-10r, pc, #%0-7W\t(adr %8-10r,%0-7a)"},
796 {ARM_EXT_V4T, 0xA800, 0xF800, "add\t%8-10r, sp, #%0-7W"},
797 /* format 15 */
798 {ARM_EXT_V4T, 0xC000, 0xF800, "stmia\t%8-10r!, %M"},
799 {ARM_EXT_V4T, 0xC800, 0xF800, "ldmia\t%8-10r!, %M"},
800 /* format 17 */
801 {ARM_EXT_V4T, 0xDF00, 0xFF00, "swi\t%0-7d"},
802 /* format 16 */
803 {ARM_EXT_V4T, 0xD000, 0xF000, "b%8-11c.n\t%0-7B"},
804 /* format 18 */
805 {ARM_EXT_V4T, 0xE000, 0xF800, "b.n\t%0-10B"},
807 /* The E800 .. FFFF range is unconditionally redirected to the
808 32-bit table, because even in pre-V6T2 ISAs, BL and BLX(1) pairs
809 are processed via that table. Thus, we can never encounter a
810 bare "second half of BL/BLX(1)" instruction here. */
811 {ARM_EXT_V1, 0x0000, 0x0000, "undefined"},
812 {0, 0, 0, 0}
815 /* Thumb32 opcodes use the same table structure as the ARM opcodes.
816 We adopt the convention that hw1 is the high 16 bits of .value and
817 .mask, hw2 the low 16 bits.
819 print_insn_thumb32 recognizes the following format control codes:
821 %% %
823 %I print a 12-bit immediate from hw1[10],hw2[14:12,7:0]
824 %M print a modified 12-bit immediate (same location)
825 %J print a 16-bit immediate from hw1[3:0,10],hw2[14:12,7:0]
826 %K print a 16-bit immediate from hw2[3:0],hw1[3:0],hw2[11:4]
827 %S print a possibly-shifted Rm
829 %a print the address of a plain load/store
830 %w print the width and signedness of a core load/store
831 %m print register mask for ldm/stm
833 %E print the lsb and width fields of a bfc/bfi instruction
834 %F print the lsb and width fields of a sbfx/ubfx instruction
835 %b print a conditional branch offset
836 %B print an unconditional branch offset
837 %s print the shift field of an SSAT instruction
838 %R print the rotation field of an SXT instruction
839 %U print barrier type.
840 %P print address for pli instruction.
842 %<bitfield>d print bitfield in decimal
843 %<bitfield>W print bitfield*4 in decimal
844 %<bitfield>r print bitfield as an ARM register
845 %<bitfield>c print bitfield as a condition code
847 %<bitnum>'c print "c" iff bit is one
848 %<bitnum>`c print "c" iff bit is zero
849 %<bitnum>?ab print "a" if bit is one, else "b"
851 With one exception at the bottom (done because BL and BLX(1) need
852 to come dead last), this table was machine-sorted first in
853 decreasing order of number of bits set in the mask, then in
854 increasing numeric order of mask, then in increasing numeric order
855 of opcode. This order is not the clearest for a human reader, but
856 is guaranteed never to catch a special-case bit pattern with a more
857 general mask, which is important, because this instruction encoding
858 makes heavy use of special-case bit patterns. */
859 static const struct opcode32 thumb32_opcodes[] =
861 /* V7 instructions. */
862 {ARM_EXT_V7, 0xf910f000, 0xff70f000, "pli\t%a"},
863 {ARM_EXT_V7, 0xf3af80f0, 0xfffffff0, "dbg\t#%0-3d"},
864 {ARM_EXT_V7, 0xf3bf8f50, 0xfffffff0, "dmb\t%U"},
865 {ARM_EXT_V7, 0xf3bf8f40, 0xfffffff0, "dsb\t%U"},
866 {ARM_EXT_V7, 0xf3bf8f60, 0xfffffff0, "isb\t%U"},
867 {ARM_EXT_DIV, 0xfb90f0f0, 0xfff0f0f0, "sdiv\t%8-11r, %16-19r, %0-3r"},
868 {ARM_EXT_DIV, 0xfbb0f0f0, 0xfff0f0f0, "udiv\t%8-11r, %16-19r, %0-3r"},
870 /* Instructions defined in the basic V6T2 set. */
871 {ARM_EXT_V6T2, 0xf3af8000, 0xffffffff, "nop.w"},
872 {ARM_EXT_V6T2, 0xf3af8001, 0xffffffff, "yield.w"},
873 {ARM_EXT_V6T2, 0xf3af8002, 0xffffffff, "wfe.w"},
874 {ARM_EXT_V6T2, 0xf3af8003, 0xffffffff, "wfi.w"},
875 {ARM_EXT_V6T2, 0xf3af9004, 0xffffffff, "sev.w"},
876 {ARM_EXT_V6T2, 0xf3af8000, 0xffffff00, "nop.w\t{%0-7d}"},
878 {ARM_EXT_V6T2, 0xf3bf8f2f, 0xffffffff, "clrex"},
879 {ARM_EXT_V6T2, 0xf3af8400, 0xffffff1f, "cpsie.w\t%7'a%6'i%5'f"},
880 {ARM_EXT_V6T2, 0xf3af8600, 0xffffff1f, "cpsid.w\t%7'a%6'i%5'f"},
881 {ARM_EXT_V6T2, 0xf3c08f00, 0xfff0ffff, "bxj\t%16-19r"},
882 {ARM_EXT_V6T2, 0xe810c000, 0xffd0ffff, "rfedb\t%16-19r%21'!"},
883 {ARM_EXT_V6T2, 0xe990c000, 0xffd0ffff, "rfeia\t%16-19r%21'!"},
884 {ARM_EXT_V6T2, 0xf3ef8000, 0xffeff000, "mrs\t%8-11r, %D"},
885 {ARM_EXT_V6T2, 0xf3af8100, 0xffffffe0, "cps\t#%0-4d"},
886 {ARM_EXT_V6T2, 0xe8d0f000, 0xfff0fff0, "tbb\t[%16-19r, %0-3r]"},
887 {ARM_EXT_V6T2, 0xe8d0f010, 0xfff0fff0, "tbh\t[%16-19r, %0-3r, lsl #1]"},
888 {ARM_EXT_V6T2, 0xf3af8500, 0xffffff00, "cpsie\t%7'a%6'i%5'f, #%0-4d"},
889 {ARM_EXT_V6T2, 0xf3af8700, 0xffffff00, "cpsid\t%7'a%6'i%5'f, #%0-4d"},
890 {ARM_EXT_V6T2, 0xf3de8f00, 0xffffff00, "subs\tpc, lr, #%0-7d"},
891 {ARM_EXT_V6T2, 0xf3808000, 0xffe0f000, "msr\t%C, %16-19r"},
892 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00fff, "ldrex\t%12-15r, [%16-19r]"},
893 {ARM_EXT_V6T2, 0xe8d00f4f, 0xfff00fef, "ldrex%4?hb\t%12-15r, [%16-19r]"},
894 {ARM_EXT_V6T2, 0xe800c000, 0xffd0ffe0, "srsdb\t#%0-4d%21'!"},
895 {ARM_EXT_V6T2, 0xe980c000, 0xffd0ffe0, "srsia\t#%0-4d%21'!"},
896 {ARM_EXT_V6T2, 0xfa0ff080, 0xfffff0c0, "sxth.w\t%8-11r, %0-3r%R"},
897 {ARM_EXT_V6T2, 0xfa1ff080, 0xfffff0c0, "uxth.w\t%8-11r, %0-3r%R"},
898 {ARM_EXT_V6T2, 0xfa2ff080, 0xfffff0c0, "sxtb16\t%8-11r, %0-3r%R"},
899 {ARM_EXT_V6T2, 0xfa3ff080, 0xfffff0c0, "uxtb16\t%8-11r, %0-3r%R"},
900 {ARM_EXT_V6T2, 0xfa4ff080, 0xfffff0c0, "sxtb.w\t%8-11r, %0-3r%R"},
901 {ARM_EXT_V6T2, 0xfa5ff080, 0xfffff0c0, "uxtb.w\t%8-11r, %0-3r%R"},
902 {ARM_EXT_V6T2, 0xe8400000, 0xfff000ff, "strex\t%8-11r, %12-15r, [%16-19r]"},
903 {ARM_EXT_V6T2, 0xe8d0007f, 0xfff000ff, "ldrexd\t%12-15r, %8-11r, [%16-19r]"},
904 {ARM_EXT_V6T2, 0xfa80f000, 0xfff0f0f0, "sadd8\t%8-11r, %16-19r, %0-3r"},
905 {ARM_EXT_V6T2, 0xfa80f010, 0xfff0f0f0, "qadd8\t%8-11r, %16-19r, %0-3r"},
906 {ARM_EXT_V6T2, 0xfa80f020, 0xfff0f0f0, "shadd8\t%8-11r, %16-19r, %0-3r"},
907 {ARM_EXT_V6T2, 0xfa80f040, 0xfff0f0f0, "uadd8\t%8-11r, %16-19r, %0-3r"},
908 {ARM_EXT_V6T2, 0xfa80f050, 0xfff0f0f0, "uqadd8\t%8-11r, %16-19r, %0-3r"},
909 {ARM_EXT_V6T2, 0xfa80f060, 0xfff0f0f0, "uhadd8\t%8-11r, %16-19r, %0-3r"},
910 {ARM_EXT_V6T2, 0xfa80f080, 0xfff0f0f0, "qadd\t%8-11r, %0-3r, %16-19r"},
911 {ARM_EXT_V6T2, 0xfa80f090, 0xfff0f0f0, "qdadd\t%8-11r, %0-3r, %16-19r"},
912 {ARM_EXT_V6T2, 0xfa80f0a0, 0xfff0f0f0, "qsub\t%8-11r, %0-3r, %16-19r"},
913 {ARM_EXT_V6T2, 0xfa80f0b0, 0xfff0f0f0, "qdsub\t%8-11r, %0-3r, %16-19r"},
914 {ARM_EXT_V6T2, 0xfa90f000, 0xfff0f0f0, "sadd16\t%8-11r, %16-19r, %0-3r"},
915 {ARM_EXT_V6T2, 0xfa90f010, 0xfff0f0f0, "qadd16\t%8-11r, %16-19r, %0-3r"},
916 {ARM_EXT_V6T2, 0xfa90f020, 0xfff0f0f0, "shadd16\t%8-11r, %16-19r, %0-3r"},
917 {ARM_EXT_V6T2, 0xfa90f040, 0xfff0f0f0, "uadd16\t%8-11r, %16-19r, %0-3r"},
918 {ARM_EXT_V6T2, 0xfa90f050, 0xfff0f0f0, "uqadd16\t%8-11r, %16-19r, %0-3r"},
919 {ARM_EXT_V6T2, 0xfa90f060, 0xfff0f0f0, "uhadd16\t%8-11r, %16-19r, %0-3r"},
920 {ARM_EXT_V6T2, 0xfa90f080, 0xfff0f0f0, "rev.w\t%8-11r, %16-19r"},
921 {ARM_EXT_V6T2, 0xfa90f090, 0xfff0f0f0, "rev16.w\t%8-11r, %16-19r"},
922 {ARM_EXT_V6T2, 0xfa90f0a0, 0xfff0f0f0, "rbit\t%8-11r, %16-19r"},
923 {ARM_EXT_V6T2, 0xfa90f0b0, 0xfff0f0f0, "revsh.w\t%8-11r, %16-19r"},
924 {ARM_EXT_V6T2, 0xfaa0f000, 0xfff0f0f0, "saddsubx\t%8-11r, %16-19r, %0-3r"},
925 {ARM_EXT_V6T2, 0xfaa0f010, 0xfff0f0f0, "qaddsubx\t%8-11r, %16-19r, %0-3r"},
926 {ARM_EXT_V6T2, 0xfaa0f020, 0xfff0f0f0, "shaddsubx\t%8-11r, %16-19r, %0-3r"},
927 {ARM_EXT_V6T2, 0xfaa0f040, 0xfff0f0f0, "uaddsubx\t%8-11r, %16-19r, %0-3r"},
928 {ARM_EXT_V6T2, 0xfaa0f050, 0xfff0f0f0, "uqaddsubx\t%8-11r, %16-19r, %0-3r"},
929 {ARM_EXT_V6T2, 0xfaa0f060, 0xfff0f0f0, "uhaddsubx\t%8-11r, %16-19r, %0-3r"},
930 {ARM_EXT_V6T2, 0xfaa0f080, 0xfff0f0f0, "sel\t%8-11r, %16-19r, %0-3r"},
931 {ARM_EXT_V6T2, 0xfab0f080, 0xfff0f0f0, "clz\t%8-11r, %16-19r"},
932 {ARM_EXT_V6T2, 0xfac0f000, 0xfff0f0f0, "ssub8\t%8-11r, %16-19r, %0-3r"},
933 {ARM_EXT_V6T2, 0xfac0f010, 0xfff0f0f0, "qsub8\t%8-11r, %16-19r, %0-3r"},
934 {ARM_EXT_V6T2, 0xfac0f020, 0xfff0f0f0, "shsub8\t%8-11r, %16-19r, %0-3r"},
935 {ARM_EXT_V6T2, 0xfac0f040, 0xfff0f0f0, "usub8\t%8-11r, %16-19r, %0-3r"},
936 {ARM_EXT_V6T2, 0xfac0f050, 0xfff0f0f0, "uqsub8\t%8-11r, %16-19r, %0-3r"},
937 {ARM_EXT_V6T2, 0xfac0f060, 0xfff0f0f0, "uhsub8\t%8-11r, %16-19r, %0-3r"},
938 {ARM_EXT_V6T2, 0xfad0f000, 0xfff0f0f0, "ssub16\t%8-11r, %16-19r, %0-3r"},
939 {ARM_EXT_V6T2, 0xfad0f010, 0xfff0f0f0, "qsub16\t%8-11r, %16-19r, %0-3r"},
940 {ARM_EXT_V6T2, 0xfad0f020, 0xfff0f0f0, "shsub16\t%8-11r, %16-19r, %0-3r"},
941 {ARM_EXT_V6T2, 0xfad0f040, 0xfff0f0f0, "usub16\t%8-11r, %16-19r, %0-3r"},
942 {ARM_EXT_V6T2, 0xfad0f050, 0xfff0f0f0, "uqsub16\t%8-11r, %16-19r, %0-3r"},
943 {ARM_EXT_V6T2, 0xfad0f060, 0xfff0f0f0, "uhsub16\t%8-11r, %16-19r, %0-3r"},
944 {ARM_EXT_V6T2, 0xfae0f000, 0xfff0f0f0, "ssubaddx\t%8-11r, %16-19r, %0-3r"},
945 {ARM_EXT_V6T2, 0xfae0f010, 0xfff0f0f0, "qsubaddx\t%8-11r, %16-19r, %0-3r"},
946 {ARM_EXT_V6T2, 0xfae0f020, 0xfff0f0f0, "shsubaddx\t%8-11r, %16-19r, %0-3r"},
947 {ARM_EXT_V6T2, 0xfae0f040, 0xfff0f0f0, "usubaddx\t%8-11r, %16-19r, %0-3r"},
948 {ARM_EXT_V6T2, 0xfae0f050, 0xfff0f0f0, "uqsubaddx\t%8-11r, %16-19r, %0-3r"},
949 {ARM_EXT_V6T2, 0xfae0f060, 0xfff0f0f0, "uhsubaddx\t%8-11r, %16-19r, %0-3r"},
950 {ARM_EXT_V6T2, 0xfb00f000, 0xfff0f0f0, "mul.w\t%8-11r, %16-19r, %0-3r"},
951 {ARM_EXT_V6T2, 0xfb70f000, 0xfff0f0f0, "usad8\t%8-11r, %16-19r, %0-3r"},
952 {ARM_EXT_V6T2, 0xfa00f000, 0xffe0f0f0, "lsl%20's.w\t%8-11r, %16-19r, %0-3r"},
953 {ARM_EXT_V6T2, 0xfa20f000, 0xffe0f0f0, "lsr%20's.w\t%8-11r, %16-19r, %0-3r"},
954 {ARM_EXT_V6T2, 0xfa40f000, 0xffe0f0f0, "asr%20's.w\t%8-11r, %16-19r, %0-3r"},
955 {ARM_EXT_V6T2, 0xfa60f000, 0xffe0f0f0, "ror%20's.w\t%8-11r, %16-19r, %0-3r"},
956 {ARM_EXT_V6T2, 0xe8c00f40, 0xfff00fe0, "strex%4?hb\t%0-3r, %12-15r, [%16-19r]"},
957 {ARM_EXT_V6T2, 0xf3200000, 0xfff0f0e0, "ssat16\t%8-11r, #%0-4d, %16-19r"},
958 {ARM_EXT_V6T2, 0xf3a00000, 0xfff0f0e0, "usat16\t%8-11r, #%0-4d, %16-19r"},
959 {ARM_EXT_V6T2, 0xfb20f000, 0xfff0f0e0, "smuad%4'x\t%8-11r, %16-19r, %0-3r"},
960 {ARM_EXT_V6T2, 0xfb30f000, 0xfff0f0e0, "smulw%4?tb\t%8-11r, %16-19r, %0-3r"},
961 {ARM_EXT_V6T2, 0xfb40f000, 0xfff0f0e0, "smusd%4'x\t%8-11r, %16-19r, %0-3r"},
962 {ARM_EXT_V6T2, 0xfb50f000, 0xfff0f0e0, "smmul%4'r\t%8-11r, %16-19r, %0-3r"},
963 {ARM_EXT_V6T2, 0xfa00f080, 0xfff0f0c0, "sxtah\t%8-11r, %16-19r, %0-3r%R"},
964 {ARM_EXT_V6T2, 0xfa10f080, 0xfff0f0c0, "uxtah\t%8-11r, %16-19r, %0-3r%R"},
965 {ARM_EXT_V6T2, 0xfa20f080, 0xfff0f0c0, "sxtab16\t%8-11r, %16-19r, %0-3r%R"},
966 {ARM_EXT_V6T2, 0xfa30f080, 0xfff0f0c0, "uxtab16\t%8-11r, %16-19r, %0-3r%R"},
967 {ARM_EXT_V6T2, 0xfa40f080, 0xfff0f0c0, "sxtab\t%8-11r, %16-19r, %0-3r%R"},
968 {ARM_EXT_V6T2, 0xfa50f080, 0xfff0f0c0, "uxtab\t%8-11r, %16-19r, %0-3r%R"},
969 {ARM_EXT_V6T2, 0xfb10f000, 0xfff0f0c0, "smul%5?tb%4?tb\t%8-11r, %16-19r, %0-3r"},
970 {ARM_EXT_V6T2, 0xf36f0000, 0xffff8020, "bfc\t%8-11r, %E"},
971 {ARM_EXT_V6T2, 0xea100f00, 0xfff08f00, "tst.w\t%16-19r, %S"},
972 {ARM_EXT_V6T2, 0xea900f00, 0xfff08f00, "teq\t%16-19r, %S"},
973 {ARM_EXT_V6T2, 0xeb100f00, 0xfff08f00, "cmn.w\t%16-19r, %S"},
974 {ARM_EXT_V6T2, 0xebb00f00, 0xfff08f00, "cmp.w\t%16-19r, %S"},
975 {ARM_EXT_V6T2, 0xf0100f00, 0xfbf08f00, "tst.w\t%16-19r, %M"},
976 {ARM_EXT_V6T2, 0xf0900f00, 0xfbf08f00, "teq\t%16-19r, %M"},
977 {ARM_EXT_V6T2, 0xf1100f00, 0xfbf08f00, "cmn.w\t%16-19r, %M"},
978 {ARM_EXT_V6T2, 0xf1b00f00, 0xfbf08f00, "cmp.w\t%16-19r, %M"},
979 {ARM_EXT_V6T2, 0xea4f0000, 0xffef8000, "mov%20's.w\t%8-11r, %S"},
980 {ARM_EXT_V6T2, 0xea6f0000, 0xffef8000, "mvn%20's.w\t%8-11r, %S"},
981 {ARM_EXT_V6T2, 0xe8c00070, 0xfff000f0, "strexd\t%0-3r, %12-15r, %8-11r, [%16-19r]"},
982 {ARM_EXT_V6T2, 0xfb000000, 0xfff000f0, "mla\t%8-11r, %16-19r, %0-3r, %12-15r"},
983 {ARM_EXT_V6T2, 0xfb000010, 0xfff000f0, "mls\t%8-11r, %16-19r, %0-3r, %12-15r"},
984 {ARM_EXT_V6T2, 0xfb700000, 0xfff000f0, "usada8\t%8-11r, %16-19r, %0-3r, %12-15r"},
985 {ARM_EXT_V6T2, 0xfb800000, 0xfff000f0, "smull\t%12-15r, %8-11r, %16-19r, %0-3r"},
986 {ARM_EXT_V6T2, 0xfba00000, 0xfff000f0, "umull\t%12-15r, %8-11r, %16-19r, %0-3r"},
987 {ARM_EXT_V6T2, 0xfbc00000, 0xfff000f0, "smlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
988 {ARM_EXT_V6T2, 0xfbe00000, 0xfff000f0, "umlal\t%12-15r, %8-11r, %16-19r, %0-3r"},
989 {ARM_EXT_V6T2, 0xfbe00060, 0xfff000f0, "umaal\t%12-15r, %8-11r, %16-19r, %0-3r"},
990 {ARM_EXT_V6T2, 0xe8500f00, 0xfff00f00, "ldrex\t%12-15r, [%16-19r, #%0-7W]"},
991 {ARM_EXT_V6T2, 0xf7f08000, 0xfff0f000, "smc\t%K"},
992 {ARM_EXT_V6T2, 0xf04f0000, 0xfbef8000, "mov%20's.w\t%8-11r, %M"},
993 {ARM_EXT_V6T2, 0xf06f0000, 0xfbef8000, "mvn%20's.w\t%8-11r, %M"},
994 {ARM_EXT_V6T2, 0xf810f000, 0xff70f000, "pld\t%a"},
995 {ARM_EXT_V6T2, 0xfb200000, 0xfff000e0, "smlad%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
996 {ARM_EXT_V6T2, 0xfb300000, 0xfff000e0, "smlaw%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
997 {ARM_EXT_V6T2, 0xfb400000, 0xfff000e0, "smlsd%4'x\t%8-11r, %16-19r, %0-3r, %12-15r"},
998 {ARM_EXT_V6T2, 0xfb500000, 0xfff000e0, "smmla%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
999 {ARM_EXT_V6T2, 0xfb600000, 0xfff000e0, "smmls%4'r\t%8-11r, %16-19r, %0-3r, %12-15r"},
1000 {ARM_EXT_V6T2, 0xfbc000c0, 0xfff000e0, "smlald%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1001 {ARM_EXT_V6T2, 0xfbd000c0, 0xfff000e0, "smlsld%4'x\t%12-15r, %8-11r, %16-19r, %0-3r"},
1002 {ARM_EXT_V6T2, 0xeac00000, 0xfff08030, "pkhbt\t%8-11r, %16-19r, %S"},
1003 {ARM_EXT_V6T2, 0xeac00020, 0xfff08030, "pkhtb\t%8-11r, %16-19r, %S"},
1004 {ARM_EXT_V6T2, 0xf3400000, 0xfff08020, "sbfx\t%8-11r, %16-19r, %F"},
1005 {ARM_EXT_V6T2, 0xf3c00000, 0xfff08020, "ubfx\t%8-11r, %16-19r, %F"},
1006 {ARM_EXT_V6T2, 0xf8000e00, 0xff900f00, "str%wt\t%12-15r, %a"},
1007 {ARM_EXT_V6T2, 0xfb100000, 0xfff000c0, "smla%5?tb%4?tb\t%8-11r, %16-19r, %0-3r, %12-15r"},
1008 {ARM_EXT_V6T2, 0xfbc00080, 0xfff000c0, "smlal%5?tb%4?tb\t%12-15r, %8-11r, %16-19r, %0-3r"},
1009 {ARM_EXT_V6T2, 0xf3600000, 0xfff08020, "bfi\t%8-11r, %16-19r, %E"},
1010 {ARM_EXT_V6T2, 0xf8100e00, 0xfe900f00, "ldr%wt\t%12-15r, %a"},
1011 {ARM_EXT_V6T2, 0xf3000000, 0xffd08020, "ssat\t%8-11r, #%0-4d, %16-19r%s"},
1012 {ARM_EXT_V6T2, 0xf3800000, 0xffd08020, "usat\t%8-11r, #%0-4d, %16-19r%s"},
1013 {ARM_EXT_V6T2, 0xf2000000, 0xfbf08000, "addw\t%8-11r, %16-19r, %I"},
1014 {ARM_EXT_V6T2, 0xf2400000, 0xfbf08000, "movw\t%8-11r, %J"},
1015 {ARM_EXT_V6T2, 0xf2a00000, 0xfbf08000, "subw\t%8-11r, %16-19r, %I"},
1016 {ARM_EXT_V6T2, 0xf2c00000, 0xfbf08000, "movt\t%8-11r, %J"},
1017 {ARM_EXT_V6T2, 0xea000000, 0xffe08000, "and%20's.w\t%8-11r, %16-19r, %S"},
1018 {ARM_EXT_V6T2, 0xea200000, 0xffe08000, "bic%20's.w\t%8-11r, %16-19r, %S"},
1019 {ARM_EXT_V6T2, 0xea400000, 0xffe08000, "orr%20's.w\t%8-11r, %16-19r, %S"},
1020 {ARM_EXT_V6T2, 0xea600000, 0xffe08000, "orn%20's\t%8-11r, %16-19r, %S"},
1021 {ARM_EXT_V6T2, 0xea800000, 0xffe08000, "eor%20's.w\t%8-11r, %16-19r, %S"},
1022 {ARM_EXT_V6T2, 0xeb000000, 0xffe08000, "add%20's.w\t%8-11r, %16-19r, %S"},
1023 {ARM_EXT_V6T2, 0xeb400000, 0xffe08000, "adc%20's.w\t%8-11r, %16-19r, %S"},
1024 {ARM_EXT_V6T2, 0xeb600000, 0xffe08000, "sbc%20's.w\t%8-11r, %16-19r, %S"},
1025 {ARM_EXT_V6T2, 0xeba00000, 0xffe08000, "sub%20's.w\t%8-11r, %16-19r, %S"},
1026 {ARM_EXT_V6T2, 0xebc00000, 0xffe08000, "rsb%20's\t%8-11r, %16-19r, %S"},
1027 {ARM_EXT_V6T2, 0xe8400000, 0xfff00000, "strex\t%8-11r, %12-15r, [%16-19r, #%0-7W]"},
1028 {ARM_EXT_V6T2, 0xf0000000, 0xfbe08000, "and%20's.w\t%8-11r, %16-19r, %M"},
1029 {ARM_EXT_V6T2, 0xf0200000, 0xfbe08000, "bic%20's.w\t%8-11r, %16-19r, %M"},
1030 {ARM_EXT_V6T2, 0xf0400000, 0xfbe08000, "orr%20's.w\t%8-11r, %16-19r, %M"},
1031 {ARM_EXT_V6T2, 0xf0600000, 0xfbe08000, "orn%20's\t%8-11r, %16-19r, %M"},
1032 {ARM_EXT_V6T2, 0xf0800000, 0xfbe08000, "eor%20's.w\t%8-11r, %16-19r, %M"},
1033 {ARM_EXT_V6T2, 0xf1000000, 0xfbe08000, "add%20's.w\t%8-11r, %16-19r, %M"},
1034 {ARM_EXT_V6T2, 0xf1400000, 0xfbe08000, "adc%20's.w\t%8-11r, %16-19r, %M"},
1035 {ARM_EXT_V6T2, 0xf1600000, 0xfbe08000, "sbc%20's.w\t%8-11r, %16-19r, %M"},
1036 {ARM_EXT_V6T2, 0xf1a00000, 0xfbe08000, "sub%20's.w\t%8-11r, %16-19r, %M"},
1037 {ARM_EXT_V6T2, 0xf1c00000, 0xfbe08000, "rsb%20's\t%8-11r, %16-19r, %M"},
1038 {ARM_EXT_V6T2, 0xe8800000, 0xffd00000, "stmia.w\t%16-19r%21'!, %m"},
1039 {ARM_EXT_V6T2, 0xe8900000, 0xffd00000, "ldmia.w\t%16-19r%21'!, %m"},
1040 {ARM_EXT_V6T2, 0xe9000000, 0xffd00000, "stmdb\t%16-19r%21'!, %m"},
1041 {ARM_EXT_V6T2, 0xe9100000, 0xffd00000, "ldmdb\t%16-19r%21'!, %m"},
1042 {ARM_EXT_V6T2, 0xe9c00000, 0xffd000ff, "strd\t%12-15r, %8-11r, [%16-19r]"},
1043 {ARM_EXT_V6T2, 0xe9d00000, 0xffd000ff, "ldrd\t%12-15r, %8-11r, [%16-19r]"},
1044 {ARM_EXT_V6T2, 0xe9400000, 0xff500000, "strd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1045 {ARM_EXT_V6T2, 0xe9500000, 0xff500000, "ldrd\t%12-15r, %8-11r, [%16-19r, #%23`-%0-7W]"},
1046 {ARM_EXT_V6T2, 0xf8000000, 0xff100000, "str%w.w\t%12-15r, %a"},
1047 {ARM_EXT_V6T2, 0xf8100000, 0xfe100000, "ldr%w.w\t%12-15r, %a"},
1049 /* Filter out Bcc with cond=E or F, which are used for other instructions. */
1050 {ARM_EXT_V6T2, 0xf3c08000, 0xfbc0d000, "undefined (bcc, cond=0xF)"},
1051 {ARM_EXT_V6T2, 0xf3808000, 0xfbc0d000, "undefined (bcc, cond=0xE)"},
1052 {ARM_EXT_V6T2, 0xf0008000, 0xf800d000, "b%22-25c.w\t%b"},
1053 {ARM_EXT_V6T2, 0xf0009000, 0xf800d000, "b.w\t%B"},
1055 /* These have been 32-bit since the invention of Thumb. */
1056 {ARM_EXT_V4T, 0xf000c000, 0xf800d000, "blx\t%B"},
1057 {ARM_EXT_V4T, 0xf000d000, 0xf800d000, "bl\t%B"},
1059 /* Fallback. */
1060 {ARM_EXT_V1, 0x00000000, 0x00000000, "undefined"},
1061 {0, 0, 0, 0}
1064 static const char *const arm_conditional[] =
1065 {"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
1066 "hi", "ls", "ge", "lt", "gt", "le", "", "<und>"};
1068 static const char *const arm_fp_const[] =
1069 {"0.0", "1.0", "2.0", "3.0", "4.0", "5.0", "0.5", "10.0"};
1071 static const char *const arm_shift[] =
1072 {"lsl", "lsr", "asr", "ror"};
1074 typedef struct
1076 const char *name;
1077 const char *description;
1078 const char *reg_names[16];
1080 arm_regname;
1082 static const arm_regname regnames[] =
1084 { "raw" , "Select raw register names",
1085 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"}},
1086 { "gcc", "Select register names used by GCC",
1087 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "sl", "fp", "ip", "sp", "lr", "pc" }},
1088 { "std", "Select register names used in ARM's ISA documentation",
1089 { "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "sp", "lr", "pc" }},
1090 { "apcs", "Select register names used in the APCS",
1091 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "sl", "fp", "ip", "sp", "lr", "pc" }},
1092 { "atpcs", "Select register names used in the ATPCS",
1093 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "IP", "SP", "LR", "PC" }},
1094 { "special-atpcs", "Select special register names used in the ATPCS",
1095 { "a1", "a2", "a3", "a4", "v1", "v2", "v3", "WR", "v5", "SB", "SL", "FP", "IP", "SP", "LR", "PC" }},
1098 static const char *const iwmmxt_wwnames[] =
1099 {"b", "h", "w", "d"};
1101 static const char *const iwmmxt_wwssnames[] =
1102 {"b", "bus", "b", "bss",
1103 "h", "hus", "h", "hss",
1104 "w", "wus", "w", "wss",
1105 "d", "dus", "d", "dss"
1108 static const char *const iwmmxt_regnames[] =
1109 { "wr0", "wr1", "wr2", "wr3", "wr4", "wr5", "wr6", "wr7",
1110 "wr8", "wr9", "wr10", "wr11", "wr12", "wr13", "wr14", "wr15"
1113 static const char *const iwmmxt_cregnames[] =
1114 { "wcid", "wcon", "wcssf", "wcasf", "reserved", "reserved", "reserved", "reserved",
1115 "wcgr0", "wcgr1", "wcgr2", "wcgr3", "reserved", "reserved", "reserved", "reserved"
1118 /* Default to GCC register name set. */
1119 static unsigned int regname_selected = 1;
1121 #define NUM_ARM_REGNAMES NUM_ELEM (regnames)
1122 #define arm_regnames regnames[regname_selected].reg_names
1124 static bfd_boolean force_thumb = FALSE;
1127 /* Functions. */
1129 get_arm_regname_num_options (void)
1131 return NUM_ARM_REGNAMES;
1135 set_arm_regname_option (int option)
1137 int old = regname_selected;
1138 regname_selected = option;
1139 return old;
1143 get_arm_regnames (int option, const char **setname, const char **setdescription,
1144 const char *const **register_names)
1146 *setname = regnames[option].name;
1147 *setdescription = regnames[option].description;
1148 *register_names = regnames[option].reg_names;
1149 return 16;
1152 static void
1153 arm_decode_shift (long given, fprintf_ftype func, void *stream)
1155 func (stream, "%s", arm_regnames[given & 0xf]);
1157 if ((given & 0xff0) != 0)
1159 if ((given & 0x10) == 0)
1161 int amount = (given & 0xf80) >> 7;
1162 int shift = (given & 0x60) >> 5;
1164 if (amount == 0)
1166 if (shift == 3)
1168 func (stream, ", rrx");
1169 return;
1172 amount = 32;
1175 func (stream, ", %s #%d", arm_shift[shift], amount);
1177 else
1178 func (stream, ", %s %s", arm_shift[(given & 0x60) >> 5],
1179 arm_regnames[(given & 0xf00) >> 8]);
1183 /* Print one coprocessor instruction on INFO->STREAM.
1184 Return TRUE if the instuction matched, FALSE if this is not a
1185 recognised coprocessor instruction. */
1187 static bfd_boolean
1188 print_insn_coprocessor (struct disassemble_info *info, long given,
1189 bfd_boolean thumb)
1191 const struct opcode32 *insn;
1192 void *stream = info->stream;
1193 fprintf_ftype func = info->fprintf_func;
1194 unsigned long mask;
1195 unsigned long value;
1197 for (insn = coprocessor_opcodes; insn->assembler; insn++)
1199 if (insn->value == FIRST_IWMMXT_INSN
1200 && info->mach != bfd_mach_arm_XScale
1201 && info->mach != bfd_mach_arm_iWMMXt)
1202 insn = insn + IWMMXT_INSN_COUNT;
1204 mask = insn->mask;
1205 value = insn->value;
1206 if (thumb)
1208 /* The high 4 bits are 0xe for Arm conditional instructions, and
1209 0xe for arm unconditional instructions. The rest of the
1210 encoding is the same. */
1211 mask |= 0xf0000000;
1212 value |= 0xe0000000;
1214 else
1216 /* Only match unconditional instuctions against unconditional
1217 patterns. */
1218 if ((given & 0xf0000000) == 0xf0000000)
1219 mask |= 0xf0000000;
1221 if ((given & mask) == value)
1223 const char *c;
1225 for (c = insn->assembler; *c; c++)
1227 if (*c == '%')
1229 switch (*++c)
1231 case '%':
1232 func (stream, "%%");
1233 break;
1235 case 'A':
1236 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1238 if ((given & (1 << 24)) != 0)
1240 int offset = given & 0xff;
1242 if (offset)
1243 func (stream, ", #%s%d]%s",
1244 ((given & 0x00800000) == 0 ? "-" : ""),
1245 offset * 4,
1246 ((given & 0x00200000) != 0 ? "!" : ""));
1247 else
1248 func (stream, "]");
1250 else
1252 int offset = given & 0xff;
1254 func (stream, "]");
1256 if (given & (1 << 21))
1258 if (offset)
1259 func (stream, ", #%s%d",
1260 ((given & 0x00800000) == 0 ? "-" : ""),
1261 offset * 4);
1263 else
1264 func (stream, ", {%d}", offset);
1266 break;
1268 case 'c':
1269 func (stream, "%s",
1270 arm_conditional [(given >> 28) & 0xf]);
1271 break;
1273 case 'I':
1274 /* Print a Cirrus/DSP shift immediate. */
1275 /* Immediates are 7bit signed ints with bits 0..3 in
1276 bits 0..3 of opcode and bits 4..6 in bits 5..7
1277 of opcode. */
1279 int imm;
1281 imm = (given & 0xf) | ((given & 0xe0) >> 1);
1283 /* Is ``imm'' a negative number? */
1284 if (imm & 0x40)
1285 imm |= (-1 << 7);
1287 func (stream, "%d", imm);
1290 break;
1292 case 'F':
1293 switch (given & 0x00408000)
1295 case 0:
1296 func (stream, "4");
1297 break;
1298 case 0x8000:
1299 func (stream, "1");
1300 break;
1301 case 0x00400000:
1302 func (stream, "2");
1303 break;
1304 default:
1305 func (stream, "3");
1307 break;
1309 case 'P':
1310 switch (given & 0x00080080)
1312 case 0:
1313 func (stream, "s");
1314 break;
1315 case 0x80:
1316 func (stream, "d");
1317 break;
1318 case 0x00080000:
1319 func (stream, "e");
1320 break;
1321 default:
1322 func (stream, _("<illegal precision>"));
1323 break;
1325 break;
1326 case 'Q':
1327 switch (given & 0x00408000)
1329 case 0:
1330 func (stream, "s");
1331 break;
1332 case 0x8000:
1333 func (stream, "d");
1334 break;
1335 case 0x00400000:
1336 func (stream, "e");
1337 break;
1338 default:
1339 func (stream, "p");
1340 break;
1342 break;
1343 case 'R':
1344 switch (given & 0x60)
1346 case 0:
1347 break;
1348 case 0x20:
1349 func (stream, "p");
1350 break;
1351 case 0x40:
1352 func (stream, "m");
1353 break;
1354 default:
1355 func (stream, "z");
1356 break;
1358 break;
1360 case '0': case '1': case '2': case '3': case '4':
1361 case '5': case '6': case '7': case '8': case '9':
1363 int bitstart = *c++ - '0';
1364 int bitend = 0;
1365 while (*c >= '0' && *c <= '9')
1366 bitstart = (bitstart * 10) + *c++ - '0';
1368 switch (*c)
1370 case '-':
1371 c++;
1373 while (*c >= '0' && *c <= '9')
1374 bitend = (bitend * 10) + *c++ - '0';
1376 if (!bitend)
1377 abort ();
1379 switch (*c)
1381 case 'r':
1383 long reg;
1385 reg = given >> bitstart;
1386 reg &= (2 << (bitend - bitstart)) - 1;
1388 func (stream, "%s", arm_regnames[reg]);
1390 break;
1391 case 'd':
1393 long reg;
1395 reg = given >> bitstart;
1396 reg &= (2 << (bitend - bitstart)) - 1;
1398 func (stream, "%ld", reg);
1400 break;
1401 case 'f':
1403 long reg;
1405 reg = given >> bitstart;
1406 reg &= (2 << (bitend - bitstart)) - 1;
1408 if (reg > 7)
1409 func (stream, "#%s",
1410 arm_fp_const[reg & 7]);
1411 else
1412 func (stream, "f%ld", reg);
1414 break;
1416 case 'w':
1418 long reg;
1420 if (bitstart != bitend)
1422 reg = given >> bitstart;
1423 reg &= (2 << (bitend - bitstart)) - 1;
1424 if (bitend - bitstart == 1)
1425 func (stream, "%s", iwmmxt_wwnames[reg]);
1426 else
1427 func (stream, "%s", iwmmxt_wwssnames[reg]);
1429 else
1431 reg = (((given >> 8) & 0x1) |
1432 ((given >> 22) & 0x1));
1433 func (stream, "%s", iwmmxt_wwnames[reg]);
1436 break;
1438 case 'g':
1440 long reg;
1441 reg = given >> bitstart;
1442 reg &= (2 << (bitend - bitstart)) - 1;
1443 func (stream, "%s", iwmmxt_regnames[reg]);
1445 break;
1447 case 'G':
1449 long reg;
1450 reg = given >> bitstart;
1451 reg &= (2 << (bitend - bitstart)) - 1;
1452 func (stream, "%s", iwmmxt_cregnames[reg]);
1454 break;
1456 default:
1457 abort ();
1459 break;
1461 case 'y':
1462 case 'z':
1464 int single = *c == 'y';
1465 int regno;
1467 switch (bitstart)
1469 case 4: /* Sm pair */
1470 func (stream, "{");
1471 /* Fall through. */
1472 case 0: /* Sm, Dm */
1473 regno = given & 0x0000000f;
1474 if (single)
1476 regno <<= 1;
1477 regno += (given >> 5) & 1;
1479 break;
1481 case 1: /* Sd, Dd */
1482 regno = (given >> 12) & 0x0000000f;
1483 if (single)
1485 regno <<= 1;
1486 regno += (given >> 22) & 1;
1488 break;
1490 case 2: /* Sn, Dn */
1491 regno = (given >> 16) & 0x0000000f;
1492 if (single)
1494 regno <<= 1;
1495 regno += (given >> 7) & 1;
1497 break;
1499 case 3: /* List */
1500 func (stream, "{");
1501 regno = (given >> 12) & 0x0000000f;
1502 if (single)
1504 regno <<= 1;
1505 regno += (given >> 22) & 1;
1507 break;
1510 default:
1511 abort ();
1514 func (stream, "%c%d", single ? 's' : 'd', regno);
1516 if (bitstart == 3)
1518 int count = given & 0xff;
1520 if (single == 0)
1521 count >>= 1;
1523 if (--count)
1525 func (stream, "-%c%d",
1526 single ? 's' : 'd',
1527 regno + count);
1530 func (stream, "}");
1532 else if (bitstart == 4)
1533 func (stream, ", %c%d}", single ? 's' : 'd',
1534 regno + 1);
1536 break;
1539 break;
1541 case '`':
1542 c++;
1543 if ((given & (1 << bitstart)) == 0)
1544 func (stream, "%c", *c);
1545 break;
1546 case '\'':
1547 c++;
1548 if ((given & (1 << bitstart)) != 0)
1549 func (stream, "%c", *c);
1550 break;
1551 case '?':
1552 ++c;
1553 if ((given & (1 << bitstart)) != 0)
1554 func (stream, "%c", *c++);
1555 else
1556 func (stream, "%c", *++c);
1557 break;
1558 default:
1559 abort ();
1561 break;
1563 case 'L':
1564 switch (given & 0x00400100)
1566 case 0x00000000: func (stream, "b"); break;
1567 case 0x00400000: func (stream, "h"); break;
1568 case 0x00000100: func (stream, "w"); break;
1569 case 0x00400100: func (stream, "d"); break;
1570 default:
1571 break;
1573 break;
1575 case 'Z':
1577 int value;
1578 /* given (20, 23) | given (0, 3) */
1579 value = ((given >> 16) & 0xf0) | (given & 0xf);
1580 func (stream, "%d", value);
1582 break;
1584 case 'l':
1585 /* This is like the 'A' operator, except that if
1586 the width field "M" is zero, then the offset is
1587 *not* multiplied by four. */
1589 int offset = given & 0xff;
1590 int multiplier = (given & 0x00000100) ? 4 : 1;
1592 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1594 if (offset)
1596 if ((given & 0x01000000) != 0)
1597 func (stream, ", #%s%d]%s",
1598 ((given & 0x00800000) == 0 ? "-" : ""),
1599 offset * multiplier,
1600 ((given & 0x00200000) != 0 ? "!" : ""));
1601 else
1602 func (stream, "], #%s%d",
1603 ((given & 0x00800000) == 0 ? "-" : ""),
1604 offset * multiplier);
1606 else
1607 func (stream, "]");
1609 break;
1611 default:
1612 abort ();
1616 else
1617 func (stream, "%c", *c);
1619 return TRUE;
1622 return FALSE;
1625 static void
1626 print_arm_address (bfd_vma pc, struct disassemble_info *info, long given)
1628 void *stream = info->stream;
1629 fprintf_ftype func = info->fprintf_func;
1631 if (((given & 0x000f0000) == 0x000f0000)
1632 && ((given & 0x02000000) == 0))
1634 int offset = given & 0xfff;
1636 func (stream, "[pc");
1638 if (given & 0x01000000)
1640 if ((given & 0x00800000) == 0)
1641 offset = - offset;
1643 /* Pre-indexed. */
1644 func (stream, ", #%d]", offset);
1646 offset += pc + 8;
1648 /* Cope with the possibility of write-back
1649 being used. Probably a very dangerous thing
1650 for the programmer to do, but who are we to
1651 argue ? */
1652 if (given & 0x00200000)
1653 func (stream, "!");
1655 else
1657 /* Post indexed. */
1658 func (stream, "], #%d", offset);
1660 /* ie ignore the offset. */
1661 offset = pc + 8;
1664 func (stream, "\t; ");
1665 info->print_address_func (offset, info);
1667 else
1669 func (stream, "[%s",
1670 arm_regnames[(given >> 16) & 0xf]);
1671 if ((given & 0x01000000) != 0)
1673 if ((given & 0x02000000) == 0)
1675 int offset = given & 0xfff;
1676 if (offset)
1677 func (stream, ", #%s%d",
1678 (((given & 0x00800000) == 0)
1679 ? "-" : ""), offset);
1681 else
1683 func (stream, ", %s",
1684 (((given & 0x00800000) == 0)
1685 ? "-" : ""));
1686 arm_decode_shift (given, func, stream);
1689 func (stream, "]%s",
1690 ((given & 0x00200000) != 0) ? "!" : "");
1692 else
1694 if ((given & 0x02000000) == 0)
1696 int offset = given & 0xfff;
1697 if (offset)
1698 func (stream, "], #%s%d",
1699 (((given & 0x00800000) == 0)
1700 ? "-" : ""), offset);
1701 else
1702 func (stream, "]");
1704 else
1706 func (stream, "], %s",
1707 (((given & 0x00800000) == 0)
1708 ? "-" : ""));
1709 arm_decode_shift (given, func, stream);
1715 /* Print one ARM instruction from PC on INFO->STREAM. */
1717 static void
1718 print_insn_arm (bfd_vma pc, struct disassemble_info *info, long given)
1720 const struct opcode32 *insn;
1721 void *stream = info->stream;
1722 fprintf_ftype func = info->fprintf_func;
1724 if (print_insn_coprocessor (info, given, FALSE))
1725 return;
1727 for (insn = arm_opcodes; insn->assembler; insn++)
1729 if (insn->value == FIRST_IWMMXT_INSN
1730 && info->mach != bfd_mach_arm_XScale
1731 && info->mach != bfd_mach_arm_iWMMXt)
1732 insn = insn + IWMMXT_INSN_COUNT;
1734 if ((given & insn->mask) == insn->value
1735 /* Special case: an instruction with all bits set in the condition field
1736 (0xFnnn_nnnn) is only matched if all those bits are set in insn->mask,
1737 or by the catchall at the end of the table. */
1738 && ((given & 0xF0000000) != 0xF0000000
1739 || (insn->mask & 0xF0000000) == 0xF0000000
1740 || (insn->mask == 0 && insn->value == 0)))
1742 const char *c;
1744 for (c = insn->assembler; *c; c++)
1746 if (*c == '%')
1748 switch (*++c)
1750 case '%':
1751 func (stream, "%%");
1752 break;
1754 case 'a':
1755 print_arm_address (pc, info, given);
1756 break;
1758 case 'P':
1759 /* Set P address bit and use normal address
1760 printing routine. */
1761 print_arm_address (pc, info, given | (1 << 24));
1762 break;
1764 case 's':
1765 if ((given & 0x004f0000) == 0x004f0000)
1767 /* PC relative with immediate offset. */
1768 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1770 if ((given & 0x00800000) == 0)
1771 offset = -offset;
1773 func (stream, "[pc, #%d]\t; ", offset);
1774 info->print_address_func (offset + pc + 8, info);
1776 else
1778 func (stream, "[%s",
1779 arm_regnames[(given >> 16) & 0xf]);
1780 if ((given & 0x01000000) != 0)
1782 /* Pre-indexed. */
1783 if ((given & 0x00400000) == 0x00400000)
1785 /* Immediate. */
1786 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1787 if (offset)
1788 func (stream, ", #%s%d",
1789 (((given & 0x00800000) == 0)
1790 ? "-" : ""), offset);
1792 else
1794 /* Register. */
1795 func (stream, ", %s%s",
1796 (((given & 0x00800000) == 0)
1797 ? "-" : ""),
1798 arm_regnames[given & 0xf]);
1801 func (stream, "]%s",
1802 ((given & 0x00200000) != 0) ? "!" : "");
1804 else
1806 /* Post-indexed. */
1807 if ((given & 0x00400000) == 0x00400000)
1809 /* Immediate. */
1810 int offset = ((given & 0xf00) >> 4) | (given & 0xf);
1811 if (offset)
1812 func (stream, "], #%s%d",
1813 (((given & 0x00800000) == 0)
1814 ? "-" : ""), offset);
1815 else
1816 func (stream, "]");
1818 else
1820 /* Register. */
1821 func (stream, "], %s%s",
1822 (((given & 0x00800000) == 0)
1823 ? "-" : ""),
1824 arm_regnames[given & 0xf]);
1828 break;
1830 case 'b':
1832 int disp = (((given & 0xffffff) ^ 0x800000) - 0x800000);
1833 info->print_address_func (disp*4 + pc + 8, info);
1835 break;
1837 case 'c':
1838 func (stream, "%s",
1839 arm_conditional [(given >> 28) & 0xf]);
1840 break;
1842 case 'm':
1844 int started = 0;
1845 int reg;
1847 func (stream, "{");
1848 for (reg = 0; reg < 16; reg++)
1849 if ((given & (1 << reg)) != 0)
1851 if (started)
1852 func (stream, ", ");
1853 started = 1;
1854 func (stream, "%s", arm_regnames[reg]);
1856 func (stream, "}");
1858 break;
1860 case 'o':
1861 if ((given & 0x02000000) != 0)
1863 int rotate = (given & 0xf00) >> 7;
1864 int immed = (given & 0xff);
1865 immed = (((immed << (32 - rotate))
1866 | (immed >> rotate)) & 0xffffffff);
1867 func (stream, "#%d\t; 0x%x", immed, immed);
1869 else
1870 arm_decode_shift (given, func, stream);
1871 break;
1873 case 'p':
1874 if ((given & 0x0000f000) == 0x0000f000)
1875 func (stream, "p");
1876 break;
1878 case 't':
1879 if ((given & 0x01200000) == 0x00200000)
1880 func (stream, "t");
1881 break;
1883 case 'A':
1884 func (stream, "[%s", arm_regnames [(given >> 16) & 0xf]);
1886 if ((given & (1 << 24)) != 0)
1888 int offset = given & 0xff;
1890 if (offset)
1891 func (stream, ", #%s%d]%s",
1892 ((given & 0x00800000) == 0 ? "-" : ""),
1893 offset * 4,
1894 ((given & 0x00200000) != 0 ? "!" : ""));
1895 else
1896 func (stream, "]");
1898 else
1900 int offset = given & 0xff;
1902 func (stream, "]");
1904 if (given & (1 << 21))
1906 if (offset)
1907 func (stream, ", #%s%d",
1908 ((given & 0x00800000) == 0 ? "-" : ""),
1909 offset * 4);
1911 else
1912 func (stream, ", {%d}", offset);
1914 break;
1916 case 'B':
1917 /* Print ARM V5 BLX(1) address: pc+25 bits. */
1919 bfd_vma address;
1920 bfd_vma offset = 0;
1922 if (given & 0x00800000)
1923 /* Is signed, hi bits should be ones. */
1924 offset = (-1) ^ 0x00ffffff;
1926 /* Offset is (SignExtend(offset field)<<2). */
1927 offset += given & 0x00ffffff;
1928 offset <<= 2;
1929 address = offset + pc + 8;
1931 if (given & 0x01000000)
1932 /* H bit allows addressing to 2-byte boundaries. */
1933 address += 2;
1935 info->print_address_func (address, info);
1937 break;
1939 case 'C':
1940 func (stream, "_");
1941 if (given & 0x80000)
1942 func (stream, "f");
1943 if (given & 0x40000)
1944 func (stream, "s");
1945 if (given & 0x20000)
1946 func (stream, "x");
1947 if (given & 0x10000)
1948 func (stream, "c");
1949 break;
1951 case 'U':
1952 switch (given & 0xf)
1954 case 0xf: func(stream, "sy"); break;
1955 case 0x7: func(stream, "un"); break;
1956 case 0xe: func(stream, "st"); break;
1957 case 0x6: func(stream, "unst"); break;
1958 default:
1959 func(stream, "#%d", (int)given & 0xf);
1960 break;
1962 break;
1964 case '0': case '1': case '2': case '3': case '4':
1965 case '5': case '6': case '7': case '8': case '9':
1967 int bitstart = *c++ - '0';
1968 int bitend = 0;
1969 while (*c >= '0' && *c <= '9')
1970 bitstart = (bitstart * 10) + *c++ - '0';
1972 switch (*c)
1974 case '-':
1975 c++;
1977 while (*c >= '0' && *c <= '9')
1978 bitend = (bitend * 10) + *c++ - '0';
1980 if (!bitend)
1981 abort ();
1983 switch (*c)
1985 case 'r':
1987 long reg;
1989 reg = given >> bitstart;
1990 reg &= (2 << (bitend - bitstart)) - 1;
1992 func (stream, "%s", arm_regnames[reg]);
1994 break;
1995 case 'd':
1997 long reg;
1999 reg = given >> bitstart;
2000 reg &= (2 << (bitend - bitstart)) - 1;
2002 func (stream, "%ld", reg);
2004 break;
2005 case 'W':
2007 long reg;
2009 reg = given >> bitstart;
2010 reg &= (2 << (bitend - bitstart)) - 1;
2012 func (stream, "%ld", reg + 1);
2014 break;
2015 case 'x':
2017 long reg;
2019 reg = given >> bitstart;
2020 reg &= (2 << (bitend - bitstart)) - 1;
2022 func (stream, "0x%08lx", reg);
2024 /* Some SWI instructions have special
2025 meanings. */
2026 if ((given & 0x0fffffff) == 0x0FF00000)
2027 func (stream, "\t; IMB");
2028 else if ((given & 0x0fffffff) == 0x0FF00001)
2029 func (stream, "\t; IMBRange");
2031 break;
2032 case 'X':
2034 long reg;
2036 reg = given >> bitstart;
2037 reg &= (2 << (bitend - bitstart)) - 1;
2039 func (stream, "%01lx", reg & 0xf);
2041 break;
2042 default:
2043 abort ();
2045 break;
2047 case '`':
2048 c++;
2049 if ((given & (1 << bitstart)) == 0)
2050 func (stream, "%c", *c);
2051 break;
2052 case '\'':
2053 c++;
2054 if ((given & (1 << bitstart)) != 0)
2055 func (stream, "%c", *c);
2056 break;
2057 case '?':
2058 ++c;
2059 if ((given & (1 << bitstart)) != 0)
2060 func (stream, "%c", *c++);
2061 else
2062 func (stream, "%c", *++c);
2063 break;
2064 default:
2065 abort ();
2067 break;
2069 case 'e':
2071 int imm;
2073 imm = (given & 0xf) | ((given & 0xfff00) >> 4);
2074 func (stream, "%d", imm);
2076 break;
2078 case 'E':
2079 /* LSB and WIDTH fields of BFI or BFC. The machine-
2080 language instruction encodes LSB and MSB. */
2082 long msb = (given & 0x001f0000) >> 16;
2083 long lsb = (given & 0x00000f80) >> 7;
2085 long width = msb - lsb + 1;
2086 if (width > 0)
2087 func (stream, "#%lu, #%lu", lsb, width);
2088 else
2089 func (stream, "(invalid: %lu:%lu)", lsb, msb);
2091 break;
2093 case 'V':
2094 /* 16-bit unsigned immediate from a MOVT or MOVW
2095 instruction, encoded in bits 0:11 and 15:19. */
2097 long hi = (given & 0x000f0000) >> 4;
2098 long lo = (given & 0x00000fff);
2099 long imm16 = hi | lo;
2100 func (stream, "#%lu\t; 0x%lx", imm16, imm16);
2102 break;
2104 default:
2105 abort ();
2109 else
2110 func (stream, "%c", *c);
2112 return;
2115 abort ();
2118 /* Print one 16-bit Thumb instruction from PC on INFO->STREAM. */
2120 static void
2121 print_insn_thumb16 (bfd_vma pc, struct disassemble_info *info, long given)
2123 const struct opcode16 *insn;
2124 void *stream = info->stream;
2125 fprintf_ftype func = info->fprintf_func;
2127 for (insn = thumb_opcodes; insn->assembler; insn++)
2128 if ((given & insn->mask) == insn->value)
2130 const char *c = insn->assembler;
2131 for (; *c; c++)
2133 int domaskpc = 0;
2134 int domasklr = 0;
2136 if (*c != '%')
2138 func (stream, "%c", *c);
2139 continue;
2142 switch (*++c)
2144 case '%':
2145 func (stream, "%%");
2146 break;
2148 case 'S':
2150 long reg;
2152 reg = (given >> 3) & 0x7;
2153 if (given & (1 << 6))
2154 reg += 8;
2156 func (stream, "%s", arm_regnames[reg]);
2158 break;
2160 case 'D':
2162 long reg;
2164 reg = given & 0x7;
2165 if (given & (1 << 7))
2166 reg += 8;
2168 func (stream, "%s", arm_regnames[reg]);
2170 break;
2172 case 'N':
2173 if (given & (1 << 8))
2174 domasklr = 1;
2175 /* Fall through. */
2176 case 'O':
2177 if (*c == 'O' && (given & (1 << 8)))
2178 domaskpc = 1;
2179 /* Fall through. */
2180 case 'M':
2182 int started = 0;
2183 int reg;
2185 func (stream, "{");
2187 /* It would be nice if we could spot
2188 ranges, and generate the rS-rE format: */
2189 for (reg = 0; (reg < 8); reg++)
2190 if ((given & (1 << reg)) != 0)
2192 if (started)
2193 func (stream, ", ");
2194 started = 1;
2195 func (stream, "%s", arm_regnames[reg]);
2198 if (domasklr)
2200 if (started)
2201 func (stream, ", ");
2202 started = 1;
2203 func (stream, arm_regnames[14] /* "lr" */);
2206 if (domaskpc)
2208 if (started)
2209 func (stream, ", ");
2210 func (stream, arm_regnames[15] /* "pc" */);
2213 func (stream, "}");
2215 break;
2217 case 'b':
2218 /* Print ARM V6T2 CZB address: pc+4+6 bits. */
2220 bfd_vma address = (pc + 4
2221 + ((given & 0x00f8) >> 2)
2222 + ((given & 0x0200) >> 3));
2223 info->print_address_func (address, info);
2225 break;
2227 case 's':
2228 /* Right shift immediate -- bits 6..10; 1-31 print
2229 as themselves, 0 prints as 32. */
2231 long imm = (given & 0x07c0) >> 6;
2232 if (imm == 0)
2233 imm = 32;
2234 func (stream, "#%ld", imm);
2236 break;
2238 case '0': case '1': case '2': case '3': case '4':
2239 case '5': case '6': case '7': case '8': case '9':
2241 int bitstart = *c++ - '0';
2242 int bitend = 0;
2244 while (*c >= '0' && *c <= '9')
2245 bitstart = (bitstart * 10) + *c++ - '0';
2247 switch (*c)
2249 case '-':
2251 long reg;
2253 c++;
2254 while (*c >= '0' && *c <= '9')
2255 bitend = (bitend * 10) + *c++ - '0';
2256 if (!bitend)
2257 abort ();
2258 reg = given >> bitstart;
2259 reg &= (2 << (bitend - bitstart)) - 1;
2260 switch (*c)
2262 case 'r':
2263 func (stream, "%s", arm_regnames[reg]);
2264 break;
2266 case 'd':
2267 func (stream, "%ld", reg);
2268 break;
2270 case 'H':
2271 func (stream, "%ld", reg << 1);
2272 break;
2274 case 'W':
2275 func (stream, "%ld", reg << 2);
2276 break;
2278 case 'a':
2279 /* PC-relative address -- the bottom two
2280 bits of the address are dropped
2281 before the calculation. */
2282 info->print_address_func
2283 (((pc + 4) & ~3) + (reg << 2), info);
2284 break;
2286 case 'x':
2287 func (stream, "0x%04lx", reg);
2288 break;
2290 case 'B':
2291 reg = ((reg ^ (1 << bitend)) - (1 << bitend));
2292 info->print_address_func (reg * 2 + pc + 4, info);
2293 break;
2295 case 'c':
2297 /* Must print 0xE as 'al' to distinguish
2298 unconditional B from conditional BAL. */
2299 if (reg == 0xE)
2300 func (stream, "al");
2301 else
2302 func (stream, "%s", arm_conditional [reg]);
2304 break;
2306 default:
2307 abort ();
2310 break;
2312 case '\'':
2313 c++;
2314 if ((given & (1 << bitstart)) != 0)
2315 func (stream, "%c", *c);
2316 break;
2318 case '?':
2319 ++c;
2320 if ((given & (1 << bitstart)) != 0)
2321 func (stream, "%c", *c++);
2322 else
2323 func (stream, "%c", *++c);
2324 break;
2326 default:
2327 abort ();
2330 break;
2332 default:
2333 abort ();
2336 return;
2339 /* No match. */
2340 abort ();
2343 /* Return the name of an V7M special register. */
2344 static const char *
2345 psr_name (int regno)
2347 switch (regno)
2349 case 0: return "APSR";
2350 case 1: return "IAPSR";
2351 case 2: return "EAPSR";
2352 case 3: return "PSR";
2353 case 5: return "IPSR";
2354 case 6: return "EPSR";
2355 case 7: return "IEPSR";
2356 case 8: return "MSP";
2357 case 9: return "PSP";
2358 case 16: return "PRIMASK";
2359 case 17: return "BASEPRI";
2360 case 18: return "BASEPRI_MASK";
2361 case 19: return "FAULTMASK";
2362 case 20: return "CONTROL";
2363 default: return "<unknown>";
2367 /* Print one 32-bit Thumb instruction from PC on INFO->STREAM. */
2369 static void
2370 print_insn_thumb32 (bfd_vma pc, struct disassemble_info *info, long given)
2372 const struct opcode32 *insn;
2373 void *stream = info->stream;
2374 fprintf_ftype func = info->fprintf_func;
2376 if (print_insn_coprocessor (info, given, TRUE))
2377 return;
2379 for (insn = thumb32_opcodes; insn->assembler; insn++)
2380 if ((given & insn->mask) == insn->value)
2382 const char *c = insn->assembler;
2383 for (; *c; c++)
2385 if (*c != '%')
2387 func (stream, "%c", *c);
2388 continue;
2391 switch (*++c)
2393 case '%':
2394 func (stream, "%%");
2395 break;
2397 case 'I':
2399 unsigned int imm12 = 0;
2400 imm12 |= (given & 0x000000ffu);
2401 imm12 |= (given & 0x00007000u) >> 4;
2402 imm12 |= (given & 0x04000000u) >> 15;
2403 func (stream, "#%u\t; 0x%x", imm12, imm12);
2405 break;
2407 case 'M':
2409 unsigned int bits = 0, imm, imm8, mod;
2410 bits |= (given & 0x000000ffu);
2411 bits |= (given & 0x00007000u) >> 4;
2412 bits |= (given & 0x04000000u) >> 15;
2413 imm8 = (bits & 0x0ff);
2414 mod = (bits & 0xf00) >> 8;
2415 switch (mod)
2417 case 0: imm = imm8; break;
2418 case 1: imm = ((imm8<<16) | imm8); break;
2419 case 2: imm = ((imm8<<24) | (imm8 << 8)); break;
2420 case 3: imm = ((imm8<<24) | (imm8 << 16) | (imm8 << 8) | imm8); break;
2421 default:
2422 mod = (bits & 0xf80) >> 7;
2423 imm8 = (bits & 0x07f) | 0x80;
2424 imm = (((imm8 << (32 - mod)) | (imm8 >> mod)) & 0xffffffff);
2426 func (stream, "#%u\t; 0x%x", imm, imm);
2428 break;
2430 case 'J':
2432 unsigned int imm = 0;
2433 imm |= (given & 0x000000ffu);
2434 imm |= (given & 0x00007000u) >> 4;
2435 imm |= (given & 0x04000000u) >> 15;
2436 imm |= (given & 0x000f0000u) >> 4;
2437 func (stream, "#%u\t; 0x%x", imm, imm);
2439 break;
2441 case 'K':
2443 unsigned int imm = 0;
2444 imm |= (given & 0x000f0000u) >> 16;
2445 imm |= (given & 0x00000ff0u) >> 0;
2446 imm |= (given & 0x0000000fu) << 12;
2447 func (stream, "#%u\t; 0x%x", imm, imm);
2449 break;
2451 case 'S':
2453 unsigned int reg = (given & 0x0000000fu);
2454 unsigned int stp = (given & 0x00000030u) >> 4;
2455 unsigned int imm = 0;
2456 imm |= (given & 0x000000c0u) >> 6;
2457 imm |= (given & 0x00007000u) >> 10;
2459 func (stream, "%s", arm_regnames[reg]);
2460 switch (stp)
2462 case 0:
2463 if (imm > 0)
2464 func (stream, ", lsl #%u", imm);
2465 break;
2467 case 1:
2468 if (imm == 0)
2469 imm = 32;
2470 func (stream, ", lsr #%u", imm);
2471 break;
2473 case 2:
2474 if (imm == 0)
2475 imm = 32;
2476 func (stream, ", asr #%u", imm);
2477 break;
2479 case 3:
2480 if (imm == 0)
2481 func (stream, ", rrx");
2482 else
2483 func (stream, ", ror #%u", imm);
2486 break;
2488 case 'a':
2490 unsigned int Rn = (given & 0x000f0000) >> 16;
2491 unsigned int U = (given & 0x00800000) >> 23;
2492 unsigned int op = (given & 0x00000f00) >> 8;
2493 unsigned int i12 = (given & 0x00000fff);
2494 unsigned int i8 = (given & 0x000000ff);
2495 bfd_boolean writeback = FALSE, postind = FALSE;
2496 int offset = 0;
2498 func (stream, "[%s", arm_regnames[Rn]);
2499 if (U) /* 12-bit positive immediate offset */
2500 offset = i12;
2501 else if (Rn == 15) /* 12-bit negative immediate offset */
2502 offset = -(int)i12;
2503 else if (op == 0x0) /* shifted register offset */
2505 unsigned int Rm = (i8 & 0x0f);
2506 unsigned int sh = (i8 & 0x30) >> 4;
2507 func (stream, ", %s", arm_regnames[Rm]);
2508 if (sh)
2509 func (stream, ", lsl #%u", sh);
2510 func (stream, "]");
2511 break;
2513 else switch (op)
2515 case 0xE: /* 8-bit positive immediate offset */
2516 offset = i8;
2517 break;
2519 case 0xC: /* 8-bit negative immediate offset */
2520 offset = -i8;
2521 break;
2523 case 0xF: /* 8-bit + preindex with wb */
2524 offset = i8;
2525 writeback = TRUE;
2526 break;
2528 case 0xD: /* 8-bit - preindex with wb */
2529 offset = -i8;
2530 writeback = TRUE;
2531 break;
2533 case 0xB: /* 8-bit + postindex */
2534 offset = i8;
2535 postind = TRUE;
2536 break;
2538 case 0x9: /* 8-bit - postindex */
2539 offset = -i8;
2540 postind = TRUE;
2541 break;
2543 default:
2544 func (stream, ", <undefined>]");
2545 goto skip;
2548 if (postind)
2549 func (stream, "], #%d", offset);
2550 else
2552 if (offset)
2553 func (stream, ", #%d", offset);
2554 func (stream, writeback ? "]!" : "]");
2557 if (Rn == 15)
2559 func (stream, "\t; ");
2560 info->print_address_func (((pc + 4) & ~3) + offset, info);
2563 skip:
2564 break;
2566 case 'A':
2568 unsigned int P = (given & 0x01000000) >> 24;
2569 unsigned int U = (given & 0x00800000) >> 23;
2570 unsigned int W = (given & 0x00400000) >> 21;
2571 unsigned int Rn = (given & 0x000f0000) >> 16;
2572 unsigned int off = (given & 0x000000ff);
2574 func (stream, "[%s", arm_regnames[Rn]);
2575 if (P)
2577 if (off || !U)
2578 func (stream, ", #%c%u", U ? '+' : '-', off * 4);
2579 func (stream, "]");
2580 if (W)
2581 func (stream, "!");
2583 else
2585 func (stream, "], ");
2586 if (W)
2587 func (stream, "#%c%u", U ? '+' : '-', off * 4);
2588 else
2589 func (stream, "{%u}", off);
2592 break;
2594 case 'w':
2596 unsigned int Sbit = (given & 0x01000000) >> 24;
2597 unsigned int type = (given & 0x00600000) >> 21;
2598 switch (type)
2600 case 0: func (stream, Sbit ? "sb" : "b"); break;
2601 case 1: func (stream, Sbit ? "sh" : "h"); break;
2602 case 2:
2603 if (Sbit)
2604 func (stream, "??");
2605 break;
2606 case 3:
2607 func (stream, "??");
2608 break;
2611 break;
2613 case 'm':
2615 int started = 0;
2616 int reg;
2618 func (stream, "{");
2619 for (reg = 0; reg < 16; reg++)
2620 if ((given & (1 << reg)) != 0)
2622 if (started)
2623 func (stream, ", ");
2624 started = 1;
2625 func (stream, "%s", arm_regnames[reg]);
2627 func (stream, "}");
2629 break;
2631 case 'E':
2633 unsigned int msb = (given & 0x0000001f);
2634 unsigned int lsb = 0;
2635 lsb |= (given & 0x000000c0u) >> 6;
2636 lsb |= (given & 0x00007000u) >> 10;
2637 func (stream, "#%u, #%u", lsb, msb - lsb + 1);
2639 break;
2641 case 'F':
2643 unsigned int width = (given & 0x0000001f) + 1;
2644 unsigned int lsb = 0;
2645 lsb |= (given & 0x000000c0u) >> 6;
2646 lsb |= (given & 0x00007000u) >> 10;
2647 func (stream, "#%u, #%u", lsb, width);
2649 break;
2651 case 'b':
2653 unsigned int S = (given & 0x04000000u) >> 26;
2654 unsigned int J1 = (given & 0x00002000u) >> 13;
2655 unsigned int J2 = (given & 0x00000800u) >> 11;
2656 int offset = 0;
2658 offset |= !S << 20;
2659 offset |= J2 << 19;
2660 offset |= J1 << 18;
2661 offset |= (given & 0x003f0000) >> 4;
2662 offset |= (given & 0x000007ff) << 1;
2663 offset -= (1 << 20);
2665 info->print_address_func (pc + 4 + offset, info);
2667 break;
2669 case 'B':
2671 unsigned int S = (given & 0x04000000u) >> 26;
2672 unsigned int I1 = (given & 0x00002000u) >> 13;
2673 unsigned int I2 = (given & 0x00000800u) >> 11;
2674 int offset = 0;
2676 offset |= !S << 24;
2677 offset |= !(I1 ^ S) << 23;
2678 offset |= !(I2 ^ S) << 22;
2679 offset |= (given & 0x03ff0000u) >> 4;
2680 offset |= (given & 0x000007ffu) << 1;
2681 offset -= (1 << 24);
2682 offset += pc + 4;
2684 /* BLX target addresses are always word aligned. */
2685 if ((given & 0x00001000u) == 0)
2686 offset &= ~2u;
2688 info->print_address_func (offset, info);
2690 break;
2692 case 's':
2694 unsigned int shift = 0;
2695 shift |= (given & 0x000000c0u) >> 6;
2696 shift |= (given & 0x00007000u) >> 10;
2697 if (given & 0x00200000u)
2698 func (stream, ", asr #%u", shift);
2699 else if (shift)
2700 func (stream, ", lsl #%u", shift);
2701 /* else print nothing - lsl #0 */
2703 break;
2705 case 'R':
2707 unsigned int rot = (given & 0x00000030) >> 4;
2708 if (rot)
2709 func (stream, ", ror #%u", rot * 8);
2711 break;
2713 case 'U':
2714 switch (given & 0xf)
2716 case 0xf: func(stream, "sy"); break;
2717 case 0x7: func(stream, "un"); break;
2718 case 0xe: func(stream, "st"); break;
2719 case 0x6: func(stream, "unst"); break;
2720 default:
2721 func(stream, "#%d", (int)given & 0xf);
2722 break;
2724 break;
2726 case 'C':
2727 if ((given & 0xff) == 0)
2729 func (stream, "%cPSR_", (given & 0x100000) ? 'S' : 'C');
2730 if (given & 0x800)
2731 func (stream, "f");
2732 if (given & 0x400)
2733 func (stream, "s");
2734 if (given & 0x200)
2735 func (stream, "x");
2736 if (given & 0x100)
2737 func (stream, "c");
2739 else
2741 func (stream, psr_name (given & 0xff));
2743 break;
2745 case 'D':
2746 if ((given & 0xff) == 0)
2747 func (stream, "%cPSR", (given & 0x100000) ? 'S' : 'C');
2748 else
2749 func (stream, psr_name (given & 0xff));
2750 break;
2752 case '0': case '1': case '2': case '3': case '4':
2753 case '5': case '6': case '7': case '8': case '9':
2755 int bitstart = *c++ - '0';
2756 int bitend = 0;
2757 unsigned int val;
2758 while (*c >= '0' && *c <= '9')
2759 bitstart = (bitstart * 10) + *c++ - '0';
2761 if (*c == '-')
2763 c++;
2764 while (*c >= '0' && *c <= '9')
2765 bitend = (bitend * 10) + *c++ - '0';
2766 if (!bitend)
2767 abort ();
2769 val = given >> bitstart;
2770 val &= (2 << (bitend - bitstart)) - 1;
2772 else
2773 val = (given >> bitstart) & 1;
2775 switch (*c)
2777 case 'd': func (stream, "%u", val); break;
2778 case 'W': func (stream, "%u", val * 4); break;
2779 case 'r': func (stream, "%s", arm_regnames[val]); break;
2781 case 'c':
2782 if (val == 0xE)
2783 func (stream, "al");
2784 else
2785 func (stream, "%s", arm_conditional[val]);
2786 break;
2788 case '\'':
2789 if (val)
2790 func (stream, "%c", c[1]);
2791 c++;
2792 break;
2794 case '`':
2795 if (!val)
2796 func (stream, "%c", c[1]);
2797 c++;
2798 break;
2800 case '?':
2801 func (stream, "%c", val ? c[1] : c[2]);
2802 c += 2;
2803 break;
2805 default:
2806 abort ();
2809 break;
2811 default:
2812 abort ();
2815 return;
2818 /* No match. */
2819 abort ();
2822 /* Disallow mapping symbols ($a, $b, $d, $t etc) from
2823 being displayed in symbol relative addresses. */
2825 bfd_boolean
2826 arm_symbol_is_valid (asymbol * sym,
2827 struct disassemble_info * info ATTRIBUTE_UNUSED)
2829 const char * name;
2831 if (sym == NULL)
2832 return FALSE;
2834 name = bfd_asymbol_name (sym);
2836 return (name && *name != '$');
2839 /* Parse an individual disassembler option. */
2841 void
2842 parse_arm_disassembler_option (char *option)
2844 if (option == NULL)
2845 return;
2847 if (strneq (option, "reg-names-", 10))
2849 int i;
2851 option += 10;
2853 for (i = NUM_ARM_REGNAMES; i--;)
2854 if (strneq (option, regnames[i].name, strlen (regnames[i].name)))
2856 regname_selected = i;
2857 break;
2860 if (i < 0)
2861 /* XXX - should break 'option' at following delimiter. */
2862 fprintf (stderr, _("Unrecognised register name set: %s\n"), option);
2864 else if (strneq (option, "force-thumb", 11))
2865 force_thumb = 1;
2866 else if (strneq (option, "no-force-thumb", 14))
2867 force_thumb = 0;
2868 else
2869 /* XXX - should break 'option' at following delimiter. */
2870 fprintf (stderr, _("Unrecognised disassembler option: %s\n"), option);
2872 return;
2875 /* Parse the string of disassembler options, spliting it at whitespaces
2876 or commas. (Whitespace separators supported for backwards compatibility). */
2878 static void
2879 parse_disassembler_options (char *options)
2881 if (options == NULL)
2882 return;
2884 while (*options)
2886 parse_arm_disassembler_option (options);
2888 /* Skip forward to next seperator. */
2889 while ((*options) && (! ISSPACE (*options)) && (*options != ','))
2890 ++ options;
2891 /* Skip forward past seperators. */
2892 while (ISSPACE (*options) || (*options == ','))
2893 ++ options;
2897 /* NOTE: There are no checks in these routines that
2898 the relevant number of data bytes exist. */
2900 static int
2901 print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
2903 unsigned char b[4];
2904 long given;
2905 int status;
2906 int is_thumb;
2907 int size;
2908 void (*printer) (bfd_vma, struct disassemble_info *, long);
2910 if (info->disassembler_options)
2912 parse_disassembler_options (info->disassembler_options);
2914 /* To avoid repeated parsing of these options, we remove them here. */
2915 info->disassembler_options = NULL;
2918 is_thumb = force_thumb;
2920 if (!is_thumb && info->symbols != NULL)
2922 if (bfd_asymbol_flavour (*info->symbols) == bfd_target_coff_flavour)
2924 coff_symbol_type * cs;
2926 cs = coffsymbol (*info->symbols);
2927 is_thumb = ( cs->native->u.syment.n_sclass == C_THUMBEXT
2928 || cs->native->u.syment.n_sclass == C_THUMBSTAT
2929 || cs->native->u.syment.n_sclass == C_THUMBLABEL
2930 || cs->native->u.syment.n_sclass == C_THUMBEXTFUNC
2931 || cs->native->u.syment.n_sclass == C_THUMBSTATFUNC);
2933 else if (bfd_asymbol_flavour (*info->symbols) == bfd_target_elf_flavour)
2935 elf_symbol_type * es;
2936 unsigned int type;
2938 es = *(elf_symbol_type **)(info->symbols);
2939 type = ELF_ST_TYPE (es->internal_elf_sym.st_info);
2941 is_thumb = (type == STT_ARM_TFUNC) || (type == STT_ARM_16BIT);
2945 info->display_endian = little ? BFD_ENDIAN_LITTLE : BFD_ENDIAN_BIG;
2946 info->bytes_per_line = 4;
2948 if (!is_thumb)
2950 /* In ARM mode endianness is a straightforward issue: the instruction
2951 is four bytes long and is either ordered 0123 or 3210. */
2952 printer = print_insn_arm;
2953 info->bytes_per_chunk = 4;
2954 size = 4;
2956 status = info->read_memory_func (pc, (bfd_byte *)b, 4, info);
2957 if (little)
2958 given = (b[0]) | (b[1] << 8) | (b[2] << 16) | (b[3] << 24);
2959 else
2960 given = (b[3]) | (b[2] << 8) | (b[1] << 16) | (b[0] << 24);
2962 else
2964 /* In Thumb mode we have the additional wrinkle of two
2965 instruction lengths. Fortunately, the bits that determine
2966 the length of the current instruction are always to be found
2967 in the first two bytes. */
2968 printer = print_insn_thumb16;
2969 info->bytes_per_chunk = 2;
2970 size = 2;
2972 status = info->read_memory_func (pc, (bfd_byte *)b, 2, info);
2973 if (little)
2974 given = (b[0]) | (b[1] << 8);
2975 else
2976 given = (b[1]) | (b[0] << 8);
2978 if (!status)
2980 /* These bit patterns signal a four-byte Thumb
2981 instruction. */
2982 if ((given & 0xF800) == 0xF800
2983 || (given & 0xF800) == 0xF000
2984 || (given & 0xF800) == 0xE800)
2986 status = info->read_memory_func (pc + 2, (bfd_byte *)b, 2, info);
2987 if (little)
2988 given = (b[0]) | (b[1] << 8) | (given << 16);
2989 else
2990 given = (b[1]) | (b[0] << 8) | (given << 16);
2992 printer = print_insn_thumb32;
2993 size = 4;
2998 if (status)
3000 info->memory_error_func (status, pc, info);
3001 return -1;
3003 if (info->flags & INSN_HAS_RELOC)
3004 /* If the instruction has a reloc associated with it, then
3005 the offset field in the instruction will actually be the
3006 addend for the reloc. (We are using REL type relocs).
3007 In such cases, we can ignore the pc when computing
3008 addresses, since the addend is not currently pc-relative. */
3009 pc = 0;
3011 printer (pc, info, given);
3012 return size;
3016 print_insn_big_arm (bfd_vma pc, struct disassemble_info *info)
3018 return print_insn (pc, info, FALSE);
3022 print_insn_little_arm (bfd_vma pc, struct disassemble_info *info)
3024 return print_insn (pc, info, TRUE);
3027 void
3028 print_arm_disassembler_options (FILE *stream)
3030 int i;
3032 fprintf (stream, _("\n\
3033 The following ARM specific disassembler options are supported for use with\n\
3034 the -M switch:\n"));
3036 for (i = NUM_ARM_REGNAMES; i--;)
3037 fprintf (stream, " reg-names-%s %*c%s\n",
3038 regnames[i].name,
3039 (int)(14 - strlen (regnames[i].name)), ' ',
3040 regnames[i].description);
3042 fprintf (stream, " force-thumb Assume all insns are Thumb insns\n");
3043 fprintf (stream, " no-force-thumb Examine preceeding label to determine an insn's type\n\n");