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