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