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